From 006a7c71855f6736631d54804bc81229b6c5fd56 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Thu, 17 Aug 2023 19:10:27 +0000 Subject: [PATCH] backport of commit a10c94df5629a3704959f961cf53785ea7232663 --- .changelog/17107.txt | 3 - .changelog/17155.txt | 3 - .changelog/17481.txt | 3 - .changelog/17593.txt | 3 - .changelog/17694.txt | 3 - .changelog/17754.txt | 4 +- .changelog/17831.txt | 3 - .changelog/17936.txt | 3 - .changelog/18007.txt | 3 - .changelog/18300.txt | 3 - .changelog/18303.txt | 3 + .changelog/18324.txt | 3 - .changelog/18336.txt | 7 - .changelog/18367.txt | 3 - .changelog/18439.txt | 3 - .changelog/18504.txt | 3 - .changelog/18560.txt | 3 - .changelog/18573.txt | 3 - .changelog/18583.txt | 3 - .changelog/18646.txt | 3 - .changelog/18668.txt | 3 - .changelog/18708.txt | 7 - .changelog/18719.txt | 7 - .changelog/18769.txt | 3 - .changelog/18813.txt | 3 - .changelog/18816.txt | 3 - .changelog/18943.txt | 3 - .changelog/18983.txt | 3 - .changelog/18994.txt | 26 - .changelog/19077.txt | 3 - .changelog/19120.txt | 3 + .changelog/19218.txt | 3 - .changelog/19273.txt | 3 + .changelog/19306.txt | 3 - .changelog/19311.txt | 3 - .changelog/19314.txt | 3 - .changelog/19389.txt | 3 - .changelog/_18366.txt | 3 - .changelog/_18422.txt | 3 - .changelog/_6074.txt | 3 - .changelog/_6870.txt | 3 - .copywrite.hcl | 14 +- .github/ISSUE_TEMPLATE/config.yml | 2 +- .github/dependabot.yml | 2 +- .github/pr-labeler.yml | 2 +- .github/scripts/changelog_checker.sh | 2 +- .github/scripts/get_runner_classes.sh | 2 +- .github/scripts/get_runner_classes_windows.sh | 26 - .github/scripts/metrics_checker.sh | 2 +- .github/scripts/notify_slack.sh | 7 +- .github/scripts/rerun_fails_report.sh | 2 +- .github/scripts/set_test_package_matrix.sh | 2 +- .github/scripts/verify_artifact.sh | 2 +- .github/scripts/verify_bin.sh | 2 +- .github/scripts/verify_deb.sh | 2 +- .github/scripts/verify_docker.sh | 2 +- .github/scripts/verify_envoy_version.sh | 11 +- .github/scripts/verify_rpm.sh | 2 +- .github/workflows/bot-auto-approve.yaml | 2 +- .github/workflows/broken-link-check.yml | 6 +- .github/workflows/build-artifacts.yml | 14 +- .github/workflows/build-distros.yml | 14 +- .github/workflows/build.yml | 40 +- .github/workflows/ce-merge-trigger.yml | 2 +- .github/workflows/changelog-checker.yml | 2 +- .github/workflows/embedded-asset-checker.yml | 2 +- .github/workflows/frontend.yml | 30 +- .github/workflows/go-tests.yml | 56 +- .github/workflows/issue-comment-created.yml | 4 +- .github/workflows/jira-issues.yaml | 14 +- .github/workflows/jira-pr.yaml | 14 +- ...t-1.16.x.yaml => nightly-test-1.12.x.yaml} | 45 +- ...t-1.17.x.yaml => nightly-test-1.13.x.yaml} | 57 +- .github/workflows/nightly-test-1.14.x.yaml | 43 +- .github/workflows/nightly-test-1.15.x.yaml | 43 +- .../nightly-test-integrations-1.15.x.yml | 320 -- .../nightly-test-integrations-1.16.x.yml | 342 -- .../nightly-test-integrations-1.17.x.yml | 342 -- .../workflows/nightly-test-integrations.yml | 127 +- .github/workflows/nightly-test-main.yaml | 55 +- .github/workflows/pr-labeler.yml | 2 +- .github/workflows/pr-metrics-test-checker.yml | 2 +- .github/workflows/reusable-check-go-mod.yml | 4 +- .../workflows/reusable-dev-build-windows.yml | 47 - .github/workflows/reusable-dev-build.yml | 14 +- .github/workflows/reusable-lint.yml | 9 +- .github/workflows/reusable-unit-split.yml | 21 +- .github/workflows/reusable-unit.yml | 12 +- .github/workflows/stale.yml | 2 +- .../workflows/test-integrations-windows.yml | 1211 ----- .github/workflows/test-integrations.yml | 139 +- .github/workflows/verify-envoy-version.yml | 6 +- .gitignore | 2 - .golangci.yml | 7 +- .release/ci.hcl | 2 +- .release/docker/docker-entrypoint-ubi.sh | 2 +- .release/docker/docker-entrypoint-windows.sh | 85 - .release/docker/docker-entrypoint.sh | 2 +- .../linux/package/etc/consul.d/consul.hcl | 2 +- .release/release-metadata.hcl | 2 +- .release/security-scan.hcl | 2 +- CHANGELOG.md | 229 - Dockerfile | 2 +- Dockerfile-windows | 51 - Makefile => GNUmakefile | 443 +- LICENSE | 417 +- NOTICE.md | 3 + README.md | 6 +- acl/MockAuthorizer.go | 45 +- acl/acl.go | 2 +- acl/acl_ce.go | 3 +- acl/acl_test.go | 225 +- acl/authorizer.go | 92 +- acl/authorizer_ce.go | 3 +- acl/authorizer_test.go | 30 +- acl/chained_authorizer.go | 52 +- acl/chained_authorizer_test.go | 23 +- acl/enterprisemeta_ce.go | 3 +- acl/errors.go | 2 +- acl/errors_ce.go | 3 +- acl/errors_test.go | 2 +- acl/policy.go | 41 +- acl/policy_authorizer.go | 181 +- acl/policy_authorizer_ce.go | 3 +- acl/policy_authorizer_test.go | 268 +- acl/policy_ce.go | 3 +- acl/policy_merger.go | 52 +- acl/policy_merger_ce.go | 3 +- acl/policy_test.go | 178 +- acl/resolver/danger.go | 10 +- acl/resolver/result.go | 2 +- acl/static_authorizer.go | 51 +- acl/static_authorizer_test.go | 2 +- acl/testing.go | 2 +- acl/validation.go | 2 +- acl/validation_test.go | 2 +- agent/acl.go | 2 +- agent/acl_ce.go | 3 +- agent/acl_endpoint.go | 143 +- agent/acl_endpoint_test.go | 109 +- agent/acl_test.go | 6 +- agent/ae/ae.go | 29 +- agent/ae/ae_test.go | 2 +- agent/ae/trigger.go | 2 +- agent/agent.go | 109 +- agent/agent_ce.go | 3 +- agent/agent_ce_test.go | 3 +- agent/agent_endpoint.go | 116 +- agent/agent_endpoint_ce.go | 3 +- agent/agent_endpoint_ce_test.go | 3 +- agent/agent_endpoint_test.go | 81 +- agent/agent_test.go | 25 +- agent/apiserver.go | 2 +- agent/apiserver_test.go | 2 +- agent/auto-config/auto_config.go | 2 +- agent/auto-config/auto_config_ce.go | 3 +- agent/auto-config/auto_config_ce_test.go | 3 +- agent/auto-config/auto_config_test.go | 2 +- agent/auto-config/auto_encrypt.go | 2 +- agent/auto-config/auto_encrypt_test.go | 2 +- agent/auto-config/config.go | 2 +- agent/auto-config/config_ce.go | 3 +- agent/auto-config/config_translate.go | 2 +- agent/auto-config/config_translate_test.go | 2 +- agent/auto-config/mock_ce_test.go | 3 +- agent/auto-config/mock_test.go | 2 +- agent/auto-config/persist.go | 2 +- agent/auto-config/run.go | 2 +- agent/auto-config/server_addr.go | 2 +- agent/auto-config/tls.go | 2 +- agent/auto-config/tls_test.go | 2 +- agent/blockingquery/blockingquery.go | 3 - agent/blockingquery/blockingquery_test.go | 3 - agent/cache-types/catalog_datacenters.go | 2 +- agent/cache-types/catalog_datacenters_test.go | 2 +- agent/cache-types/catalog_list_services.go | 2 +- .../cache-types/catalog_list_services_test.go | 2 +- agent/cache-types/catalog_service_list.go | 2 +- .../cache-types/catalog_service_list_test.go | 2 +- agent/cache-types/catalog_services.go | 2 +- agent/cache-types/catalog_services_test.go | 2 +- agent/cache-types/config_entry.go | 2 +- agent/cache-types/config_entry_test.go | 2 +- agent/cache-types/connect_ca_root.go | 5 +- agent/cache-types/connect_ca_root_test.go | 2 +- agent/cache-types/discovery_chain.go | 2 +- agent/cache-types/discovery_chain_test.go | 2 +- agent/cache-types/exported_peered_services.go | 2 +- .../exported_peered_services_test.go | 2 +- .../federation_state_list_gateways.go | 2 +- .../federation_state_list_gateways_test.go | 2 +- agent/cache-types/gateway_services.go | 2 +- agent/cache-types/gateway_services_test.go | 2 +- agent/cache-types/health_services.go | 2 +- agent/cache-types/health_services_test.go | 2 +- agent/cache-types/intention_match.go | 2 +- agent/cache-types/intention_match_test.go | 2 +- agent/cache-types/intention_upstreams.go | 2 +- .../intention_upstreams_destination.go | 2 +- .../intention_upstreams_destination_test.go | 2 +- agent/cache-types/intention_upstreams_test.go | 2 +- agent/cache-types/node_services.go | 2 +- agent/cache-types/node_services_test.go | 2 +- agent/cache-types/options.go | 2 +- agent/cache-types/peered_upstreams.go | 2 +- agent/cache-types/peered_upstreams_test.go | 2 +- agent/cache-types/peerings.go | 2 +- agent/cache-types/peerings_test.go | 2 +- agent/cache-types/prepared_query.go | 2 +- agent/cache-types/prepared_query_test.go | 2 +- agent/cache-types/resolved_service_config.go | 2 +- .../resolved_service_config_test.go | 2 +- agent/cache-types/rpc.go | 2 +- agent/cache-types/service_checks.go | 2 +- agent/cache-types/service_checks_test.go | 2 +- agent/cache-types/service_dump.go | 2 +- agent/cache-types/service_dump_test.go | 2 +- agent/cache-types/service_gateways.go | 2 +- agent/cache-types/service_gateways_test.go | 2 +- agent/cache-types/testing.go | 2 +- agent/cache-types/trust_bundle.go | 2 +- agent/cache-types/trust_bundle_test.go | 2 +- agent/cache-types/trust_bundles.go | 2 +- agent/cache-types/trust_bundles_test.go | 2 +- agent/cache/cache.go | 30 +- agent/cache/cache_test.go | 2 +- agent/cache/entry.go | 2 +- agent/cache/request.go | 60 +- agent/cache/testing.go | 2 +- agent/cache/type.go | 2 +- agent/cache/watch.go | 25 +- agent/cache/watch_test.go | 2 +- agent/cacheshim/cache.go | 118 - agent/catalog_endpoint.go | 2 +- agent/catalog_endpoint_ce.go | 3 +- agent/catalog_endpoint_test.go | 52 +- agent/check.go | 2 +- agent/checks/alias.go | 2 +- agent/checks/alias_test.go | 2 +- agent/checks/check.go | 2 +- agent/checks/check_test.go | 2 +- agent/checks/check_windows_test.go | 3 +- agent/checks/docker.go | 2 +- agent/checks/docker_unix.go | 3 +- agent/checks/docker_windows.go | 2 +- agent/checks/grpc.go | 2 +- agent/checks/grpc_test.go | 2 +- agent/checks/os_service.go | 2 +- agent/checks/os_service_unix.go | 3 +- agent/checks/os_service_windows.go | 3 +- agent/config/agent_limits.go | 2 +- agent/config/builder.go | 35 +- agent/config/builder_ce.go | 3 +- agent/config/builder_ce_test.go | 3 +- agent/config/builder_test.go | 71 +- agent/config/config.deepcopy.go | 3 - agent/config/config.go | 3 +- agent/config/config_ce.go | 3 +- agent/config/deep-copy.sh | 2 - agent/config/default.go | 7 +- agent/config/default_ce.go | 3 +- agent/config/deprecated.go | 2 +- agent/config/deprecated_test.go | 2 +- agent/config/doc.go | 2 +- agent/config/file_watcher.go | 2 +- agent/config/file_watcher_test.go | 2 +- agent/config/flags.go | 2 +- agent/config/flags_test.go | 2 +- agent/config/flagset.go | 2 +- agent/config/golden_test.go | 2 +- agent/config/limits.go | 3 +- agent/config/limits_windows.go | 3 +- agent/config/merge.go | 2 +- agent/config/merge_test.go | 2 +- agent/config/ratelimited_file_watcher.go | 2 +- agent/config/ratelimited_file_watcher_test.go | 2 +- agent/config/runtime.go | 2 +- agent/config/runtime_ce.go | 3 +- agent/config/runtime_ce_test.go | 3 +- agent/config/runtime_test.go | 142 +- agent/config/segment_ce.go | 3 +- agent/config/segment_ce_test.go | 3 +- .../TestRuntimeConfig_Sanitize.golden | 1 - agent/config/testdata/full-config.hcl | 2 +- agent/config_endpoint.go | 2 +- agent/config_endpoint_test.go | 19 +- agent/configentry/compare.go | 3 - agent/configentry/compare_test.go | 3 - agent/configentry/config_entry.go | 2 +- agent/configentry/discoverychain.go | 2 +- agent/configentry/doc.go | 2 +- agent/configentry/merge_service_config.go | 32 +- .../configentry/merge_service_config_test.go | 110 +- agent/configentry/resolve.go | 5 +- agent/configentry/resolve_test.go | 2 +- agent/configentry/service_config.go | 2 +- agent/connect/authz.go | 2 +- agent/connect/authz_test.go | 2 +- agent/connect/ca/common.go | 2 +- agent/connect/ca/provider.go | 4 +- agent/connect/ca/provider_aws.go | 2 +- agent/connect/ca/provider_aws_test.go | 2 +- agent/connect/ca/provider_consul.go | 2 +- agent/connect/ca/provider_consul_config.go | 2 +- agent/connect/ca/provider_consul_test.go | 2 +- agent/connect/ca/provider_test.go | 4 +- agent/connect/ca/provider_vault.go | 16 +- agent/connect/ca/provider_vault_auth.go | 2 +- .../ca/provider_vault_auth_alicloud.go | 2 +- .../connect/ca/provider_vault_auth_approle.go | 2 +- agent/connect/ca/provider_vault_auth_aws.go | 2 +- agent/connect/ca/provider_vault_auth_azure.go | 2 +- agent/connect/ca/provider_vault_auth_gcp.go | 2 +- agent/connect/ca/provider_vault_auth_jwt.go | 2 +- agent/connect/ca/provider_vault_auth_k8s.go | 2 +- agent/connect/ca/provider_vault_auth_test.go | 2 +- agent/connect/ca/provider_vault_test.go | 31 +- agent/connect/ca/testing.go | 2 +- agent/connect/common_names.go | 2 +- agent/connect/csr.go | 2 +- agent/connect/csr_test.go | 2 +- agent/connect/generate.go | 2 +- agent/connect/generate_test.go | 2 +- agent/connect/parsing.go | 4 +- agent/connect/sni.go | 2 +- agent/connect/sni_test.go | 2 +- agent/connect/testing_ca.go | 2 +- agent/connect/testing_ca_test.go | 2 +- agent/connect/testing_spiffe.go | 2 +- agent/connect/uri.go | 30 +- agent/connect/uri_agent.go | 2 +- agent/connect/uri_agent_ce.go | 3 +- agent/connect/uri_agent_ce_test.go | 3 +- agent/connect/uri_mesh_gateway.go | 2 +- agent/connect/uri_mesh_gateway_ce.go | 3 +- agent/connect/uri_mesh_gateway_ce_test.go | 3 +- agent/connect/uri_server.go | 2 +- agent/connect/uri_service.go | 14 +- agent/connect/uri_service_ce.go | 3 +- agent/connect/uri_service_ce_test.go | 3 +- agent/connect/uri_signing.go | 12 +- agent/connect/uri_signing_test.go | 26 +- agent/connect/uri_test.go | 57 +- agent/connect/uri_workload_identity.go | 46 - agent/connect/uri_workload_identity_ce.go | 30 - .../connect/uri_workload_identity_ce_test.go | 40 - agent/connect/x509_patch.go | 2 +- agent/connect/x509_patch_test.go | 2 +- agent/connect_auth.go | 143 + agent/connect_ca_endpoint.go | 2 +- agent/connect_ca_endpoint_test.go | 2 +- agent/consul/acl.go | 42 +- agent/consul/acl_authmethod.go | 2 +- agent/consul/acl_authmethod_ce.go | 3 +- agent/consul/acl_ce.go | 3 +- agent/consul/acl_ce_test.go | 3 +- agent/consul/acl_client.go | 2 +- agent/consul/acl_endpoint.go | 60 +- agent/consul/acl_endpoint_ce.go | 3 +- agent/consul/acl_endpoint_test.go | 148 +- agent/consul/acl_replication.go | 2 +- agent/consul/acl_replication_test.go | 2 +- agent/consul/acl_replication_types.go | 2 +- agent/consul/acl_server.go | 2 +- agent/consul/acl_server_ce.go | 3 +- agent/consul/acl_test.go | 89 +- agent/consul/acl_token_exp.go | 2 +- agent/consul/acl_token_exp_test.go | 2 +- agent/consul/auth/binder.go | 149 +- agent/consul/auth/binder_ce.go | 3 +- agent/consul/auth/binder_test.go | 88 +- agent/consul/auth/login.go | 3 +- agent/consul/auth/token_writer.go | 37 +- agent/consul/auth/token_writer_ce.go | 3 +- agent/consul/auth/token_writer_test.go | 56 +- agent/consul/authmethod/authmethods.go | 2 +- agent/consul/authmethod/authmethods_ce.go | 3 +- agent/consul/authmethod/awsauth/aws.go | 2 +- agent/consul/authmethod/awsauth/aws_test.go | 2 +- agent/consul/authmethod/kubeauth/k8s.go | 2 +- agent/consul/authmethod/kubeauth/k8s_ce.go | 3 +- agent/consul/authmethod/kubeauth/k8s_test.go | 2 +- agent/consul/authmethod/kubeauth/testing.go | 2 +- agent/consul/authmethod/ssoauth/sso.go | 2 +- agent/consul/authmethod/ssoauth/sso_ce.go | 3 +- agent/consul/authmethod/ssoauth/sso_test.go | 2 +- agent/consul/authmethod/testauth/testing.go | 2 +- .../consul/authmethod/testauth/testing_ce.go | 3 +- agent/consul/authmethod/testing.go | 2 +- agent/consul/auto_config_backend.go | 4 +- agent/consul/auto_config_backend_test.go | 2 +- agent/consul/auto_config_endpoint.go | 2 +- agent/consul/auto_config_endpoint_test.go | 2 +- agent/consul/auto_encrypt_endpoint.go | 2 +- agent/consul/auto_encrypt_endpoint_test.go | 2 +- agent/consul/autopilot.go | 2 +- agent/consul/autopilot_ce.go | 3 +- agent/consul/autopilot_test.go | 2 +- .../autopilotevents/ready_servers_events.go | 2 +- .../ready_servers_events_test.go | 2 +- agent/consul/catalog_endpoint.go | 2 +- agent/consul/catalog_endpoint_test.go | 2 +- agent/consul/client.go | 17 +- agent/consul/client_serf.go | 2 +- agent/consul/client_test.go | 12 +- agent/consul/cluster_test.go | 2 +- agent/consul/config.go | 7 +- agent/consul/config_ce.go | 3 +- agent/consul/config_cloud.go | 3 - agent/consul/config_endpoint.go | 2 +- agent/consul/config_endpoint_test.go | 2 +- agent/consul/config_replication.go | 2 +- agent/consul/config_replication_test.go | 2 +- agent/consul/config_test.go | 2 +- agent/consul/connect_ca_endpoint.go | 12 +- agent/consul/connect_ca_endpoint_test.go | 2 +- agent/consul/context.go | 2 +- agent/consul/context_test.go | 2 +- agent/consul/controller/controller.go | 2 +- agent/consul/controller/controller_test.go | 2 +- agent/consul/controller/doc.go | 2 +- agent/consul/controller/queue/defer.go | 2 +- agent/consul/controller/queue/queue.go | 2 +- agent/consul/controller/queue/rate.go | 2 +- agent/consul/controller/queue/rate_test.go | 2 +- agent/consul/controller/queue_test.go | 2 +- agent/consul/controller/reconciler.go | 2 +- agent/consul/controller/reconciler_test.go | 2 +- agent/consul/coordinate_endpoint.go | 2 +- agent/consul/coordinate_endpoint_test.go | 2 +- agent/consul/discovery_chain_endpoint.go | 2 +- agent/consul/discovery_chain_endpoint_test.go | 2 +- agent/consul/discoverychain/compile.go | 2 +- agent/consul/discoverychain/compile_ce.go | 3 +- agent/consul/discoverychain/compile_test.go | 2 +- agent/consul/discoverychain/gateway.go | 23 +- .../discoverychain/gateway_httproute.go | 51 +- .../consul/discoverychain/gateway_tcproute.go | 2 +- agent/consul/discoverychain/gateway_test.go | 108 +- agent/consul/discoverychain/string_stack.go | 2 +- .../discoverychain/string_stack_test.go | 2 +- agent/consul/discoverychain/testing.go | 2 +- agent/consul/enterprise_client_ce.go | 3 +- agent/consul/enterprise_config_ce.go | 3 +- agent/consul/enterprise_server_ce.go | 3 +- agent/consul/enterprise_server_ce_test.go | 3 +- agent/consul/federation_state_endpoint.go | 2 +- .../consul/federation_state_endpoint_test.go | 2 +- agent/consul/federation_state_replication.go | 2 +- .../federation_state_replication_test.go | 2 +- agent/consul/filter.go | 2 +- agent/consul/filter_test.go | 2 +- agent/consul/flood.go | 2 +- agent/consul/fsm/commands_ce.go | 91 +- agent/consul/fsm/commands_ce_test.go | 2 +- agent/consul/fsm/decode_ce.go | 145 - agent/consul/fsm/decode_downgrade.go | 1011 ---- agent/consul/fsm/fsm.go | 11 +- agent/consul/fsm/fsm_test.go | 2 +- .../fsm/log_verification_chunking_shim.go | 2 +- agent/consul/fsm/snapshot.go | 2 +- agent/consul/fsm/snapshot_ce.go | 2 +- agent/consul/fsm/snapshot_ce_test.go | 3 +- agent/consul/fsm/snapshot_test.go | 2 +- agent/consul/gateway_locator.go | 2 +- agent/consul/gateway_locator_test.go | 2 +- agent/consul/gateways/controller_gateways.go | 104 +- .../consul/gateways/controller_gateways_ce.go | 26 - .../gateways/controller_gateways_test.go | 28 +- agent/consul/grpc_integration_test.go | 2 +- agent/consul/health_endpoint.go | 2 +- agent/consul/health_endpoint_test.go | 2 +- agent/consul/helper_test.go | 2 +- agent/consul/intention_endpoint.go | 2 +- agent/consul/intention_endpoint_test.go | 2 +- agent/consul/internal_endpoint.go | 2 +- agent/consul/internal_endpoint_test.go | 2 +- agent/consul/issue_test.go | 2 +- agent/consul/kvs_endpoint.go | 2 +- agent/consul/kvs_endpoint_test.go | 2 +- agent/consul/leader.go | 2 +- agent/consul/leader_ce_test.go | 3 +- agent/consul/leader_connect.go | 2 +- agent/consul/leader_connect_ca.go | 20 +- agent/consul/leader_connect_ca_test.go | 19 +- agent/consul/leader_connect_test.go | 2 +- agent/consul/leader_federation_state_ae.go | 2 +- .../consul/leader_federation_state_ae_test.go | 2 +- agent/consul/leader_intentions.go | 2 +- agent/consul/leader_intentions_ce.go | 3 +- agent/consul/leader_intentions_ce_test.go | 3 +- agent/consul/leader_intentions_test.go | 2 +- agent/consul/leader_log_verification.go | 2 +- agent/consul/leader_metrics.go | 2 +- agent/consul/leader_metrics_test.go | 2 +- agent/consul/leader_peering.go | 2 +- agent/consul/leader_peering_test.go | 2 +- agent/consul/leader_test.go | 4 +- agent/consul/logging.go | 2 +- agent/consul/logging_test.go | 2 +- agent/consul/merge.go | 2 +- agent/consul/merge_ce.go | 3 +- agent/consul/merge_ce_test.go | 3 +- agent/consul/merge_test.go | 2 +- agent/consul/multilimiter/multilimiter.go | 2 +- .../consul/multilimiter/multilimiter_test.go | 2 +- agent/consul/operator_autopilot_endpoint.go | 2 +- .../operator_autopilot_endpoint_test.go | 2 +- agent/consul/operator_backend.go | 2 +- agent/consul/operator_backend_test.go | 2 +- agent/consul/operator_endpoint.go | 2 +- agent/consul/operator_raft_endpoint.go | 2 +- agent/consul/operator_raft_endpoint_test.go | 2 +- agent/consul/operator_usage_endpoint.go | 2 +- agent/consul/options.go | 25 +- agent/consul/options_ce.go | 3 +- agent/consul/peering_backend.go | 2 +- agent/consul/peering_backend_ce.go | 3 +- agent/consul/peering_backend_ce_test.go | 3 +- agent/consul/peering_backend_test.go | 2 +- agent/consul/prepared_query/template.go | 2 +- agent/consul/prepared_query/template_test.go | 2 +- agent/consul/prepared_query/walk.go | 2 +- agent/consul/prepared_query/walk_ce_test.go | 3 +- agent/consul/prepared_query/walk_test.go | 2 +- agent/consul/prepared_query_endpoint.go | 2 +- agent/consul/prepared_query_endpoint_ce.go | 3 +- .../consul/prepared_query_endpoint_ce_test.go | 3 +- agent/consul/prepared_query_endpoint_test.go | 4 +- agent/consul/raft_handle.go | 2 +- agent/consul/raft_rpc.go | 2 +- agent/consul/rate/handler.go | 2 +- agent/consul/rate/handler_ce.go | 3 +- agent/consul/rate/handler_test.go | 2 +- agent/consul/rate/metrics.go | 2 +- agent/consul/replication.go | 2 +- agent/consul/replication_test.go | 2 +- agent/consul/reporting/reporting.go | 2 +- agent/consul/reporting/reporting_ce.go | 3 +- agent/consul/rpc.go | 2 +- agent/consul/rpc_test.go | 2 +- agent/consul/rtt.go | 2 +- agent/consul/rtt_test.go | 2 +- agent/consul/segment_ce.go | 3 +- agent/consul/serf_filter.go | 2 +- agent/consul/serf_test.go | 2 +- agent/consul/server.go | 285 +- agent/consul/server_ce.go | 3 +- agent/consul/server_ce_test.go | 3 +- agent/consul/server_connect.go | 34 +- agent/consul/server_log_verification.go | 2 +- agent/consul/server_lookup.go | 2 +- agent/consul/server_lookup_test.go | 2 +- agent/consul/server_metadata.go | 2 +- agent/consul/server_metadata_test.go | 2 +- agent/consul/server_overview.go | 2 +- agent/consul/server_overview_test.go | 2 +- agent/consul/server_register.go | 2 +- agent/consul/server_serf.go | 2 +- agent/consul/server_test.go | 52 +- agent/consul/servercert/manager.go | 2 +- agent/consul/servercert/manager_test.go | 2 +- agent/consul/session_endpoint.go | 2 +- agent/consul/session_endpoint_test.go | 2 +- agent/consul/session_timers.go | 2 +- agent/consul/session_timers_test.go | 2 +- agent/consul/session_ttl.go | 2 +- agent/consul/session_ttl_test.go | 2 +- agent/consul/snapshot_endpoint.go | 2 +- agent/consul/snapshot_endpoint_test.go | 2 +- agent/consul/state/acl.go | 25 +- agent/consul/state/acl_ce.go | 3 +- agent/consul/state/acl_ce_test.go | 3 +- agent/consul/state/acl_events.go | 2 +- agent/consul/state/acl_events_test.go | 2 +- agent/consul/state/acl_schema.go | 2 +- agent/consul/state/acl_test.go | 2 +- agent/consul/state/autopilot.go | 2 +- agent/consul/state/autopilot_test.go | 2 +- agent/consul/state/catalog.go | 8 +- agent/consul/state/catalog_ce.go | 3 +- agent/consul/state/catalog_ce_test.go | 3 +- agent/consul/state/catalog_events.go | 4 +- agent/consul/state/catalog_events_ce.go | 3 +- agent/consul/state/catalog_events_ce_test.go | 3 +- agent/consul/state/catalog_events_test.go | 2 +- agent/consul/state/catalog_schema.deepcopy.go | 3 - agent/consul/state/catalog_schema.go | 2 +- agent/consul/state/catalog_test.go | 2 +- agent/consul/state/config_entry.go | 2 +- agent/consul/state/config_entry_ce.go | 3 +- agent/consul/state/config_entry_ce_test.go | 3 +- agent/consul/state/config_entry_events.go | 2 +- .../consul/state/config_entry_events_test.go | 2 +- .../state/config_entry_exported_services.go | 2 +- .../config_entry_exported_services_ce.go | 3 +- agent/consul/state/config_entry_intention.go | 2 +- .../consul/state/config_entry_intention_ce.go | 3 +- .../state/config_entry_sameness_group.go | 3 - .../state/config_entry_sameness_group_ce.go | 3 +- .../config_entry_sameness_group_ce_test.go | 3 +- agent/consul/state/config_entry_schema.go | 2 +- agent/consul/state/config_entry_test.go | 2 +- agent/consul/state/connect_ca.go | 2 +- agent/consul/state/connect_ca_events.go | 2 +- agent/consul/state/connect_ca_events_test.go | 2 +- agent/consul/state/connect_ca_test.go | 2 +- agent/consul/state/coordinate.go | 2 +- agent/consul/state/coordinate_ce.go | 3 +- agent/consul/state/coordinate_ce_test.go | 3 +- agent/consul/state/coordinate_test.go | 2 +- agent/consul/state/deep-copy.sh | 3 - agent/consul/state/delay_ce.go | 3 +- agent/consul/state/delay_test.go | 2 +- agent/consul/state/events.go | 2 +- agent/consul/state/events_test.go | 2 +- agent/consul/state/federation_state.go | 2 +- agent/consul/state/graveyard.go | 2 +- agent/consul/state/graveyard_ce.go | 3 +- agent/consul/state/graveyard_test.go | 2 +- agent/consul/state/index_connect_test.go | 2 +- agent/consul/state/indexer.go | 2 +- agent/consul/state/intention.go | 2 +- agent/consul/state/intention_ce.go | 3 +- agent/consul/state/intention_test.go | 2 +- agent/consul/state/kvs.go | 2 +- agent/consul/state/kvs_ce.go | 3 +- agent/consul/state/kvs_ce_test.go | 3 +- agent/consul/state/kvs_test.go | 2 +- agent/consul/state/memdb.go | 2 +- agent/consul/state/memdb_test.go | 2 +- agent/consul/state/operations_ce.go | 3 +- agent/consul/state/peering.go | 5 +- agent/consul/state/peering_ce.go | 3 +- agent/consul/state/peering_ce_test.go | 3 +- agent/consul/state/peering_test.go | 2 +- agent/consul/state/prepared_query.go | 2 +- agent/consul/state/prepared_query_index.go | 2 +- .../consul/state/prepared_query_index_test.go | 2 +- agent/consul/state/prepared_query_test.go | 2 +- agent/consul/state/query.go | 2 +- agent/consul/state/query_ce.go | 3 +- agent/consul/state/schema.go | 2 +- agent/consul/state/schema_ce.go | 3 +- agent/consul/state/schema_ce_test.go | 3 +- agent/consul/state/schema_test.go | 2 +- agent/consul/state/session.go | 2 +- agent/consul/state/session_ce.go | 3 +- agent/consul/state/session_test.go | 2 +- agent/consul/state/state_store.go | 2 +- agent/consul/state/state_store_ce_test.go | 3 +- agent/consul/state/state_store_test.go | 2 +- agent/consul/state/store_integration_test.go | 2 +- agent/consul/state/system_metadata.go | 2 +- agent/consul/state/system_metadata_test.go | 2 +- agent/consul/state/tombstone_gc.go | 2 +- agent/consul/state/tombstone_gc_test.go | 2 +- agent/consul/state/txn.go | 2 +- agent/consul/state/txn_test.go | 2 +- agent/consul/state/usage.go | 2 +- agent/consul/state/usage_ce.go | 3 +- agent/consul/state/usage_test.go | 2 +- agent/consul/stats_fetcher.go | 2 +- agent/consul/stats_fetcher_test.go | 2 +- agent/consul/status_endpoint.go | 2 +- agent/consul/status_endpoint_test.go | 2 +- agent/consul/stream/event.go | 2 +- agent/consul/stream/event_buffer.go | 2 +- agent/consul/stream/event_buffer_test.go | 2 +- agent/consul/stream/event_publisher.go | 2 +- agent/consul/stream/event_publisher_test.go | 2 +- agent/consul/stream/event_snapshot.go | 2 +- agent/consul/stream/event_snapshot_test.go | 2 +- agent/consul/stream/event_test.go | 2 +- agent/consul/stream/noop.go | 2 +- agent/consul/stream/string_types.go | 2 +- agent/consul/stream/subscription.go | 2 +- agent/consul/stream/subscription_test.go | 2 +- agent/consul/subscribe_backend.go | 2 +- agent/consul/subscribe_backend_test.go | 2 +- agent/consul/system_metadata.go | 2 +- agent/consul/system_metadata_test.go | 2 +- agent/consul/tenancy_bridge.go | 17 - agent/consul/tenancy_bridge_ce.go | 28 - .../testdata/v2-resource-dependencies.md | 45 - agent/consul/txn_endpoint.go | 2 +- agent/consul/txn_endpoint_test.go | 2 +- agent/consul/type_registry.go | 34 - agent/consul/usagemetrics/usagemetrics.go | 2 +- agent/consul/usagemetrics/usagemetrics_ce.go | 3 +- .../usagemetrics/usagemetrics_ce_test.go | 3 +- .../consul/usagemetrics/usagemetrics_test.go | 2 +- agent/consul/util.go | 2 +- agent/consul/util_test.go | 2 +- agent/consul/wanfed/pool.go | 2 +- agent/consul/wanfed/wanfed.go | 2 +- agent/consul/wanfed/wanfed_test.go | 2 +- agent/consul/watch/server_local.go | 2 +- agent/consul/watch/server_local_test.go | 2 +- agent/consul/xdscapacity/capacity.go | 2 +- agent/consul/xdscapacity/capacity_test.go | 2 +- agent/coordinate_endpoint.go | 2 +- agent/coordinate_endpoint_test.go | 2 +- agent/debug/host.go | 2 +- agent/debug/host_test.go | 2 +- agent/delegate_mock_test.go | 7 +- agent/denylist.go | 2 +- agent/denylist_test.go | 2 +- agent/discovery_chain_endpoint.go | 2 +- agent/discovery_chain_endpoint_test.go | 2 +- agent/dns.go | 24 +- agent/dns/dns.go | 2 +- agent/dns/dns_test.go | 2 +- agent/dns/validation.go | 2 +- agent/dns/validation_test.go | 2 +- agent/dns_ce.go | 3 +- agent/dns_ce_test.go | 8 +- agent/dns_test.go | 47 +- agent/enterprise_delegate_ce.go | 3 +- .../builtin/aws-lambda/aws_lambda.go | 2 +- .../builtin/aws-lambda/aws_lambda_test.go | 2 +- .../builtin/ext-authz/ext_authz.go | 19 +- .../builtin/ext-authz/ext_authz_test.go | 2 +- .../builtin/ext-authz/structs.go | 2 +- agent/envoyextensions/builtin/lua/lua.go | 2 +- agent/envoyextensions/builtin/lua/lua_test.go | 2 +- .../otel_access_logging.go | 274 -- .../otel_access_logging_test.go | 113 - .../builtin/otel-access-logging/structs.go | 424 -- .../property-override/property_override.go | 3 - .../property_override_test.go | 3 - .../property-override/structpatcher.go | 3 - .../property-override/structpatcher_test.go | 3 - agent/envoyextensions/builtin/wasm/structs.go | 2 +- agent/envoyextensions/builtin/wasm/wasm.go | 2 +- .../envoyextensions/builtin/wasm/wasm_test.go | 17 +- .../envoyextensions/registered_extensions.go | 24 +- .../registered_extensions_ce.go | 8 - .../registered_extensions_test.go | 2 +- agent/event_endpoint.go | 2 +- agent/event_endpoint_test.go | 2 +- agent/exec/exec.go | 2 +- agent/exec/exec_unix.go | 3 +- agent/exec/exec_windows.go | 3 +- agent/federation_state_endpoint.go | 2 +- agent/grpc-external/forward.go | 2 +- agent/grpc-external/limiter/limiter.go | 2 +- agent/grpc-external/limiter/limiter_test.go | 2 +- agent/grpc-external/options.go | 2 +- agent/grpc-external/options_test.go | 2 +- agent/grpc-external/querymeta.go | 3 - agent/grpc-external/querymeta_test.go | 3 - agent/grpc-external/server.go | 2 +- agent/grpc-external/services/acl/login.go | 2 +- .../grpc-external/services/acl/login_test.go | 2 +- agent/grpc-external/services/acl/logout.go | 2 +- .../grpc-external/services/acl/logout_test.go | 2 +- agent/grpc-external/services/acl/server.go | 2 +- .../grpc-external/services/acl/server_test.go | 2 +- .../services/connectca/server.go | 2 +- .../services/connectca/server_test.go | 2 +- .../grpc-external/services/connectca/sign.go | 2 +- .../services/connectca/sign_test.go | 2 +- .../services/connectca/watch_roots.go | 2 +- .../services/connectca/watch_roots_test.go | 2 +- .../dataplane/get_envoy_bootstrap_params.go | 150 +- .../get_envoy_bootstrap_params_test.go | 262 +- .../dataplane/get_supported_features.go | 4 +- .../dataplane/get_supported_features_test.go | 2 +- .../services/dataplane/server.go | 7 +- .../services/dataplane/server_test.go | 2 +- agent/grpc-external/services/dns/server.go | 2 +- .../grpc-external/services/dns/server_test.go | 2 +- .../services/peerstream/health_snapshot.go | 2 +- .../peerstream/health_snapshot_test.go | 2 +- .../services/peerstream/replication.go | 2 +- .../services/peerstream/server.go | 2 +- .../services/peerstream/server_test.go | 2 +- .../services/peerstream/stream_resources.go | 2 +- .../services/peerstream/stream_test.go | 2 +- .../services/peerstream/stream_tracker.go | 2 +- .../peerstream/stream_tracker_test.go | 2 +- .../peerstream/subscription_blocking.go | 2 +- .../peerstream/subscription_manager.go | 2 +- .../peerstream/subscription_manager_test.go | 2 +- .../services/peerstream/subscription_state.go | 2 +- .../peerstream/subscription_state_test.go | 2 +- .../services/peerstream/subscription_view.go | 2 +- .../peerstream/subscription_view_test.go | 2 +- .../services/peerstream/testing.go | 2 +- .../grpc-external/services/resource/delete.go | 84 +- .../services/resource/delete_test.go | 203 +- agent/grpc-external/services/resource/list.go | 72 +- .../services/resource/list_by_owner.go | 85 +- .../services/resource/list_by_owner_test.go | 233 +- .../services/resource/list_test.go | 144 +- .../services/resource/mock_TenancyBridge.go | 121 - agent/grpc-external/services/resource/read.go | 106 +- .../services/resource/read_test.go | 355 +- .../grpc-external/services/resource/server.go | 170 +- .../services/resource/server_ce.go | 39 - .../services/resource/server_ce_test.go | 16 - .../services/resource/server_test.go | 160 +- .../services/resource/testing/testing.go | 121 +- .../services/resource/testing/testing_ce.go | 65 - .../grpc-external/services/resource/watch.go | 68 +- .../services/resource/watch_test.go | 115 +- .../grpc-external/services/resource/write.go | 79 +- .../services/resource/write_status.go | 96 +- .../services/resource/write_status_test.go | 393 +- .../services/resource/write_test.go | 417 +- .../services/serverdiscovery/server.go | 2 +- .../services/serverdiscovery/server_test.go | 2 +- .../services/serverdiscovery/watch_servers.go | 2 +- .../serverdiscovery/watch_servers_test.go | 2 +- agent/grpc-external/stats_test.go | 2 +- agent/grpc-external/testutils/acl.go | 14 +- agent/grpc-external/testutils/fsm.go | 2 +- agent/grpc-external/testutils/server.go | 2 +- agent/grpc-external/utils.go | 2 +- agent/grpc-internal/balancer/balancer.go | 2 +- agent/grpc-internal/balancer/balancer_test.go | 2 +- agent/grpc-internal/balancer/registry.go | 2 +- agent/grpc-internal/client.go | 2 +- agent/grpc-internal/client_test.go | 2 +- agent/grpc-internal/handler.go | 2 +- agent/grpc-internal/handler_test.go | 2 +- agent/grpc-internal/listener.go | 2 +- agent/grpc-internal/pipe.go | 2 +- agent/grpc-internal/pipe_test.go | 2 +- agent/grpc-internal/resolver/registry.go | 2 +- agent/grpc-internal/resolver/resolver.go | 2 +- agent/grpc-internal/resolver/resolver_test.go | 3 - agent/grpc-internal/server_test.go | 2 +- .../services/subscribe/logger.go | 2 +- .../services/subscribe/subscribe.go | 2 +- .../services/subscribe/subscribe_test.go | 2 +- agent/grpc-internal/stats_test.go | 2 +- agent/grpc-internal/tracker.go | 2 +- agent/grpc-middleware/auth_interceptor.go | 2 +- .../grpc-middleware/auth_interceptor_test.go | 2 +- agent/grpc-middleware/handshake.go | 2 +- agent/grpc-middleware/handshake_test.go | 2 +- agent/grpc-middleware/rate.go | 2 +- agent/grpc-middleware/rate_test.go | 2 +- agent/grpc-middleware/recovery.go | 2 +- agent/grpc-middleware/stats.go | 2 +- agent/grpc-middleware/testutil/fake_sink.go | 2 +- .../testutil/testservice/buf.gen.yaml | 2 +- .../testutil/testservice/fake_service.go | 2 +- .../testutil/testservice/simple.pb.go | 2 +- .../testutil/testservice/simple.proto | 2 +- agent/hcp/bootstrap/bootstrap.go | 2 +- agent/hcp/bootstrap/bootstrap_test.go | 3 - agent/hcp/bootstrap/testing.go | 2 +- agent/hcp/client/client.go | 2 +- agent/hcp/client/client_test.go | 3 - agent/hcp/client/metrics_client.go | 3 - agent/hcp/client/metrics_client_test.go | 3 - agent/hcp/client/mock_CloudConfig.go | 3 - agent/hcp/client/telemetry_config.go | 22 +- agent/hcp/client/telemetry_config_test.go | 50 +- agent/hcp/config/config.go | 2 +- agent/hcp/deps.go | 41 +- agent/hcp/deps_test.go | 87 +- agent/hcp/discover/discover.go | 2 +- agent/hcp/manager.go | 2 +- agent/hcp/manager_test.go | 2 +- agent/hcp/scada/capabilities.go | 2 +- agent/hcp/scada/scada.go | 2 +- agent/hcp/telemetry/custom_metrics.go | 3 - agent/hcp/telemetry/doc.go | 3 - agent/hcp/telemetry/gauge_store.go | 3 - agent/hcp/telemetry/gauge_store_test.go | 3 - agent/hcp/telemetry/otel_exporter.go | 9 - agent/hcp/telemetry/otel_exporter_test.go | 20 +- agent/hcp/telemetry/otel_sink.go | 25 +- agent/hcp/telemetry/otel_sink_test.go | 37 +- agent/hcp/telemetry/otlp_transform.go | 13 +- agent/hcp/telemetry/otlp_transform_test.go | 9 +- agent/hcp/telemetry_provider.go | 115 +- agent/hcp/telemetry_provider_test.go | 211 +- agent/hcp/testing.go | 2 +- agent/hcp/testserver/main.go | 2 +- agent/health_endpoint.go | 2 +- agent/health_endpoint_test.go | 47 +- agent/http.go | 96 +- agent/http_ce.go | 3 +- agent/http_ce_test.go | 2 +- agent/http_decode_test.go | 2 +- agent/http_register.go | 5 +- agent/http_test.go | 8 +- agent/intentions_endpoint.go | 2 +- agent/intentions_endpoint_ce_test.go | 3 +- agent/intentions_endpoint_test.go | 2 +- agent/keyring.go | 2 +- agent/keyring_test.go | 2 +- agent/kvs_endpoint.go | 2 +- agent/kvs_endpoint_test.go | 2 +- agent/leafcert/cached_roots.go | 16 +- agent/leafcert/cert.go | 3 - agent/leafcert/generate.go | 17 +- agent/leafcert/leafcert.go | 21 +- agent/leafcert/leafcert_test.go | 131 +- agent/leafcert/roots.go | 7 +- agent/leafcert/signer_netrpc.go | 3 - ...eafcert_test_helpers.go => signer_test.go} | 175 +- agent/leafcert/structs.go | 28 +- agent/leafcert/structs_test.go | 3 - agent/leafcert/util.go | 3 - agent/leafcert/util_test.go | 3 - agent/leafcert/watch.go | 15 +- agent/local/state.go | 2 +- agent/local/state_internal_test.go | 2 +- agent/local/state_test.go | 2 +- agent/local/testing.go | 2 +- agent/log-drop/log-drop.go | 2 +- agent/log-drop/log-drop_test.go | 2 +- agent/metadata/build.go | 2 +- agent/metadata/build_test.go | 2 +- agent/metadata/server.go | 2 +- agent/metadata/server_internal_test.go | 2 +- agent/metadata/server_test.go | 2 +- agent/metrics.go | 2 +- agent/metrics/testing.go | 2 +- agent/metrics_test.go | 80 +- agent/mock/notify.go | 2 +- agent/nodeid.go | 2 +- agent/nodeid_test.go | 2 +- agent/notify.go | 2 +- agent/notify_test.go | 2 +- agent/operator_endpoint.go | 2 +- agent/operator_endpoint_ce.go | 3 +- agent/operator_endpoint_ce_test.go | 3 +- agent/operator_endpoint_test.go | 2 +- agent/peering_endpoint.go | 2 +- agent/peering_endpoint_ce_test.go | 3 +- agent/peering_endpoint_test.go | 2 +- agent/pool/conn.go | 2 +- agent/pool/peek.go | 2 +- agent/pool/peek_test.go | 2 +- agent/pool/pool.go | 2 +- agent/prepared_query_endpoint.go | 2 +- agent/prepared_query_endpoint_test.go | 2 +- agent/proxycfg-glue/config_entry.go | 2 +- agent/proxycfg-glue/discovery_chain.go | 2 +- agent/proxycfg-glue/discovery_chain_test.go | 2 +- .../proxycfg-glue/exported_peered_services.go | 2 +- .../exported_peered_services_test.go | 2 +- .../federation_state_list_mesh_gateways.go | 2 +- ...ederation_state_list_mesh_gateways_test.go | 2 +- agent/proxycfg-glue/gateway_services.go | 2 +- agent/proxycfg-glue/gateway_services_test.go | 2 +- agent/proxycfg-glue/glue.go | 2 +- agent/proxycfg-glue/health.go | 2 +- agent/proxycfg-glue/health_blocking.go | 2 +- agent/proxycfg-glue/health_blocking_test.go | 3 - agent/proxycfg-glue/health_test.go | 2 +- agent/proxycfg-glue/helpers_test.go | 2 +- agent/proxycfg-glue/intention_upstreams.go | 2 +- .../proxycfg-glue/intention_upstreams_test.go | 2 +- agent/proxycfg-glue/intentions.go | 2 +- agent/proxycfg-glue/intentions_ce.go | 3 +- agent/proxycfg-glue/intentions_test.go | 2 +- agent/proxycfg-glue/internal_service_dump.go | 2 +- .../internal_service_dump_test.go | 2 +- agent/proxycfg-glue/leafcerts.go | 2 +- agent/proxycfg-glue/peered_upstreams.go | 2 +- agent/proxycfg-glue/peered_upstreams_test.go | 2 +- agent/proxycfg-glue/peering_list.go | 2 +- agent/proxycfg-glue/peering_list_test.go | 2 +- .../proxycfg-glue/resolved_service_config.go | 2 +- .../resolved_service_config_test.go | 2 +- agent/proxycfg-glue/service_http_checks.go | 2 +- .../proxycfg-glue/service_http_checks_test.go | 2 +- agent/proxycfg-glue/service_list.go | 2 +- agent/proxycfg-glue/service_list_test.go | 2 +- agent/proxycfg-glue/trust_bundle.go | 2 +- agent/proxycfg-glue/trust_bundle_test.go | 2 +- .../proxycfg-sources/catalog/config_source.go | 15 +- .../catalog/config_source_oss.go | 15 - .../catalog/config_source_test.go | 45 +- .../catalog/mock_ConfigManager.go | 30 +- .../catalog/mock_SessionLimiter.go | 21 +- .../proxycfg-sources/catalog/mock_Watcher.go | 40 +- agent/proxycfg-sources/local/config_source.go | 9 +- agent/proxycfg-sources/local/local.go | 2 +- .../local/mock_ConfigManager.go | 30 +- agent/proxycfg-sources/local/sync.go | 5 +- agent/proxycfg-sources/local/sync_test.go | 2 +- agent/proxycfg/api_gateway.go | 23 +- agent/proxycfg/api_gateway_ce.go | 16 - agent/proxycfg/config_snapshot_glue.go | 69 - agent/proxycfg/config_snapshot_glue_test.go | 315 -- agent/proxycfg/connect_proxy.go | 2 +- agent/proxycfg/data_sources.go | 2 +- agent/proxycfg/data_sources_ce.go | 3 +- agent/proxycfg/deep-copy.sh | 2 +- agent/proxycfg/ingress_gateway.go | 2 +- agent/proxycfg/internal/watch/watchmap.go | 2 +- .../proxycfg/internal/watch/watchmap_test.go | 2 +- agent/proxycfg/manager.go | 19 +- agent/proxycfg/manager_test.go | 11 +- agent/proxycfg/mesh_gateway.go | 3 +- agent/proxycfg/mesh_gateway_ce.go | 3 +- agent/proxycfg/naming.go | 2 +- agent/proxycfg/naming_ce.go | 3 +- agent/proxycfg/naming_test.go | 2 +- agent/proxycfg/proxycfg.deepcopy.go | 4 - agent/proxycfg/proxycfg.go | 4 +- agent/proxycfg/snapshot.go | 3 +- agent/proxycfg/snapshot_test.go | 2 +- agent/proxycfg/state.go | 5 +- agent/proxycfg/state_ce_test.go | 3 +- agent/proxycfg/state_test.go | 2 +- agent/proxycfg/terminating_gateway.go | 2 +- agent/proxycfg/testing.go | 62 +- agent/proxycfg/testing_api_gateway.go | 5 +- agent/proxycfg/testing_ce.go | 3 +- agent/proxycfg/testing_connect_proxy.go | 42 +- agent/proxycfg/testing_ingress_gateway.go | 213 +- agent/proxycfg/testing_mesh_gateway.go | 170 +- agent/proxycfg/testing_peering.go | 135 +- agent/proxycfg/testing_terminating_gateway.go | 5 +- agent/proxycfg/testing_tproxy.go | 2 +- agent/proxycfg/testing_upstreams.go | 122 +- agent/proxycfg/testing_upstreams_ce.go | 3 +- agent/proxycfg/upstreams.go | 2 +- agent/proxycfg_test.go | 14 +- agent/reload.go | 2 +- agent/remote_exec.go | 2 +- agent/remote_exec_test.go | 2 +- agent/retry_join.go | 2 +- agent/retry_join_test.go | 2 +- agent/router/grpc.go | 2 +- agent/router/manager.go | 2 +- agent/router/manager_internal_test.go | 2 +- agent/router/manager_test.go | 2 +- agent/router/router.go | 2 +- agent/router/router_test.go | 2 +- agent/router/serf_adapter.go | 2 +- agent/router/serf_flooder.go | 2 +- agent/routine-leak-checker/leak_test.go | 2 +- agent/rpc/middleware/interceptors.go | 24 +- agent/rpc/middleware/interceptors_test.go | 2 +- agent/rpc/middleware/rate_limit_mappings.go | 2 +- agent/rpc/middleware/recovery.go | 2 +- agent/rpc/operator/service.go | 2 +- agent/rpc/operator/service_test.go | 2 +- agent/rpc/peering/service.go | 2 +- agent/rpc/peering/service_ce_test.go | 3 +- agent/rpc/peering/service_test.go | 7 +- agent/rpc/peering/testing.go | 2 +- agent/rpc/peering/testutil_ce_test.go | 3 +- agent/rpc/peering/validate.go | 2 +- agent/rpc/peering/validate_test.go | 2 +- agent/rpcclient/common.go | 2 +- agent/rpcclient/configentry/configentry.go | 2 +- .../rpcclient/configentry/configentry_test.go | 2 +- agent/rpcclient/configentry/view.go | 2 +- agent/rpcclient/configentry/view_test.go | 2 +- agent/rpcclient/health/health.go | 2 +- agent/rpcclient/health/health_test.go | 2 +- agent/rpcclient/health/streaming_test.go | 2 +- agent/rpcclient/health/view.go | 2 +- agent/rpcclient/health/view_test.go | 2 +- agent/service_checks_test.go | 2 +- agent/service_manager.go | 8 +- agent/service_manager_test.go | 2 +- agent/session_endpoint.go | 2 +- agent/session_endpoint_test.go | 2 +- agent/setup.go | 14 +- agent/setup_ce.go | 3 +- agent/sidecar_service.go | 2 +- agent/sidecar_service_test.go | 2 +- agent/signal_unix.go | 3 +- agent/signal_windows.go | 3 +- agent/snapshot_endpoint.go | 2 +- agent/snapshot_endpoint_test.go | 2 +- agent/status_endpoint.go | 2 +- agent/status_endpoint_test.go | 2 +- agent/streaming_test.go | 2 +- agent/structs/acl.go | 134 +- agent/structs/acl_cache.go | 2 +- agent/structs/acl_cache_test.go | 2 +- agent/structs/acl_ce.go | 3 +- agent/structs/acl_templated_policy.go | 294 -- agent/structs/acl_templated_policy_ce.go | 47 - agent/structs/acl_templated_policy_ce_test.go | 115 - agent/structs/acl_templated_policy_test.go | 103 - agent/structs/acl_test.go | 2 +- agent/structs/aclfilter/filter.go | 2 +- agent/structs/aclfilter/filter_test.go | 2 +- .../acltemplatedpolicy/policies/ce/dns.hcl | 10 - .../acltemplatedpolicy/policies/ce/node.hcl | 7 - .../policies/ce/nomad-server.hcl | 11 - .../policies/ce/service.hcl | 13 - .../policies/ce/workload-identity.hcl | 3 - .../acltemplatedpolicy/schemas/node.json | 13 - .../acltemplatedpolicy/schemas/service.json | 13 - .../schemas/workload-identity.json | 13 - agent/structs/auto_encrypt.go | 2 +- agent/structs/autopilot.go | 2 +- agent/structs/autopilot_ce.go | 3 +- agent/structs/catalog.go | 2 +- agent/structs/catalog_ce.go | 3 +- agent/structs/check_definition.go | 2 +- agent/structs/check_definition_test.go | 2 +- agent/structs/check_type.go | 2 +- agent/structs/config_entry.go | 70 +- agent/structs/config_entry_apigw_jwt_ce.go | 12 - agent/structs/config_entry_ce.go | 27 +- agent/structs/config_entry_ce_test.go | 60 +- agent/structs/config_entry_discoverychain.go | 2 +- .../structs/config_entry_discoverychain_ce.go | 3 +- .../config_entry_discoverychain_ce_test.go | 3 +- .../config_entry_discoverychain_test.go | 2 +- agent/structs/config_entry_exports.go | 2 +- agent/structs/config_entry_exports_ce.go | 3 +- agent/structs/config_entry_exports_ce_test.go | 3 +- agent/structs/config_entry_exports_test.go | 2 +- agent/structs/config_entry_gateways.go | 13 +- agent/structs/config_entry_gateways_test.go | 2 +- .../config_entry_inline_certificate.go | 3 +- .../config_entry_inline_certificate_test.go | 2 +- agent/structs/config_entry_intentions.go | 2 +- agent/structs/config_entry_intentions_ce.go | 3 +- .../config_entry_intentions_ce_test.go | 3 +- agent/structs/config_entry_intentions_test.go | 2 +- agent/structs/config_entry_jwt_provider.go | 2 +- agent/structs/config_entry_jwt_provider_ce.go | 3 +- .../structs/config_entry_jwt_provider_test.go | 2 +- agent/structs/config_entry_mesh.go | 2 +- agent/structs/config_entry_mesh_ce.go | 3 +- agent/structs/config_entry_mesh_test.go | 2 +- agent/structs/config_entry_routes.go | 67 +- agent/structs/config_entry_routes_test.go | 475 +- agent/structs/config_entry_sameness_group.go | 2 +- .../structs/config_entry_sameness_group_ce.go | 3 +- agent/structs/config_entry_status.go | 2 +- agent/structs/config_entry_test.go | 2 +- agent/structs/connect.go | 2 +- agent/structs/connect_ca.go | 13 +- agent/structs/connect_ca_test.go | 2 +- agent/structs/connect_ce.go | 3 +- agent/structs/connect_proxy_config.go | 45 +- agent/structs/connect_proxy_config_ce.go | 3 +- agent/structs/connect_proxy_config_test.go | 2 +- agent/structs/deep-copy.sh | 2 +- agent/structs/discovery_chain.go | 2 +- agent/structs/discovery_chain_ce.go | 3 +- agent/structs/envoy_extension.go | 2 +- agent/structs/errors.go | 16 +- agent/structs/federation_state.go | 2 +- agent/structs/identity.go | 2 +- agent/structs/intention.go | 2 +- agent/structs/intention_ce.go | 3 +- agent/structs/intention_test.go | 2 +- agent/structs/operator.go | 2 +- agent/structs/peering.go | 2 +- agent/structs/prepared_query.go | 4 +- agent/structs/prepared_query_test.go | 2 +- agent/structs/protobuf_compat.go | 2 +- agent/structs/service_definition.go | 2 +- agent/structs/service_definition_test.go | 2 +- agent/structs/snapshot.go | 2 +- agent/structs/structs.deepcopy.go | 108 - agent/structs/structs.deepcopy_ce.go | 16 - agent/structs/structs.go | 34 +- agent/structs/structs_ce.go | 13 +- agent/structs/structs_ce_test.go | 3 +- agent/structs/structs_ext_test.go | 2 +- agent/structs/structs_filtering_test.go | 2 +- agent/structs/structs_test.go | 48 +- agent/structs/system_metadata.go | 2 +- agent/structs/testing.go | 2 +- agent/structs/testing_catalog.go | 11 +- agent/structs/testing_connect_proxy_config.go | 2 +- agent/structs/testing_intention.go | 2 +- agent/structs/testing_service_definition.go | 2 +- agent/structs/txn.go | 2 +- agent/submatview/handler.go | 2 +- agent/submatview/local_materializer.go | 2 +- agent/submatview/local_materializer_test.go | 2 +- agent/submatview/materializer.go | 2 +- agent/submatview/rpc_materializer.go | 2 +- agent/submatview/store.go | 2 +- agent/submatview/store_integration_test.go | 2 +- agent/submatview/store_test.go | 2 +- agent/submatview/streaming_test.go | 2 +- agent/systemd/notify.go | 2 +- agent/testagent.go | 57 +- agent/testagent_test.go | 2 +- agent/token/persistence.go | 18 +- agent/token/persistence_test.go | 184 +- agent/token/store.go | 41 +- agent/token/store_ce.go | 3 +- agent/token/store_test.go | 52 +- agent/translate_addr.go | 2 +- agent/txn_endpoint.go | 2 +- agent/txn_endpoint_test.go | 2 +- agent/ui_endpoint.go | 3 +- agent/ui_endpoint_ce_test.go | 3 +- agent/ui_endpoint_test.go | 24 +- agent/uiserver/buf_index_fs.go | 2 +- agent/uiserver/buffered_file.go | 2 +- agent/uiserver/redirect_fs.go | 2 +- agent/uiserver/ui_template_data.go | 2 +- agent/uiserver/uiserver.go | 2 +- agent/uiserver/uiserver_test.go | 2 +- agent/user_event.go | 2 +- agent/user_event_test.go | 2 +- agent/util.go | 2 +- agent/util_test.go | 2 +- agent/watch_handler.go | 2 +- agent/watch_handler_test.go | 2 +- agent/xds/accesslogs/accesslogs.go | 33 +- agent/xds/clusters.go | 132 +- agent/xds/clusters_test.go | 338 +- agent/xds/{config => }/config.go | 8 +- agent/xds/{config => }/config_test.go | 4 +- agent/xds/configfetcher/config_fetcher.go | 10 - agent/xds/delta.go | 229 +- agent/xds/delta_envoy_extender_ce_test.go | 56 +- agent/xds/delta_envoy_extender_test.go | 2 +- agent/xds/delta_test.go | 25 +- agent/xds/endpoints.go | 117 +- agent/xds/endpoints_test.go | 173 +- agent/xds/extensionruntime/runtime_config.go | 2 +- .../runtime_config_ce_test.go | 3 +- agent/xds/failover_policy.go | 8 +- agent/xds/failover_policy_ce.go | 3 +- agent/xds/golden_test.go | 21 +- agent/xds/gw_per_route_filters_ce.go | 23 - agent/xds/jwt_authn.go | 2 +- agent/xds/jwt_authn_ce.go | 24 - agent/xds/jwt_authn_test.go | 2 +- agent/xds/listeners.go | 44 +- agent/xds/listeners_apigateway.go | 137 +- agent/xds/listeners_ingress.go | 5 +- agent/xds/listeners_test.go | 184 +- agent/xds/locality_policy.go | 23 - agent/xds/locality_policy_ce.go | 15 - agent/xds/naming.go | 19 + agent/xds/naming/naming.go | 29 - agent/xds/net_fallback.go | 11 + agent/xds/{platform => }/net_linux.go | 7 +- agent/xds/platform/net_fallback.go | 10 - agent/xds/protocol_trace.go | 17 +- agent/xds/proxystateconverter/clusters.go | 1263 ----- agent/xds/proxystateconverter/converter.go | 136 - agent/xds/proxystateconverter/endpoints.go | 671 --- .../proxystateconverter/failover_policy.go | 158 - .../proxystateconverter/failover_policy_ce.go | 14 - agent/xds/proxystateconverter/listeners.go | 1695 ------- .../proxystateconverter/locality_policy.go | 21 - .../proxystateconverter/locality_policy_ce.go | 14 - agent/xds/proxystateconverter/routes.go | 777 --- agent/xds/rbac.go | 70 +- agent/xds/rbac_test.go | 242 +- agent/xds/resources.go | 7 +- agent/xds/resources_ce_test.go | 7 +- agent/xds/resources_test.go | 248 +- agent/xds/{response => }/response.go | 16 +- agent/xds/routes.go | 149 +- agent/xds/routes_test.go | 120 +- agent/xds/secrets.go | 2 +- agent/xds/server.go | 65 +- agent/xds/server_ce.go | 3 +- agent/xds/testcommon/testcommon.go | 2 +- ...uthz-http-local-grpc-service.latest.golden | 118 +- ...uthz-http-local-http-service.latest.golden | 110 +- ...z-http-upstream-grpc-service.latest.golden | 84 +- ...z-http-upstream-http-service.latest.golden | 84 +- ...authz-tcp-local-grpc-service.latest.golden | 118 +- ...hz-tcp-upstream-grpc-service.latest.golden | 84 +- ...lambda-and-lua-connect-proxy.latest.golden | 148 +- ...-connect-proxy-opposite-meta.latest.golden | 148 +- .../lambda-connect-proxy-tproxy.latest.golden | 294 +- ...terminating-gateway-upstream.latest.golden | 166 +- .../lambda-connect-proxy.latest.golden | 148 +- ...teway-with-service-resolvers.latest.golden | 296 +- .../lambda-terminating-gateway.latest.golden | 196 +- ...terminating-gateway-upstream.latest.golden | 166 +- ...a-inbound-applies-to-inbound.latest.golden | 166 +- ...snt-apply-to-local-upstreams.latest.golden | 166 +- ...es-to-local-upstreams-tproxy.latest.golden | 152 +- ...d-applies-to-local-upstreams.latest.golden | 166 +- ...ound-doesnt-apply-to-inbound.latest.golden | 166 +- ...-consul-constraint-violation.latest.golden | 166 +- ...h-envoy-constraint-violation.latest.golden | 166 +- .../otel-access-logging-http.latest.golden | 127 - ...opertyoverride-add-keepalive.latest.golden | 174 +- ...d-outlier-detection-multiple.latest.golden | 174 +- ...erride-add-outlier-detection.latest.golden | 170 +- ...de-add-round-robin-lb-config.latest.golden | 170 +- ...-load-assignment-inbound-add.latest.golden | 56 +- ...load-assignment-outbound-add.latest.golden | 56 +- ...und-doesnt-apply-to-outbound.latest.golden | 166 +- ...verride-listener-inbound-add.latest.golden | 166 +- ...erride-listener-outbound-add.latest.golden | 166 +- ...ound-doesnt-apply-to-inbound.latest.golden | 166 +- ...ic-upstream-service-failover.latest.golden | 262 +- ...ic-upstream-service-splitter.latest.golden | 82 +- ...ide-remove-outlier-detection.latest.golden | 162 +- .../wasm-http-local-file.latest.golden | 82 +- .../wasm-http-remote-file.latest.golden | 82 +- ...wasm-tcp-local-file-outbound.latest.golden | 82 +- .../wasm-tcp-local-file.latest.golden | 82 +- ...asm-tcp-remote-file-outbound.latest.golden | 82 +- .../wasm-tcp-remote-file.latest.golden | 82 +- ...uthz-http-local-grpc-service.latest.golden | 6 +- ...uthz-http-local-http-service.latest.golden | 6 +- ...z-http-upstream-grpc-service.latest.golden | 6 +- ...z-http-upstream-http-service.latest.golden | 6 +- ...authz-tcp-local-grpc-service.latest.golden | 6 +- ...hz-tcp-upstream-grpc-service.latest.golden | 6 +- ...lambda-and-lua-connect-proxy.latest.golden | 80 +- ...-connect-proxy-opposite-meta.latest.golden | 80 +- .../lambda-connect-proxy-tproxy.latest.golden | 108 +- ...terminating-gateway-upstream.latest.golden | 80 +- .../lambda-connect-proxy.latest.golden | 80 +- ...teway-with-service-resolvers.latest.golden | 116 +- .../lambda-terminating-gateway.latest.golden | 44 +- ...terminating-gateway-upstream.latest.golden | 80 +- ...a-inbound-applies-to-inbound.latest.golden | 80 +- ...snt-apply-to-local-upstreams.latest.golden | 80 +- ...es-to-local-upstreams-tproxy.latest.golden | 4 +- ...d-applies-to-local-upstreams.latest.golden | 80 +- ...ound-doesnt-apply-to-inbound.latest.golden | 80 +- ...-consul-constraint-violation.latest.golden | 80 +- ...h-envoy-constraint-violation.latest.golden | 80 +- .../otel-access-logging-http.latest.golden | 75 - ...opertyoverride-add-keepalive.latest.golden | 4 +- ...d-outlier-detection-multiple.latest.golden | 4 +- ...erride-add-outlier-detection.latest.golden | 4 +- ...de-add-round-robin-lb-config.latest.golden | 4 +- ...-load-assignment-inbound-add.latest.golden | 4 +- ...load-assignment-outbound-add.latest.golden | 4 +- ...und-doesnt-apply-to-outbound.latest.golden | 80 +- ...verride-listener-inbound-add.latest.golden | 80 +- ...erride-listener-outbound-add.latest.golden | 80 +- ...ound-doesnt-apply-to-inbound.latest.golden | 80 +- ...ic-upstream-service-failover.latest.golden | 124 +- ...ic-upstream-service-splitter.latest.golden | 124 +- ...ide-remove-outlier-detection.latest.golden | 4 +- .../wasm-http-local-file.latest.golden | 4 +- .../wasm-http-remote-file.latest.golden | 4 +- ...wasm-tcp-local-file-outbound.latest.golden | 4 +- .../wasm-tcp-local-file.latest.golden | 4 +- ...asm-tcp-remote-file-outbound.latest.golden | 4 +- .../wasm-tcp-remote-file.latest.golden | 4 +- ...uthz-http-local-grpc-service.latest.golden | 96 +- ...uthz-http-local-http-service.latest.golden | 100 +- ...z-http-upstream-grpc-service.latest.golden | 122 +- ...z-http-upstream-http-service.latest.golden | 170 +- ...authz-tcp-local-grpc-service.latest.golden | 30 +- ...hz-tcp-upstream-grpc-service.latest.golden | 36 +- ...lambda-and-lua-connect-proxy.latest.golden | 126 +- ...-connect-proxy-opposite-meta.latest.golden | 60 +- .../lambda-connect-proxy-tproxy.latest.golden | 90 +- ...terminating-gateway-upstream.latest.golden | 40 +- .../lambda-connect-proxy.latest.golden | 60 +- ...teway-with-service-resolvers.latest.golden | 118 +- .../lambda-terminating-gateway.latest.golden | 58 +- ...terminating-gateway-upstream.latest.golden | 40 +- ...a-inbound-applies-to-inbound.latest.golden | 90 +- ...snt-apply-to-local-upstreams.latest.golden | 106 +- ...es-to-local-upstreams-tproxy.latest.golden | 124 +- ...d-applies-to-local-upstreams.latest.golden | 120 +- ...ound-doesnt-apply-to-inbound.latest.golden | 90 +- ...-consul-constraint-violation.latest.golden | 106 +- ...h-envoy-constraint-violation.latest.golden | 106 +- .../otel-access-logging-http.latest.golden | 289 -- ...opertyoverride-add-keepalive.latest.golden | 90 +- ...d-outlier-detection-multiple.latest.golden | 90 +- ...erride-add-outlier-detection.latest.golden | 90 +- ...de-add-round-robin-lb-config.latest.golden | 90 +- ...-load-assignment-inbound-add.latest.golden | 90 +- ...load-assignment-outbound-add.latest.golden | 90 +- ...und-doesnt-apply-to-outbound.latest.golden | 96 +- ...verride-listener-inbound-add.latest.golden | 92 +- ...erride-listener-outbound-add.latest.golden | 94 +- ...ound-doesnt-apply-to-inbound.latest.golden | 96 +- ...ic-upstream-service-failover.latest.golden | 92 +- ...ic-upstream-service-splitter.latest.golden | 104 +- ...ide-remove-outlier-detection.latest.golden | 90 +- .../wasm-http-local-file.latest.golden | 106 +- .../wasm-http-remote-file.latest.golden | 110 +- ...wasm-tcp-local-file-outbound.latest.golden | 56 +- .../wasm-tcp-local-file.latest.golden | 40 +- ...asm-tcp-remote-file-outbound.latest.golden | 64 +- .../wasm-tcp-remote-file.latest.golden | 44 +- ...uthz-http-local-grpc-service.latest.golden | 6 +- ...uthz-http-local-http-service.latest.golden | 6 +- ...z-http-upstream-grpc-service.latest.golden | 6 +- ...z-http-upstream-http-service.latest.golden | 6 +- ...authz-tcp-local-grpc-service.latest.golden | 6 +- ...hz-tcp-upstream-grpc-service.latest.golden | 6 +- ...lambda-and-lua-connect-proxy.latest.golden | 6 +- ...-connect-proxy-opposite-meta.latest.golden | 6 +- .../lambda-connect-proxy-tproxy.latest.golden | 6 +- ...terminating-gateway-upstream.latest.golden | 6 +- .../routes/lambda-connect-proxy.latest.golden | 6 +- ...teway-with-service-resolvers.latest.golden | 80 +- .../lambda-terminating-gateway.latest.golden | 32 +- ...terminating-gateway-upstream.latest.golden | 6 +- ...a-inbound-applies-to-inbound.latest.golden | 6 +- ...snt-apply-to-local-upstreams.latest.golden | 6 +- ...es-to-local-upstreams-tproxy.latest.golden | 20 +- ...d-applies-to-local-upstreams.latest.golden | 6 +- ...ound-doesnt-apply-to-inbound.latest.golden | 6 +- ...-consul-constraint-violation.latest.golden | 6 +- ...h-envoy-constraint-violation.latest.golden | 6 +- .../otel-access-logging-http.latest.golden | 5 - ...opertyoverride-add-keepalive.latest.golden | 4 +- ...d-outlier-detection-multiple.latest.golden | 4 +- ...erride-add-outlier-detection.latest.golden | 4 +- ...de-add-round-robin-lb-config.latest.golden | 4 +- ...-load-assignment-inbound-add.latest.golden | 4 +- ...load-assignment-outbound-add.latest.golden | 4 +- ...und-doesnt-apply-to-outbound.latest.golden | 6 +- ...verride-listener-inbound-add.latest.golden | 6 +- ...erride-listener-outbound-add.latest.golden | 6 +- ...ound-doesnt-apply-to-inbound.latest.golden | 6 +- ...ic-upstream-service-failover.latest.golden | 36 +- ...ic-upstream-service-splitter.latest.golden | 46 +- ...ide-remove-outlier-detection.latest.golden | 4 +- .../routes/wasm-http-local-file.latest.golden | 4 +- .../wasm-http-remote-file.latest.golden | 4 +- ...wasm-tcp-local-file-outbound.latest.golden | 4 +- .../routes/wasm-tcp-local-file.latest.golden | 4 +- ...asm-tcp-remote-file-outbound.latest.golden | 4 +- .../routes/wasm-tcp-remote-file.latest.golden | 4 +- ...route-and-inline-certificate.latest.golden | 55 + .../api-gateway-with-http-route.latest.golden | 55 - ...nd-inline-certificate.envoy-1-21-x.golden} | 40 +- ...route-and-inline-certificate.latest.golden | 30 +- ...nect-proxy-exported-to-peers.latest.golden | 10 +- ...connect-proxy-lb-in-resolver.latest.golden | 126 +- ...and-failover-to-cluster-peer.latest.golden | 254 +- ...roxy-with-chain-and-failover.latest.golden | 254 +- ...oxy-with-chain-and-overrides.latest.golden | 98 +- ...and-redirect-to-cluster-peer.latest.golden | 166 +- ...roxy-with-chain-external-sni.latest.golden | 82 +- ...nnect-proxy-with-chain-http2.latest.golden | 135 - .../connect-proxy-with-chain.latest.golden | 82 +- ...-jwt-config-entry-with-local.latest.golden | 82 +- ...onfig-entry-with-remote-jwks.latest.golden | 88 +- ...d-upstreams-escape-overrides.latest.golden | 135 - ...-with-peered-upstreams-http2.latest.golden | 163 - ...-proxy-with-peered-upstreams.latest.golden | 80 +- ...ough-local-gateway-triggered.latest.golden | 322 +- ...ilover-through-local-gateway.latest.golden | 322 +- ...ugh-remote-gateway-triggered.latest.golden | 322 +- ...lover-through-remote-gateway.latest.golden | 322 +- ...ough-local-gateway-triggered.latest.golden | 254 +- ...ilover-through-local-gateway.latest.golden | 254 +- ...ugh-remote-gateway-triggered.latest.golden | 254 +- ...lover-through-remote-gateway.latest.golden | 254 +- ...h-tls-outgoing-cipher-suites.latest.golden | 98 +- ...ith-tls-outgoing-max-version.latest.golden | 86 +- ...ls-outgoing-min-version-auto.latest.golden | 82 +- ...ith-tls-outgoing-min-version.latest.golden | 86 +- ...-limits-max-connections-only.latest.golden | 86 +- .../custom-limits-set-to-zero.latest.golden | 86 +- .../clusters/custom-limits.latest.golden | 86 +- .../clusters/custom-local-app.latest.golden | 80 +- ...stom-max-inbound-connections.latest.golden | 94 +- ...thcheck-zero-consecutive_5xx.latest.golden | 133 - .../custom-passive-healthcheck.latest.golden | 84 +- .../clusters/custom-timeouts.latest.golden | 82 +- ...ustom-upstream-default-chain.latest.golden | 56 +- ...upstream-with-prepared-query.latest.golden | 136 - .../clusters/custom-upstream.latest.golden | 56 +- .../testdata/clusters/defaults.latest.golden | 82 +- ...am-service-with-unix-sockets.latest.golden | 82 +- .../clusters/expose-checks.latest.golden | 57 - ...paths-grpc-new-cluster-http1.latest.golden | 21 +- ...expose-paths-local-app-paths.latest.golden | 10 +- ...pose-paths-new-cluster-http2.latest.golden | 18 +- ...ess-gateway-nil-config-entry.latest.golden | 4 +- .../ingress-gateway-no-services.latest.golden | 4 +- ...h-tls-outgoing-cipher-suites.latest.golden | 52 +- ...ith-tls-outgoing-max-version.latest.golden | 46 +- ...ith-tls-outgoing-min-version.latest.golden | 46 +- .../clusters/ingress-gateway.latest.golden | 44 +- .../ingress-lb-in-resolver.latest.golden | 88 +- ...-listeners-duplicate-service.latest.golden | 84 +- ...itter-with-resolver-redirect.latest.golden | 84 +- ...and-failover-to-cluster-peer.latest.golden | 166 +- ...ress-with-chain-and-failover.latest.golden | 166 +- ...ress-with-chain-external-sni.latest.golden | 44 +- .../clusters/ingress-with-chain.latest.golden | 44 +- ...efaults-passive-health-check.latest.golden | 49 +- ...ults-service-max-connections.latest.golden | 44 +- ...efaults-passive-health-check.latest.golden | 50 +- ...ults-service-max-connections.latest.golden | 44 +- ...ervice-passive-health-check.latest.golden} | 56 +- ...with-service-max-connections.latest.golden | 44 +- ...service-passive-health-check.latest.golden | 49 +- ...ough-local-gateway-triggered.latest.golden | 234 +- ...ilover-through-local-gateway.latest.golden | 234 +- ...ugh-remote-gateway-triggered.latest.golden | 234 +- ...lover-through-remote-gateway.latest.golden | 234 +- ...ough-local-gateway-triggered.latest.golden | 166 +- ...ilover-through-local-gateway.latest.golden | 166 +- ...ugh-remote-gateway-triggered.latest.golden | 166 +- ...lover-through-remote-gateway.latest.golden | 166 +- ...ateway-with-peered-upstreams.latest.golden | 80 +- ...mesh-gateway-hash-lb-ignored.latest.golden | 98 +- ...teway-ignore-extra-resolvers.latest.golden | 98 +- .../mesh-gateway-no-services.latest.golden | 4 +- ...gateway-non-hash-lb-injected.latest.golden | 104 +- ...ateway-peering-control-plane.latest.golden | 18 +- ...mesh-gateway-service-subsets.latest.golden | 98 +- ...esh-gateway-service-timeouts.latest.golden | 98 +- .../mesh-gateway-tcp-keepalives.latest.golden | 82 +- ...ing-federation-control-plane.latest.golden | 205 - ...eway-using-federation-states.latest.golden | 70 +- ...ed-services-http-with-router.latest.golden | 187 +- ...xported-peered-services-http.latest.golden | 166 +- ...ith-exported-peered-services.latest.golden | 124 +- ...ith-imported-peered-services.latest.golden | 30 +- ...through-mesh-gateway-enabled.latest.golden | 30 +- .../clusters/mesh-gateway.latest.golden | 70 +- ...itter-with-resolver-redirect.latest.golden | 122 +- .../telemetry-collector.latest.golden | 246 +- ...way-hostname-service-subsets.latest.golden | 96 +- ...teway-http2-upstream-subsets.latest.golden | 106 +- ...ating-gateway-http2-upstream.latest.golden | 38 +- ...teway-ignore-extra-resolvers.latest.golden | 106 +- ...erminating-gateway-lb-config.latest.golden | 118 +- ...minating-gateway-no-services.latest.golden | 4 +- ...ting-gateway-service-subsets.latest.golden | 118 +- .../terminating-gateway-sni.latest.golden | 82 +- ...ating-gateway-tcp-keepalives.latest.golden | 78 +- .../terminating-gateway.latest.golden | 66 +- ...xy-catalog-destinations-only.latest.golden | 162 +- ...arent-proxy-destination-http.latest.golden | 226 +- ...ransparent-proxy-destination.latest.golden | 226 +- ...roxy-dial-instances-directly.latest.golden | 204 +- ...ng-gateway-destinations-only.latest.golden | 98 +- ...-proxy-with-peered-upstreams.latest.golden | 116 +- .../clusters/transparent-proxy.latest.golden | 168 +- ...oute-and-inline-certificate.latest.golden} | 28 +- ...-route-timeoutfilter-one-set.latest.golden | 41 - .../api-gateway-with-http-route.latest.golden | 41 - ...multiple-inline-certificates.latest.golden | 5 - ...route-and-inline-certificate.latest.golden | 4 +- ...nect-proxy-exported-to-peers.latest.golden | 4 +- ...and-failover-to-cluster-peer.latest.golden | 102 +- ...roxy-with-chain-and-failover.latest.golden | 116 +- ...oxy-with-chain-and-overrides.latest.golden | 4 +- ...and-redirect-to-cluster-peer.latest.golden | 66 +- ...roxy-with-chain-external-sni.latest.golden | 4 +- .../connect-proxy-with-chain.latest.golden | 4 +- ...ult-chain-and-custom-cluster.latest.golden | 4 +- ...d-upstreams-escape-overrides.latest.golden | 29 - ...-with-peered-upstreams-http2.latest.golden | 29 - ...-proxy-with-peered-upstreams.latest.golden | 4 +- ...ough-local-gateway-triggered.latest.golden | 152 +- ...ilover-through-local-gateway.latest.golden | 116 +- ...ugh-remote-gateway-triggered.latest.golden | 152 +- ...lover-through-remote-gateway.latest.golden | 116 +- ...ough-local-gateway-triggered.latest.golden | 116 +- ...ilover-through-local-gateway.latest.golden | 116 +- ...ugh-remote-gateway-triggered.latest.golden | 116 +- ...lover-through-remote-gateway.latest.golden | 116 +- .../testdata/endpoints/defaults.latest.golden | 4 +- ...ess-gateway-nil-config-entry.latest.golden | 4 +- .../ingress-gateway-no-services.latest.golden | 4 +- .../endpoints/ingress-gateway.latest.golden | 4 +- ...-listeners-duplicate-service.latest.golden | 4 +- ...itter-with-resolver-redirect.latest.golden | 4 +- ...and-failover-to-cluster-peer.latest.golden | 66 +- ...ress-with-chain-and-failover.latest.golden | 80 +- ...ress-with-chain-external-sni.latest.golden | 4 +- .../ingress-with-chain.latest.golden | 4 +- ...ough-local-gateway-triggered.latest.golden | 116 +- ...ilover-through-local-gateway.latest.golden | 80 +- ...ugh-remote-gateway-triggered.latest.golden | 116 +- ...lover-through-remote-gateway.latest.golden | 80 +- ...ough-local-gateway-triggered.latest.golden | 80 +- ...ilover-through-local-gateway.latest.golden | 80 +- ...ugh-remote-gateway-triggered.latest.golden | 80 +- ...lover-through-remote-gateway.latest.golden | 80 +- ...ateway-with-peered-upstreams.latest.golden | 4 +- ...teway-default-service-subset.latest.golden | 4 +- ...rmation-in-federation-states.latest.golden | 4 +- .../mesh-gateway-no-services.latest.golden | 4 +- ...rmation-in-federation-states.latest.golden | 4 +- ...ateway-peering-control-plane.latest.golden | 4 +- ...mesh-gateway-service-subsets.latest.golden | 4 +- ...ing-federation-control-plane.latest.golden | 249 - ...eway-using-federation-states.latest.golden | 4 +- ...ed-services-http-with-router.latest.golden | 104 +- ...xported-peered-services-http.latest.golden | 4 +- ...ith-exported-peered-services.latest.golden | 4 +- ...ith-imported-peered-services.latest.golden | 4 +- ...through-mesh-gateway-enabled.latest.golden | 4 +- .../endpoints/mesh-gateway.latest.golden | 4 +- ...itter-with-resolver-redirect.latest.golden | 4 +- .../telemetry-collector.latest.golden | 102 +- ...teway-default-service-subset.latest.golden | 4 +- ...minating-gateway-no-services.latest.golden | 4 +- ...ting-gateway-service-subsets.latest.golden | 4 +- .../terminating-gateway.latest.golden | 4 +- ...arent-proxy-destination-http.latest.golden | 4 +- ...ransparent-proxy-destination.latest.golden | 4 +- ...ng-gateway-destinations-only.latest.golden | 4 +- ...-proxy-with-peered-upstreams.latest.golden | 8 +- .../endpoints/transparent-proxy.latest.golden | 8 +- .../jwt_authn/intention-with-path.golden | 18 +- .../testdata/jwt_authn/local-provider.golden | 12 +- ...ltiple-providers-and-one-permission.golden | 49 +- .../testdata/jwt_authn/remote-provider.golden | 18 +- .../top-level-provider-with-permission.golden | 19 +- ...ttp-provider-with-hostname-and-port.golden | 2 +- ...http-provider-with-hostname-no-port.golden | 2 +- .../http-provider-with-ip-and-port.golden | 2 +- .../http-provider-with-ip-no-port.golden | 2 +- ...tps-provider-with-hostname-and-port.golden | 4 +- ...ttps-provider-with-hostname-no-port.golden | 4 +- .../https-provider-with-ip-and-port.golden | 6 +- .../https-provider-with-ip-no-port.golden | 4 +- .../access-logs-defaults.latest.golden | 398 +- .../access-logs-json-file.latest.golden | 144 +- ...t-stderr-disablelistenerlogs.latest.golden | 36 +- ...ttp-listener-with-http-route.latest.golden | 22 +- .../api-gateway-http-listener.latest.golden | 6 +- ...api-gateway-nil-config-entry.latest.golden | 6 +- ...ener-with-tcp-and-http-route.latest.golden | 28 +- ...-tcp-listener-with-tcp-route.latest.golden | 36 +- .../api-gateway-tcp-listener.latest.golden | 6 +- .../api-gateway-tcp-listeners.latest.golden | 5 + ...route-and-inline-certificate.latest.golden | 54 + ...-route-timeoutfilter-one-set.latest.golden | 85 - .../api-gateway-with-http-route.latest.golden | 85 - ...multiple-inline-certificates.latest.golden | 102 - ...route-and-inline-certificate.latest.golden | 14 +- .../listeners/api-gateway.latest.golden | 6 +- ...nect-proxy-exported-to-peers.latest.golden | 18 +- ...nect-proxy-upstream-defaults.latest.golden | 30 +- ...and-failover-to-cluster-peer.latest.golden | 132 +- ...oxy-with-chain-and-overrides.latest.golden | 38 +- ...and-redirect-to-cluster-peer.latest.golden | 132 +- ...roxy-with-chain-external-sni.latest.golden | 30 +- ...onnect-proxy-with-grpc-chain.latest.golden | 38 +- ...onnect-proxy-with-http-chain.latest.golden | 36 +- ...nnect-proxy-with-http2-chain.latest.golden | 38 +- ...-jwt-config-entry-with-local.latest.golden | 100 +- ...d-upstreams-escape-overrides.latest.golden | 114 - ...-with-peered-upstreams-http2.latest.golden | 189 - ...-proxy-with-peered-upstreams.latest.golden | 30 +- ...ilover-through-local-gateway.latest.golden | 30 +- ...lover-through-remote-gateway.latest.golden | 30 +- ...connect-proxy-with-tcp-chain.latest.golden | 30 +- ...h-tls-incoming-cipher-suites.latest.golden | 38 +- ...ith-tls-incoming-max-version.latest.golden | 32 +- ...ith-tls-incoming-min-version.latest.golden | 32 +- ...ls-outgoing-min-version-auto.latest.golden | 30 +- ...h-tproxy-and-permissive-mtls.latest.golden | 38 +- ...t-tproxy-and-permissive-mtls.latest.golden | 26 +- ...ustom-public-listener-http-2.latest.golden | 62 +- ...public-listener-http-missing.latest.golden | 40 +- .../custom-public-listener-http.latest.golden | 62 +- .../custom-public-listener.latest.golden | 32 +- .../custom-trace-listener.latest.golden | 110 +- ...eam-ignored-with-disco-chain.latest.golden | 30 +- ...upstream-with-prepared-query.latest.golden | 114 - .../listeners/custom-upstream.latest.golden | 32 +- .../testdata/listeners/defaults.latest.golden | 30 +- .../expose-checks-grpc.latest.golden | 143 - ...ecks-http-with-bind-override.latest.golden | 142 - ...est.golden => expose-checks.latest.golden} | 34 +- ...expose-paths-local-app-paths.latest.golden | 56 +- ...pose-paths-new-cluster-http2.latest.golden | 58 +- .../grpc-public-listener.latest.golden | 76 +- .../http-listener-with-timeouts.latest.golden | 94 +- ...http-public-listener-no-xfcc.latest.golden | 62 +- .../http-public-listener.latest.golden | 90 +- .../listeners/http-upstream.latest.golden | 40 +- .../http2-public-listener.latest.golden | 94 +- .../ingress-gateway-bind-addrs.latest.golden | 22 +- ...ess-gateway-nil-config-entry.latest.golden | 4 +- .../ingress-gateway-no-services.latest.golden | 4 +- .../listeners/ingress-gateway.latest.golden | 10 +- ...gress-grpc-multiple-services.latest.golden | 24 +- ...gress-http-multiple-services.latest.golden | 40 +- ...itter-with-resolver-redirect.latest.golden | 22 +- ...ress-with-chain-external-sni.latest.golden | 10 +- ...ith-grpc-single-tls-listener.latest.golden | 60 +- ...d-grpc-multiple-tls-listener.latest.golden | 76 +- ...th-http2-single-tls-listener.latest.golden | 60 +- ...h-sds-listener+service-level.latest.golden | 62 +- ...h-sds-listener-gw-level-http.latest.golden | 34 +- ...-listener-gw-level-mixed-tls.latest.golden | 26 +- ...s-with-sds-listener-gw-level.latest.golden | 20 +- ...-sds-listener-listener-level.latest.golden | 20 +- ...s-service-level-mixed-no-tls.latest.golden | 50 +- ...gress-with-sds-service-level.latest.golden | 62 +- ...ess-with-single-tls-listener.latest.golden | 54 +- ...ilover-through-local-gateway.latest.golden | 10 +- ...lover-through-remote-gateway.latest.golden | 10 +- ...h-tls-listener-cipher-suites.latest.golden | 22 +- ...ith-tls-listener-max-version.latest.golden | 16 +- ...ith-tls-listener-min-version.latest.golden | 16 +- .../ingress-with-tls-listener.latest.golden | 14 +- ...n-listeners-gateway-defaults.latest.golden | 160 +- ...ixed-cipher-suites-listeners.latest.golden | 166 - ...ess-with-tls-mixed-listeners.latest.golden | 50 +- ...-mixed-max-version-listeners.latest.golden | 238 - ...-mixed-min-version-listeners.latest.golden | 100 +- ...-balance-inbound-connections.latest.golden | 40 +- ...tbound-connections-bind-port.latest.golden | 40 +- .../listener-bind-address-port.latest.golden | 30 +- .../listener-bind-address.latest.golden | 30 +- .../listener-bind-port.latest.golden | 30 +- ...ener-max-inbound-connections.latest.golden | 34 +- .../listener-unix-domain-socket.latest.golden | 34 +- ...ateway-with-peered-upstreams.latest.golden | 30 +- ...esh-gateway-custom-addresses.latest.golden | 84 +- .../mesh-gateway-no-services.latest.golden | 12 +- ...ateway-peering-control-plane.latest.golden | 16 +- ...esh-gateway-tagged-addresses.latest.golden | 44 +- ...ing-federation-control-plane.latest.golden | 181 - ...eway-using-federation-states.latest.golden | 24 +- ...ed-services-http-with-router.latest.golden | 38 +- ...xported-peered-services-http.latest.golden | 90 +- ...ith-exported-peered-services.latest.golden | 24 +- ...ith-imported-peered-services.latest.golden | 12 +- ...through-mesh-gateway-enabled.latest.golden | 24 +- .../listeners/mesh-gateway.latest.golden | 24 +- ...itter-with-resolver-redirect.latest.golden | 36 +- .../telemetry-collector.latest.golden | 72 +- ...-custom-and-tagged-addresses.latest.golden | 112 +- ...ateway-custom-trace-listener.latest.golden | 246 - ...minating-gateway-no-api-cert.latest.golden | 46 +- ...minating-gateway-no-services.latest.golden | 10 +- ...ting-gateway-service-subsets.latest.golden | 106 +- ...h-tls-incoming-cipher-suites.latest.golden | 90 +- ...ith-tls-incoming-max-version.latest.golden | 66 +- ...ith-tls-incoming-min-version.latest.golden | 66 +- .../terminating-gateway.latest.golden | 58 +- ...xy-catalog-destinations-only.latest.golden | 36 +- ...arent-proxy-destination-http.latest.golden | 58 +- ...ransparent-proxy-destination.latest.golden | 48 +- ...roxy-dial-instances-directly.latest.golden | 68 +- ...nsparent-proxy-http-upstream.latest.golden | 70 +- ...ng-gateway-destinations-only.latest.golden | 98 +- ...nt-proxy-terminating-gateway.latest.golden | 40 +- ...-proxy-with-peered-upstreams.latest.golden | 60 +- ...h-resolver-redirect-upstream.latest.golden | 54 +- .../listeners/transparent-proxy.latest.golden | 60 +- ...deny-all-and-path-allow--httpfilter.golden | 8 +- ...fault-allow-deny-all-and-path-allow.golden | 12 +- ...-deny-all-and-path-deny--httpfilter.golden | 12 +- ...efault-allow-deny-all-and-path-deny.golden | 12 +- ...ault-allow-kitchen-sink--httpfilter.golden | 24 +- .../rbac/default-allow-kitchen-sink.golden | 24 +- .../default-allow-one-deny--httpfilter.golden | 4 +- .../rbac/default-allow-one-deny.golden | 4 +- .../rbac/default-allow-path-allow.golden | 4 +- ...default-allow-path-deny--httpfilter.golden | 4 +- .../rbac/default-allow-path-deny.golden | 4 +- ...w-service-wildcard-deny--httpfilter.golden | 4 +- ...default-allow-service-wildcard-deny.golden | 4 +- ...with-kitchen-sink-perms--httpfilter.golden | 78 +- ...e-intention-with-kitchen-sink-perms.golden | 4 +- ...ath-deny-and-path-allow--httpfilter.golden | 4 +- ...-allow-two-path-deny-and-path-allow.golden | 4 +- ...default-deny-allow-deny--httpfilter.golden | 8 +- .../rbac/default-deny-allow-deny.golden | 8 +- ...deny-all-and-path-allow--httpfilter.golden | 4 +- ...efault-deny-deny-all-and-path-allow.golden | 4 +- ...-deny-all-and-path-deny--httpfilter.golden | 4 +- ...default-deny-deny-all-and-path-deny.golden | 4 +- ...fault-deny-kitchen-sink--httpfilter.golden | 24 +- .../rbac/default-deny-kitchen-sink.golden | 24 +- ...t-deny-mixed-precedence--httpfilter.golden | 4 +- .../rbac/default-deny-mixed-precedence.golden | 4 +- .../default-deny-one-allow--httpfilter.golden | 4 +- .../rbac/default-deny-one-allow.golden | 4 +- ...default-deny-path-allow--httpfilter.golden | 4 +- .../rbac/default-deny-path-allow.golden | 4 +- .../default-deny-path-deny--httpfilter.golden | 4 +- .../rbac/default-deny-path-deny.golden | 4 +- ...eny-peered-kitchen-sink--httpfilter.golden | 16 +- .../default-deny-peered-kitchen-sink.golden | 12 +- ...-service-wildcard-allow--httpfilter.golden | 4 +- ...default-deny-service-wildcard-allow.golden | 4 +- ...with-kitchen-sink-perms--httpfilter.golden | 78 +- ...e-intention-with-kitchen-sink-perms.golden | 4 +- ...ath-deny-and-path-allow--httpfilter.golden | 4 +- ...t-deny-two-path-deny-and-path-allow.golden | 4 +- ...jwt-with-one-permission--httpfilter.golden | 16 +- ...y-top-level-jwt-with-one-permission.golden | 4 +- ...evel-jwt-no-permissions--httpfilter.golden | 28 +- .../rbac/top-level-jwt-no-permissions.golden | 4 +- ...th-multiple-permissions--httpfilter.golden | 114 +- ...level-jwt-with-multiple-permissions.golden | 4 +- ...jwt-with-one-permission--httpfilter.golden | 48 +- .../top-level-jwt-with-one-permission.golden | 4 +- .../xds/testdata/rbac/v2-default-allow.golden | 1 - .../xds/testdata/rbac/v2-default-deny.golden | 8 - .../rbac/v2-ignore-empty-permissions.golden | 22 - .../xds/testdata/rbac/v2-kitchen-sink.golden | 122 - ...oute-and-inline-certificate.latest.golden} | 27 +- .../api-gateway-with-http-route.latest.golden | 59 - ...eway-with-multiple-hostnames.latest.golden | 68 +- ...multiple-inline-certificates.latest.golden | 5 - ...route-and-inline-certificate.latest.golden | 4 +- ...nect-proxy-exported-to-peers.latest.golden | 4 +- ...connect-proxy-lb-in-resolver.latest.golden | 43 +- ...nnect-proxy-resolver-with-lb.latest.golden | 30 - ...t-proxy-route-to-lb-resolver.latest.golden | 38 - ...ct-proxy-splitter-overweight.latest.golden | 99 - ...and-failover-to-cluster-peer.latest.golden | 34 +- ...oxy-with-chain-and-overrides.latest.golden | 10 +- ...and-redirect-to-cluster-peer.latest.golden | 34 +- ...-proxy-with-chain-and-router.latest.golden | 128 +- ...roxy-with-chain-and-splitter.latest.golden | 46 +- ...roxy-with-chain-external-sni.latest.golden | 34 +- .../connect-proxy-with-chain.latest.golden | 34 +- ...nnect-proxy-with-grpc-router.latest.golden | 10 +- ...d-upstreams-escape-overrides.latest.golden | 5 - ...-with-peered-upstreams-http2.latest.golden | 5 - ...-proxy-with-peered-upstreams.latest.golden | 4 +- .../testdata/routes/defaults.latest.golden | 4 +- .../ingress-config-entry-nil.latest.golden | 4 +- .../ingress-defaults-no-chain.latest.golden | 4 +- ...gress-grpc-multiple-services.latest.golden | 50 +- ...gress-http-multiple-services.latest.golden | 20 +- .../ingress-lb-in-resolver.latest.golden | 43 +- ...itter-with-resolver-redirect.latest.golden | 10 +- ...hain-and-router-header-manip.latest.golden | 204 +- ...ngress-with-chain-and-router.latest.golden | 128 +- ...ress-with-chain-and-splitter.latest.golden | 46 +- ...ress-with-chain-external-sni.latest.golden | 4 +- .../routes/ingress-with-chain.latest.golden | 4 +- .../ingress-with-grpc-router.latest.golden | 10 +- ...-sds-listener-level-wildcard.latest.golden | 50 +- ...ress-with-sds-listener-level.latest.golden | 50 +- ...-sds-service-level-mixed-tls.latest.golden | 60 +- ...gress-with-sds-service-level.latest.golden | 60 +- ...ateway-with-peered-upstreams.latest.golden | 4 +- ...ateway-peering-control-plane.latest.golden | 4 +- ...ed-services-http-with-router.latest.golden | 10 +- ...xported-peered-services-http.latest.golden | 22 +- ...ith-exported-peered-services.latest.golden | 4 +- ...ith-imported-peered-services.latest.golden | 4 +- ...through-mesh-gateway-enabled.latest.golden | 4 +- ...itter-with-resolver-redirect.latest.golden | 10 +- .../routes/telemetry-collector.latest.golden | 6 +- ...erminating-gateway-lb-config.latest.golden | 37 +- ...arent-proxy-destination-http.latest.golden | 20 +- ...ransparent-proxy-destination.latest.golden | 4 +- ...ng-gateway-destinations-only.latest.golden | 16 +- ...-proxy-with-peered-upstreams.latest.golden | 4 +- .../routes/transparent-proxy.latest.golden | 4 +- ...-route-timeoutfilter-one-set.latest.golden | 5 - .../api-gateway-with-http-route.latest.golden | 5 - ...multiple-inline-certificates.latest.golden | 5 - ...route-and-inline-certificate.latest.golden | 4 +- ...nect-proxy-exported-to-peers.latest.golden | 6 +- ...and-failover-to-cluster-peer.latest.golden | 6 +- ...and-redirect-to-cluster-peer.latest.golden | 6 +- ...d-upstreams-escape-overrides.latest.golden | 5 - ...-with-peered-upstreams-http2.latest.golden | 5 - ...-upstreams-listener-override.latest.golden | 5 - ...-proxy-with-peered-upstreams.latest.golden | 6 +- .../testdata/secrets/defaults.latest.golden | 6 +- ...ateway-with-peered-upstreams.latest.golden | 6 +- ...ateway-peering-control-plane.latest.golden | 6 +- ...ed-services-http-with-router.latest.golden | 6 +- ...xported-peered-services-http.latest.golden | 6 +- ...ith-exported-peered-services.latest.golden | 6 +- ...ith-imported-peered-services.latest.golden | 6 +- ...through-mesh-gateway-enabled.latest.golden | 6 +- .../secrets/telemetry-collector.latest.golden | 6 +- ...arent-proxy-destination-http.latest.golden | 6 +- ...ransparent-proxy-destination.latest.golden | 6 +- ...ng-gateway-destinations-only.latest.golden | 6 +- ...-proxy-with-peered-upstreams.latest.golden | 6 +- .../secrets/transparent-proxy.latest.golden | 6 +- agent/xds/testing.go | 2 +- .../validateupstream_test.go | 2 +- agent/xds/xds.go | 2 +- agent/xds/xds_protocol_helpers_test.go | 51 +- agent/xds/z_xds_packages_test.go | 2 +- agent/xdsv2/cluster_resources.go | 384 -- agent/xdsv2/endpoint_resources.go | 61 - agent/xdsv2/listener_resources.go | 1146 ----- agent/xdsv2/rbac_resources.go | 256 - agent/xdsv2/resources.go | 75 - agent/xdsv2/resources_test.go | 150 - agent/xdsv2/route_resources.go | 544 -- ...it-and-explicit-destinations-tproxy.golden | 110 - .../destination/l4-multi-destination.golden | 205 - ...ltiple-implicit-destinations-tproxy.golden | 110 - ...le-destination-ip-port-bind-address.golden | 109 - ...estination-unix-socket-bind-address.golden | 55 - ...-single-implicit-destination-tproxy.golden | 62 - .../mixed-multi-destination.golden | 157 - ...ltiple-implicit-destinations-tproxy.golden | 302 -- ...-single-implicit-destination-tproxy.golden | 158 - ...tion-with-multiple-workloads-tproxy.golden | 158 - ...kload-addresses-with-specific-ports.golden | 31 - ...le-workload-addresses-without-ports.golden | 31 - ...ngle-workload-address-without-ports.golden | 31 - .../clusters/source/l7-expose-paths.golden | 87 - .../local-and-inbound-connections.golden | 127 - ...kload-addresses-with-specific-ports.golden | 55 - ...le-workload-addresses-without-ports.golden | 55 - ...ort-l4-workload-with-only-mesh-port.golden | 12 - ...kload-addresses-with-specific-ports.golden | 63 - ...le-workload-addresses-without-ports.golden | 95 - ...it-and-explicit-destinations-tproxy.golden | 49 - .../destination/l4-multi-destination.golden | 91 - ...ltiple-implicit-destinations-tproxy.golden | 49 - ...le-destination-ip-port-bind-address.golden | 49 - ...estination-unix-socket-bind-address.golden | 28 - ...-single-implicit-destination-tproxy.golden | 28 - .../mixed-multi-destination.golden | 91 - ...ltiple-implicit-destinations-tproxy.golden | 133 - ...-single-implicit-destination-tproxy.golden | 70 - ...tion-with-multiple-workloads-tproxy.golden | 70 - ...kload-addresses-with-specific-ports.golden | 27 - ...le-workload-addresses-without-ports.golden | 27 - ...ngle-workload-address-without-ports.golden | 27 - .../endpoints/source/l7-expose-paths.golden | 67 - .../local-and-inbound-connections.golden | 87 - ...kload-addresses-with-specific-ports.golden | 47 - ...ort-l4-workload-with-only-mesh-port.golden | 5 - ...kload-addresses-with-specific-ports.golden | 47 - ...le-workload-addresses-without-ports.golden | 67 - ...it-and-explicit-destinations-tproxy.golden | 90 - .../destination/l4-multi-destination.golden | 137 - ...ltiple-implicit-destinations-tproxy.golden | 86 - ...le-destination-ip-port-bind-address.golden | 47 - ...estination-unix-socket-bind-address.golden | 32 - ...-single-implicit-destination-tproxy.golden | 61 - .../mixed-multi-destination.golden | 119 - ...ltiple-implicit-destinations-tproxy.golden | 222 - ...-single-implicit-destination-tproxy.golden | 125 - ...tion-with-multiple-workloads-tproxy.golden | 125 - ...kload-addresses-with-specific-ports.golden | 100 - ...le-workload-addresses-without-ports.golden | 78 - ...ngle-workload-address-without-ports.golden | 78 - .../listeners/source/l7-expose-paths.golden | 201 - .../local-and-inbound-connections.golden | 309 -- ...kload-addresses-with-specific-ports.golden | 128 - ...le-workload-addresses-without-ports.golden | 128 - ...ort-l4-workload-with-only-mesh-port.golden | 40 - ...kload-addresses-with-specific-ports.golden | 206 - ...le-workload-addresses-without-ports.golden | 309 -- ...it-and-explicit-destinations-tproxy.golden | 5 - .../destination/l4-multi-destination.golden | 5 - ...ltiple-implicit-destinations-tproxy.golden | 5 - ...le-destination-ip-port-bind-address.golden | 5 - ...estination-unix-socket-bind-address.golden | 5 - ...-single-implicit-destination-tproxy.golden | 5 - .../mixed-multi-destination.golden | 67 - ...ltiple-implicit-destinations-tproxy.golden | 53 - ...-single-implicit-destination-tproxy.golden | 30 - ...tion-with-multiple-workloads-tproxy.golden | 30 - ...kload-addresses-with-specific-ports.golden | 5 - ...le-workload-addresses-without-ports.golden | 5 - ...ngle-workload-address-without-ports.golden | 5 - .../routes/source/l7-expose-paths.golden | 53 - .../local-and-inbound-connections.golden | 77 - ...kload-addresses-with-specific-ports.golden | 5 - ...le-workload-addresses-without-ports.golden | 5 - ...ort-l4-workload-with-only-mesh-port.golden | 5 - ...kload-addresses-with-specific-ports.golden | 53 - ...le-workload-addresses-without-ports.golden | 76 - api/.copywrite.hcl | 8 - api/LICENSE | 365 -- api/acl.go | 113 - api/agent.go | 18 - api/agent_test.go | 52 +- api/ce_test.go | 1 + api/config_entry.go | 54 +- api/config_entry_gateways.go | 40 - api/config_entry_gateways_test.go | 147 - api/config_entry_routes.go | 40 +- api/config_entry_routes_test.go | 137 - api/config_entry_status.go | 19 - api/config_entry_status_test.go | 3 - api/go.mod | 2 +- api/go.sum | 4 +- api/internal.go | 3 - api/internal_test.go | 3 - api/namespace_test.go | 1 + api/operator_raft.go | 7 +- api/operator_raft_test.go | 187 +- api/watch/funcs_test.go | 104 - buf.work.yaml | 2 +- build-support/docker/Build-Go.dockerfile | 2 +- build-support/docker/Build-UI.dockerfile | 5 +- .../docker/Consul-Dev-Dbg.dockerfile | 2 +- .../docker/Consul-Dev-Multiarch.dockerfile | 2 +- build-support/docker/Consul-Dev.dockerfile | 2 +- build-support/functions/00-vars.sh | 2 +- build-support/functions/10-util.sh | 2 +- build-support/functions/20-build.sh | 2 +- build-support/functions/30-release.sh | 2 +- build-support/scripts/build-date.sh | 2 +- build-support/scripts/build-docker.sh | 2 +- .../scripts/check-allowed-imports.sh | 124 - build-support/scripts/copywrite-exceptions.sh | 14 - build-support/scripts/devtools.sh | 46 +- .../scripts/envoy-library-references.sh | 2 +- build-support/scripts/functions.sh | 2 +- build-support/scripts/protobuf.sh | 12 +- build-support/scripts/release.sh | 2 +- build-support/scripts/version.sh | 2 +- .../windows/Dockerfile-consul-dev-windows | 4 - .../windows/Dockerfile-consul-local-windows | 52 - .../windows/Dockerfile-openzipkin-windows | 12 - .../windows/build-consul-dev-image.sh | 8 - .../windows/build-consul-local-images.sh | 95 - .../windows/build-test-sds-server-image.sh | 8 - build-support/windows/windows-test.md | 119 - command/acl/acl.go | 2 +- command/acl/acl_helpers.go | 78 +- command/acl/acl_test.go | 2 +- command/acl/agenttokens/agent_tokens.go | 12 +- command/acl/agenttokens/agent_tokens_test.go | 2 +- command/acl/authmethod/authmethod.go | 2 +- .../authmethod/create/authmethod_create.go | 2 +- .../authmethod/create/authmethod_create_ce.go | 3 +- .../create/authmethod_create_test.go | 2 +- .../authmethod/delete/authmethod_delete.go | 2 +- .../delete/authmethod_delete_test.go | 2 +- command/acl/authmethod/formatter.go | 2 +- .../acl/authmethod/list/authmethod_list.go | 2 +- .../authmethod/list/authmethod_list_test.go | 2 +- .../acl/authmethod/read/authmethod_read.go | 2 +- .../authmethod/read/authmethod_read_test.go | 2 +- .../authmethod/update/authmethod_update.go | 2 +- .../authmethod/update/authmethod_update_ce.go | 3 +- .../update/authmethod_update_test.go | 2 +- command/acl/bindingrule/bindingrule.go | 2 +- .../bindingrule/create/bindingrule_create.go | 33 +- .../create/bindingrule_create_test.go | 55 +- .../bindingrule/delete/bindingrule_delete.go | 2 +- .../delete/bindingrule_delete_test.go | 2 +- command/acl/bindingrule/formatter.go | 9 +- .../acl/bindingrule/list/bindingrule_list.go | 2 +- .../bindingrule/list/bindingrule_list_test.go | 2 +- .../acl/bindingrule/read/bindingrule_read.go | 2 +- .../bindingrule/read/bindingrule_read_test.go | 2 +- .../bindingrule/update/bindingrule_update.go | 37 +- .../update/bindingrule_update_test.go | 227 +- command/acl/bootstrap/bootstrap.go | 2 +- command/acl/bootstrap/bootstrap_test.go | 2 +- command/acl/policy/create/policy_create.go | 4 +- .../acl/policy/create/policy_create_test.go | 2 +- command/acl/policy/delete/policy_delete.go | 2 +- .../acl/policy/delete/policy_delete_test.go | 2 +- command/acl/policy/formatter.go | 2 +- command/acl/policy/list/policy_list.go | 2 +- command/acl/policy/list/policy_list_test.go | 2 +- command/acl/policy/policy.go | 2 +- command/acl/policy/read/policy_read.go | 2 +- command/acl/policy/read/policy_read_test.go | 2 +- command/acl/policy/update/policy_update.go | 2 +- .../acl/policy/update/policy_update_test.go | 2 +- command/acl/role/create/role_create.go | 48 +- command/acl/role/create/role_create_test.go | 18 +- command/acl/role/delete/role_delete.go | 2 +- command/acl/role/delete/role_delete_test.go | 2 +- command/acl/role/formatter.go | 31 +- command/acl/role/formatter_test.go | 16 +- command/acl/role/list/role_list.go | 2 +- command/acl/role/list/role_list_test.go | 2 +- command/acl/role/read/role_read.go | 2 +- command/acl/role/read/role_read_test.go | 2 +- command/acl/role/role.go | 2 +- .../testdata/FormatRole/complex.json.golden | 18 - .../FormatRole/complex.pretty-meta.golden | 7 - .../testdata/FormatRole/complex.pretty.golden | 7 - .../FormatRoleList/complex.json.golden | 14 - .../FormatRoleList/complex.pretty-meta.golden | 7 - .../FormatRoleList/complex.pretty.golden | 7 - command/acl/role/update/role_update.go | 60 +- command/acl/role/update/role_update_test.go | 110 +- command/acl/templatedpolicy/formatter.go | 136 - .../acl/templatedpolicy/formatter_ce_test.go | 16 - command/acl/templatedpolicy/formatter_test.go | 125 - .../list/templated_policy_list.go | 101 - .../list/templated_policy_list_test.go | 102 - .../preview/templated_policy_preview.go | 134 - .../preview/templated_policy_preview_test.go | 204 - .../read/templated_policy_read.go | 119 - .../read/templated_policy_read_test.go | 134 - .../acl/templatedpolicy/templated_policy.go | 50 - .../ce/dns-templated-policy.json.golden | 5 - .../dns-templated-policy.pretty-meta.golden | 15 - .../ce/dns-templated-policy.pretty.golden | 4 - .../ce/node-templated-policy.json.golden | 5 - .../node-templated-policy.pretty-meta.golden | 28 - .../ce/node-templated-policy.pretty.golden | 5 - .../nomad-server-templated-policy.json.golden | 5 - ...server-templated-policy.pretty-meta.golden | 16 - ...omad-server-templated-policy.pretty.golden | 4 - .../ce/service-templated-policy.json.golden | 5 - ...ervice-templated-policy.pretty-meta.golden | 34 - .../ce/service-templated-policy.pretty.golden | 5 - .../ce/list.json.golden | 17 - .../ce/list.pretty.golden | 3 - command/acl/token/clone/token_clone.go | 2 +- command/acl/token/clone/token_clone_test.go | 11 +- command/acl/token/create/token_create.go | 60 +- command/acl/token/create/token_create_test.go | 38 +- command/acl/token/delete/token_delete.go | 2 +- command/acl/token/delete/token_delete_test.go | 2 +- command/acl/token/formatter.go | 76 +- command/acl/token/formatter_ce_test.go | 3 +- command/acl/token/formatter_test.go | 47 +- command/acl/token/list/token_list.go | 2 +- command/acl/token/list/token_list_test.go | 2 +- command/acl/token/read/token_read.go | 2 +- command/acl/token/read/token_read_test.go | 2 +- .../testdata/FormatToken/complex.json.golden | 18 - .../FormatToken/complex.pretty-meta.golden | 7 - .../FormatToken/complex.pretty.golden | 7 - .../ce/complex.json.golden | 17 - .../ce/complex.pretty-meta.golden | 43 +- .../ce/complex.pretty.golden | 43 +- .../FormatTokenList/complex.json.golden | 17 - .../complex.pretty-meta.golden | 7 - .../FormatTokenList/complex.pretty.golden | 7 - command/acl/token/token.go | 2 +- command/acl/token/update/token_update.go | 80 +- command/acl/token/update/token_update_test.go | 47 +- command/agent/agent.go | 2 +- command/agent/agent_test.go | 2 +- command/agent/startup_logger.go | 2 +- command/catalog/catalog.go | 2 +- command/catalog/catalog_test.go | 2 +- command/catalog/helpers.go | 2 +- command/catalog/helpers_ce.go | 3 +- .../list/dc/catalog_list_datacenters.go | 2 +- .../list/dc/catalog_list_datacenters_test.go | 2 +- .../catalog/list/nodes/catalog_list_nodes.go | 2 +- .../list/nodes/catalog_list_nodes_test.go | 2 +- .../list/services/catalog_list_services.go | 2 +- .../services/catalog_list_services_test.go | 2 +- command/cli/cli.go | 2 +- command/cli/formatting.go | 2 +- command/config/config.go | 2 +- command/config/delete/config_delete.go | 2 +- command/config/delete/config_delete_test.go | 2 +- command/config/list/config_list.go | 2 +- command/config/list/config_list_test.go | 2 +- command/config/read/config_read.go | 2 +- command/config/read/config_read_test.go | 2 +- command/config/write/config_write.go | 68 +- command/config/write/config_write_test.go | 2 +- command/connect/ca/ca.go | 2 +- command/connect/ca/ca_test.go | 2 +- command/connect/ca/get/connect_ca_get.go | 2 +- command/connect/ca/get/connect_ca_get_test.go | 2 +- command/connect/ca/set/connect_ca_set.go | 2 +- command/connect/ca/set/connect_ca_set_test.go | 2 +- command/connect/connect.go | 2 +- command/connect/connect_test.go | 2 +- command/connect/envoy/bootstrap_config.go | 2 +- .../connect/envoy/bootstrap_config_test.go | 2 +- command/connect/envoy/bootstrap_tpl.go | 4 +- command/connect/envoy/envoy.go | 4 +- command/connect/envoy/envoy_ce_test.go | 3 +- command/connect/envoy/envoy_test.go | 2 +- command/connect/envoy/exec.go | 2 +- command/connect/envoy/exec_supported.go | 57 - command/connect/envoy/exec_test.go | 3 +- command/connect/envoy/exec_unix.go | 54 +- command/connect/envoy/exec_unsupported.go | 5 +- command/connect/envoy/exec_windows.go | 111 - command/connect/envoy/flags.go | 2 +- command/connect/envoy/flags_test.go | 2 +- .../connect_envoy_pipe-bootstrap.go | 2 +- .../connect_envoy_pipe-bootstrap_test.go | 2 +- command/connect/expose/expose.go | 2 +- command/connect/expose/expose_test.go | 2 +- command/connect/proxy/flag_upstreams.go | 2 +- command/connect/proxy/flag_upstreams_test.go | 2 +- command/connect/proxy/proxy.go | 2 +- command/connect/proxy/proxy_test.go | 2 +- command/connect/proxy/register.go | 2 +- command/connect/proxy/register_test.go | 2 +- .../redirecttraffic/redirect_traffic.go | 2 +- .../redirecttraffic/redirect_traffic_test.go | 2 +- command/debug/debug.go | 2 +- command/debug/debug_test.go | 2 +- command/event/event.go | 2 +- command/event/event_test.go | 2 +- command/exec/exec.go | 2 +- command/exec/exec_test.go | 2 +- command/flags/config.go | 2 +- command/flags/config_test.go | 2 +- command/flags/flag_map_value.go | 2 +- command/flags/flag_map_value_test.go | 2 +- command/flags/flag_slice_value.go | 2 +- command/flags/flag_slice_value_test.go | 2 +- command/flags/http.go | 13 +- command/flags/http_test.go | 2 +- command/flags/merge.go | 2 +- command/flags/usage.go | 2 +- command/forceleave/forceleave.go | 2 +- command/forceleave/forceleave_test.go | 2 +- command/helpers/decode_shim.go | 2 +- command/helpers/helpers.go | 24 +- command/helpers/helpers_test.go | 2 +- command/info/info.go | 2 +- command/info/info_test.go | 2 +- command/intention/check/check.go | 2 +- command/intention/check/check_test.go | 2 +- command/intention/create/create.go | 2 +- command/intention/create/create_test.go | 2 +- command/intention/delete/delete.go | 2 +- command/intention/delete/delete_test.go | 2 +- command/intention/format.go | 2 +- command/intention/get/get.go | 2 +- command/intention/get/get_test.go | 2 +- command/intention/helpers.go | 2 +- command/intention/helpers_test.go | 2 +- command/intention/intention.go | 2 +- command/intention/intention_test.go | 2 +- command/intention/list/intention_list.go | 2 +- command/intention/list/intention_list_test.go | 2 +- command/intention/match/match.go | 2 +- command/intention/match/match_test.go | 2 +- command/join/join.go | 2 +- command/join/join_test.go | 2 +- command/keygen/keygen.go | 2 +- command/keygen/keygen_test.go | 2 +- command/keyring/keyring.go | 2 +- command/keyring/keyring_test.go | 2 +- command/kv/del/kv_delete.go | 2 +- command/kv/del/kv_delete_test.go | 2 +- command/kv/exp/kv_export.go | 2 +- command/kv/exp/kv_export_test.go | 2 +- command/kv/get/kv_get.go | 2 +- command/kv/get/kv_get_test.go | 2 +- command/kv/imp/kv_import.go | 2 +- command/kv/imp/kv_import_test.go | 2 +- command/kv/impexp/kvimpexp.go | 2 +- command/kv/kv.go | 2 +- command/kv/kv_test.go | 2 +- command/kv/put/kv_put.go | 2 +- command/kv/put/kv_put_test.go | 2 +- command/leave/leave.go | 2 +- command/leave/leave_test.go | 2 +- command/lock/lock.go | 2 +- command/lock/lock_test.go | 2 +- command/lock/util_unix.go | 3 +- command/lock/util_windows.go | 3 +- command/login/aws.go | 2 +- command/login/login.go | 2 +- command/login/login_ce.go | 3 +- command/login/login_test.go | 2 +- command/logout/logout.go | 2 +- command/logout/logout_test.go | 2 +- command/maint/maint.go | 2 +- command/maint/maint_test.go | 2 +- command/members/members.go | 2 +- command/members/members_test.go | 2 +- command/monitor/monitor.go | 2 +- command/monitor/monitor_test.go | 2 +- .../autopilot/get/operator_autopilot_get.go | 2 +- .../get/operator_autopilot_get_test.go | 2 +- .../operator/autopilot/operator_autopilot.go | 2 +- .../autopilot/operator_autopilot_test.go | 2 +- .../autopilot/set/operator_autopilot_set.go | 2 +- .../set/operator_autopilot_set_test.go | 2 +- command/operator/autopilot/state/formatter.go | 2 +- .../state/operator_autopilot_state.go | 2 +- .../state/operator_autopilot_state_test.go | 2 +- command/operator/operator.go | 2 +- command/operator/operator_test.go | 2 +- .../raft/listpeers/operator_raft_list.go | 2 +- .../raft/listpeers/operator_raft_list_test.go | 2 +- command/operator/raft/operator_raft.go | 2 +- command/operator/raft/operator_raft_test.go | 2 +- .../raft/removepeer/operator_raft_remove.go | 2 +- .../removepeer/operator_raft_remove_test.go | 2 +- .../raft/transferleader/transfer_leader.go | 8 +- .../transferleader/transfer_leader_test.go | 2 +- .../usage/instances/usage_instances.go | 14 +- .../usage/instances/usage_instances_ce.go | 3 +- .../instances/usage_instances_ce_test.go | 3 +- .../usage/instances/usage_instances_test.go | 2 +- command/operator/usage/usage.go | 2 +- command/peering/delete/delete.go | 2 +- command/peering/delete/delete_test.go | 2 +- command/peering/establish/establish.go | 2 +- command/peering/establish/establish_test.go | 2 +- command/peering/generate/generate.go | 2 +- command/peering/generate/generate_test.go | 2 +- command/peering/list/list.go | 2 +- command/peering/list/list_test.go | 2 +- command/peering/peering.go | 2 +- command/peering/read/read.go | 2 +- command/peering/read/read_test.go | 2 +- command/registry.go | 20 +- command/registry_ce.go | 3 +- command/reload/reload.go | 2 +- command/reload/reload_test.go | 2 +- command/resource/apply/apply.go | 201 - command/resource/apply/apply_test.go | 237 - command/resource/client/client.go | 1073 ---- command/resource/delete/delete.go | 165 - command/resource/delete/delete_test.go | 158 - command/resource/helper.go | 315 -- command/resource/helper_test.go | 33 - command/resource/list/list.go | 199 - command/resource/list/list_test.go | 177 - command/resource/read/read.go | 179 - command/resource/read/read_test.go | 156 - command/resource/resource.go | 55 - command/resource/testdata/demo.hcl | 21 - command/resource/testdata/invalid.hcl | 21 - command/resource/testdata/invalid_type.hcl | 11 - command/resource/testdata/nested_data.hcl | 29 - command/rtt/rtt.go | 2 +- command/rtt/rtt_test.go | 2 +- command/services/config.go | 2 +- command/services/config_test.go | 2 +- command/services/deregister/deregister.go | 2 +- .../services/deregister/deregister_test.go | 2 +- command/services/export/export.go | 3 - command/services/export/export_test.go | 3 - command/services/register/register.go | 2 +- command/services/register/register_test.go | 2 +- command/services/services.go | 2 +- command/services/services_test.go | 2 +- command/snapshot/inspect/formatter.go | 2 +- command/snapshot/inspect/formatter_test.go | 2 +- command/snapshot/inspect/snapshot_inspect.go | 2 +- .../snapshot/inspect/snapshot_inspect_test.go | 2 +- command/snapshot/restore/snapshot_restore.go | 2 +- .../snapshot/restore/snapshot_restore_test.go | 2 +- command/snapshot/save/snapshot_save.go | 2 +- command/snapshot/save/snapshot_save_test.go | 2 +- command/snapshot/snapshot_command.go | 2 +- command/snapshot/snapshot_command_test.go | 2 +- command/tls/ca/create/tls_ca_create.go | 2 +- command/tls/ca/create/tls_ca_create_test.go | 2 +- command/tls/ca/tls_ca.go | 2 +- command/tls/ca/tls_ca_test.go | 2 +- command/tls/cert/create/tls_cert_create.go | 2 +- .../tls/cert/create/tls_cert_create_test.go | 2 +- command/tls/cert/tls_cert.go | 2 +- command/tls/cert/tls_cert_test.go | 2 +- command/tls/tls.go | 2 +- command/tls/tls_test.go | 2 +- .../troubleshoot/proxy/troubleshoot_proxy.go | 2 +- command/troubleshoot/troubleshoot.go | 2 +- command/troubleshoot/troubleshoot_test.go | 2 +- .../upstreams/troubleshoot_upstreams.go | 2 +- command/validate/validate.go | 2 +- command/validate/validate_test.go | 2 +- command/version/formatter.go | 2 +- command/version/formatter_test.go | 2 +- command/version/version.go | 2 +- command/version/version_test.go | 2 +- command/watch/watch.go | 2 +- command/watch/watch_test.go | 2 +- connect/certgen/certgen.go | 2 +- connect/example_test.go | 2 +- connect/proxy/config.go | 2 +- connect/proxy/config_test.go | 2 +- connect/proxy/conn.go | 2 +- connect/proxy/conn_test.go | 2 +- connect/proxy/listener.go | 2 +- connect/proxy/listener_test.go | 2 +- connect/proxy/proxy.go | 2 +- connect/proxy/proxy_test.go | 2 +- connect/proxy/testing.go | 2 +- connect/resolver.go | 2 +- connect/resolver_test.go | 2 +- connect/service.go | 2 +- connect/service_test.go | 2 +- connect/testing.go | 2 +- connect/tls.go | 4 +- connect/tls_test.go | 2 +- docs/README.md | 6 +- docs/resources/guide.md | 68 +- .../extensioncommon/basic_envoy_extender.go | 2 +- .../basic_extension_adapter.go | 2 +- .../extensioncommon/envoy_extender.go | 4 +- .../extensioncommon/envoy_extender_test.go | 3 - envoyextensions/extensioncommon/resources.go | 12 +- .../extensioncommon/resources_test.go | 2 +- .../extensioncommon/runtime_config.go | 2 +- .../extensioncommon/runtime_config_test.go | 2 +- .../upstream_envoy_extender.go | 2 +- envoyextensions/go.mod | 7 +- envoyextensions/go.sum | 6 +- envoyextensions/xdscommon/envoy_versioning.go | 2 +- .../xdscommon/envoy_versioning_test.go | 4 +- envoyextensions/xdscommon/proxysupport.go | 4 +- .../xdscommon/proxysupport_test.go | 2 +- envoyextensions/xdscommon/xdscommon.go | 6 +- envoyextensions/xdscommon/xdscommon_test.go | 3 - fixup_acl_move.sh | 27 + go.mod | 27 +- go.sum | 35 +- grafana/README.md | 4 - .../consul-k8s-control-plane-monitoring.json | 3598 -------------- internal/auth/exports.go | 41 - .../auth/internal/controllers/register.go | 17 - .../trafficpermissions/controller.go | 195 - .../trafficpermissions/controller_test.go | 681 --- .../controllers/trafficpermissions/status.go | 46 - .../traffic_permissions_mapper.go | 73 - .../types/computed_traffic_permissions.go | 71 - .../computed_traffic_permissions_test.go | 176 - internal/auth/internal/types/errors.go | 15 - .../internal/types/traffic_permissions.go | 270 - .../types/traffic_permissions_test.go | 777 --- internal/auth/internal/types/types.go | 14 - .../auth/internal/types/workload_identity.go | 59 - .../internal/types/workload_identity_test.go | 156 - .../helpers/acl_hooks_test_helpers.go | 21 - .../{v2beta1 => v1alpha1}/api-service.json | 4 +- .../api-workload-1-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-1.json | 4 +- .../api-workload-10-health.json | 6 +- .../api-workload-10.json | 4 +- .../api-workload-11-health.json | 6 +- .../api-workload-11.json | 4 +- .../api-workload-12-health.json | 6 +- .../api-workload-12.json | 4 +- .../api-workload-13-health.json | 6 +- .../api-workload-13.json | 4 +- .../api-workload-14-health.json | 6 +- .../api-workload-14.json | 4 +- .../api-workload-15-health.json | 6 +- .../api-workload-15.json | 4 +- .../api-workload-16-health.json | 6 +- .../api-workload-16.json | 4 +- .../api-workload-17-health.json | 6 +- .../api-workload-17.json | 4 +- .../api-workload-18-health.json | 6 +- .../api-workload-18.json | 4 +- .../api-workload-19-health.json | 6 +- .../api-workload-19.json | 4 +- .../api-workload-2-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-2.json | 4 +- .../api-workload-20-health.json | 6 +- .../api-workload-20.json | 4 +- .../api-workload-3-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-3.json | 4 +- .../api-workload-4-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-4.json | 4 +- .../api-workload-5-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-5.json | 4 +- .../api-workload-6-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-6.json | 4 +- .../api-workload-7-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-7.json | 4 +- .../api-workload-8-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-8.json | 4 +- .../api-workload-9-health.json | 6 +- .../{v2beta1 => v1alpha1}/api-workload-9.json | 4 +- .../foo-service-endpoints.json | 6 +- .../{v2beta1 => v1alpha1}/foo-service.json | 4 +- .../grpc-api-service.json | 4 +- .../http-api-service.json | 4 +- .../{v2beta1 => v1alpha1}/node-1-health.json | 6 +- .../{v2beta1 => v1alpha1}/node-1.json | 4 +- .../{v2beta1 => v1alpha1}/node-2-health.json | 6 +- .../{v2beta1 => v1alpha1}/node-2.json | 4 +- .../{v2beta1 => v1alpha1}/node-3-health.json | 6 +- .../{v2beta1 => v1alpha1}/node-3.json | 4 +- .../{v2beta1 => v1alpha1}/node-4-health.json | 6 +- .../{v2beta1 => v1alpha1}/node-4.json | 4 +- internal/catalog/catalogtest/run_test.go | 10 +- ...2beta1.go => test_integration_v1alpha1.go} | 231 +- .../catalogtest/test_lifecycle_v2beta1.go | 716 --- internal/catalog/exports.go | 124 +- .../controllers/endpoints/controller.go | 56 +- .../controllers/endpoints/controller_test.go | 215 +- .../endpoints/reconciliation_data.go | 24 +- .../endpoints/reconciliation_data_test.go | 80 +- .../internal/controllers/endpoints/status.go | 41 +- .../controllers/failover/controller.go | 276 -- .../controllers/failover/controller_test.go | 268 - .../internal/controllers/failover/status.go | 84 - .../controllers/nodehealth/controller.go | 16 +- .../controllers/nodehealth/controller_test.go | 39 +- .../internal/controllers/nodehealth/status.go | 4 +- .../catalog/internal/controllers/register.go | 5 +- .../controllers/workloadhealth/controller.go | 25 +- .../workloadhealth/controller_test.go | 97 +- .../controllers/workloadhealth/status.go | 5 +- .../mappers/failovermapper/failover_mapper.go | 63 - .../failovermapper/failover_mapper_test.go | 192 - .../mappers/nodemapper/node_mapper.go | 78 +- .../mappers/nodemapper/node_mapper_test.go | 27 +- .../selectiontracker/selection_tracker.go | 120 +- .../selection_tracker_test.go | 275 ++ .../testhelpers/acl_hooks_test_helpers.go | 198 - internal/catalog/internal/types/acl_hooks.go | 47 - internal/catalog/internal/types/dns_policy.go | 36 +- .../catalog/internal/types/dns_policy_test.go | 28 +- internal/catalog/internal/types/errors.go | 2 +- .../catalog/internal/types/errors_test.go | 2 +- .../catalog/internal/types/failover_policy.go | 358 -- .../internal/types/failover_policy_test.go | 849 ---- .../catalog/internal/types/health_checks.go | 36 +- .../internal/types/health_checks_test.go | 21 +- .../catalog/internal/types/health_status.go | 74 +- .../internal/types/health_status_test.go | 133 +- internal/catalog/internal/types/node.go | 57 +- internal/catalog/internal/types/node_test.go | 57 +- internal/catalog/internal/types/service.go | 64 +- .../internal/types/service_endpoints.go | 86 +- .../internal/types/service_endpoints_test.go | 190 +- .../catalog/internal/types/service_test.go | 85 +- internal/catalog/internal/types/types.go | 17 +- internal/catalog/internal/types/types_test.go | 27 +- internal/catalog/internal/types/validators.go | 154 +- .../catalog/internal/types/validators_test.go | 62 +- .../catalog/internal/types/virtual_ips.go | 44 +- .../internal/types/virtual_ips_test.go | 56 +- internal/catalog/internal/types/workload.go | 95 +- .../internal/types/workload_selecting.go | 16 - .../catalog/internal/types/workload_test.go | 193 +- internal/controller/api.go | 72 +- internal/controller/api_test.go | 48 +- internal/controller/controller.go | 100 +- internal/controller/dependencies.go | 100 - internal/controller/dependencies_test.go | 66 - internal/controller/dependency_mappers.go | 11 - .../controller/dependency_mappers_test.go | 3 - internal/controller/doc.go | 2 +- internal/controller/helper.go | 38 - internal/controller/helper_test.go | 77 - internal/controller/lease.go | 3 - internal/controller/manager.go | 3 - internal/controller/supervisor.go | 3 - internal/controller/supervisor_test.go | 3 - .../controller/testdata/dependencies.golden | 5 - internal/go-sso/oidcauth/auth.go | 2 +- internal/go-sso/oidcauth/config.go | 2 +- internal/go-sso/oidcauth/config_test.go | 2 +- .../go-sso/oidcauth/internal/strutil/util.go | 2 +- .../oidcauth/internal/strutil/util_test.go | 2 +- internal/go-sso/oidcauth/jwt.go | 2 +- internal/go-sso/oidcauth/jwt_test.go | 2 +- internal/go-sso/oidcauth/oidc.go | 2 +- internal/go-sso/oidcauth/oidc_test.go | 2 +- .../go-sso/oidcauth/oidcauthtest/testing.go | 2 +- internal/go-sso/oidcauth/oidcjwt.go | 2 +- internal/go-sso/oidcauth/oidcjwt_test.go | 2 +- internal/go-sso/oidcauth/util.go | 2 +- internal/go-sso/oidcauth/util_test.go | 2 +- internal/mesh/exports.go | 49 +- .../explicitdestinations/controller.go | 318 -- .../explicitdestinations/controller_test.go | 846 ---- .../explicitdestinations/mapper/mapper.go | 74 - .../explicitdestinations/status.go | 121 - .../proxyconfiguration/controller.go | 187 - .../proxyconfiguration/controller_test.go | 308 -- .../controllers/proxyconfiguration/sort.go | 108 - .../proxyconfiguration/sort_test.go | 158 - .../mesh/internal/controllers/register.go | 51 - .../internal/controllers/routes/bound_refs.go | 66 - .../internal/controllers/routes/controller.go | 184 - .../controllers/routes/controller_test.go | 1340 ----- .../internal/controllers/routes/generate.go | 835 ---- .../controllers/routes/generate_test.go | 1684 ------- .../controllers/routes/intermediate.go | 72 - .../controllers/routes/loader/loader.go | 323 -- .../controllers/routes/loader/loader_test.go | 413 -- .../controllers/routes/loader/memoized.go | 93 - .../controllers/routes/loader/related.go | 233 - .../controllers/routes/pending_status.go | 92 - .../controllers/routes/ref_validation.go | 121 - .../controllers/routes/ref_validation_test.go | 233 - .../routes/routestest/routestest.go | 104 - .../internal/controllers/routes/sort_rules.go | 230 - .../controllers/routes/sort_rules_test.go | 493 -- .../internal/controllers/routes/status.go | 168 - .../mesh/internal/controllers/routes/util.go | 20 - .../controllers/routes/xroutemapper/util.go | 58 - .../routes/xroutemapper/xroutemapper.go | 322 -- .../routes/xroutemapper/xroutemapper_test.go | 694 --- .../sidecarproxy/builder/builder.go | 122 - .../sidecarproxy/builder/builder_test.go | 36 - .../builder/destination_multiport_test.go | 261 - .../sidecarproxy/builder/destinations.go | 715 --- .../sidecarproxy/builder/destinations_test.go | 581 --- .../sidecarproxy/builder/expose_paths.go | 153 - .../sidecarproxy/builder/expose_paths_test.go | 103 - .../sidecarproxy/builder/local_app.go | 500 -- .../builder/local_app_multiport_test.go | 170 - .../sidecarproxy/builder/local_app_test.go | 559 --- .../sidecarproxy/builder/naming.go | 46 - .../sidecarproxy/builder/routes.go | 595 --- ...it-and-explicit-destinations-tproxy.golden | 194 - .../destination/l4-multi-destination.golden | 320 -- ...ltiple-implicit-destinations-tproxy.golden | 193 - ...le-destination-ip-port-bind-address.golden | 165 - ...estination-unix-socket-bind-address.golden | 97 - ...-single-implicit-destination-tproxy.golden | 128 - .../mixed-multi-destination.golden | 415 -- ...ltiple-implicit-destinations-tproxy.golden | 495 -- ...-single-implicit-destination-tproxy.golden | 276 -- ...tion-with-multiple-workloads-tproxy.golden | 276 -- ...kload-addresses-with-specific-ports.golden | 101 - ...le-workload-addresses-without-ports.golden | 89 - ...ngle-workload-address-without-ports.golden | 89 - .../testdata/source/l7-expose-paths.golden | 212 - .../local-and-inbound-connections.golden | 304 -- ...kload-addresses-with-specific-ports.golden | 130 - ...le-workload-addresses-without-ports.golden | 130 - ...ngle-workload-address-without-ports.golden | 130 - ...ort-l4-workload-with-only-mesh-port.golden | 61 - ...kload-addresses-with-specific-ports.golden | 183 - ...le-workload-addresses-without-ports.golden | 250 - ...ngle-workload-address-without-ports.golden | 250 - .../controllers/sidecarproxy/cache/cache.go | 251 - .../sidecarproxy/cache/cache_test.go | 443 -- .../controllers/sidecarproxy/controller.go | 350 -- .../sidecarproxy/controller_test.go | 921 ---- .../sidecarproxy/fetcher/data_fetcher.go | 374 -- .../sidecarproxy/fetcher/data_fetcher_test.go | 598 --- .../internal/controllers/xds/controller.go | 418 -- .../controllers/xds/controller_test.go | 1169 ----- .../controllers/xds/endpoint_builder.go | 75 - .../controllers/xds/endpoint_builder_test.go | 235 - .../internal/controllers/xds/leaf_cancels.go | 34 - .../internal/controllers/xds/leaf_mapper.go | 39 - .../internal/controllers/xds/mock_updater.go | 122 - .../controllers/xds/proxy_tracker_watch.go | 24 - .../controllers/xds/reconciliation_data.go | 61 - .../internal/controllers/xds/status/status.go | 131 - ...it-and-explicit-destinations-tproxy.golden | 185 - .../destination/l4-multi-destination.golden | 301 -- ...ltiple-implicit-destinations-tproxy.golden | 184 - ...le-destination-ip-port-bind-address.golden | 156 - ...estination-unix-socket-bind-address.golden | 93 - ...-single-implicit-destination-tproxy.golden | 124 - .../mixed-multi-destination.golden | 380 -- ...ltiple-implicit-destinations-tproxy.golden | 466 -- ...-single-implicit-destination-tproxy.golden | 262 - ...tion-with-multiple-workloads-tproxy.golden | 262 - ...kload-addresses-with-specific-ports.golden | 102 - ...le-workload-addresses-without-ports.golden | 90 - ...ngle-workload-address-without-ports.golden | 90 - .../testdata/source/l7-expose-paths.golden | 213 - .../local-and-inbound-connections.golden | 305 -- ...kload-addresses-with-specific-ports.golden | 131 - ...le-workload-addresses-without-ports.golden | 131 - ...ngle-workload-address-without-ports.golden | 129 - ...ort-l4-workload-with-only-mesh-port.golden | 62 - ...kload-addresses-with-specific-ports.golden | 184 - ...le-workload-addresses-without-ports.golden | 251 - ...ngle-workload-address-without-ports.golden | 248 - .../mappers/common/workload_selector_util.go | 58 - .../common/workload_selector_util_test.go | 66 - .../workload_selection_mapper.go | 80 - .../workload_selection_mapper_test.go | 142 - .../types/computed_explicit_destinations.go | 17 - .../types/computed_proxy_configuration.go | 17 - .../mesh/internal/types/computed_routes.go | 158 - .../internal/types/computed_routes_test.go | 218 - internal/mesh/internal/types/decoded.go | 30 - .../mesh/internal/types/destination_policy.go | 231 - .../internal/types/destination_policy_test.go | 609 --- internal/mesh/internal/types/destinations.go | 171 - .../types/destinations_configuration.go | 39 - .../types/destinations_configuration_test.go | 90 - .../mesh/internal/types/destinations_test.go | 427 -- internal/mesh/internal/types/errors.go | 16 - internal/mesh/internal/types/grpc_route.go | 237 - .../mesh/internal/types/grpc_route_test.go | 653 --- internal/mesh/internal/types/http_route.go | 350 -- .../mesh/internal/types/http_route_test.go | 911 ---- .../mesh/internal/types/intermediate/types.go | 24 - .../internal/types/proxy_configuration.go | 219 +- .../types/proxy_configuration_test.go | 362 -- .../internal/types/proxy_state_template.go | 202 - .../types/proxy_state_template_test.go | 191 - internal/mesh/internal/types/tcp_route.go | 104 - .../mesh/internal/types/tcp_route_test.go | 237 - internal/mesh/internal/types/types.go | 20 +- internal/mesh/internal/types/types_test.go | 22 +- internal/mesh/internal/types/upstreams.go | 32 + internal/mesh/internal/types/util.go | 100 - internal/mesh/internal/types/xroute.go | 335 -- internal/mesh/internal/types/xroute_test.go | 559 --- .../mesh/proxy-snapshot/proxy_snapshot.go | 20 - .../mesh/proxy-tracker/mock_SessionLimiter.go | 53 - .../mesh/proxy-tracker/proxy_state_exports.go | 50 - .../proxy-tracker/proxy_state_exports_test.go | 78 - internal/mesh/proxy-tracker/proxy_tracker.go | 284 -- .../mesh/proxy-tracker/proxy_tracker_test.go | 340 -- internal/multicluster/exports.go | 22 - .../types/computed_exported_services.go | 37 - .../types/computed_exported_services_test.go | 178 - .../internal/types/exported_services.go | 59 - .../internal/types/exported_services_test.go | 218 - .../multicluster/internal/types/helpers.go | 135 - .../multicluster/internal/types/helpers_ce.go | 66 - .../types/namespace_exported_services.go | 33 - .../types/namespace_exported_services_test.go | 184 - .../types/partition_exported_services.go | 33 - .../types/partition_exported_services_test.go | 185 - internal/multicluster/internal/types/types.go | 21 - internal/protohcl/any.go | 117 - internal/protohcl/attributes.go | 157 - internal/protohcl/blocks.go | 115 - internal/protohcl/cty.go | 149 - internal/protohcl/decoder.go | 287 -- internal/protohcl/doc.go | 79 - internal/protohcl/naming.go | 21 - internal/protohcl/oneof.go | 54 - internal/protohcl/primitives.go | 147 - internal/protohcl/testproto/buf.gen.yaml | 12 - internal/protohcl/testproto/example.pb.go | 997 ---- internal/protohcl/testproto/example.proto | 77 - internal/protohcl/unmarshal.go | 137 - internal/protohcl/unmarshal_test.go | 610 --- internal/protohcl/well_known_types.go | 421 -- internal/protoutil/protoutil.go | 23 - internal/radix/doc.go | 3 - internal/radix/radix.go | 3 - internal/radix/radix_test.go | 3 - internal/resource/acls.go | 13 - internal/resource/authz.go | 20 - internal/resource/authz_ce.go | 18 - internal/resource/authz_ce_test.go | 51 - internal/resource/decode.go | 72 - internal/resource/decode_test.go | 114 - internal/resource/demo/controller.go | 4 +- internal/resource/demo/controller_test.go | 2 +- internal/resource/demo/demo.go | 153 +- internal/resource/equality.go | 22 +- internal/resource/equality_test.go | 306 +- internal/resource/errors.go | 65 +- internal/resource/errors_test.go | 7 +- internal/resource/filter.go | 105 - internal/resource/filter_test.go | 195 - internal/resource/hooks.go | 107 - internal/resource/hooks_test.go | 243 - internal/resource/http/http.go | 309 -- internal/resource/http/http_test.go | 618 --- .../resource/mappers/bimapper/bimapper.go | 323 -- .../mappers/bimapper/bimapper_test.go | 489 -- .../selection_tracker_test.go | 383 -- .../internal/generate/generate.go | 64 - internal/resource/protoc-gen-deepcopy/main.go | 30 - .../internal/generate/generate.go | 112 - .../resource/protoc-gen-json-shim/main.go | 30 - .../internal/generate/generate.go | 158 - .../protoc-gen-resource-types/main.go | 27 - internal/resource/reaper/controller.go | 2 +- internal/resource/reaper/controller_test.go | 2 +- internal/resource/reference.go | 47 +- internal/resource/refkey.go | 93 - internal/resource/refkey_test.go | 87 - internal/resource/registry.go | 105 +- internal/resource/registry_test.go | 61 +- internal/resource/resource.go | 22 - internal/resource/resourcetest/acls.go | 119 - internal/resource/resourcetest/builder.go | 89 +- internal/resource/resourcetest/client.go | 100 +- internal/resource/resourcetest/decode.go | 18 - internal/resource/resourcetest/fs.go | 3 - internal/resource/resourcetest/require.go | 29 - internal/resource/resourcetest/tenancy.go | 52 - internal/resource/resourcetest/testing.go | 7 +- internal/resource/resourcetest/validation.go | 31 - internal/resource/sort.go | 71 - internal/resource/sort_test.go | 145 - internal/resource/stringer.go | 60 - internal/resource/tenancy.go | 192 - internal/resource/tenancy_test.go | 237 - internal/resource/tombstone.go | 3 - internal/resourcehcl/any.go | 52 - internal/resourcehcl/naming.go | 41 - .../resourcehcl/testdata/destinations.golden | 1 - .../resourcehcl/testdata/destinations.hcl | 25 - .../fuzz/FuzzUnmarshall/0e4b8ec300611dbc | 2 - .../fuzz/FuzzUnmarshall/c800420b7494c6d1 | 2 - .../fuzz/FuzzUnmarshall/eaba8205942c3f31 | 2 - .../testdata/gvk-no-arguments.error | 1 - .../resourcehcl/testdata/gvk-no-arguments.hcl | 4 - .../resourcehcl/testdata/invalid-group.error | 1 - .../resourcehcl/testdata/invalid-group.hcl | 8 - .../resourcehcl/testdata/invalid-gvk.error | 1 - internal/resourcehcl/testdata/invalid-gvk.hcl | 4 - .../testdata/invalid-metadata.error | 1 - .../resourcehcl/testdata/invalid-metadata.hcl | 8 - .../resourcehcl/testdata/invalid-name.error | 1 - .../resourcehcl/testdata/invalid-name.hcl | 4 - .../testdata/no-blocks-any-first.golden | 1 - .../testdata/no-blocks-any-first.hcl | 8 - .../resourcehcl/testdata/no-blocks.golden | 1 - internal/resourcehcl/testdata/no-blocks.hcl | 33 - internal/resourcehcl/testdata/owner.golden | 1 - internal/resourcehcl/testdata/owner.hcl | 9 - .../resourcehcl/testdata/simple-gvk.golden | 1 - internal/resourcehcl/testdata/simple-gvk.hcl | 13 - .../resourcehcl/testdata/type-block.golden | 1 - internal/resourcehcl/testdata/type-block.hcl | 8 - .../testdata/unknown-field-block.error | 1 - .../testdata/unknown-field-block.hcl | 3 - .../testdata/unknown-field-object.error | 1 - .../testdata/unknown-field-object.hcl | 3 - .../resourcehcl/testdata/unknown-type.error | 1 - .../resourcehcl/testdata/unknown-type.hcl | 8 - internal/resourcehcl/unmarshal.go | 55 - internal/resourcehcl/unmarshal_test.go | 147 - internal/storage/conformance/conformance.go | 2 +- internal/storage/inmem/backend.go | 2 +- internal/storage/inmem/backend_test.go | 2 +- internal/storage/inmem/event_index.go | 2 +- internal/storage/inmem/schema.go | 2 +- internal/storage/inmem/snapshot.go | 2 +- internal/storage/inmem/snapshot_test.go | 2 +- internal/storage/inmem/store.go | 2 +- internal/storage/inmem/watch.go | 2 +- internal/storage/raft/backend.go | 2 +- internal/storage/raft/conformance_test.go | 2 +- internal/storage/raft/forwarding.go | 2 +- internal/storage/storage.go | 6 +- internal/tenancy/exports.go | 32 - .../tenancy/internal/bridge/tenancy_bridge.go | 55 - .../internal/bridge/tenancy_bridge_ce.go | 17 - .../internal/controllers/register_ce.go | 14 - internal/tenancy/internal/types/errors.go | 11 - internal/tenancy/internal/types/namespace.go | 52 - internal/tenancy/internal/types/types.go | 10 - internal/tenancy/internal/types/types_ce.go | 12 - internal/tenancy/internal/types/types_test.go | 121 - .../tenancy/tenancytest/namespace_test.go | 130 - internal/testing/golden/golden.go | 24 +- .../e2e/consul/agent/structs/structs.go | 2 +- .../e2e/consul/proto/pbcommon/common.go | 2 +- .../tools/proto-gen-rpc-glue/e2e/source.pb.go | 2 +- internal/tools/proto-gen-rpc-glue/main.go | 2 +- .../tools/proto-gen-rpc-glue/main_test.go | 2 +- .../protoc-gen-consul-rate-limit/main.go | 4 +- .../postprocess/main.go | 3 +- ipaddr/detect.go | 2 +- ipaddr/detect_test.go | 2 +- ipaddr/ipaddr.go | 2 +- ipaddr/ipaddr_test.go | 2 +- lib/cluster.go | 2 +- lib/cluster_test.go | 2 +- lib/decode/decode.go | 2 +- lib/decode/decode_test.go | 2 +- lib/eof.go | 2 +- lib/eof_test.go | 2 +- lib/file/atomic.go | 2 +- lib/file/atomic_test.go | 2 +- lib/hoststats/collector.go | 3 - lib/hoststats/cpu.go | 3 - lib/hoststats/cpu_test.go | 3 - lib/hoststats/host.go | 3 - lib/hoststats/metrics.go | 3 - lib/json.go | 2 +- lib/map_walker.go | 2 +- lib/map_walker_test.go | 2 +- lib/maps/maps.go | 2 +- lib/maps/maps_test.go | 2 +- lib/math.go | 2 +- lib/math_test.go | 2 +- lib/mutex/mutex.go | 2 +- lib/mutex/mutex_test.go | 2 +- lib/path.go | 2 +- lib/retry/retry.go | 2 +- lib/retry/retry_test.go | 2 +- lib/routine/routine.go | 2 +- lib/routine/routine_test.go | 2 +- lib/rtt.go | 2 +- lib/rtt_test.go | 2 +- lib/semaphore/semaphore.go | 2 +- lib/semaphore/semaphore_test.go | 2 +- lib/serf/serf.go | 2 +- lib/stop_context.go | 2 +- lib/stop_context_test.go | 2 +- lib/strings.go | 2 +- lib/stringslice/stringslice.go | 2 +- lib/stringslice/stringslice_test.go | 2 +- lib/telemetry.go | 2 +- lib/telemetry_test.go | 2 +- lib/template/hil.go | 2 +- lib/template/hil_test.go | 2 +- lib/translate.go | 2 +- lib/translate_test.go | 2 +- lib/ttlcache/eviction.go | 2 +- lib/ttlcache/eviction_test.go | 2 +- lib/useragent.go | 2 +- lib/useragent_test.go | 2 +- lib/uuid.go | 2 +- logging/gated_writer.go | 2 +- logging/gated_writer_test.go | 2 +- logging/grpc.go | 2 +- logging/grpc_test.go | 2 +- logging/log_levels.go | 2 +- logging/logfile.go | 2 +- logging/logfile_bsd.go | 4 +- logging/logfile_linux.go | 4 +- logging/logfile_solaris.go | 4 +- logging/logfile_test.go | 2 +- logging/logfile_windows.go | 3 - logging/logger.go | 2 +- logging/logger_test.go | 2 +- logging/monitor/monitor.go | 2 +- logging/monitor/monitor_test.go | 2 +- logging/names.go | 2 +- logging/syslog.go | 2 +- logging/syslog_test.go | 3 +- logging/syslog_unsupported_test.go | 3 +- main.go | 2 +- proto-public/LICENSE | 365 -- .../ratelimit/ratelimit_deepcopy.gen.go | 27 - .../ratelimit/ratelimit_json.gen.go | 22 - proto-public/buf.gen.yaml | 11 - proto-public/go.mod | 1 - proto-public/go.sum | 2 - proto-public/pbacl/acl_deepcopy.gen.go | 111 - proto-public/pbacl/acl_json.gen.go | 66 - .../computed_traffic_permissions.pb.binary.go | 18 - .../computed_traffic_permissions.pb.go | 201 - .../computed_traffic_permissions.proto | 14 - ...mputed_traffic_permissions_deepcopy.gen.go | 27 - .../computed_traffic_permissions_json.gen.go | 22 - .../pbauth/v2beta1/resource_types.gen.go | 50 - .../v2beta1/traffic_permissions.pb.binary.go | 108 - .../pbauth/v2beta1/traffic_permissions.pb.go | 1182 ----- .../pbauth/v2beta1/traffic_permissions.proto | 129 - .../v2beta1/traffic_permissions_addon.go | 25 - .../traffic_permissions_deepcopy.gen.go | 216 - .../v2beta1/traffic_permissions_json.gen.go | 121 - .../v2beta1/workload_identity.pb.binary.go | 18 - .../pbauth/v2beta1/workload_identity.pb.go | 155 - .../pbauth/v2beta1/workload_identity.proto | 9 - .../v2beta1/workload_identity_deepcopy.gen.go | 27 - .../v2beta1/workload_identity_json.gen.go | 22 - .../{v2beta1 => v1alpha1}/dns.pb.binary.go | 4 +- proto-public/pbcatalog/v1alpha1/dns.pb.go | 259 + .../pbcatalog/{v2beta1 => v1alpha1}/dns.proto | 7 +- .../{v2beta1 => v1alpha1}/health.pb.binary.go | 4 +- .../{v2beta1 => v1alpha1}/health.pb.go | 439 +- .../{v2beta1 => v1alpha1}/health.proto | 12 +- .../{v2beta1 => v1alpha1}/node.pb.binary.go | 4 +- proto-public/pbcatalog/v1alpha1/node.pb.go | 244 + .../{v2beta1 => v1alpha1}/node.proto | 9 +- .../pbcatalog/v1alpha1/protocol.pb.go | 166 + .../pbcatalog/v1alpha1/protocol.proto | 17 + .../selector.pb.binary.go | 4 +- .../pbcatalog/v1alpha1/selector.pb.go | 177 + .../{v2beta1 => v1alpha1}/selector.proto | 3 +- .../service.pb.binary.go | 4 +- proto-public/pbcatalog/v1alpha1/service.pb.go | 301 ++ .../{v2beta1 => v1alpha1}/service.proto | 9 +- .../service_endpoints.pb.binary.go | 4 +- .../v1alpha1/service_endpoints.pb.go | 308 ++ .../service_endpoints.proto | 12 +- .../{v2beta1 => v1alpha1}/vip.pb.binary.go | 4 +- proto-public/pbcatalog/v1alpha1/vip.pb.go | 244 + .../pbcatalog/{v2beta1 => v1alpha1}/vip.proto | 6 +- .../workload.pb.binary.go | 4 +- .../pbcatalog/v1alpha1/workload.pb.go | 520 ++ .../{v2beta1 => v1alpha1}/workload.proto | 7 +- proto-public/pbcatalog/v2beta1/dns.pb.go | 262 - .../pbcatalog/v2beta1/dns_deepcopy.gen.go | 48 - .../pbcatalog/v2beta1/dns_json.gen.go | 33 - .../v2beta1/failover_policy.pb.binary.go | 38 - .../pbcatalog/v2beta1/failover_policy.pb.go | 458 -- .../pbcatalog/v2beta1/failover_policy.proto | 50 - .../v2beta1/failover_policy_deepcopy.gen.go | 69 - .../v2beta1/failover_policy_extras.go | 65 - .../v2beta1/failover_policy_extras_test.go | 171 - .../v2beta1/failover_policy_json.gen.go | 44 - .../pbcatalog/v2beta1/health_deepcopy.gen.go | 195 - .../pbcatalog/v2beta1/health_json.gen.go | 110 - proto-public/pbcatalog/v2beta1/node.pb.go | 247 - .../pbcatalog/v2beta1/node_deepcopy.gen.go | 48 - .../pbcatalog/v2beta1/node_json.gen.go | 33 - proto-public/pbcatalog/v2beta1/protocol.pb.go | 171 - proto-public/pbcatalog/v2beta1/protocol.proto | 19 - .../pbcatalog/v2beta1/resource_types.gen.go | 78 - proto-public/pbcatalog/v2beta1/selector.pb.go | 185 - .../v2beta1/selector_deepcopy.gen.go | 27 - .../pbcatalog/v2beta1/selector_json.gen.go | 22 - proto-public/pbcatalog/v2beta1/service.pb.go | 303 -- .../pbcatalog/v2beta1/service_addon.go | 19 - .../pbcatalog/v2beta1/service_addon_test.go | 120 - .../pbcatalog/v2beta1/service_deepcopy.gen.go | 48 - .../pbcatalog/v2beta1/service_endpoints.pb.go | 321 -- .../v2beta1/service_endpoints_addon.go | 26 - .../v2beta1/service_endpoints_addon_test.go | 49 - .../v2beta1/service_endpoints_deepcopy.gen.go | 48 - .../v2beta1/service_endpoints_json.gen.go | 33 - .../pbcatalog/v2beta1/service_json.gen.go | 33 - proto-public/pbcatalog/v2beta1/vip.pb.go | 247 - .../pbcatalog/v2beta1/vip_deepcopy.gen.go | 48 - .../pbcatalog/v2beta1/vip_json.gen.go | 33 - proto-public/pbcatalog/v2beta1/workload.pb.go | 523 -- .../pbcatalog/v2beta1/workload_addon.go | 77 - .../pbcatalog/v2beta1/workload_addon_test.go | 259 - .../v2beta1/workload_deepcopy.gen.go | 90 - .../pbcatalog/v2beta1/workload_json.gen.go | 55 - proto-public/pbconnectca/ca_deepcopy.gen.go | 111 - proto-public/pbconnectca/ca_json.gen.go | 66 - proto-public/pbdataplane/dataplane.pb.go | 310 +- proto-public/pbdataplane/dataplane.proto | 25 +- .../pbdataplane/dataplane_deepcopy.gen.go | 111 - .../pbdataplane/dataplane_json.gen.go | 66 - proto-public/pbdns/dns_deepcopy.gen.go | 48 - proto-public/pbdns/dns_json.gen.go | 33 - .../connection.pb.binary.go | 4 +- proto-public/pbmesh/v1alpha1/connection.pb.go | 316 ++ proto-public/pbmesh/v1alpha1/connection.proto | 22 + .../{v2beta1 => v1alpha1}/expose.pb.binary.go | 4 +- proto-public/pbmesh/v1alpha1/expose.pb.go | 269 + proto-public/pbmesh/v1alpha1/expose.proto | 19 + .../proxy.pb.binary.go} | 24 +- proto-public/pbmesh/v1alpha1/proxy.pb.go | 816 +++ proto-public/pbmesh/v1alpha1/proxy.proto | 104 + proto-public/pbmesh/v1alpha1/routing.pb.go | 181 + .../{v2beta1 => v1alpha1}/routing.proto | 6 +- .../upstreams.pb.binary.go} | 36 +- proto-public/pbmesh/v1alpha1/upstreams.pb.go | 997 ++++ proto-public/pbmesh/v1alpha1/upstreams.proto | 100 + .../pbmesh/v2beta1/common.pb.binary.go | 28 - proto-public/pbmesh/v2beta1/common.pb.go | 275 -- proto-public/pbmesh/v2beta1/common.proto | 32 - .../pbmesh/v2beta1/common_deepcopy.gen.go | 48 - .../pbmesh/v2beta1/common_json.gen.go | 33 - ...omputed_explicit_destinations.pb.binary.go | 18 - .../computed_explicit_destinations.pb.go | 180 - .../computed_explicit_destinations.proto | 16 - ...uted_explicit_destinations_deepcopy.gen.go | 27 - ...computed_explicit_destinations_json.gen.go | 22 - .../computed_proxy_configuration.pb.binary.go | 18 - .../computed_proxy_configuration.pb.go | 199 - .../computed_proxy_configuration.proto | 21 - ...mputed_proxy_configuration_deepcopy.gen.go | 27 - .../computed_proxy_configuration_json.gen.go | 22 - .../v2beta1/computed_routes.pb.binary.go | 148 - .../pbmesh/v2beta1/computed_routes.pb.go | 1635 ------ .../pbmesh/v2beta1/computed_routes.proto | 172 - .../v2beta1/computed_routes_deepcopy.gen.go | 300 -- .../v2beta1/computed_routes_json.gen.go | 165 - proto-public/pbmesh/v2beta1/connection.pb.go | 328 -- proto-public/pbmesh/v2beta1/connection.proto | 30 - .../pbmesh/v2beta1/connection_deepcopy.gen.go | 48 - .../pbmesh/v2beta1/connection_json.gen.go | 33 - .../v2beta1/destination_policy.pb.binary.go | 88 - .../pbmesh/v2beta1/destination_policy.pb.go | 1102 ----- .../pbmesh/v2beta1/destination_policy.proto | 159 - .../destination_policy_deepcopy.gen.go | 174 - .../v2beta1/destination_policy_json.gen.go | 99 - .../pbmesh/v2beta1/destinations.pb.binary.go | 58 - .../pbmesh/v2beta1/destinations.pb.go | 670 --- .../pbmesh/v2beta1/destinations.proto | 79 - .../destinations_configuration.pb.binary.go | 58 - .../v2beta1/destinations_configuration.pb.go | 701 --- .../v2beta1/destinations_configuration.proto | 109 - ...destinations_configuration_deepcopy.gen.go | 111 - .../destinations_configuration_json.gen.go | 66 - .../v2beta1/destinations_deepcopy.gen.go | 111 - .../pbmesh/v2beta1/destinations_json.gen.go | 66 - proto-public/pbmesh/v2beta1/expose.pb.go | 322 -- proto-public/pbmesh/v2beta1/expose.proto | 25 - .../pbmesh/v2beta1/expose_deepcopy.gen.go | 48 - .../pbmesh/v2beta1/expose_json.gen.go | 33 - .../pbmesh/v2beta1/grpc_route.pb.binary.go | 78 - proto-public/pbmesh/v2beta1/grpc_route.pb.go | 908 ---- proto-public/pbmesh/v2beta1/grpc_route.proto | 145 - .../pbmesh/v2beta1/grpc_route_deepcopy.gen.go | 153 - .../pbmesh/v2beta1/grpc_route_json.gen.go | 88 - .../pbmesh/v2beta1/http_route.pb.binary.go | 118 - proto-public/pbmesh/v2beta1/http_route.pb.go | 1445 ------ proto-public/pbmesh/v2beta1/http_route.proto | 263 - .../pbmesh/v2beta1/http_route_deepcopy.gen.go | 237 - .../pbmesh/v2beta1/http_route_json.gen.go | 132 - .../v2beta1/http_route_retries.pb.binary.go | 18 - .../pbmesh/v2beta1/http_route_retries.pb.go | 211 - .../pbmesh/v2beta1/http_route_retries.proto | 26 - .../http_route_retries_deepcopy.gen.go | 27 - .../v2beta1/http_route_retries_json.gen.go | 22 - .../v2beta1/http_route_timeouts.pb.binary.go | 18 - .../pbmesh/v2beta1/http_route_timeouts.pb.go | 191 - .../pbmesh/v2beta1/http_route_timeouts.proto | 21 - .../http_route_timeouts_deepcopy.gen.go | 27 - .../v2beta1/http_route_timeouts_json.gen.go | 22 - .../pbproxystate/access_logs.pb.binary.go | 18 - .../v2beta1/pbproxystate/access_logs.pb.go | 327 -- .../v2beta1/pbproxystate/access_logs.proto | 34 - .../pbproxystate/access_logs_deepcopy.gen.go | 27 - .../pbproxystate/access_logs_json.gen.go | 22 - .../v2beta1/pbproxystate/address.pb.binary.go | 28 - .../pbmesh/v2beta1/pbproxystate/address.pb.go | 253 - .../pbmesh/v2beta1/pbproxystate/address.proto | 20 - .../pbproxystate/address_deepcopy.gen.go | 48 - .../v2beta1/pbproxystate/address_json.gen.go | 33 - .../v2beta1/pbproxystate/cluster.pb.binary.go | 268 - .../pbmesh/v2beta1/pbproxystate/cluster.pb.go | 2643 ---------- .../pbmesh/v2beta1/pbproxystate/cluster.proto | 197 - .../pbproxystate/cluster_deepcopy.gen.go | 552 --- .../v2beta1/pbproxystate/cluster_json.gen.go | 297 -- .../pbproxystate/endpoints.pb.binary.go | 28 - .../v2beta1/pbproxystate/endpoints.pb.go | 387 -- .../v2beta1/pbproxystate/endpoints.proto | 31 - .../pbproxystate/endpoints_deepcopy.gen.go | 48 - .../pbproxystate/endpoints_json.gen.go | 33 - .../pbproxystate/escape_hatches.pb.binary.go | 18 - .../v2beta1/pbproxystate/escape_hatches.pb.go | 173 - .../v2beta1/pbproxystate/escape_hatches.proto | 11 - .../escape_hatches_deepcopy.gen.go | 27 - .../pbproxystate/escape_hatches_json.gen.go | 22 - .../header_mutations.pb.binary.go | 68 - .../pbproxystate/header_mutations.pb.go | 694 --- .../pbproxystate/header_mutations.proto | 49 - .../header_mutations_deepcopy.gen.go | 132 - .../pbproxystate/header_mutations_json.gen.go | 77 - .../v2beta1/pbproxystate/intentions.pb.go | 211 - .../v2beta1/pbproxystate/listener.pb.go | 1500 ------ .../v2beta1/pbproxystate/listener.proto | 171 - .../pbproxystate/listener_deepcopy.gen.go | 174 - .../v2beta1/pbproxystate/listener_json.gen.go | 99 - .../v2beta1/pbproxystate/protocol.pb.go | 175 - .../v2beta1/pbproxystate/protocol.proto | 19 - .../v2beta1/pbproxystate/protocol_test.go | 19 - .../pbproxystate/references.pb.binary.go | 38 - .../v2beta1/pbproxystate/references.pb.go | 371 -- .../v2beta1/pbproxystate/references.proto | 29 - .../pbproxystate/references_deepcopy.gen.go | 69 - .../pbproxystate/references_json.gen.go | 44 - .../v2beta1/pbproxystate/route.pb.binary.go | 168 - .../pbmesh/v2beta1/pbproxystate/route.pb.go | 1830 ------- .../pbmesh/v2beta1/pbproxystate/route.proto | 134 - .../pbproxystate/route_deepcopy.gen.go | 342 -- .../v2beta1/pbproxystate/route_json.gen.go | 187 - .../traffic_permissions.pb.binary.go | 48 - .../pbproxystate/traffic_permissions.pb.go | 429 -- .../pbproxystate/traffic_permissions.proto | 37 - .../traffic_permissions_deepcopy.gen.go | 90 - .../traffic_permissions_json.gen.go | 55 - .../transport_socket.pb.binary.go | 138 - .../pbproxystate/transport_socket.pb.go | 1507 ------ .../pbproxystate/transport_socket.proto | 141 - .../transport_socket_deepcopy.gen.go | 279 -- .../pbproxystate/transport_socket_json.gen.go | 154 - .../pbmesh/v2beta1/proxy_configuration.pb.go | 1227 ----- .../pbmesh/v2beta1/proxy_configuration.proto | 173 - .../v2beta1/proxy_configuration_addon.go | 11 - .../v2beta1/proxy_configuration_addon_test.go | 50 - .../proxy_configuration_deepcopy.gen.go | 132 - .../v2beta1/proxy_configuration_json.gen.go | 77 - .../pbmesh/v2beta1/proxy_state.pb.binary.go | 28 - proto-public/pbmesh/v2beta1/proxy_state.pb.go | 551 --- proto-public/pbmesh/v2beta1/proxy_state.proto | 56 - .../v2beta1/proxy_state_deepcopy.gen.go | 48 - .../pbmesh/v2beta1/proxy_state_json.gen.go | 33 - .../pbmesh/v2beta1/resource_types.gen.go | 92 - proto-public/pbmesh/v2beta1/routing.pb.go | 183 - .../pbmesh/v2beta1/tcp_route.pb.binary.go | 38 - proto-public/pbmesh/v2beta1/tcp_route.pb.go | 362 -- proto-public/pbmesh/v2beta1/tcp_route.proto | 56 - .../pbmesh/v2beta1/tcp_route_deepcopy.gen.go | 69 - .../pbmesh/v2beta1/tcp_route_json.gen.go | 44 - proto-public/pbmesh/v2beta1/xroute_addons.go | 91 - .../pbmesh/v2beta1/xroute_addons_test.go | 174 - .../computed_exported_services.pb.binary.go | 38 - .../v2beta1/computed_exported_services.pb.go | 373 -- .../v2beta1/computed_exported_services.proto | 28 - ...computed_exported_services_deepcopy.gen.go | 69 - .../computed_exported_services_json.gen.go | 44 - .../v2beta1/exported_services.pb.binary.go | 18 - .../v2beta1/exported_services.pb.go | 193 - .../v2beta1/exported_services.proto | 16 - .../exported_services_consumer.pb.binary.go | 18 - .../v2beta1/exported_services_consumer.pb.go | 230 - .../v2beta1/exported_services_consumer.proto | 14 - ...exported_services_consumer_deepcopy.gen.go | 27 - .../exported_services_consumer_json.gen.go | 22 - .../v2beta1/exported_services_deepcopy.gen.go | 27 - .../v2beta1/exported_services_json.gen.go | 22 - .../namespace_exported_services.pb.binary.go | 18 - .../v2beta1/namespace_exported_services.pb.go | 185 - .../v2beta1/namespace_exported_services.proto | 15 - ...amespace_exported_services_deepcopy.gen.go | 27 - .../namespace_exported_services_json.gen.go | 22 - .../partition_exported_services.pb.binary.go | 18 - .../v2beta1/partition_exported_services.pb.go | 185 - .../v2beta1/partition_exported_services.proto | 15 - ...artition_exported_services_deepcopy.gen.go | 27 - .../partition_exported_services_json.gen.go | 22 - .../v2beta1/resource_types.gen.go | 43 - .../pbresource/annotations.pb.binary.go | 18 - proto-public/pbresource/annotations.pb.go | 266 - proto-public/pbresource/annotations.proto | 25 - .../pbresource/annotations_deepcopy.gen.go | 27 - .../pbresource/annotations_json.gen.go | 22 - .../pbresource/resource_deepcopy.gen.go | 468 -- proto-public/pbresource/resource_json.gen.go | 253 - .../serverdiscovery_deepcopy.gen.go | 69 - .../serverdiscovery_json.gen.go | 44 - .../pbtenancy/v2beta1/namespace.pb.binary.go | 18 - .../pbtenancy/v2beta1/namespace.pb.go | 171 - .../pbtenancy/v2beta1/namespace.proto | 16 - .../v2beta1/namespace_deepcopy.gen.go | 27 - .../pbtenancy/v2beta1/namespace_json.gen.go | 22 - .../pbtenancy/v2beta1/resource_types.gen.go | 22 - proto/buf.gen.yaml | 2 +- proto/buf.yaml | 4 +- proto/private/pbacl/acl.go | 2 +- proto/private/pbacl/acl.pb.go | 2 +- proto/private/pbacl/acl.proto | 2 +- proto/private/pbautoconf/auto_config.go | 2 +- proto/private/pbautoconf/auto_config.pb.go | 2 +- proto/private/pbautoconf/auto_config.proto | 2 +- proto/private/pbautoconf/auto_config_ce.go | 3 +- proto/private/pbcommon/common.go | 2 +- proto/private/pbcommon/common.pb.go | 2 +- proto/private/pbcommon/common.proto | 2 +- proto/private/pbcommon/common_ce.go | 3 +- proto/private/pbcommon/convert_pbstruct.go | 2 +- .../private/pbcommon/convert_pbstruct_test.go | 2 +- proto/private/pbconfig/config.pb.go | 2 +- proto/private/pbconfig/config.proto | 2 +- .../private/pbconfigentry/config_entry.gen.go | 210 - proto/private/pbconfigentry/config_entry.go | 2 +- .../pbconfigentry/config_entry.pb.binary.go | 110 - .../private/pbconfigentry/config_entry.pb.go | 3213 +++++------- .../private/pbconfigentry/config_entry.proto | 109 +- .../private/pbconfigentry/config_entry_ce.go | 24 - proto/private/pbconnect/connect.gen.go | 4 - proto/private/pbconnect/connect.go | 2 +- proto/private/pbconnect/connect.pb.go | 100 +- proto/private/pbconnect/connect.proto | 7 +- proto/private/pbdemo/v1/demo.pb.binary.go | 30 - proto/private/pbdemo/v1/demo.pb.go | 331 +- proto/private/pbdemo/v1/demo.proto | 18 +- proto/private/pbdemo/v2/demo.pb.go | 2 +- proto/private/pbdemo/v2/demo.proto | 2 +- proto/private/pboperator/operator.pb.go | 2 +- proto/private/pboperator/operator.proto | 2 +- proto/private/pbpeering/peering.go | 2 +- proto/private/pbpeering/peering.pb.go | 4 +- proto/private/pbpeering/peering.proto | 4 +- proto/private/pbpeering/peering_ce.go | 3 +- proto/private/pbpeerstream/convert.go | 2 +- proto/private/pbpeerstream/peerstream.go | 2 +- proto/private/pbpeerstream/peerstream.pb.go | 2 +- proto/private/pbpeerstream/peerstream.proto | 2 +- proto/private/pbpeerstream/types.go | 2 +- proto/private/pbservice/convert.go | 2 +- proto/private/pbservice/convert_ce.go | 3 +- proto/private/pbservice/convert_ce_test.go | 3 +- proto/private/pbservice/convert_test.go | 2 +- proto/private/pbservice/healthcheck.pb.go | 2 +- proto/private/pbservice/healthcheck.proto | 2 +- proto/private/pbservice/ids.go | 2 +- proto/private/pbservice/ids_test.go | 2 +- proto/private/pbservice/node.pb.go | 2 +- proto/private/pbservice/node.proto | 2 +- proto/private/pbservice/service.pb.go | 2 +- proto/private/pbservice/service.proto | 2 +- proto/private/pbstorage/raft.pb.go | 2 +- proto/private/pbstorage/raft.proto | 2 +- proto/private/pbsubscribe/subscribe.go | 2 +- proto/private/pbsubscribe/subscribe.pb.go | 4 +- proto/private/pbsubscribe/subscribe.proto | 2 +- proto/private/prototest/golden_json.go | 37 - proto/private/prototest/testing.go | 9 +- proto/private/prototest/testing_test.go | 3 - sdk/.copywrite.hcl | 8 - sdk/LICENSE | 365 -- sdk/freeport/ephemeral_darwin.go | 1 + sdk/freeport/ephemeral_darwin_test.go | 1 + sdk/freeport/ephemeral_fallback.go | 1 + sdk/freeport/ephemeral_linux.go | 1 + sdk/freeport/ephemeral_linux_test.go | 1 + sdk/freeport/systemlimit.go | 1 + sdk/freeport/systemlimit_windows.go | 1 + sdk/iptables/iptables.go | 2 +- sdk/iptables/iptables_executor_linux.go | 1 + sdk/iptables/iptables_executor_unsupported.go | 1 + sdk/testutil/context.go | 8 +- sdk/testutil/io.go | 1 - sdk/testutil/retry/counter.go | 26 - sdk/testutil/retry/retry.go | 98 +- sdk/testutil/retry/retry_test.go | 63 - sdk/testutil/retry/timer.go | 46 - sdk/testutil/server.go | 140 +- sdk/testutil/testlog.go | 6 +- sentinel/evaluator.go | 2 +- sentinel/scope.go | 2 +- sentinel/sentinel_ce.go | 3 +- service_os/service.go | 2 +- service_os/service_windows.go | 3 +- snapshot/archive.go | 2 +- snapshot/archive_test.go | 2 +- snapshot/snapshot.go | 2 +- snapshot/snapshot_test.go | 2 +- test-integ/README.md | 3 - test-integ/connect/snapshot_test.go | 212 - test-integ/go.mod | 248 - test-integ/go.sum | 1345 ----- test-integ/peering_commontopo/README.md | 66 - .../peering_commontopo/ac1_basic_test.go | 275 -- .../ac2_disco_chain_test.go | 206 - .../ac3_service_defaults_upstream_test.go | 267 - .../ac4_proxy_defaults_test.go | 216 - .../ac5_1_no_svc_mesh_test.go | 132 - .../ac5_2_pq_failover_test.go | 407 -- .../peering_commontopo/ac6_failovers_test.go | 432 -- .../ac7_1_rotate_gw_test.go | 195 - .../ac7_2_rotate_leader_test.go | 218 - test-integ/peering_commontopo/asserter.go | 296 -- test-integ/peering_commontopo/commontopo.go | 625 --- .../peering_commontopo/sharedtopology_test.go | 85 - test/bin/cluster.bash | 2 +- test/ca/generate.sh | 2 +- test/client_certs/generate.sh | 2 +- test/hostname/generate.sh | 2 +- .../envoy/Dockerfile-consul-envoy-windows | 12 - .../connect/envoy/Dockerfile-tcpdump-windows | 7 - .../envoy/Dockerfile-test-sds-server-windows | 8 - test/integration/connect/envoy/README.md | 1 - .../integration/connect/envoy/WINDOWS-TEST.md | 40 - .../capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../case-api-gateway-http-hostnames/setup.sh | 2 +- .../case-api-gateway-http-hostnames/vars.sh | 2 +- .../case-api-gateway-http-simple/capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../case-api-gateway-http-simple/setup.sh | 2 +- .../case-api-gateway-http-simple/vars.sh | 2 +- .../capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../service_s3.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../case-api-gateway-tcp-conflicted/setup.sh | 2 +- .../case-api-gateway-tcp-conflicted/vars.sh | 2 +- .../case-api-gateway-tcp-simple/capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../case-api-gateway-tcp-simple/setup.sh | 2 +- .../envoy/case-api-gateway-tcp-simple/vars.sh | 2 +- .../capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../connect/envoy/case-badauthz/capture.sh | 2 +- .../connect/envoy/case-badauthz/setup.sh | 2 +- .../connect/envoy/case-basic/capture.sh | 2 +- .../connect/envoy/case-basic/setup.sh | 2 +- .../connect/envoy/case-centralconf/capture.sh | 2 +- .../envoy/case-centralconf/service_s1.hcl | 2 +- .../envoy/case-centralconf/service_s2.hcl | 2 +- .../connect/envoy/case-centralconf/setup.sh | 2 +- .../alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../alpha/service_s1.hcl | 2 +- .../alpha/service_s2.hcl | 2 +- .../alpha/setup.sh | 2 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/base.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../primary/setup.sh | 2 +- .../vars.sh | 2 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/setup.sh | 2 +- .../secondary/join.hcl | 2 +- .../secondary/service_gateway.hcl | 2 +- .../secondary/service_s1.hcl | 2 +- .../secondary/setup.sh | 2 +- .../vars.sh | 2 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/setup.sh | 2 +- .../secondary/join.hcl | 2 +- .../secondary/service_gateway.hcl | 2 +- .../secondary/service_s1.hcl | 2 +- .../secondary/setup.sh | 2 +- .../vars.sh | 2 +- .../service_s2-v1.hcl | 2 +- .../service_s2-v2.hcl | 2 +- .../case-cfg-resolver-defaultsubset/setup.sh | 2 +- .../case-cfg-resolver-defaultsubset/vars.sh | 2 +- .../case-cfg-resolver-features/capture.sh | 2 +- .../service_s2-v1.hcl | 2 +- .../service_s2-v2.hcl | 2 +- .../envoy/case-cfg-resolver-features/setup.sh | 2 +- .../envoy/case-cfg-resolver-features/vars.sh | 2 +- .../service_s2-v1.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../service_s3-v1.hcl | 2 +- .../service_s3-v2.hcl | 2 +- .../service_s3.hcl | 2 +- .../setup.sh | 2 +- .../case-cfg-resolver-subset-redirect/vars.sh | 2 +- .../service_s3-v1.hcl | 2 +- .../service_s3-v2.hcl | 2 +- .../service_s3.hcl | 2 +- .../case-cfg-resolver-svc-failover/setup.sh | 2 +- .../case-cfg-resolver-svc-failover/vars.sh | 2 +- .../service_s3.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../service_s3.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../envoy/case-cfg-router-features/capture.sh | 2 +- .../service_s2-v1.hcl | 2 +- .../service_s2-v2.hcl | 2 +- .../envoy/case-cfg-router-features/setup.sh | 2 +- .../envoy/case-cfg-router-features/vars.sh | 2 +- .../alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../alpha/service_s1.hcl | 2 +- .../alpha/service_s2.hcl | 2 +- .../alpha/setup.sh | 2 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/base.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../primary/setup.sh | 2 +- .../case-cfg-splitter-cluster-peering/vars.sh | 2 +- .../case-cfg-splitter-features/capture.sh | 2 +- .../service_s2-v1.hcl | 2 +- .../service_s2-v2.hcl | 2 +- .../envoy/case-cfg-splitter-features/setup.sh | 2 +- .../envoy/case-cfg-splitter-features/vars.sh | 2 +- .../alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../alpha/service_s1.hcl | 2 +- .../alpha/service_s2.hcl | 2 +- .../alpha/setup.sh | 2 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/base.hcl | 2 +- .../primary/service_ingress.hcl | 2 +- .../primary/setup.sh | 2 +- .../vars.sh | 2 +- .../connect/envoy/case-consul-exec/setup.sh | 2 +- .../connect/envoy/case-consul-exec/vars.sh | 2 +- .../alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../alpha/service_s1.hcl | 2 +- .../alpha/service_s2.hcl | 2 +- .../alpha/setup.sh | 2 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/base.hcl | 2 +- .../primary/service_gateway.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../primary/setup.sh | 2 +- .../case-cross-peer-control-plane-mgw/vars.sh | 2 +- .../alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../alpha/service_s1.hcl | 2 +- .../alpha/service_s2.hcl | 2 +- .../alpha/service_s3.hcl | 2 +- .../alpha/setup.sh | 2 +- .../case-cross-peers-http-router/bind.hcl | 2 +- .../case-cross-peers-http-router/capture.sh | 2 +- .../primary/base.hcl | 2 +- .../primary/service_gateway.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../primary/setup.sh | 2 +- .../case-cross-peers-http-router/vars.sh | 2 +- .../case-cross-peers-http/alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../alpha/service_s1.hcl | 2 +- .../alpha/service_s2.hcl | 2 +- .../case-cross-peers-http/alpha/setup.sh | 2 +- .../envoy/case-cross-peers-http/bind.hcl | 2 +- .../envoy/case-cross-peers-http/capture.sh | 2 +- .../case-cross-peers-http/primary/base.hcl | 2 +- .../primary/service_gateway.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../case-cross-peers-http/primary/setup.sh | 2 +- .../envoy/case-cross-peers-http/vars.sh | 2 +- .../alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../alpha/service_s1.hcl | 2 +- .../alpha/service_s2.hcl | 2 +- .../alpha/service_s3.hcl | 2 +- .../alpha/setup.sh | 2 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/base.hcl | 2 +- .../primary/service_gateway.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../primary/setup.sh | 2 +- .../vars.sh | 2 +- .../envoy/case-cross-peers/alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../case-cross-peers/alpha/service_s1.hcl | 2 +- .../case-cross-peers/alpha/service_s2.hcl | 2 +- .../envoy/case-cross-peers/alpha/setup.sh | 2 +- .../connect/envoy/case-cross-peers/bind.hcl | 2 +- .../connect/envoy/case-cross-peers/capture.sh | 2 +- .../envoy/case-cross-peers/primary/base.hcl | 2 +- .../primary/service_gateway.hcl | 2 +- .../case-cross-peers/primary/service_s1.hcl | 2 +- .../case-cross-peers/primary/service_s2.hcl | 2 +- .../envoy/case-cross-peers/primary/setup.sh | 2 +- .../connect/envoy/case-cross-peers/vars.sh | 2 +- .../envoy/case-dogstatsd-udp/service_s1.hcl | 2 +- .../connect/envoy/case-dogstatsd-udp/setup.sh | 2 +- .../connect/envoy/case-dogstatsd-udp/vars.sh | 2 +- .../envoy/case-dogstatsd-udp/verify.bats | 9 +- .../envoy/case-expose-checks/capture.sh | 2 +- .../envoy/case-expose-checks/service_s1.hcl | 2 +- .../envoy/case-expose-checks/service_s2.hcl | 2 +- .../connect/envoy/case-expose-checks/setup.sh | 2 +- .../case-gateway-without-services/bind.hcl | 2 +- .../case-gateway-without-services/capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../service_s1.hcl | 2 +- .../service_s2.hcl | 2 +- .../case-gateway-without-services/setup.sh | 2 +- .../case-gateway-without-services/vars.sh | 2 +- .../envoy/case-gateways-local/bind.hcl | 2 +- .../envoy/case-gateways-local/capture.sh | 2 +- .../primary/service_gateway.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../case-gateways-local/primary/setup.sh | 2 +- .../case-gateways-local/secondary/join.hcl | 2 +- .../secondary/service_gateway.hcl | 2 +- .../secondary/service_s1.hcl | 2 +- .../case-gateways-local/secondary/setup.sh | 4 +- .../connect/envoy/case-gateways-local/vars.sh | 2 +- .../envoy/case-gateways-remote/bind.hcl | 2 +- .../envoy/case-gateways-remote/capture.sh | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../case-gateways-remote/primary/setup.sh | 2 +- .../case-gateways-remote/secondary/join.hcl | 2 +- .../secondary/service_gateway.hcl | 2 +- .../secondary/service_s1.hcl | 2 +- .../case-gateways-remote/secondary/setup.sh | 2 +- .../envoy/case-gateways-remote/vars.sh | 2 +- .../connect/envoy/case-grpc/service_s1.hcl | 4 +- .../connect/envoy/case-grpc/service_s2.hcl | 2 +- .../connect/envoy/case-grpc/setup.sh | 2 +- .../connect/envoy/case-grpc/vars.sh | 2 +- .../connect/envoy/case-grpc/verify.bats | 2 +- .../envoy/case-http-badauthz/capture.sh | 2 +- .../envoy/case-http-badauthz/service_s1.hcl | 2 +- .../envoy/case-http-badauthz/service_s2.hcl | 2 +- .../connect/envoy/case-http-badauthz/setup.sh | 6 +- .../connect/envoy/case-http/capture.sh | 2 +- .../connect/envoy/case-http/service_s1.hcl | 2 +- .../connect/envoy/case-http/service_s2.hcl | 2 +- .../connect/envoy/case-http/setup.sh | 2 +- .../case-ingress-gateway-grpc/capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../case-ingress-gateway-grpc/service_s1.hcl | 2 +- .../envoy/case-ingress-gateway-grpc/setup.sh | 2 +- .../envoy/case-ingress-gateway-grpc/vars.sh | 2 +- .../case-ingress-gateway-http/capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../envoy/case-ingress-gateway-http/setup.sh | 2 +- .../envoy/case-ingress-gateway-http/vars.sh | 2 +- .../capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../alpha/base.hcl | 2 +- .../alpha/service_gateway.hcl | 2 +- .../alpha/service_s1.hcl | 2 +- .../alpha/service_s2.hcl | 2 +- .../alpha/setup.sh | 2 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/base.hcl | 2 +- .../primary/service_ingress.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../primary/setup.sh | 2 +- .../vars.sh | 2 +- .../envoy/case-ingress-gateway-sds/capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../envoy/case-ingress-gateway-sds/setup.sh | 2 +- .../envoy/case-ingress-gateway-sds/vars.sh | 2 +- .../case-ingress-gateway-simple/capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../case-ingress-gateway-simple/setup.sh | 2 +- .../envoy/case-ingress-gateway-simple/vars.sh | 2 +- .../envoy/case-ingress-gateway-tls/capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../envoy/case-ingress-gateway-tls/setup.sh | 2 +- .../envoy/case-ingress-gateway-tls/vars.sh | 2 +- .../case-ingress-gateway-tls/verify.bats | 10 +- .../bind.hcl | 2 +- .../capture.sh | 2 +- .../primary/service_gateway.hcl | 2 +- .../primary/service_ingress.hcl | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../primary/setup.sh | 2 +- .../secondary/join.hcl | 2 +- .../secondary/service_gateway.hcl | 2 +- .../secondary/setup.sh | 2 +- .../vars.sh | 2 +- .../connect/envoy/case-l7-intentions/acl.hcl | 2 +- .../envoy/case-l7-intentions/capture.sh | 2 +- .../connect/envoy/case-l7-intentions/setup.sh | 2 +- .../connect/envoy/case-lua/capture.sh | 2 +- .../connect/envoy/case-lua/service_s1.hcl | 2 +- .../connect/envoy/case-lua/service_s2.hcl | 2 +- .../connect/envoy/case-lua/setup.sh | 2 +- .../connect/envoy/case-lua/vars.sh | 2 +- .../envoy/case-mesh-to-lambda/capture.sh | 2 +- .../case-mesh-to-lambda/service_gateway.hcl | 2 +- .../envoy/case-mesh-to-lambda/service_s1.hcl | 2 +- .../envoy/case-mesh-to-lambda/setup.sh | 2 +- .../connect/envoy/case-mesh-to-lambda/vars.sh | 2 +- .../envoy/case-multidc-rsa-ca/bind.hcl | 2 +- .../envoy/case-multidc-rsa-ca/ca_config.hcl | 2 +- .../envoy/case-multidc-rsa-ca/capture.sh | 2 +- .../primary/service_s1.hcl | 2 +- .../primary/service_s2.hcl | 2 +- .../case-multidc-rsa-ca/primary/setup.sh | 2 +- .../case-multidc-rsa-ca/secondary/join.hcl | 2 +- .../secondary/service_s1.hcl | 2 +- .../case-multidc-rsa-ca/secondary/setup.sh | 2 +- .../connect/envoy/case-multidc-rsa-ca/vars.sh | 2 +- .../connect/envoy/case-prometheus/capture.sh | 2 +- .../envoy/case-prometheus/service_s1.hcl | 2 +- .../envoy/case-prometheus/service_s2.hcl | 2 +- .../connect/envoy/case-prometheus/setup.sh | 2 +- .../envoy/case-property-override/capture.sh | 2 +- .../case-property-override/service_s1.hcl | 2 +- .../case-property-override/service_s2.hcl | 2 +- .../case-property-override/service_s3.hcl | 2 +- .../envoy/case-property-override/setup.sh | 2 +- .../envoy/case-property-override/vars.sh | 2 +- .../envoy/case-stats-proxy/service_s1.hcl | 2 +- .../envoy/case-stats-proxy/service_s2.hcl | 2 +- .../connect/envoy/case-stats-proxy/setup.sh | 2 +- .../envoy/case-stats-proxy/verify.bats | 2 +- .../envoy/case-statsd-udp/service_s1.hcl | 2 +- .../connect/envoy/case-statsd-udp/setup.sh | 2 +- .../connect/envoy/case-statsd-udp/vars.sh | 2 +- .../capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../service_s1.hcl | 2 +- .../service_s4.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../service_gateway.hcl | 2 +- .../case-terminating-gateway-simple/setup.sh | 2 +- .../case-terminating-gateway-simple/vars.sh | 2 +- .../capture.sh | 2 +- .../service_gateway.hcl | 2 +- .../service_s2-v1.hcl | 2 +- .../service_s2-v2.hcl | 2 +- .../service_s3.hcl | 2 +- .../case-terminating-gateway-subsets/setup.sh | 2 +- .../case-terminating-gateway-subsets/vars.sh | 2 +- .../bind.hcl | 2 +- .../service_gateway.hcl | 2 +- .../service_s1.hcl | 2 +- .../service_s2.hcl | 2 +- .../setup.sh | 2 +- .../vars.sh | 2 +- .../envoy/case-upstream-config/service_s1.hcl | 2 +- .../envoy/case-upstream-config/service_s2.hcl | 2 +- .../envoy/case-upstream-config/setup.sh | 2 +- .../connect/envoy/case-wanfed-gw/bind.hcl | 2 +- .../connect/envoy/case-wanfed-gw/capture.sh | 2 +- .../case-wanfed-gw/global-setup-windows.sh | 47 - .../envoy/case-wanfed-gw/global-setup.sh | 2 +- .../envoy/case-wanfed-gw/primary/common.hcl | 2 +- .../envoy/case-wanfed-gw/primary/server.hcl | 2 +- .../primary/service_gateway.hcl | 2 +- .../case-wanfed-gw/primary/service_s1.hcl | 2 +- .../case-wanfed-gw/primary/service_s2.hcl | 2 +- .../envoy/case-wanfed-gw/primary/setup.sh | 2 +- .../envoy/case-wanfed-gw/secondary/common.hcl | 2 +- .../envoy/case-wanfed-gw/secondary/server.hcl | 2 +- .../secondary/service_gateway.hcl | 2 +- .../case-wanfed-gw/secondary/service_s1.hcl | 2 +- .../case-wanfed-gw/secondary/service_s2.hcl | 2 +- .../envoy/case-wanfed-gw/secondary/setup.sh | 2 +- .../connect/envoy/case-wanfed-gw/vars.sh | 2 +- .../connect/envoy/case-wasm/capture.sh | 2 +- .../connect/envoy/case-wasm/service_s1.hcl | 2 +- .../connect/envoy/case-wasm/service_s2.hcl | 2 +- .../connect/envoy/case-wasm/setup.sh | 2 +- .../connect/envoy/case-wasm/vars.sh | 2 +- .../connect/envoy/case-zipkin/service_s1.hcl | 2 +- .../connect/envoy/case-zipkin/service_s2.hcl | 2 +- .../connect/envoy/case-zipkin/setup.sh | 2 +- .../connect/envoy/case-zipkin/vars.sh | 2 +- .../connect/envoy/case-zipkin/verify.bats | 7 +- .../connect/envoy/consul-base-cfg/base.hcl | 2 +- .../envoy/consul-base-cfg/service_s1.hcl | 2 +- .../envoy/consul-base-cfg/service_s2.hcl | 2 +- test/integration/connect/envoy/defaults.sh | 2 +- .../connect/envoy/docker-windows.md | 42 - .../connect/envoy/docs/img/linux-arch.png | Bin 63964 -> 0 bytes .../docs/img/windows-arch-singlecontainer.png | Bin 114040 -> 0 bytes .../envoy/docs/img/windows-linux-arch.png | Bin 61475 -> 0 bytes .../docs/windows-testing-architecture.md | 106 - test/integration/connect/envoy/down.sh | 2 +- test/integration/connect/envoy/helpers.bash | 4 +- .../connect/envoy/helpers.windows.bash | 1195 ----- test/integration/connect/envoy/main_test.go | 141 +- test/integration/connect/envoy/run-tests.sh | 16 +- .../connect/envoy/run-tests.windows.sh | 916 ---- .../connect/envoy/test-sds-server/Dockerfile | 2 +- .../envoy/test-sds-server/certs/gen-certs.sh | 2 +- .../connect/envoy/test-sds-server/sds.go | 2 +- .../connect/envoy/windows-troubleshooting.md | 90 - .../assets/Dockerfile-consul-dataplane | 31 - .../consul-container/assets/tproxy-startup.sh | 3 - test/integration/consul-container/go.mod | 159 +- test/integration/consul-container/go.sum | 960 +--- .../consul-container/libs/assert/common.go | 2 +- .../consul-container/libs/assert/envoy.go | 6 +- .../consul-container/libs/assert/grpc.go | 3 +- .../consul-container/libs/assert/peering.go | 16 +- .../consul-container/libs/assert/service.go | 4 +- .../consul-container/libs/cluster/agent.go | 78 +- .../consul-container/libs/cluster/app.go | 2 +- .../consul-container/libs/cluster/builder.go | 7 +- .../consul-container/libs/cluster/cluster.go | 24 +- .../consul-container/libs/cluster/config.go | 2 +- .../libs/cluster/container.go | 82 +- .../libs/cluster/dataplane.go | 171 - .../libs/cluster/encryption.go | 140 +- .../consul-container/libs/cluster/log.go | 2 +- .../consul-container/libs/cluster/network.go | 3 +- .../consul-container/libs/service/common.go | 4 +- .../consul-container/libs/service/connect.go | 22 +- .../consul-container/libs/service/examples.go | 40 +- .../consul-container/libs/service/gateway.go | 7 +- .../consul-container/libs/service/helpers.go | 122 +- .../consul-container/libs/service/log.go | 2 +- .../consul-container/libs/service/service.go | 2 +- .../libs/topology/peering_topology.go | 33 +- .../libs/topology/service_topology.go | 14 +- .../consul-container/libs/utils/debug.go | 2 +- .../consul-container/libs/utils/defer.go | 2 +- .../consul-container/libs/utils/docker.go | 17 +- .../consul-container/libs/utils/helpers.go | 2 +- .../consul-container/libs/utils/retry.go | 2 +- .../consul-container/libs/utils/tenancy.go | 17 +- .../consul-container/libs/utils/utils.go | 2 +- .../consul-container/libs/utils/version.go | 17 +- .../consul-container/libs/utils/version_ce.go | 3 +- .../test/basic/connect_service_test.go | 57 +- .../test/catalog/catalog_test.go | 38 - .../consul_envoy_version.go | 2 +- .../consul-container/test/debugging.md | 78 - .../test/envoy_extensions/ext_authz_test.go | 2 +- .../otel_access_logging_test.go | 133 - .../testdata/otel/config.yaml | 30 - .../testdata/wasm_test_files/Dockerfile | 6 - .../testdata/wasm_test_files/README.md | 14 - .../testdata/wasm_test_files/build.sh | 6 - .../testdata/wasm_test_files/go.mod | 5 - .../testdata/wasm_test_files/go.sum | 6 - .../testdata/wasm_test_files/nginx.conf | 13 - .../wasm_test_files/wasm_add_header.go | 50 - .../wasm_test_files/wasm_add_header.wasm | Bin 400008 -> 0 bytes .../test/envoy_extensions/wasm_test.go | 464 -- .../test/gateways/gateway_endpoint_test.go | 27 +- .../test/gateways/http_route_test.go | 263 +- .../test/gateways/ingress_gateway_test.go | 4 +- .../test/gateways/tenancy_ce.go | 4 +- .../test/gateways/terminating_gateway_test.go | 187 - .../test/jwtauth/jwt_auth_test.go | 2 +- .../multiport/explicit_destination_test.go | 228 - .../test/observability/access_logs_test.go | 4 +- .../test/observability/metrics_leader_test.go | 2 +- .../rotate_server_and_ca_then_fail_test.go | 2 +- .../test/ratelimit/ratelimit_test.go | 106 +- .../resource/http_api/acl_enabled_test.go | 223 - .../test/resource/http_api/client/client.go | 312 -- .../test/resource/http_api/helper.go | 213 - .../test/snapshot/snapshot_restore_test.go | 2 +- .../test/tproxy/tproxy_test.go | 2 +- .../test/trafficpermissions/tcp_test.go | 657 --- .../test/troubleshoot/troubleshoot_test.go | 4 +- .../test/upgrade/acl_node_test.go | 2 +- .../test/upgrade/basic/basic_test.go | 2 +- .../upgrade/basic/fullstopupgrade_test.go | 2 +- .../test/upgrade/basic/healthcheck_test.go | 2 +- .../test/upgrade/catalog/catalog_test.go | 88 - .../consul-container/test/upgrade/common.go | 5 +- .../test/upgrade/ingress_gateway_grpc_test.go | 2 +- .../test/upgrade/ingress_gateway_sds_test.go | 2 +- .../test/upgrade/ingress_gateway_test.go | 2 +- .../resolver_default_subset_test.go | 6 +- .../peering/peering_control_plane_mgw_test.go | 2 +- .../test/upgrade/peering/peering_http_test.go | 2 +- .../test/util/test_debug_breakpoint_hit.png | Bin 654866 -> 0 bytes .../test/util/test_debug_configuration.png | Bin 294046 -> 0 bytes .../test/util/test_debug_info.png | Bin 622325 -> 0 bytes .../util/test_debug_remote_configuration.png | Bin 285715 -> 0 bytes .../test/util/test_debug_remote_connected.png | Bin 111968 -> 0 bytes .../test/util/test_debug_resume_program.png | Bin 51972 -> 0 bytes .../wanfed/acl_bootstrap_replication_test.go | 2 +- .../test/wanfed/wanfed_peering_test.go | 2 +- test/load/packer/consul-ami/consul.pkr.hcl | 2 +- test/load/packer/consul-ami/scripts/conf.yaml | 2 +- .../packer/consul-ami/scripts/datadog.yaml | 2 +- .../packer/consul-ami/scripts/move-files.sh | 2 +- .../load/packer/loadtest-ami/loadtest.pkr.hcl | 2 +- .../packer/loadtest-ami/scripts/install-k6.sh | 2 +- .../packer/loadtest-ami/scripts/loadtest.js | 2 +- test/load/terraform/consul.tf | 2 +- test/load/terraform/main.tf | 2 +- test/load/terraform/outputs.tf | 2 +- test/load/terraform/providers.tf | 2 +- test/load/terraform/test-servers.tf | 2 +- test/load/terraform/user-data-client.sh | 2 +- test/load/terraform/user-data-server.sh | 2 +- test/load/terraform/variables.tf | 2 +- testing/deployer/.gitignore | 4 - testing/deployer/README.md | 179 - testing/deployer/TODO.md | 9 - testing/deployer/go.mod | 48 - testing/deployer/go.sum | 245 - testing/deployer/sprawl/acl.go | 335 -- testing/deployer/sprawl/acl_rules.go | 195 - testing/deployer/sprawl/boot.go | 524 -- testing/deployer/sprawl/catalog.go | 460 -- testing/deployer/sprawl/configentries.go | 61 - testing/deployer/sprawl/consul.go | 102 - testing/deployer/sprawl/debug.go | 11 - testing/deployer/sprawl/details.go | 173 - testing/deployer/sprawl/ent.go | 177 - testing/deployer/sprawl/helpers.go | 14 - .../deployer/sprawl/internal/build/docker.go | 87 - .../deployer/sprawl/internal/runner/exec.go | 123 - .../deployer/sprawl/internal/secrets/store.go | 73 - .../deployer/sprawl/internal/tfgen/agent.go | 218 - .../deployer/sprawl/internal/tfgen/digest.go | 48 - testing/deployer/sprawl/internal/tfgen/dns.go | 180 - .../deployer/sprawl/internal/tfgen/docker.go | 45 - .../sprawl/internal/tfgen/docker_test.go | 18 - testing/deployer/sprawl/internal/tfgen/gen.go | 476 -- testing/deployer/sprawl/internal/tfgen/io.go | 73 - .../deployer/sprawl/internal/tfgen/nodes.go | 159 - .../deployer/sprawl/internal/tfgen/prelude.go | 19 - .../deployer/sprawl/internal/tfgen/proxy.go | 87 - testing/deployer/sprawl/internal/tfgen/res.go | 98 - .../templates/container-app-dataplane.tf.tmpl | 44 - .../templates/container-app-sidecar.tf.tmpl | 37 - .../tfgen/templates/container-app.tf.tmpl | 25 - .../tfgen/templates/container-consul.tf.tmpl | 37 - .../tfgen/templates/container-coredns.tf.tmpl | 28 - .../templates/container-mgw-dataplane.tf.tmpl | 45 - .../tfgen/templates/container-mgw.tf.tmpl | 39 - .../tfgen/templates/container-pause.tf.tmpl | 38 - .../tfgen/templates/container-proxy.tf.tmpl | 33 - .../deployer/sprawl/internal/tfgen/tfgen.go | 32 - testing/deployer/sprawl/peering.go | 183 - testing/deployer/sprawl/sprawl.go | 508 -- .../deployer/sprawl/sprawltest/sprawltest.go | 208 - .../deployer/sprawl/sprawltest/test_test.go | 183 - testing/deployer/sprawl/tls.go | 119 - testing/deployer/topology/compile.go | 678 --- testing/deployer/topology/default_cdp.go | 6 - testing/deployer/topology/default_consul.go | 7 - testing/deployer/topology/default_envoy.go | 6 - testing/deployer/topology/ids.go | 145 - testing/deployer/topology/images.go | 132 - testing/deployer/topology/images_test.go | 101 - testing/deployer/topology/topology.go | 788 --- testing/deployer/topology/util.go | 20 - testing/deployer/topology/util_test.go | 14 - testing/deployer/util/consul.go | 66 - testing/deployer/util/files.go | 60 - .../deployer/util/internal/ipamutils/doc.go | 21 - .../deployer/util/internal/ipamutils/utils.go | 120 - .../util/internal/ipamutils/utils_test.go | 105 - testing/deployer/util/net.go | 20 - testrpc/wait.go | 2 +- tlsutil/config.go | 27 +- tlsutil/config_test.go | 11 +- tlsutil/generate.go | 2 +- tlsutil/generate_test.go | 2 +- tools/internal-grpc-proxy/main.go | 2 +- troubleshoot/go.mod | 7 +- troubleshoot/go.sum | 16 +- troubleshoot/proxy/certs.go | 2 +- troubleshoot/proxy/certs_test.go | 2 +- troubleshoot/proxy/stats.go | 2 +- troubleshoot/proxy/troubleshoot_proxy.go | 2 +- troubleshoot/proxy/upstreams.go | 2 +- troubleshoot/proxy/upstreams_test.go | 2 +- troubleshoot/proxy/utils.go | 2 +- troubleshoot/proxy/validateupstream.go | 2 +- troubleshoot/proxy/validateupstream_test.go | 2 +- troubleshoot/validate/validate.go | 2 +- troubleshoot/validate/validate_test.go | 2 +- types/area.go | 2 +- types/checks.go | 2 +- types/node_id.go | 2 +- types/tls.go | 2 +- types/tls_test.go | 2 +- ui/.nvmrc | 2 +- ui/package.json | 2 +- .../components/consul/acl/selector/index.hbs | 2 +- .../consul/token/selector/index.hbs | 2 +- .../components/consul/token/selector/index.js | 2 +- .../consul-acls/vendor/consul-acls/routes.js | 2 +- .../vendor/consul-acls/services.js | 2 +- .../app/components/consul/hcp/home/index.hbs | 2 +- .../app/components/consul/hcp/home/index.scss | 2 +- .../components/consul/hcp/home/index.test.js | 2 +- .../consul-hcp/vendor/consul-hcp/routes.js | 2 +- .../consul-hcp/vendor/consul-hcp/services.js | 2 +- .../consul/lock-session/form/index.hbs | 2 +- .../consul/lock-session/form/index.scss | 2 +- .../consul/lock-session/list/index.hbs | 6 +- .../consul/lock-session/list/index.scss | 2 +- .../lock-session/notifications/index.hbs | 2 +- .../app/templates/dc/nodes/show/sessions.hbs | 2 +- .../vendor/consul-lock-sessions/routes.js | 2 +- .../vendor/consul-lock-sessions/services.js | 2 +- .../components/consul/nspace/form/index.hbs | 2 +- .../components/consul/nspace/form/index.js | 2 +- .../components/consul/nspace/list/index.hbs | 2 +- .../consul/nspace/list/pageobject.js | 2 +- .../consul/nspace/notifications/index.hbs | 2 +- .../consul/nspace/search-bar/index.hbs | 2 +- .../consul/nspace/selector/index.hbs | 2 +- .../app/templates/dc/nspaces/edit.hbs | 2 +- .../app/templates/dc/nspaces/index.hbs | 2 +- .../vendor/consul-nspaces/routes.js | 2 +- .../vendor/consul-nspaces/services.js | 2 +- .../consul/partition/form/index.hbs | 2 +- .../consul/partition/list/index.hbs | 2 +- .../consul/partition/list/test-support.js | 2 +- .../consul/partition/notifications/index.hbs | 2 +- .../consul/partition/search-bar/index.hbs | 2 +- .../consul/partition/selector/index.hbs | 2 +- .../app/templates/dc/partitions/edit.hbs | 2 +- .../app/templates/dc/partitions/index.hbs | 2 +- .../vendor/consul-partitions/routes.js | 2 +- .../vendor/consul-partitions/services.js | 2 +- .../consul/peer/address/list/index.hbs | 4 +- .../consul/peer/address/list/index.scss | 2 +- .../consul/peer/bento-box/index.hbs | 2 +- .../components/consul/peer/components.scss | 2 +- .../consul/peer/form/chart.xstate.js | 2 +- .../peer/form/generate/actions/index.hbs | 2 +- .../consul/peer/form/generate/chart.xstate.js | 2 +- .../peer/form/generate/fieldsets/index.hbs | 2 +- .../peer/form/generate/fieldsets/index.js | 2 +- .../consul/peer/form/generate/index.hbs | 2 +- .../app/components/consul/peer/form/index.hbs | 2 +- .../components/consul/peer/form/index.scss | 2 +- .../peer/form/initiate/actions/index.hbs | 2 +- .../peer/form/initiate/fieldsets/index.hbs | 2 +- .../consul/peer/form/initiate/index.hbs | 2 +- .../consul/peer/form/token/actions/index.hbs | 2 +- .../peer/form/token/fieldsets/index.hbs | 4 +- .../app/components/consul/peer/index.scss | 2 +- .../app/components/consul/peer/list/index.hbs | 2 +- .../consul/peer/list/test-support.js | 2 +- .../consul/peer/notifications/index.hbs | 2 +- .../consul/peer/search-bar/index.hbs | 2 +- .../consul/peer/search-bar/index.scss | 2 +- .../components/consul/peer/selector/index.hbs | 2 +- .../app/controllers/dc/peers/index.js | 2 +- .../app/controllers/dc/peers/show/exported.js | 2 +- .../app/controllers/dc/peers/show/index.js | 2 +- .../app/templates/dc/peers/index.hbs | 2 +- .../app/templates/dc/peers/show.hbs | 2 +- .../app/templates/dc/peers/show/addresses.hbs | 2 +- .../app/templates/dc/peers/show/exported.hbs | 2 +- .../app/templates/dc/peers/show/imported.hbs | 2 +- .../app/templates/dc/peers/show/index.hbs | 2 +- .../vendor/consul-peerings/routes.js | 2 +- .../vendor/consul-peerings/services.js | 2 +- ui/packages/consul-ui/.docfy-config.js | 2 +- ui/packages/consul-ui/.eslintrc.js | 2 +- ui/packages/consul-ui/.istanbul.yml | 2 +- ui/packages/consul-ui/.prettierrc.js | 2 +- ui/packages/consul-ui/.template-lintrc.js | 2 +- ui/packages/consul-ui/README.md | 2 +- ui/packages/consul-ui/app/abilities/acl.js | 2 +- .../consul-ui/app/abilities/auth-method.js | 2 +- ui/packages/consul-ui/app/abilities/base.js | 2 +- .../consul-ui/app/abilities/intention.js | 2 +- ui/packages/consul-ui/app/abilities/kv.js | 2 +- .../consul-ui/app/abilities/license.js | 2 +- ui/packages/consul-ui/app/abilities/node.js | 2 +- ui/packages/consul-ui/app/abilities/nspace.js | 2 +- .../consul-ui/app/abilities/overview.js | 2 +- .../consul-ui/app/abilities/partition.js | 2 +- ui/packages/consul-ui/app/abilities/peer.js | 2 +- .../consul-ui/app/abilities/permission.js | 2 +- ui/packages/consul-ui/app/abilities/policy.js | 2 +- ui/packages/consul-ui/app/abilities/role.js | 2 +- ui/packages/consul-ui/app/abilities/server.js | 2 +- .../app/abilities/service-instance.js | 2 +- .../consul-ui/app/abilities/session.js | 2 +- ui/packages/consul-ui/app/abilities/token.js | 2 +- .../consul-ui/app/abilities/upstream.js | 2 +- .../consul-ui/app/abilities/zervice.js | 2 +- ui/packages/consul-ui/app/abilities/zone.js | 2 +- .../consul-ui/app/adapters/application.js | 2 +- .../consul-ui/app/adapters/auth-method.js | 2 +- .../consul-ui/app/adapters/binding-rule.js | 2 +- .../consul-ui/app/adapters/coordinate.js | 2 +- .../consul-ui/app/adapters/discovery-chain.js | 2 +- ui/packages/consul-ui/app/adapters/http.js | 2 +- .../consul-ui/app/adapters/intention.js | 2 +- ui/packages/consul-ui/app/adapters/kv.js | 2 +- ui/packages/consul-ui/app/adapters/node.js | 2 +- ui/packages/consul-ui/app/adapters/nspace.js | 2 +- .../consul-ui/app/adapters/oidc-provider.js | 2 +- .../consul-ui/app/adapters/partition.js | 2 +- .../consul-ui/app/adapters/permission.js | 2 +- ui/packages/consul-ui/app/adapters/policy.js | 2 +- ui/packages/consul-ui/app/adapters/proxy.js | 2 +- ui/packages/consul-ui/app/adapters/role.js | 2 +- .../app/adapters/service-instance.js | 2 +- ui/packages/consul-ui/app/adapters/service.js | 2 +- ui/packages/consul-ui/app/adapters/session.js | 2 +- ui/packages/consul-ui/app/adapters/token.js | 2 +- .../consul-ui/app/adapters/topology.js | 2 +- ui/packages/consul-ui/app/app.js | 2 +- .../consul-ui/app/components/action/index.hbs | 2 +- .../app/components/anchors/index.scss | 2 +- .../app/components/anchors/skin.scss | 2 +- .../app/components/anonymous/index.hbs | 2 +- .../app/components/anonymous/index.js | 2 +- .../app/components/app-error/index.hbs | 2 +- .../app/components/app-view/index.hbs | 2 +- .../app/components/app-view/index.js | 2 +- .../app/components/app-view/index.scss | 2 +- .../app/components/app-view/layout.scss | 2 +- .../app/components/app-view/skin.scss | 2 +- .../consul-ui/app/components/app/index.hbs | 2 +- .../consul-ui/app/components/app/index.js | 2 +- .../consul-ui/app/components/app/index.scss | 2 +- .../app/components/app/notification/index.hbs | 2 +- .../app/components/aria-menu/index.hbs | 2 +- .../app/components/aria-menu/index.js | 2 +- .../components/auth-dialog/chart.xstate.js | 2 +- .../app/components/auth-dialog/index.hbs | 2 +- .../app/components/auth-dialog/index.js | 2 +- .../app/components/auth-form/chart.xstate.js | 2 +- .../app/components/auth-form/index.hbs | 2 +- .../app/components/auth-form/index.js | 2 +- .../app/components/auth-form/index.scss | 2 +- .../app/components/auth-form/layout.scss | 2 +- .../app/components/auth-form/pageobject.js | 2 +- .../app/components/auth-form/skin.scss | 2 +- .../app/components/auth-form/tabs.xstate.js | 2 +- .../app/components/auth-modal/index.scss | 2 +- .../app/components/auth-modal/layout.scss | 2 +- .../app/components/auth-modal/skin.scss | 2 +- .../app/components/auth-profile/index.hbs | 2 +- .../app/components/auth-profile/index.scss | 2 +- .../consul-ui/app/components/badge/debug.scss | 2 +- .../consul-ui/app/components/badge/index.scss | 2 +- .../app/components/brand-loader/index.scss | 2 +- .../app/components/brand-loader/layout.scss | 2 +- .../app/components/brand-loader/skin.scss | 2 +- .../app/components/breadcrumbs/index.scss | 2 +- .../app/components/breadcrumbs/layout.scss | 2 +- .../app/components/breadcrumbs/skin.scss | 2 +- .../app/components/buttons/index.scss | 2 +- .../app/components/buttons/layout.scss | 2 +- .../app/components/buttons/skin.scss | 2 +- .../consul-ui/app/components/card/index.scss | 2 +- .../consul-ui/app/components/card/layout.scss | 2 +- .../consul-ui/app/components/card/skin.scss | 2 +- .../app/components/checkbox-group/index.scss | 2 +- .../app/components/checkbox-group/layout.scss | 2 +- .../app/components/checkbox-group/skin.scss | 2 +- .../app/components/child-selector/index.hbs | 2 +- .../app/components/child-selector/index.js | 2 +- .../app/components/code-editor/README.mdx | 2 +- .../app/components/code-editor/index.hbs | 4 +- .../app/components/code-editor/index.js | 34 +- .../app/components/code-editor/index.scss | 2 +- .../app/components/code-editor/layout.scss | 2 +- .../app/components/code-editor/skin.scss | 2 +- .../app/components/composite-row/index.scss | 2 +- .../app/components/composite-row/layout.scss | 2 +- .../components/confirmation-alert/index.hbs | 2 +- .../components/confirmation-alert/index.js | 2 +- .../components/confirmation-dialog/index.hbs | 2 +- .../components/confirmation-dialog/index.js | 2 +- .../components/confirmation-dialog/index.scss | 2 +- .../confirmation-dialog/layout.scss | 2 +- .../components/confirmation-dialog/skin.scss | 2 +- .../components/consul/acl/disabled/index.hbs | 2 +- .../consul/auth-method/binding-list/index.hbs | 2 +- .../components/consul/auth-method/index.scss | 2 +- .../consul/auth-method/list/index.hbs | 2 +- .../consul/auth-method/list/pageobject.js | 2 +- .../consul/auth-method/nspace-list/index.hbs | 2 +- .../consul/auth-method/search-bar/index.hbs | 2 +- .../consul/auth-method/type/index.hbs | 2 +- .../consul/auth-method/view/index.hbs | 2 +- .../components/consul/bucket/list/index.hbs | 2 +- .../components/consul/bucket/list/index.js | 2 +- .../components/consul/bucket/list/index.scss | 2 +- .../consul/datacenter/selector/index.hbs | 2 +- .../consul/discovery-chain/index.hbs | 2 +- .../consul/discovery-chain/index.js | 2 +- .../consul/discovery-chain/index.scss | 2 +- .../consul/discovery-chain/layout.scss | 2 +- .../discovery-chain/resolver-card/index.hbs | 2 +- .../discovery-chain/route-card/index.hbs | 2 +- .../discovery-chain/route-card/index.js | 2 +- .../consul/discovery-chain/skin.scss | 2 +- .../discovery-chain/splitter-card/index.hbs | 2 +- .../consul/discovery-chain/utils.js | 2 +- .../consul/exposed-path/list/index.hbs | 4 +- .../consul/exposed-path/list/index.scss | 2 +- .../consul/external-source/index.hbs | 2 +- .../consul/external-source/index.scss | 2 +- .../consul/health-check/list/index.hbs | 4 +- .../consul/health-check/list/index.scss | 2 +- .../consul/health-check/list/layout.scss | 2 +- .../consul/health-check/list/pageobject.js | 2 +- .../consul/health-check/list/skin.scss | 2 +- .../consul/health-check/search-bar/index.hbs | 2 +- .../consul/instance-checks/index.hbs | 2 +- .../consul/instance-checks/index.scss | 2 +- .../consul/intention/components.scss | 2 +- .../consul/intention/form/fieldsets/index.hbs | 2 +- .../consul/intention/form/fieldsets/index.js | 2 +- .../intention/form/fieldsets/index.scss | 2 +- .../intention/form/fieldsets/layout.scss | 2 +- .../consul/intention/form/fieldsets/skin.scss | 2 +- .../consul/intention/form/index.hbs | 2 +- .../components/consul/intention/form/index.js | 2 +- .../consul/intention/form/index.scss | 2 +- .../components/consul/intention/index.scss | 2 +- .../consul/intention/list/check/index.hbs | 2 +- .../consul/intention/list/components.scss | 2 +- .../consul/intention/list/index.hbs | 2 +- .../components/consul/intention/list/index.js | 2 +- .../consul/intention/list/index.scss | 2 +- .../consul/intention/list/layout.scss | 2 +- .../consul/intention/list/pageobject.js | 2 +- .../consul/intention/list/skin.scss | 2 +- .../consul/intention/list/table/index.hbs | 2 +- .../consul/intention/list/table/index.scss | 2 +- .../notice/custom-resource/index.hbs | 2 +- .../intention/notice/permissions/index.hbs | 2 +- .../consul/intention/notifications/index.hbs | 2 +- .../intention/permission/form/index.hbs | 2 +- .../consul/intention/permission/form/index.js | 2 +- .../intention/permission/form/index.scss | 2 +- .../intention/permission/form/layout.scss | 2 +- .../intention/permission/form/pageobject.js | 2 +- .../intention/permission/form/skin.scss | 2 +- .../permission/header/form/index.hbs | 2 +- .../intention/permission/header/form/index.js | 2 +- .../permission/header/form/pageobject.js | 2 +- .../permission/header/list/index.hbs | 2 +- .../intention/permission/header/list/index.js | 2 +- .../permission/header/list/index.scss | 2 +- .../permission/header/list/layout.scss | 2 +- .../permission/header/list/pageobject.js | 2 +- .../permission/header/list/skin.scss | 2 +- .../intention/permission/list/index.hbs | 2 +- .../consul/intention/permission/list/index.js | 2 +- .../intention/permission/list/index.scss | 2 +- .../intention/permission/list/layout.scss | 2 +- .../intention/permission/list/pageobject.js | 2 +- .../intention/permission/list/skin.scss | 2 +- .../consul/intention/search-bar/index.hbs | 2 +- .../consul/intention/search-bar/index.scss | 2 +- .../consul/intention/view/index.hbs | 2 +- .../components/consul/intention/view/index.js | 2 +- .../app/components/consul/kind/index.hbs | 2 +- .../app/components/consul/kind/index.js | 2 +- .../app/components/consul/kind/index.scss | 2 +- .../app/components/consul/kv/form/index.hbs | 2 +- .../app/components/consul/kv/form/index.js | 2 +- .../app/components/consul/kv/list/index.hbs | 2 +- .../components/consul/kv/list/pageobject.js | 2 +- .../components/consul/kv/search-bar/index.hbs | 2 +- .../app/components/consul/loader/index.hbs | 2 +- .../app/components/consul/loader/index.scss | 2 +- .../app/components/consul/loader/layout.scss | 2 +- .../app/components/consul/loader/skin.scss | 2 +- .../components/consul/metadata/list/index.hbs | 2 +- .../components/consul/metadata/list/index.js | 2 +- .../consul/node-identity/template/index.hbs | 2 +- .../consul/node/agentless-notice/index.hbs | 2 +- .../consul/node/agentless-notice/index.js | 2 +- .../consul/node/agentless-notice/index.scss | 2 +- .../app/components/consul/node/list/index.hbs | 4 +- .../consul/node/peer-info/index.hbs | 2 +- .../consul/node/peer-info/index.scss | 2 +- .../consul/node/search-bar/index.hbs | 260 +- .../app/components/consul/peer/info/index.hbs | 2 +- .../components/consul/peer/info/index.scss | 2 +- .../components/consul/peer/list/index.scss | 2 +- .../components/consul/policy/list/index.hbs | 2 +- .../consul/policy/list/pageobject.js | 2 +- .../consul/policy/notifications/index.hbs | 2 +- .../consul/policy/search-bar/index.hbs | 2 +- .../consul/policy/search-bar/index.js | 2 +- .../app/components/consul/role/list/index.hbs | 2 +- .../components/consul/role/list/pageobject.js | 2 +- .../consul/role/notifications/index.hbs | 2 +- .../consul/role/search-bar/index.hbs | 2 +- .../components/consul/server/card/index.hbs | 2 +- .../components/consul/server/card/index.scss | 2 +- .../components/consul/server/card/layout.scss | 2 +- .../components/consul/server/card/skin.scss | 2 +- .../components/consul/server/list/index.hbs | 2 +- .../components/consul/server/list/index.scss | 2 +- .../service-identity/template/index.hbs | 2 +- .../consul/service-instance/list/index.hbs | 2 +- .../consul/service-instance/list/index.js | 2 +- .../service-instance/search-bar/index.hbs | 2 +- .../components/consul/service/list/index.hbs | 2 +- .../consul/service/search-bar/index.hbs | 2 +- .../consul/service/search-bar/index.js | 2 +- .../app/components/consul/source/index.hbs | 2 +- .../app/components/consul/source/index.scss | 2 +- .../consul/sources-select/index.hbs | 2 +- .../components/consul/token/list/index.hbs | 6 +- .../consul/token/list/pageobject.js | 2 +- .../consul/token/notifications/index.hbs | 2 +- .../consul/token/ruleset/list/index.hbs | 2 +- .../consul/token/ruleset/list/index.js | 2 +- .../consul/token/search-bar/index.hbs | 2 +- .../consul/tomography/graph/index.hbs | 2 +- .../consul/tomography/graph/index.js | 2 +- .../consul/tomography/graph/index.scss | 2 +- .../consul/transparent-proxy/index.hbs | 2 +- .../consul/upstream-instance/list/index.hbs | 6 +- .../consul/upstream-instance/list/index.scss | 2 +- .../upstream-instance/list/pageobject.js | 2 +- .../upstream-instance/search-bar/index.hbs | 2 +- .../components/consul/upstream/list/index.hbs | 4 +- .../consul/upstream/list/index.scss | 2 +- .../consul/upstream/search-bar/index.hbs | 2 +- .../README.mdx | 8 +- .../chart.xstate.js | 2 +- .../index.hbs | 6 +- .../index.js | 4 +- .../index.scss | 2 +- .../layout.scss | 2 +- .../skin.scss | 2 +- .../app/components/copyable-code/index.hbs | 6 +- .../app/components/copyable-code/index.scss | 2 +- .../app/components/csv-list/debug.scss | 2 +- .../app/components/csv-list/index.scss | 2 +- .../app/components/data-collection/index.hbs | 2 +- .../app/components/data-collection/index.js | 2 +- .../app/components/data-form/index.hbs | 2 +- .../app/components/data-form/index.js | 2 +- .../components/data-loader/chart.xstate.js | 2 +- .../app/components/data-loader/index.hbs | 2 +- .../app/components/data-loader/index.js | 2 +- .../app/components/data-sink/index.hbs | 2 +- .../app/components/data-sink/index.js | 2 +- .../app/components/data-source/index.hbs | 2 +- .../app/components/data-source/index.js | 2 +- .../components/data-writer/chart.xstate.js | 2 +- .../app/components/data-writer/index.hbs | 2 +- .../app/components/data-writer/index.js | 2 +- .../app/components/debug/navigation/index.hbs | 2 +- .../components/definition-table/debug.scss | 2 +- .../components/definition-table/index.scss | 2 +- .../components/definition-table/layout.scss | 2 +- .../app/components/definition-table/skin.scss | 2 +- .../components/delete-confirmation/index.hbs | 2 +- .../components/delete-confirmation/index.js | 2 +- .../disclosure-menu/action/index.hbs | 2 +- .../app/components/disclosure-menu/index.hbs | 2 +- .../app/components/disclosure-menu/index.scss | 2 +- .../components/disclosure-menu/menu/index.hbs | 20 +- .../components/disclosure/action/index.hbs | 2 +- .../components/disclosure/details/index.hbs | 2 +- .../app/components/disclosure/index.hbs | 2 +- .../app/components/disclosure/index.js | 2 +- .../app/components/display-toggle/index.scss | 2 +- .../app/components/display-toggle/layout.scss | 2 +- .../app/components/display-toggle/skin.scss | 2 +- .../components/dom-recycling-table/index.scss | 2 +- .../dom-recycling-table/layout.scss | 2 +- .../app/components/empty-state/index.hbs | 2 +- .../app/components/empty-state/index.js | 2 +- .../app/components/empty-state/index.scss | 2 +- .../app/components/empty-state/layout.scss | 2 +- .../app/components/empty-state/pageobject.js | 2 +- .../app/components/empty-state/skin.scss | 2 +- .../app/components/error-state/index.hbs | 2 +- .../app/components/event-source/index.hbs | 2 +- .../app/components/event-source/index.js | 2 +- .../expanded-single-select/index.scss | 2 +- .../expanded-single-select/layout.scss | 2 +- .../expanded-single-select/skin.scss | 2 +- .../app/components/filter-bar/index.scss | 2 +- .../app/components/filter-bar/layout.scss | 2 +- .../app/components/filter-bar/skin.scss | 2 +- .../app/components/form-component/index.hbs | 2 +- .../app/components/form-component/index.js | 2 +- .../app/components/form-elements/index.scss | 2 +- .../app/components/form-elements/layout.scss | 2 +- .../app/components/form-elements/skin.scss | 2 +- .../form-group/element/checkbox/index.hbs | 2 +- .../form-group/element/error/index.hbs | 2 +- .../components/form-group/element/index.hbs | 2 +- .../components/form-group/element/index.js | 2 +- .../form-group/element/label/index.hbs | 2 +- .../form-group/element/radio/index.hbs | 2 +- .../form-group/element/text/index.hbs | 2 +- .../app/components/form-group/index.hbs | 2 +- .../app/components/form-group/index.js | 2 +- .../app/components/form-input/index.hbs | 2 +- .../app/components/freetext-filter/index.hbs | 2 +- .../app/components/freetext-filter/index.js | 2 +- .../app/components/freetext-filter/index.scss | 2 +- .../components/freetext-filter/layout.scss | 2 +- .../components/freetext-filter/pageobject.js | 2 +- .../app/components/freetext-filter/skin.scss | 2 +- .../app/components/hashicorp-consul/index.hbs | 2 +- .../app/components/hashicorp-consul/index.js | 2 +- .../components/hashicorp-consul/index.scss | 2 +- .../components/horizontal-kv-list/README.mdx | 8 +- .../components/horizontal-kv-list/debug.scss | 2 +- .../components/horizontal-kv-list/index.scss | 2 +- .../components/horizontal-kv-list/layout.scss | 2 +- .../components/horizontal-kv-list/skin.scss | 2 +- .../app/components/icon-definition/debug.scss | 2 +- .../app/components/icon-definition/index.scss | 2 +- .../app/components/informed-action/index.hbs | 2 +- .../app/components/informed-action/index.scss | 2 +- .../components/informed-action/layout.scss | 2 +- .../app/components/informed-action/skin.scss | 2 +- .../app/components/inline-alert/debug.scss | 2 +- .../app/components/inline-alert/index.scss | 2 +- .../app/components/inline-alert/layout.scss | 2 +- .../app/components/inline-alert/skin.scss | 2 +- .../app/components/inline-code/index.scss | 2 +- .../app/components/inline-code/layout.scss | 2 +- .../app/components/inline-code/skin.scss | 2 +- .../app/components/jwt-source/index.js | 2 +- .../app/components/list-collection/index.hbs | 2 +- .../app/components/list-collection/index.js | 2 +- .../app/components/list-collection/index.scss | 2 +- .../components/list-collection/layout.scss | 2 +- .../app/components/list-collection/skin.scss | 2 +- .../app/components/list-row/index.scss | 2 +- .../app/components/list-row/layout.scss | 2 +- .../app/components/list-row/skin.scss | 2 +- .../main-header-horizontal/index.scss | 2 +- .../main-header-horizontal/layout.scss | 2 +- .../main-header-horizontal/skin.scss | 2 +- .../components/main-nav-horizontal/index.scss | 2 +- .../main-nav-horizontal/layout.scss | 2 +- .../components/main-nav-horizontal/skin.scss | 2 +- .../components/main-nav-vertical/debug.scss | 2 +- .../components/main-nav-vertical/index.scss | 2 +- .../components/main-nav-vertical/layout.scss | 2 +- .../components/main-nav-vertical/skin.scss | 2 +- .../app/components/menu-panel/deprecated.scss | 2 +- .../app/components/menu-panel/index.hbs | 2 +- .../app/components/menu-panel/index.js | 2 +- .../app/components/menu-panel/index.scss | 2 +- .../app/components/menu-panel/layout.scss | 2 +- .../app/components/menu-panel/skin.scss | 2 +- .../app/components/menu/action/index.hbs | 2 +- .../consul-ui/app/components/menu/index.hbs | 27 +- .../app/components/menu/item/index.hbs | 2 +- .../app/components/menu/separator/index.hbs | 2 +- .../app/components/modal-dialog/index.hbs | 2 +- .../app/components/modal-dialog/index.js | 2 +- .../app/components/modal-dialog/index.scss | 2 +- .../app/components/modal-dialog/layout.scss | 2 +- .../app/components/modal-dialog/skin.scss | 2 +- .../app/components/modal-layer/index.hbs | 2 +- .../components/more-popover-menu/index.hbs | 2 +- .../app/components/more-popover-menu/index.js | 2 +- .../components/more-popover-menu/index.scss | 2 +- .../more-popover-menu/pageobject.js | 2 +- .../components/oidc-select/chart.xstate.js | 2 +- .../app/components/oidc-select/index.hbs | 2 +- .../app/components/oidc-select/index.js | 2 +- .../app/components/oidc-select/index.scss | 2 +- .../app/components/oidc-select/layout.scss | 2 +- .../app/components/oidc-select/skin.scss | 2 +- .../app/components/option-input/index.hbs | 2 +- .../consul-ui/app/components/outlet/index.hbs | 2 +- .../consul-ui/app/components/outlet/index.js | 2 +- .../app/components/overlay/index.scss | 2 +- .../app/components/overlay/none.scss | 2 +- .../app/components/overlay/square-tail.scss | 2 +- .../app/components/paged-collection/index.hbs | 2 +- .../app/components/paged-collection/index.js | 2 +- .../components/paged-collection/index.scss | 2 +- .../consul-ui/app/components/panel/debug.scss | 2 +- .../app/components/panel/index.css.js | 2 +- .../consul-ui/app/components/panel/index.scss | 2 +- .../app/components/panel/layout.scss | 2 +- .../consul-ui/app/components/panel/skin.scss | 2 +- .../components/peerings/badge/icon/index.hbs | 2 +- .../app/components/peerings/badge/index.hbs | 2 +- .../app/components/peerings/badge/index.js | 2 +- .../app/components/peerings/badge/index.scss | 2 +- .../components/peerings/provider/index.hbs | 2 +- .../app/components/peerings/provider/index.js | 2 +- .../consul-ui/app/components/pill/index.scss | 2 +- .../consul-ui/app/components/pill/layout.scss | 2 +- .../consul-ui/app/components/pill/skin.scss | 2 +- .../app/components/policy-form/index.hbs | 2 +- .../app/components/policy-form/index.js | 2 +- .../app/components/policy-form/pageobject.js | 2 +- .../app/components/policy-selector/index.hbs | 2 +- .../app/components/policy-selector/index.js | 2 +- .../components/policy-selector/pageobject.js | 2 +- .../app/components/popover-menu/index.hbs | 2 +- .../app/components/popover-menu/index.js | 2 +- .../app/components/popover-menu/index.scss | 2 +- .../app/components/popover-menu/layout.scss | 2 +- .../popover-menu/menu-item/index.hbs | 2 +- .../popover-menu/menu-item/index.js | 2 +- .../popover-menu/menu-separator/index.hbs | 2 +- .../popover-menu/menu-separator/index.js | 2 +- .../app/components/popover-menu/skin.scss | 2 +- .../app/components/popover-select/index.hbs | 2 +- .../app/components/popover-select/index.js | 2 +- .../app/components/popover-select/index.scss | 2 +- .../popover-select/optgroup/index.hbs | 2 +- .../popover-select/option/index.hbs | 2 +- .../components/popover-select/option/index.js | 2 +- .../components/popover-select/pageobject.js | 2 +- .../app/components/power-select/pageobject.js | 2 +- .../app/components/progress/index.hbs | 2 +- .../app/components/progress/index.scss | 2 +- .../app/components/progress/layout.scss | 2 +- .../app/components/progress/skin.scss | 2 +- .../components/providers/dimension/index.hbs | 2 +- .../components/providers/dimension/index.js | 2 +- .../app/components/providers/search/index.hbs | 2 +- .../app/components/providers/search/index.js | 2 +- .../app/components/radio-card/index.hbs | 2 +- .../app/components/radio-card/index.js | 2 +- .../app/components/radio-card/index.scss | 2 +- .../app/components/radio-card/layout.scss | 2 +- .../app/components/radio-card/skin.scss | 2 +- .../app/components/radio-group/index.hbs | 2 +- .../app/components/radio-group/index.js | 2 +- .../app/components/radio-group/index.scss | 2 +- .../app/components/radio-group/layout.scss | 2 +- .../app/components/radio-group/pageobject.js | 2 +- .../app/components/radio-group/skin.scss | 2 +- .../consul-ui/app/components/ref/index.js | 2 +- .../app/components/role-form/index.hbs | 2 +- .../app/components/role-form/index.js | 2 +- .../app/components/role-form/pageobject.js | 2 +- .../app/components/role-selector/index.hbs | 2 +- .../app/components/role-selector/index.js | 2 +- .../app/components/role-selector/index.scss | 2 +- .../components/role-selector/pageobject.js | 2 +- .../app/components/route/announcer/index.hbs | 2 +- .../consul-ui/app/components/route/index.hbs | 2 +- .../consul-ui/app/components/route/index.js | 2 +- .../app/components/route/title/index.hbs | 2 +- .../app/components/route/title/index.scss | 2 +- .../app/components/search-bar/index.hbs | 2 +- .../app/components/search-bar/index.js | 2 +- .../app/components/search-bar/index.scss | 2 +- .../search-bar/remove-filter/index.hbs | 2 +- .../app/components/search-bar/utils.js | 2 +- .../app/components/skip-links/index.scss | 2 +- .../app/components/skip-links/layout.scss | 2 +- .../app/components/skip-links/skin.scss | 2 +- .../app/components/sliding-toggle/index.scss | 2 +- .../app/components/sliding-toggle/layout.scss | 2 +- .../app/components/sliding-toggle/skin.scss | 2 +- .../components/state-chart/action/index.hbs | 2 +- .../components/state-chart/action/index.js | 2 +- .../components/state-chart/guard/index.hbs | 2 +- .../app/components/state-chart/guard/index.js | 2 +- .../app/components/state-chart/index.hbs | 2 +- .../app/components/state-chart/index.js | 2 +- .../app/components/state-machine/index.hbs | 2 +- .../app/components/state-machine/index.js | 2 +- .../consul-ui/app/components/state/index.hbs | 2 +- .../consul-ui/app/components/state/index.js | 2 +- .../app/components/tab-nav/index.hbs | 2 +- .../consul-ui/app/components/tab-nav/index.js | 2 +- .../app/components/tab-nav/index.scss | 2 +- .../app/components/tab-nav/layout.scss | 2 +- .../app/components/tab-nav/pageobject.js | 2 +- .../app/components/tab-nav/skin.scss | 2 +- .../consul-ui/app/components/table/index.scss | 2 +- .../app/components/table/layout.scss | 2 +- .../consul-ui/app/components/table/skin.scss | 2 +- .../components/tabular-collection/index.hbs | 2 +- .../components/tabular-collection/index.js | 2 +- .../components/tabular-collection/index.scss | 2 +- .../app/components/tabular-details/index.hbs | 2 +- .../app/components/tabular-details/index.js | 2 +- .../app/components/tabular-details/index.scss | 2 +- .../components/tabular-details/layout.scss | 2 +- .../app/components/tabular-details/skin.scss | 2 +- .../app/components/tabular-dl/index.scss | 2 +- .../app/components/tabular-dl/layout.scss | 2 +- .../app/components/tabular-dl/skin.scss | 2 +- .../app/components/tag-list/index.hbs | 2 +- .../app/components/tag-list/index.scss | 2 +- .../app/components/text-input/index.hbs | 2 +- .../consul-ui/app/components/tile/debug.scss | 2 +- .../consul-ui/app/components/tile/index.scss | 2 +- .../app/components/toggle-button/index.hbs | 2 +- .../app/components/toggle-button/index.js | 2 +- .../app/components/toggle-button/index.scss | 2 +- .../app/components/toggle-button/layout.scss | 2 +- .../app/components/toggle-button/skin.scss | 2 +- .../app/components/token-list/index.hbs | 2 +- .../app/components/token-list/index.js | 2 +- .../app/components/token-list/pageobject.js | 2 +- .../components/token-source/chart.xstate.js | 2 +- .../app/components/token-source/index.hbs | 2 +- .../app/components/token-source/index.js | 2 +- .../app/components/tooltip-panel/index.scss | 2 +- .../app/components/tooltip-panel/layout.scss | 2 +- .../app/components/tooltip-panel/skin.scss | 2 +- .../app/components/tooltip/index.hbs | 2 +- .../app/components/tooltip/index.scss | 2 +- .../topology-metrics/card/index.hbs | 2 +- .../components/topology-metrics/card/index.js | 2 +- .../topology-metrics/card/index.scss | 2 +- .../topology-metrics/down-lines/index.hbs | 2 +- .../topology-metrics/down-lines/index.js | 2 +- .../app/components/topology-metrics/index.hbs | 2 +- .../app/components/topology-metrics/index.js | 2 +- .../components/topology-metrics/index.scss | 2 +- .../components/topology-metrics/layout.scss | 2 +- .../topology-metrics/notifications/index.hbs | 2 +- .../topology-metrics/popover/index.hbs | 2 +- .../topology-metrics/popover/index.js | 2 +- .../topology-metrics/popover/index.scss | 2 +- .../topology-metrics/series/index.hbs | 2 +- .../topology-metrics/series/index.js | 2 +- .../topology-metrics/series/index.scss | 2 +- .../topology-metrics/series/layout.scss | 2 +- .../topology-metrics/series/skin.scss | 2 +- .../app/components/topology-metrics/skin.scss | 2 +- .../topology-metrics/source-type/index.hbs | 2 +- .../topology-metrics/source-type/index.scss | 2 +- .../topology-metrics/stats/index.hbs | 2 +- .../topology-metrics/stats/index.js | 2 +- .../topology-metrics/stats/index.scss | 2 +- .../topology-metrics/status/index.hbs | 2 +- .../topology-metrics/status/index.scss | 2 +- .../topology-metrics/up-lines/index.hbs | 2 +- .../topology-metrics/up-lines/index.js | 2 +- .../app/components/watcher/index.hbs | 2 +- .../consul-ui/app/components/watcher/index.js | 2 +- .../consul-ui/app/components/yield/index.hbs | 2 +- .../app/controllers/_peered-resource.js | 2 +- .../consul-ui/app/controllers/application.js | 2 +- .../controllers/dc/acls/policies/create.js | 2 +- .../app/controllers/dc/acls/policies/edit.js | 2 +- .../app/controllers/dc/acls/roles/create.js | 2 +- .../app/controllers/dc/acls/roles/edit.js | 2 +- .../app/controllers/dc/acls/tokens/create.js | 2 +- .../app/controllers/dc/acls/tokens/edit.js | 2 +- .../app/controllers/dc/nodes/index.js | 2 +- .../app/controllers/dc/services/index.js | 2 +- .../dc/services/instance/healthchecks.js | 2 +- .../consul-ui/app/decorators/data-source.js | 2 +- .../consul-ui/app/decorators/replace.js | 2 +- ui/packages/consul-ui/app/env.js | 2 +- .../app/filter/predicates/auth-method.js | 2 +- .../app/filter/predicates/health-check.js | 2 +- .../app/filter/predicates/intention.js | 2 +- .../consul-ui/app/filter/predicates/kv.js | 2 +- .../consul-ui/app/filter/predicates/node.js | 11 +- .../consul-ui/app/filter/predicates/peer.js | 2 +- .../consul-ui/app/filter/predicates/policy.js | 2 +- .../app/filter/predicates/service-instance.js | 2 +- .../app/filter/predicates/service.js | 2 +- .../consul-ui/app/filter/predicates/token.js | 2 +- ui/packages/consul-ui/app/formats.js | 2 +- ui/packages/consul-ui/app/forms/intention.js | 2 +- ui/packages/consul-ui/app/forms/kv.js | 2 +- ui/packages/consul-ui/app/forms/policy.js | 2 +- ui/packages/consul-ui/app/forms/role.js | 2 +- ui/packages/consul-ui/app/forms/token.js | 2 +- .../consul-ui/app/helpers/adopt-styles.js | 2 +- ui/packages/consul-ui/app/helpers/atob.js | 2 +- .../consul-ui/app/helpers/cached-model.js | 2 +- .../consul-ui/app/helpers/class-map.js | 2 +- .../consul-ui/app/helpers/collection.js | 2 +- ui/packages/consul-ui/app/helpers/css-map.js | 2 +- ui/packages/consul-ui/app/helpers/css.js | 2 +- .../consul-ui/app/helpers/document-attrs.js | 2 +- .../consul-ui/app/helpers/dom-position.js | 2 +- .../consul-ui/app/helpers/duration-from.js | 2 +- ui/packages/consul-ui/app/helpers/env.js | 2 +- .../consul-ui/app/helpers/flatten-property.js | 2 +- .../app/helpers/format-short-time.js | 2 +- ui/packages/consul-ui/app/helpers/href-to.js | 2 +- .../consul-ui/app/helpers/icon-mapping.js | 2 +- .../consul-ui/app/helpers/icons-debug.js | 2 +- ui/packages/consul-ui/app/helpers/is-href.js | 2 +- ui/packages/consul-ui/app/helpers/is.js | 2 +- .../consul-ui/app/helpers/json-stringify.js | 2 +- ui/packages/consul-ui/app/helpers/last.js | 2 +- .../consul-ui/app/helpers/left-trim.js | 2 +- .../consul-ui/app/helpers/merge-checks.js | 2 +- .../consul-ui/app/helpers/percentage-of.js | 2 +- .../app/helpers/policy/datacenters.js | 2 +- .../consul-ui/app/helpers/policy/group.js | 2 +- .../consul-ui/app/helpers/policy/typeof.js | 2 +- .../consul-ui/app/helpers/refresh-route.js | 2 +- .../consul-ui/app/helpers/render-template.js | 2 +- ui/packages/consul-ui/app/helpers/require.js | 2 +- .../consul-ui/app/helpers/right-trim.js | 2 +- .../consul-ui/app/helpers/route-match.js | 2 +- .../app/helpers/service/card-permissions.js | 2 +- .../app/helpers/service/external-source.js | 2 +- .../app/helpers/service/health-percentage.js | 2 +- ui/packages/consul-ui/app/helpers/slugify.js | 2 +- .../app/helpers/smart-date-format.js | 2 +- ui/packages/consul-ui/app/helpers/split.js | 2 +- .../consul-ui/app/helpers/state-chart.js | 2 +- .../consul-ui/app/helpers/state-matches.js | 2 +- .../consul-ui/app/helpers/style-map.js | 2 +- ui/packages/consul-ui/app/helpers/substr.js | 2 +- .../consul-ui/app/helpers/svg-curve.js | 2 +- .../consul-ui/app/helpers/temporal-format.js | 2 +- .../consul-ui/app/helpers/temporal-within.js | 2 +- ui/packages/consul-ui/app/helpers/test.js | 2 +- ui/packages/consul-ui/app/helpers/to-hash.js | 2 +- ui/packages/consul-ui/app/helpers/to-route.js | 2 +- .../app/helpers/token/is-anonymous.js | 2 +- .../consul-ui/app/helpers/token/is-legacy.js | 2 +- ui/packages/consul-ui/app/helpers/tween-to.js | 2 +- ui/packages/consul-ui/app/helpers/uniq-by.js | 2 +- .../consul-ui/app/helpers/unique-id.js | 2 +- ui/packages/consul-ui/app/helpers/uri.js | 2 +- ui/packages/consul-ui/app/index.html | 2 +- .../app/instance-initializers/container.js | 2 +- .../app/instance-initializers/href-to.js | 2 +- .../instance-initializers/ivy-codemirror.js | 2 +- .../app/instance-initializers/selection.js | 2 +- .../app/locations/fsm-with-optional-test.js | 2 +- .../app/locations/fsm-with-optional.js | 2 +- ui/packages/consul-ui/app/locations/fsm.js | 2 +- .../consul-ui/app/machines/boolean.xstate.js | 2 +- .../consul-ui/app/machines/validate.xstate.js | 2 +- .../consul-ui/app/mixins/policy/as-many.js | 2 +- .../consul-ui/app/mixins/role/as-many.js | 2 +- .../app/mixins/with-blocking-actions.js | 2 +- .../consul-ui/app/models/auth-method.js | 2 +- .../consul-ui/app/models/binding-rule.js | 2 +- .../consul-ui/app/models/coordinate.js | 2 +- ui/packages/consul-ui/app/models/dc.js | 2 +- .../consul-ui/app/models/discovery-chain.js | 2 +- .../consul-ui/app/models/gateway-config.js | 2 +- .../consul-ui/app/models/health-check.js | 2 +- .../intention-permission-http-header.js | 2 +- .../app/models/intention-permission-http.js | 2 +- .../app/models/intention-permission.js | 2 +- ui/packages/consul-ui/app/models/intention.js | 2 +- ui/packages/consul-ui/app/models/kv.js | 2 +- ui/packages/consul-ui/app/models/license.js | 2 +- ui/packages/consul-ui/app/models/node.js | 2 +- ui/packages/consul-ui/app/models/nspace.js | 2 +- .../consul-ui/app/models/oidc-provider.js | 2 +- ui/packages/consul-ui/app/models/partition.js | 2 +- ui/packages/consul-ui/app/models/peer.js | 2 +- .../consul-ui/app/models/permission.js | 2 +- ui/packages/consul-ui/app/models/policy.js | 2 +- ui/packages/consul-ui/app/models/proxy.js | 2 +- ui/packages/consul-ui/app/models/role.js | 2 +- .../consul-ui/app/models/service-instance.js | 2 +- ui/packages/consul-ui/app/models/service.js | 2 +- ui/packages/consul-ui/app/models/session.js | 2 +- ui/packages/consul-ui/app/models/token.js | 2 +- ui/packages/consul-ui/app/models/topology.js | 2 +- .../consul-ui/app/modifiers/aria-menu.js | 48 +- .../consul-ui/app/modifiers/css-prop.js | 11 +- .../consul-ui/app/modifiers/css-props.js | 2 +- .../consul-ui/app/modifiers/did-upsert.js | 48 +- .../consul-ui/app/modifiers/disabled.js | 2 +- .../consul-ui/app/modifiers/notification.js | 31 +- .../consul-ui/app/modifiers/on-outside.js | 45 +- ui/packages/consul-ui/app/modifiers/style.js | 16 +- .../consul-ui/app/modifiers/tooltip.js | 2 +- .../consul-ui/app/modifiers/validate.js | 59 +- .../consul-ui/app/modifiers/with-copyable.js | 34 +- .../consul-ui/app/modifiers/with-overlay.js | 2 +- ui/packages/consul-ui/app/router.js | 2 +- .../consul-ui/app/routes/application.js | 2 +- ui/packages/consul-ui/app/routes/dc.js | 2 +- .../app/routes/dc/acls/auth-methods/index.js | 2 +- .../routes/dc/acls/auth-methods/show/index.js | 2 +- .../app/routes/dc/acls/policies/create.js | 2 +- .../app/routes/dc/acls/policies/edit.js | 2 +- .../app/routes/dc/acls/policies/index.js | 2 +- .../app/routes/dc/acls/roles/create.js | 2 +- .../app/routes/dc/acls/roles/edit.js | 2 +- .../app/routes/dc/acls/roles/index.js | 2 +- .../app/routes/dc/acls/tokens/create.js | 2 +- .../app/routes/dc/acls/tokens/edit.js | 2 +- .../app/routes/dc/acls/tokens/index.js | 2 +- .../consul-ui/app/routes/dc/kv/folder.js | 2 +- .../consul-ui/app/routes/dc/kv/index.js | 2 +- .../app/routes/dc/services/notfound.js | 2 +- .../app/routes/dc/services/show/topology.js | 2 +- .../app/routing/application-debug.js | 2 +- ui/packages/consul-ui/app/routing/route.js | 2 +- ui/packages/consul-ui/app/routing/single.js | 2 +- .../consul-ui/app/search/predicates/acl.js | 2 +- .../app/search/predicates/auth-method.js | 2 +- .../app/search/predicates/health-check.js | 2 +- .../app/search/predicates/intention.js | 2 +- .../consul-ui/app/search/predicates/kv.js | 2 +- .../consul-ui/app/search/predicates/node.js | 2 +- .../consul-ui/app/search/predicates/nspace.js | 2 +- .../consul-ui/app/search/predicates/peer.js | 2 +- .../consul-ui/app/search/predicates/policy.js | 2 +- .../consul-ui/app/search/predicates/role.js | 2 +- .../app/search/predicates/service-instance.js | 2 +- .../app/search/predicates/service.js | 2 +- .../consul-ui/app/search/predicates/token.js | 2 +- .../search/predicates/upstream-instance.js | 2 +- .../consul-ui/app/serializers/application.js | 2 +- .../consul-ui/app/serializers/auth-method.js | 2 +- .../consul-ui/app/serializers/binding-rule.js | 2 +- .../consul-ui/app/serializers/coordinate.js | 2 +- .../app/serializers/discovery-chain.js | 2 +- ui/packages/consul-ui/app/serializers/http.js | 2 +- .../consul-ui/app/serializers/intention.js | 2 +- ui/packages/consul-ui/app/serializers/kv.js | 2 +- ui/packages/consul-ui/app/serializers/node.js | 2 +- .../consul-ui/app/serializers/nspace.js | 2 +- .../app/serializers/oidc-provider.js | 2 +- .../consul-ui/app/serializers/partition.js | 2 +- .../consul-ui/app/serializers/permission.js | 2 +- .../consul-ui/app/serializers/policy.js | 2 +- .../consul-ui/app/serializers/proxy.js | 2 +- ui/packages/consul-ui/app/serializers/role.js | 2 +- .../app/serializers/service-instance.js | 2 +- .../consul-ui/app/serializers/service.js | 2 +- .../consul-ui/app/serializers/session.js | 2 +- .../consul-ui/app/serializers/token.js | 2 +- .../consul-ui/app/serializers/topology.js | 2 +- .../consul-ui/app/services/abilities.js | 2 +- ui/packages/consul-ui/app/services/atob.js | 2 +- .../oauth2-code-with-url-provider.js | 2 +- ui/packages/consul-ui/app/services/btoa.js | 2 +- ui/packages/consul-ui/app/services/change.js | 2 +- .../app/services/client/connections.js | 2 +- .../consul-ui/app/services/client/http.js | 2 +- .../app/services/client/transports/xhr.js | 2 +- .../app/services/clipboard/local-storage.js | 2 +- .../consul-ui/app/services/clipboard/os.js | 2 +- .../app/services/code-mirror/linter.js | 2 +- .../consul-ui/app/services/container.js | 2 +- .../app/services/data-sink/protocols/http.js | 2 +- .../data-sink/protocols/local-storage.js | 2 +- .../app/services/data-sink/service.js | 2 +- .../services/data-source/protocols/http.js | 2 +- .../data-source/protocols/http/blocking.js | 2 +- .../data-source/protocols/http/promise.js | 2 +- .../data-source/protocols/local-storage.js | 2 +- .../app/services/data-source/service.js | 2 +- .../consul-ui/app/services/data-structs.js | 2 +- ui/packages/consul-ui/app/services/dom.js | 2 +- ui/packages/consul-ui/app/services/encoder.js | 2 +- ui/packages/consul-ui/app/services/env.js | 2 +- .../consul-ui/app/services/feedback.js | 2 +- ui/packages/consul-ui/app/services/filter.js | 2 +- ui/packages/consul-ui/app/services/form.js | 2 +- ui/packages/consul-ui/app/services/hcp.js | 2 +- .../consul-ui/app/services/i18n-debug.js | 2 +- .../consul-ui/app/services/local-storage.js | 2 +- ui/packages/consul-ui/app/services/logger.js | 2 +- .../consul-ui/app/services/repository.js | 2 +- .../app/services/repository/auth-method.js | 2 +- .../app/services/repository/binding-rule.js | 2 +- .../app/services/repository/coordinate.js | 2 +- .../consul-ui/app/services/repository/dc.js | 2 +- .../services/repository/discovery-chain.js | 2 +- .../intention-permission-http-header.js | 2 +- .../repository/intention-permission.js | 2 +- .../app/services/repository/intention.js | 2 +- .../consul-ui/app/services/repository/kv.js | 2 +- .../app/services/repository/license.js | 2 +- .../app/services/repository/metrics.js | 2 +- .../consul-ui/app/services/repository/node.js | 2 +- .../app/services/repository/nspace.js | 2 +- .../app/services/repository/oidc-provider.js | 2 +- .../app/services/repository/partition.js | 2 +- .../consul-ui/app/services/repository/peer.js | 2 +- .../app/services/repository/permission.js | 2 +- .../app/services/repository/policy.js | 2 +- .../app/services/repository/proxy.js | 2 +- .../consul-ui/app/services/repository/role.js | 2 +- .../services/repository/service-instance.js | 2 +- .../app/services/repository/service.js | 2 +- .../app/services/repository/session.js | 2 +- .../app/services/repository/token.js | 2 +- .../app/services/repository/topology.js | 2 +- ui/packages/consul-ui/app/services/routlet.js | 2 +- ui/packages/consul-ui/app/services/schema.js | 2 +- ui/packages/consul-ui/app/services/search.js | 2 +- .../consul-ui/app/services/settings.js | 2 +- ui/packages/consul-ui/app/services/sort.js | 2 +- .../app/services/state-with-charts.js | 2 +- ui/packages/consul-ui/app/services/state.js | 2 +- ui/packages/consul-ui/app/services/store.js | 2 +- .../consul-ui/app/services/temporal.js | 2 +- ui/packages/consul-ui/app/services/ticker.js | 2 +- ui/packages/consul-ui/app/services/timeout.js | 2 +- .../consul-ui/app/services/ui-config.js | 2 +- .../app/sort/comparators/auth-method.js | 2 +- .../app/sort/comparators/health-check.js | 2 +- .../app/sort/comparators/intention.js | 2 +- .../consul-ui/app/sort/comparators/kv.js | 2 +- .../consul-ui/app/sort/comparators/node.js | 2 +- .../consul-ui/app/sort/comparators/nspace.js | 2 +- .../app/sort/comparators/partition.js | 2 +- .../consul-ui/app/sort/comparators/peer.js | 2 +- .../consul-ui/app/sort/comparators/policy.js | 2 +- .../consul-ui/app/sort/comparators/role.js | 2 +- .../app/sort/comparators/service-instance.js | 2 +- .../consul-ui/app/sort/comparators/service.js | 2 +- .../consul-ui/app/sort/comparators/token.js | 2 +- .../app/sort/comparators/upstream-instance.js | 2 +- ui/packages/consul-ui/app/storages/base.js | 2 +- ui/packages/consul-ui/app/storages/notices.js | 2 +- ui/packages/consul-ui/app/styles/app.scss | 2 +- .../app/styles/base/animation/index.scss | 2 +- .../app/styles/base/color/index.scss | 2 +- .../styles/base/color/semantic-variables.scss | 2 +- .../base/color/ui/frame-placeholders.scss | 2 +- .../app/styles/base/color/ui/index.scss | 2 +- .../app/styles/base/component/index.scss | 2 +- .../base/decoration/base-placeholders.scss | 2 +- .../base/decoration/base-variables.scss | 2 +- .../app/styles/base/decoration/index.scss | 2 +- .../base/decoration/visually-hidden.css.js | 2 +- .../styles/base/icons/base-keyframes.css.js | 2 +- .../app/styles/base/icons/base-keyframes.scss | 2 +- .../styles/base/icons/base-placeholders.scss | 2 +- .../app/styles/base/icons/debug.scss | 2 +- .../base/icons/icons/activity/index.scss | 2 +- .../base/icons/icons/activity/keyframes.scss | 2 +- .../icons/icons/activity/placeholders.scss | 2 +- .../icons/icons/activity/property-16.scss | 2 +- .../icons/icons/activity/property-24.scss | 2 +- .../icons/icons/alert-circle-fill/index.scss | 2 +- .../icons/alert-circle-fill/keyframes.scss | 2 +- .../icons/alert-circle-fill/placeholders.scss | 2 +- .../icons/alert-circle-fill/property-16.scss | 2 +- .../icons/alert-circle-fill/property-24.scss | 2 +- .../icons/alert-circle-outline/index.scss | 2 +- .../icons/alert-circle-outline/keyframes.scss | 2 +- .../alert-circle-outline/placeholders.scss | 2 +- .../base/icons/icons/alert-circle/index.scss | 2 +- .../icons/icons/alert-circle/keyframes.scss | 2 +- .../icons/alert-circle/placeholders.scss | 2 +- .../icons/icons/alert-circle/property-16.scss | 2 +- .../icons/icons/alert-circle/property-24.scss | 2 +- .../icons/icons/alert-octagon-fill/index.scss | 2 +- .../icons/alert-octagon-fill/keyframes.scss | 2 +- .../alert-octagon-fill/placeholders.scss | 2 +- .../icons/alert-octagon-fill/property-16.scss | 2 +- .../icons/alert-octagon-fill/property-24.scss | 2 +- .../base/icons/icons/alert-octagon/index.scss | 2 +- .../icons/icons/alert-octagon/keyframes.scss | 2 +- .../icons/alert-octagon/placeholders.scss | 2 +- .../icons/alert-octagon/property-16.scss | 2 +- .../icons/alert-octagon/property-24.scss | 2 +- .../icons/alert-triangle-fill/index.scss | 2 +- .../icons/alert-triangle-fill/keyframes.scss | 2 +- .../alert-triangle-fill/placeholders.scss | 2 +- .../alert-triangle-fill/property-16.scss | 2 +- .../alert-triangle-fill/property-24.scss | 2 +- .../icons/icons/alert-triangle/index.scss | 2 +- .../icons/icons/alert-triangle/keyframes.scss | 2 +- .../icons/alert-triangle/placeholders.scss | 2 +- .../icons/alert-triangle/property-16.scss | 2 +- .../icons/alert-triangle/property-24.scss | 2 +- .../base/icons/icons/alibaba-color/index.scss | 2 +- .../icons/icons/alibaba-color/keyframes.scss | 2 +- .../icons/alibaba-color/placeholders.scss | 2 +- .../icons/alibaba-color/property-16.scss | 2 +- .../icons/alibaba-color/property-24.scss | 2 +- .../base/icons/icons/alibaba/index.scss | 2 +- .../base/icons/icons/alibaba/keyframes.scss | 2 +- .../icons/icons/alibaba/placeholders.scss | 2 +- .../base/icons/icons/alibaba/property-16.scss | 2 +- .../base/icons/icons/alibaba/property-24.scss | 2 +- .../base/icons/icons/align-center/index.scss | 2 +- .../icons/icons/align-center/keyframes.scss | 2 +- .../icons/align-center/placeholders.scss | 2 +- .../icons/icons/align-center/property-16.scss | 2 +- .../icons/icons/align-center/property-24.scss | 2 +- .../base/icons/icons/align-justify/index.scss | 2 +- .../icons/icons/align-justify/keyframes.scss | 2 +- .../icons/align-justify/placeholders.scss | 2 +- .../icons/align-justify/property-16.scss | 2 +- .../icons/align-justify/property-24.scss | 2 +- .../base/icons/icons/align-left/index.scss | 2 +- .../icons/icons/align-left/keyframes.scss | 2 +- .../icons/icons/align-left/placeholders.scss | 2 +- .../icons/icons/align-left/property-16.scss | 2 +- .../icons/icons/align-left/property-24.scss | 2 +- .../base/icons/icons/align-right/index.scss | 2 +- .../icons/icons/align-right/keyframes.scss | 2 +- .../icons/icons/align-right/placeholders.scss | 2 +- .../icons/icons/align-right/property-16.scss | 2 +- .../icons/icons/align-right/property-24.scss | 2 +- .../icons/icons/amazon-eks-color/index.scss | 2 +- .../icons/amazon-eks-color/keyframes.scss | 2 +- .../icons/amazon-eks-color/placeholders.scss | 2 +- .../icons/amazon-eks-color/property-16.scss | 2 +- .../icons/amazon-eks-color/property-24.scss | 2 +- .../base/icons/icons/amazon-eks/index.scss | 2 +- .../icons/icons/amazon-eks/keyframes.scss | 2 +- .../icons/icons/amazon-eks/placeholders.scss | 2 +- .../icons/icons/amazon-eks/property-16.scss | 2 +- .../icons/icons/amazon-eks/property-24.scss | 2 +- .../base/icons/icons/apple-color/index.scss | 2 +- .../icons/icons/apple-color/keyframes.scss | 2 +- .../icons/icons/apple-color/placeholders.scss | 2 +- .../icons/icons/apple-color/property-16.scss | 2 +- .../icons/icons/apple-color/property-24.scss | 2 +- .../styles/base/icons/icons/apple/index.scss | 2 +- .../base/icons/icons/apple/keyframes.scss | 2 +- .../base/icons/icons/apple/placeholders.scss | 2 +- .../base/icons/icons/apple/property-16.scss | 2 +- .../base/icons/icons/apple/property-24.scss | 2 +- .../base/icons/icons/archive/index.scss | 2 +- .../base/icons/icons/archive/keyframes.scss | 2 +- .../icons/icons/archive/placeholders.scss | 2 +- .../base/icons/icons/archive/property-16.scss | 2 +- .../base/icons/icons/archive/property-24.scss | 2 +- .../icons/icons/arrow-down-circle/index.scss | 2 +- .../icons/arrow-down-circle/keyframes.scss | 2 +- .../icons/arrow-down-circle/placeholders.scss | 2 +- .../icons/arrow-down-circle/property-16.scss | 2 +- .../icons/arrow-down-circle/property-24.scss | 2 +- .../icons/icons/arrow-down-left/index.scss | 2 +- .../icons/arrow-down-left/keyframes.scss | 2 +- .../icons/arrow-down-left/placeholders.scss | 2 +- .../icons/arrow-down-left/property-16.scss | 2 +- .../icons/arrow-down-left/property-24.scss | 2 +- .../icons/icons/arrow-down-right/index.scss | 2 +- .../icons/arrow-down-right/keyframes.scss | 2 +- .../icons/arrow-down-right/placeholders.scss | 2 +- .../icons/arrow-down-right/property-16.scss | 2 +- .../icons/arrow-down-right/property-24.scss | 2 +- .../base/icons/icons/arrow-down/index.scss | 2 +- .../icons/icons/arrow-down/keyframes.scss | 2 +- .../icons/icons/arrow-down/placeholders.scss | 2 +- .../icons/icons/arrow-down/property-16.scss | 2 +- .../icons/icons/arrow-down/property-24.scss | 2 +- .../icons/icons/arrow-left-circle/index.scss | 2 +- .../icons/arrow-left-circle/keyframes.scss | 2 +- .../icons/arrow-left-circle/placeholders.scss | 2 +- .../icons/arrow-left-circle/property-16.scss | 2 +- .../icons/arrow-left-circle/property-24.scss | 2 +- .../base/icons/icons/arrow-left/index.scss | 2 +- .../icons/icons/arrow-left/keyframes.scss | 2 +- .../icons/icons/arrow-left/placeholders.scss | 2 +- .../icons/icons/arrow-left/property-16.scss | 2 +- .../icons/icons/arrow-left/property-24.scss | 2 +- .../icons/icons/arrow-right-circle/index.scss | 2 +- .../icons/arrow-right-circle/keyframes.scss | 2 +- .../arrow-right-circle/placeholders.scss | 2 +- .../icons/arrow-right-circle/property-16.scss | 2 +- .../icons/arrow-right-circle/property-24.scss | 2 +- .../base/icons/icons/arrow-right/index.scss | 2 +- .../icons/icons/arrow-right/keyframes.scss | 2 +- .../icons/icons/arrow-right/placeholders.scss | 2 +- .../icons/icons/arrow-right/property-16.scss | 2 +- .../icons/icons/arrow-right/property-24.scss | 2 +- .../icons/icons/arrow-up-circle/index.scss | 2 +- .../icons/arrow-up-circle/keyframes.scss | 2 +- .../icons/arrow-up-circle/placeholders.scss | 2 +- .../icons/arrow-up-circle/property-16.scss | 2 +- .../icons/arrow-up-circle/property-24.scss | 2 +- .../base/icons/icons/arrow-up-left/index.scss | 2 +- .../icons/icons/arrow-up-left/keyframes.scss | 2 +- .../icons/arrow-up-left/placeholders.scss | 2 +- .../icons/arrow-up-left/property-16.scss | 2 +- .../icons/arrow-up-left/property-24.scss | 2 +- .../icons/icons/arrow-up-right/index.scss | 2 +- .../icons/icons/arrow-up-right/keyframes.scss | 2 +- .../icons/arrow-up-right/placeholders.scss | 2 +- .../icons/arrow-up-right/property-16.scss | 2 +- .../icons/arrow-up-right/property-24.scss | 2 +- .../base/icons/icons/arrow-up/index.scss | 2 +- .../base/icons/icons/arrow-up/keyframes.scss | 2 +- .../icons/icons/arrow-up/placeholders.scss | 2 +- .../icons/icons/arrow-up/property-16.scss | 2 +- .../icons/icons/arrow-up/property-24.scss | 2 +- .../base/icons/icons/at-sign/index.scss | 2 +- .../base/icons/icons/at-sign/keyframes.scss | 2 +- .../icons/icons/at-sign/placeholders.scss | 2 +- .../base/icons/icons/at-sign/property-16.scss | 2 +- .../base/icons/icons/at-sign/property-24.scss | 2 +- .../base/icons/icons/auth0-color/index.scss | 2 +- .../icons/icons/auth0-color/keyframes.scss | 2 +- .../icons/icons/auth0-color/placeholders.scss | 2 +- .../icons/icons/auth0-color/property-16.scss | 2 +- .../icons/icons/auth0-color/property-24.scss | 2 +- .../styles/base/icons/icons/auth0/index.scss | 2 +- .../base/icons/icons/auth0/keyframes.scss | 2 +- .../base/icons/icons/auth0/placeholders.scss | 2 +- .../base/icons/icons/auth0/property-16.scss | 2 +- .../base/icons/icons/auth0/property-24.scss | 2 +- .../base/icons/icons/auto-apply/index.scss | 2 +- .../icons/icons/auto-apply/keyframes.scss | 2 +- .../icons/icons/auto-apply/placeholders.scss | 2 +- .../icons/icons/auto-apply/property-16.scss | 2 +- .../icons/icons/auto-apply/property-24.scss | 2 +- .../styles/base/icons/icons/award/index.scss | 2 +- .../base/icons/icons/award/keyframes.scss | 2 +- .../base/icons/icons/award/placeholders.scss | 2 +- .../base/icons/icons/award/property-16.scss | 2 +- .../base/icons/icons/award/property-24.scss | 2 +- .../base/icons/icons/azure-color/index.scss | 2 +- .../icons/icons/azure-color/keyframes.scss | 2 +- .../icons/icons/azure-color/placeholders.scss | 2 +- .../icons/icons/azure-color/property-16.scss | 2 +- .../icons/icons/azure-color/property-24.scss | 2 +- .../icons/icons/azure-devops-color/index.scss | 2 +- .../icons/azure-devops-color/keyframes.scss | 2 +- .../azure-devops-color/placeholders.scss | 2 +- .../icons/azure-devops-color/property-16.scss | 2 +- .../icons/azure-devops-color/property-24.scss | 2 +- .../base/icons/icons/azure-devops/index.scss | 2 +- .../icons/icons/azure-devops/keyframes.scss | 2 +- .../icons/azure-devops/placeholders.scss | 2 +- .../icons/icons/azure-devops/property-16.scss | 2 +- .../icons/icons/azure-devops/property-24.scss | 2 +- .../styles/base/icons/icons/azure/index.scss | 2 +- .../base/icons/icons/azure/keyframes.scss | 2 +- .../base/icons/icons/azure/placeholders.scss | 2 +- .../base/icons/icons/azure/property-16.scss | 2 +- .../base/icons/icons/azure/property-24.scss | 2 +- .../base/icons/icons/bank-vault/index.scss | 2 +- .../icons/icons/bank-vault/keyframes.scss | 2 +- .../icons/icons/bank-vault/placeholders.scss | 2 +- .../icons/icons/bank-vault/property-16.scss | 2 +- .../icons/icons/bank-vault/property-24.scss | 2 +- .../base/icons/icons/bar-chart-alt/index.scss | 2 +- .../icons/icons/bar-chart-alt/keyframes.scss | 2 +- .../icons/bar-chart-alt/placeholders.scss | 2 +- .../icons/bar-chart-alt/property-16.scss | 2 +- .../icons/bar-chart-alt/property-24.scss | 2 +- .../base/icons/icons/bar-chart/index.scss | 2 +- .../base/icons/icons/bar-chart/keyframes.scss | 2 +- .../icons/icons/bar-chart/placeholders.scss | 2 +- .../icons/icons/bar-chart/property-16.scss | 2 +- .../icons/icons/bar-chart/property-24.scss | 2 +- .../icons/icons/battery-charging/index.scss | 2 +- .../icons/battery-charging/keyframes.scss | 2 +- .../icons/battery-charging/placeholders.scss | 2 +- .../icons/battery-charging/property-16.scss | 2 +- .../icons/battery-charging/property-24.scss | 2 +- .../base/icons/icons/battery/index.scss | 2 +- .../base/icons/icons/battery/keyframes.scss | 2 +- .../icons/icons/battery/placeholders.scss | 2 +- .../base/icons/icons/battery/property-16.scss | 2 +- .../base/icons/icons/battery/property-24.scss | 2 +- .../styles/base/icons/icons/beaker/index.scss | 2 +- .../base/icons/icons/beaker/keyframes.scss | 2 +- .../base/icons/icons/beaker/placeholders.scss | 2 +- .../base/icons/icons/beaker/property-16.scss | 2 +- .../base/icons/icons/beaker/property-24.scss | 2 +- .../icons/icons/bell-active-fill/index.scss | 2 +- .../icons/bell-active-fill/keyframes.scss | 2 +- .../icons/bell-active-fill/placeholders.scss | 2 +- .../icons/bell-active-fill/property-16.scss | 2 +- .../icons/bell-active-fill/property-24.scss | 2 +- .../base/icons/icons/bell-active/index.scss | 2 +- .../icons/icons/bell-active/keyframes.scss | 2 +- .../icons/icons/bell-active/placeholders.scss | 2 +- .../icons/icons/bell-active/property-16.scss | 2 +- .../icons/icons/bell-active/property-24.scss | 2 +- .../base/icons/icons/bell-off/index.scss | 2 +- .../base/icons/icons/bell-off/keyframes.scss | 2 +- .../icons/icons/bell-off/placeholders.scss | 2 +- .../icons/icons/bell-off/property-16.scss | 2 +- .../icons/icons/bell-off/property-24.scss | 2 +- .../styles/base/icons/icons/bell/index.scss | 2 +- .../base/icons/icons/bell/keyframes.scss | 2 +- .../base/icons/icons/bell/placeholders.scss | 2 +- .../base/icons/icons/bell/property-16.scss | 2 +- .../base/icons/icons/bell/property-24.scss | 2 +- .../icons/icons/bitbucket-color/index.scss | 2 +- .../icons/bitbucket-color/keyframes.scss | 2 +- .../icons/bitbucket-color/placeholders.scss | 2 +- .../icons/bitbucket-color/property-16.scss | 2 +- .../icons/bitbucket-color/property-24.scss | 2 +- .../base/icons/icons/bitbucket/index.scss | 2 +- .../base/icons/icons/bitbucket/keyframes.scss | 2 +- .../icons/icons/bitbucket/placeholders.scss | 2 +- .../icons/icons/bitbucket/property-16.scss | 2 +- .../icons/icons/bitbucket/property-24.scss | 2 +- .../styles/base/icons/icons/bolt/index.scss | 2 +- .../base/icons/icons/bolt/keyframes.scss | 2 +- .../base/icons/icons/bolt/placeholders.scss | 2 +- .../icons/icons/bookmark-add-fill/index.scss | 2 +- .../icons/bookmark-add-fill/keyframes.scss | 2 +- .../icons/bookmark-add-fill/placeholders.scss | 2 +- .../icons/bookmark-add-fill/property-16.scss | 2 +- .../icons/bookmark-add-fill/property-24.scss | 2 +- .../base/icons/icons/bookmark-add/index.scss | 2 +- .../icons/icons/bookmark-add/keyframes.scss | 2 +- .../icons/bookmark-add/placeholders.scss | 2 +- .../icons/icons/bookmark-add/property-16.scss | 2 +- .../icons/icons/bookmark-add/property-24.scss | 2 +- .../base/icons/icons/bookmark-fill/index.scss | 2 +- .../icons/icons/bookmark-fill/keyframes.scss | 2 +- .../icons/bookmark-fill/placeholders.scss | 2 +- .../icons/bookmark-fill/property-16.scss | 2 +- .../icons/bookmark-fill/property-24.scss | 2 +- .../icons/bookmark-remove-fill/index.scss | 2 +- .../icons/bookmark-remove-fill/keyframes.scss | 2 +- .../bookmark-remove-fill/placeholders.scss | 2 +- .../bookmark-remove-fill/property-16.scss | 2 +- .../bookmark-remove-fill/property-24.scss | 2 +- .../icons/icons/bookmark-remove/index.scss | 2 +- .../icons/bookmark-remove/keyframes.scss | 2 +- .../icons/bookmark-remove/placeholders.scss | 2 +- .../icons/bookmark-remove/property-16.scss | 2 +- .../icons/bookmark-remove/property-24.scss | 2 +- .../base/icons/icons/bookmark/index.scss | 2 +- .../base/icons/icons/bookmark/keyframes.scss | 2 +- .../icons/icons/bookmark/placeholders.scss | 2 +- .../icons/icons/bookmark/property-16.scss | 2 +- .../icons/icons/bookmark/property-24.scss | 2 +- .../styles/base/icons/icons/bottom/index.scss | 2 +- .../base/icons/icons/bottom/keyframes.scss | 2 +- .../base/icons/icons/bottom/placeholders.scss | 2 +- .../base/icons/icons/bottom/property-16.scss | 2 +- .../base/icons/icons/bottom/property-24.scss | 2 +- .../icons/icons/boundary-color/index.scss | 2 +- .../icons/icons/boundary-color/keyframes.scss | 2 +- .../icons/boundary-color/placeholders.scss | 2 +- .../icons/boundary-color/property-16.scss | 2 +- .../icons/boundary-color/property-24.scss | 2 +- .../base/icons/icons/boundary/index.scss | 2 +- .../base/icons/icons/boundary/keyframes.scss | 2 +- .../icons/icons/boundary/placeholders.scss | 2 +- .../icons/icons/boundary/property-16.scss | 2 +- .../icons/icons/boundary/property-24.scss | 2 +- .../icons/icons/box-check-fill/index.scss | 2 +- .../icons/icons/box-check-fill/keyframes.scss | 2 +- .../icons/box-check-fill/placeholders.scss | 2 +- .../base/icons/icons/box-outline/index.scss | 2 +- .../icons/icons/box-outline/keyframes.scss | 2 +- .../icons/icons/box-outline/placeholders.scss | 2 +- .../styles/base/icons/icons/box/index.scss | 2 +- .../base/icons/icons/box/keyframes.scss | 2 +- .../base/icons/icons/box/placeholders.scss | 2 +- .../base/icons/icons/box/property-16.scss | 2 +- .../base/icons/icons/box/property-24.scss | 2 +- .../base/icons/icons/briefcase/index.scss | 2 +- .../base/icons/icons/briefcase/keyframes.scss | 2 +- .../icons/icons/briefcase/placeholders.scss | 2 +- .../icons/icons/briefcase/property-16.scss | 2 +- .../icons/icons/briefcase/property-24.scss | 2 +- .../base/icons/icons/broadcast/index.scss | 2 +- .../base/icons/icons/broadcast/keyframes.scss | 2 +- .../icons/icons/broadcast/placeholders.scss | 2 +- .../styles/base/icons/icons/bug/index.scss | 2 +- .../base/icons/icons/bug/keyframes.scss | 2 +- .../base/icons/icons/bug/placeholders.scss | 2 +- .../base/icons/icons/bug/property-16.scss | 2 +- .../base/icons/icons/bug/property-24.scss | 2 +- .../styles/base/icons/icons/build/index.scss | 2 +- .../base/icons/icons/build/keyframes.scss | 2 +- .../base/icons/icons/build/placeholders.scss | 2 +- .../base/icons/icons/build/property-16.scss | 2 +- .../base/icons/icons/build/property-24.scss | 2 +- .../styles/base/icons/icons/bulb/index.scss | 2 +- .../base/icons/icons/bulb/keyframes.scss | 2 +- .../base/icons/icons/bulb/placeholders.scss | 2 +- .../base/icons/icons/bulb/property-16.scss | 2 +- .../base/icons/icons/bulb/property-24.scss | 2 +- .../base/icons/icons/calendar/index.scss | 2 +- .../base/icons/icons/calendar/keyframes.scss | 2 +- .../icons/icons/calendar/placeholders.scss | 2 +- .../icons/icons/calendar/property-16.scss | 2 +- .../icons/icons/calendar/property-24.scss | 2 +- .../base/icons/icons/camera-off/index.scss | 2 +- .../icons/icons/camera-off/keyframes.scss | 2 +- .../icons/icons/camera-off/placeholders.scss | 2 +- .../icons/icons/camera-off/property-16.scss | 2 +- .../icons/icons/camera-off/property-24.scss | 2 +- .../styles/base/icons/icons/camera/index.scss | 2 +- .../base/icons/icons/camera/keyframes.scss | 2 +- .../base/icons/icons/camera/placeholders.scss | 2 +- .../base/icons/icons/camera/property-16.scss | 2 +- .../base/icons/icons/camera/property-24.scss | 2 +- .../icons/icons/cancel-circle-fill/index.scss | 2 +- .../icons/cancel-circle-fill/keyframes.scss | 2 +- .../cancel-circle-fill/placeholders.scss | 2 +- .../icons/cancel-circle-outline/index.scss | 2 +- .../cancel-circle-outline/keyframes.scss | 2 +- .../cancel-circle-outline/placeholders.scss | 2 +- .../base/icons/icons/cancel-plain/index.scss | 2 +- .../icons/icons/cancel-plain/keyframes.scss | 2 +- .../icons/cancel-plain/placeholders.scss | 2 +- .../icons/icons/cancel-square-fill/index.scss | 2 +- .../icons/cancel-square-fill/keyframes.scss | 2 +- .../cancel-square-fill/placeholders.scss | 2 +- .../icons/cancel-square-outline/index.scss | 2 +- .../cancel-square-outline/keyframes.scss | 2 +- .../cancel-square-outline/placeholders.scss | 2 +- .../base/icons/icons/caret-down/index.scss | 2 +- .../icons/icons/caret-down/keyframes.scss | 2 +- .../icons/icons/caret-down/placeholders.scss | 2 +- .../base/icons/icons/caret-up/index.scss | 2 +- .../base/icons/icons/caret-up/keyframes.scss | 2 +- .../icons/icons/caret-up/placeholders.scss | 2 +- .../styles/base/icons/icons/caret/index.scss | 2 +- .../base/icons/icons/caret/keyframes.scss | 2 +- .../base/icons/icons/caret/placeholders.scss | 2 +- .../base/icons/icons/caret/property-16.scss | 2 +- .../base/icons/icons/caret/property-24.scss | 2 +- .../styles/base/icons/icons/cast/index.scss | 2 +- .../base/icons/icons/cast/keyframes.scss | 2 +- .../base/icons/icons/cast/placeholders.scss | 2 +- .../base/icons/icons/cast/property-16.scss | 2 +- .../base/icons/icons/cast/property-24.scss | 2 +- .../base/icons/icons/certificate/index.scss | 2 +- .../icons/icons/certificate/keyframes.scss | 2 +- .../icons/icons/certificate/placeholders.scss | 2 +- .../icons/icons/certificate/property-16.scss | 2 +- .../icons/icons/certificate/property-24.scss | 2 +- .../base/icons/icons/change-circle/index.scss | 2 +- .../icons/icons/change-circle/keyframes.scss | 2 +- .../icons/change-circle/placeholders.scss | 2 +- .../icons/change-circle/property-16.scss | 2 +- .../icons/change-circle/property-24.scss | 2 +- .../base/icons/icons/change-square/index.scss | 2 +- .../icons/icons/change-square/keyframes.scss | 2 +- .../icons/change-square/placeholders.scss | 2 +- .../icons/change-square/property-16.scss | 2 +- .../icons/change-square/property-24.scss | 2 +- .../styles/base/icons/icons/change/index.scss | 2 +- .../base/icons/icons/change/keyframes.scss | 2 +- .../base/icons/icons/change/placeholders.scss | 2 +- .../base/icons/icons/change/property-16.scss | 2 +- .../base/icons/icons/change/property-24.scss | 2 +- .../icons/icons/check-circle-fill/index.scss | 2 +- .../icons/check-circle-fill/keyframes.scss | 2 +- .../icons/check-circle-fill/placeholders.scss | 2 +- .../icons/check-circle-fill/property-16.scss | 2 +- .../icons/check-circle-fill/property-24.scss | 2 +- .../icons/check-circle-outline/index.scss | 2 +- .../icons/check-circle-outline/keyframes.scss | 2 +- .../check-circle-outline/placeholders.scss | 2 +- .../base/icons/icons/check-circle/index.scss | 2 +- .../icons/icons/check-circle/keyframes.scss | 2 +- .../icons/check-circle/placeholders.scss | 2 +- .../icons/icons/check-circle/property-16.scss | 2 +- .../icons/icons/check-circle/property-24.scss | 2 +- .../icons/icons/check-diamond-fill/index.scss | 2 +- .../icons/check-diamond-fill/keyframes.scss | 2 +- .../check-diamond-fill/placeholders.scss | 2 +- .../icons/check-diamond-fill/property-16.scss | 2 +- .../icons/check-diamond-fill/property-24.scss | 2 +- .../base/icons/icons/check-diamond/index.scss | 2 +- .../icons/icons/check-diamond/keyframes.scss | 2 +- .../icons/check-diamond/placeholders.scss | 2 +- .../icons/check-diamond/property-16.scss | 2 +- .../icons/check-diamond/property-24.scss | 2 +- .../icons/icons/check-hexagon-fill/index.scss | 2 +- .../icons/check-hexagon-fill/keyframes.scss | 2 +- .../check-hexagon-fill/placeholders.scss | 2 +- .../icons/check-hexagon-fill/property-16.scss | 2 +- .../icons/check-hexagon-fill/property-24.scss | 2 +- .../base/icons/icons/check-hexagon/index.scss | 2 +- .../icons/icons/check-hexagon/keyframes.scss | 2 +- .../icons/check-hexagon/placeholders.scss | 2 +- .../icons/check-hexagon/property-16.scss | 2 +- .../icons/check-hexagon/property-24.scss | 2 +- .../base/icons/icons/check-plain/index.scss | 2 +- .../icons/icons/check-plain/keyframes.scss | 2 +- .../icons/icons/check-plain/placeholders.scss | 2 +- .../icons/icons/check-square-fill/index.scss | 2 +- .../icons/check-square-fill/keyframes.scss | 2 +- .../icons/check-square-fill/placeholders.scss | 2 +- .../icons/check-square-fill/property-16.scss | 2 +- .../icons/check-square-fill/property-24.scss | 2 +- .../base/icons/icons/check-square/index.scss | 2 +- .../icons/icons/check-square/keyframes.scss | 2 +- .../icons/check-square/placeholders.scss | 2 +- .../icons/icons/check-square/property-16.scss | 2 +- .../icons/icons/check-square/property-24.scss | 2 +- .../styles/base/icons/icons/check/index.scss | 2 +- .../base/icons/icons/check/keyframes.scss | 2 +- .../base/icons/icons/check/placeholders.scss | 2 +- .../base/icons/icons/check/property-16.scss | 2 +- .../base/icons/icons/check/property-24.scss | 2 +- .../base/icons/icons/chevron-down/index.scss | 2 +- .../icons/icons/chevron-down/keyframes.scss | 2 +- .../icons/chevron-down/placeholders.scss | 2 +- .../icons/icons/chevron-down/property-16.scss | 2 +- .../icons/icons/chevron-down/property-24.scss | 2 +- .../base/icons/icons/chevron-left/index.scss | 2 +- .../icons/icons/chevron-left/keyframes.scss | 2 +- .../icons/chevron-left/placeholders.scss | 2 +- .../icons/icons/chevron-left/property-16.scss | 2 +- .../icons/icons/chevron-left/property-24.scss | 2 +- .../base/icons/icons/chevron-right/index.scss | 2 +- .../icons/icons/chevron-right/keyframes.scss | 2 +- .../icons/chevron-right/placeholders.scss | 2 +- .../icons/chevron-right/property-16.scss | 2 +- .../icons/chevron-right/property-24.scss | 2 +- .../base/icons/icons/chevron-up/index.scss | 2 +- .../icons/icons/chevron-up/keyframes.scss | 2 +- .../icons/icons/chevron-up/placeholders.scss | 2 +- .../icons/icons/chevron-up/property-16.scss | 2 +- .../icons/icons/chevron-up/property-24.scss | 2 +- .../base/icons/icons/chevrons-down/index.scss | 2 +- .../icons/icons/chevrons-down/keyframes.scss | 2 +- .../icons/chevrons-down/placeholders.scss | 2 +- .../icons/chevrons-down/property-16.scss | 2 +- .../icons/chevrons-down/property-24.scss | 2 +- .../base/icons/icons/chevrons-left/index.scss | 2 +- .../icons/icons/chevrons-left/keyframes.scss | 2 +- .../icons/chevrons-left/placeholders.scss | 2 +- .../icons/chevrons-left/property-16.scss | 2 +- .../icons/chevrons-left/property-24.scss | 2 +- .../icons/icons/chevrons-right/index.scss | 2 +- .../icons/icons/chevrons-right/keyframes.scss | 2 +- .../icons/chevrons-right/placeholders.scss | 2 +- .../icons/chevrons-right/property-16.scss | 2 +- .../icons/chevrons-right/property-24.scss | 2 +- .../base/icons/icons/chevrons-up/index.scss | 2 +- .../icons/icons/chevrons-up/keyframes.scss | 2 +- .../icons/icons/chevrons-up/placeholders.scss | 2 +- .../icons/icons/chevrons-up/property-16.scss | 2 +- .../icons/icons/chevrons-up/property-24.scss | 2 +- .../base/icons/icons/circle-dot/index.scss | 2 +- .../icons/icons/circle-dot/keyframes.scss | 2 +- .../icons/icons/circle-dot/placeholders.scss | 2 +- .../icons/icons/circle-dot/property-16.scss | 2 +- .../icons/icons/circle-dot/property-24.scss | 2 +- .../base/icons/icons/circle-fill/index.scss | 2 +- .../icons/icons/circle-fill/keyframes.scss | 2 +- .../icons/icons/circle-fill/placeholders.scss | 2 +- .../icons/icons/circle-fill/property-16.scss | 2 +- .../icons/icons/circle-fill/property-24.scss | 2 +- .../base/icons/icons/circle-half/index.scss | 2 +- .../icons/icons/circle-half/keyframes.scss | 2 +- .../icons/icons/circle-half/placeholders.scss | 2 +- .../icons/icons/circle-half/property-16.scss | 2 +- .../icons/icons/circle-half/property-24.scss | 2 +- .../styles/base/icons/icons/circle/index.scss | 2 +- .../base/icons/icons/circle/keyframes.scss | 2 +- .../base/icons/icons/circle/placeholders.scss | 2 +- .../base/icons/icons/circle/property-16.scss | 2 +- .../base/icons/icons/circle/property-24.scss | 2 +- .../icons/icons/clipboard-checked/index.scss | 2 +- .../icons/clipboard-checked/keyframes.scss | 2 +- .../icons/clipboard-checked/placeholders.scss | 2 +- .../icons/clipboard-checked/property-16.scss | 2 +- .../icons/clipboard-checked/property-24.scss | 2 +- .../icons/icons/clipboard-copy/index.scss | 2 +- .../icons/icons/clipboard-copy/keyframes.scss | 2 +- .../icons/clipboard-copy/placeholders.scss | 2 +- .../icons/clipboard-copy/property-16.scss | 2 +- .../icons/clipboard-copy/property-24.scss | 2 +- .../base/icons/icons/clipboard/index.scss | 2 +- .../base/icons/icons/clipboard/keyframes.scss | 2 +- .../icons/icons/clipboard/placeholders.scss | 2 +- .../icons/icons/clipboard/property-16.scss | 2 +- .../icons/icons/clipboard/property-24.scss | 2 +- .../base/icons/icons/clock-fill/index.scss | 2 +- .../icons/icons/clock-fill/keyframes.scss | 2 +- .../icons/icons/clock-fill/placeholders.scss | 2 +- .../base/icons/icons/clock-outline/index.scss | 2 +- .../icons/icons/clock-outline/keyframes.scss | 2 +- .../icons/clock-outline/placeholders.scss | 2 +- .../styles/base/icons/icons/clock/index.scss | 2 +- .../base/icons/icons/clock/keyframes.scss | 2 +- .../base/icons/icons/clock/placeholders.scss | 2 +- .../base/icons/icons/clock/property-16.scss | 2 +- .../base/icons/icons/clock/property-24.scss | 2 +- .../base/icons/icons/cloud-check/index.scss | 2 +- .../icons/icons/cloud-check/keyframes.scss | 2 +- .../icons/icons/cloud-check/placeholders.scss | 2 +- .../icons/icons/cloud-check/property-16.scss | 2 +- .../icons/icons/cloud-check/property-24.scss | 2 +- .../base/icons/icons/cloud-cross/index.scss | 2 +- .../icons/icons/cloud-cross/keyframes.scss | 2 +- .../icons/icons/cloud-cross/placeholders.scss | 2 +- .../icons/icons/cloud-cross/property-16.scss | 2 +- .../icons/icons/cloud-cross/property-24.scss | 2 +- .../icons/icons/cloud-download/index.scss | 2 +- .../icons/icons/cloud-download/keyframes.scss | 2 +- .../icons/cloud-download/placeholders.scss | 2 +- .../icons/cloud-download/property-16.scss | 2 +- .../icons/cloud-download/property-24.scss | 2 +- .../icons/icons/cloud-lightning/index.scss | 2 +- .../icons/cloud-lightning/keyframes.scss | 2 +- .../icons/cloud-lightning/placeholders.scss | 2 +- .../icons/cloud-lightning/property-16.scss | 2 +- .../icons/cloud-lightning/property-24.scss | 2 +- .../base/icons/icons/cloud-lock/index.scss | 2 +- .../icons/icons/cloud-lock/keyframes.scss | 2 +- .../icons/icons/cloud-lock/placeholders.scss | 2 +- .../icons/icons/cloud-lock/property-16.scss | 2 +- .../icons/icons/cloud-lock/property-24.scss | 2 +- .../base/icons/icons/cloud-off/index.scss | 2 +- .../base/icons/icons/cloud-off/keyframes.scss | 2 +- .../icons/icons/cloud-off/placeholders.scss | 2 +- .../icons/icons/cloud-off/property-16.scss | 2 +- .../icons/icons/cloud-off/property-24.scss | 2 +- .../base/icons/icons/cloud-upload/index.scss | 2 +- .../icons/icons/cloud-upload/keyframes.scss | 2 +- .../icons/cloud-upload/placeholders.scss | 2 +- .../icons/icons/cloud-upload/property-16.scss | 2 +- .../icons/icons/cloud-upload/property-24.scss | 2 +- .../base/icons/icons/cloud-x/index.scss | 2 +- .../base/icons/icons/cloud-x/keyframes.scss | 2 +- .../icons/icons/cloud-x/placeholders.scss | 2 +- .../base/icons/icons/cloud-x/property-16.scss | 2 +- .../base/icons/icons/cloud-x/property-24.scss | 2 +- .../styles/base/icons/icons/cloud/index.scss | 2 +- .../base/icons/icons/cloud/keyframes.scss | 2 +- .../base/icons/icons/cloud/placeholders.scss | 2 +- .../base/icons/icons/cloud/property-16.scss | 2 +- .../base/icons/icons/cloud/property-24.scss | 2 +- .../styles/base/icons/icons/code/index.scss | 2 +- .../base/icons/icons/code/keyframes.scss | 2 +- .../base/icons/icons/code/placeholders.scss | 2 +- .../base/icons/icons/code/property-16.scss | 2 +- .../base/icons/icons/code/property-24.scss | 2 +- .../base/icons/icons/codepen-color/index.scss | 2 +- .../icons/icons/codepen-color/keyframes.scss | 2 +- .../icons/codepen-color/placeholders.scss | 2 +- .../icons/codepen-color/property-16.scss | 2 +- .../icons/codepen-color/property-24.scss | 2 +- .../base/icons/icons/codepen/index.scss | 2 +- .../base/icons/icons/codepen/keyframes.scss | 2 +- .../icons/icons/codepen/placeholders.scss | 2 +- .../base/icons/icons/codepen/property-16.scss | 2 +- .../base/icons/icons/codepen/property-24.scss | 2 +- .../base/icons/icons/collections/index.scss | 2 +- .../icons/icons/collections/keyframes.scss | 2 +- .../icons/icons/collections/placeholders.scss | 2 +- .../icons/icons/collections/property-16.scss | 2 +- .../icons/icons/collections/property-24.scss | 2 +- .../base/icons/icons/command/index.scss | 2 +- .../base/icons/icons/command/keyframes.scss | 2 +- .../icons/icons/command/placeholders.scss | 2 +- .../base/icons/icons/command/property-16.scss | 2 +- .../base/icons/icons/command/property-24.scss | 2 +- .../base/icons/icons/compass/index.scss | 2 +- .../base/icons/icons/compass/keyframes.scss | 2 +- .../icons/icons/compass/placeholders.scss | 2 +- .../base/icons/icons/compass/property-16.scss | 2 +- .../base/icons/icons/compass/property-24.scss | 2 +- .../icons/icons/connection-gateway/index.scss | 2 +- .../icons/connection-gateway/keyframes.scss | 2 +- .../connection-gateway/placeholders.scss | 2 +- .../icons/connection-gateway/property-16.scss | 2 +- .../icons/connection-gateway/property-24.scss | 2 +- .../base/icons/icons/connection/index.scss | 2 +- .../icons/icons/connection/keyframes.scss | 2 +- .../icons/icons/connection/placeholders.scss | 2 +- .../icons/icons/connection/property-16.scss | 2 +- .../icons/icons/connection/property-24.scss | 2 +- .../base/icons/icons/console/index.scss | 2 +- .../base/icons/icons/console/keyframes.scss | 2 +- .../icons/icons/console/placeholders.scss | 2 +- .../base/icons/icons/copy-action/index.scss | 2 +- .../icons/icons/copy-action/keyframes.scss | 2 +- .../icons/icons/copy-action/placeholders.scss | 2 +- .../base/icons/icons/copy-success/index.scss | 2 +- .../icons/icons/copy-success/keyframes.scss | 2 +- .../icons/copy-success/placeholders.scss | 2 +- .../icons/icons/corner-down-left/index.scss | 2 +- .../icons/corner-down-left/keyframes.scss | 2 +- .../icons/corner-down-left/placeholders.scss | 2 +- .../icons/corner-down-left/property-16.scss | 2 +- .../icons/corner-down-left/property-24.scss | 2 +- .../icons/icons/corner-down-right/index.scss | 2 +- .../icons/corner-down-right/keyframes.scss | 2 +- .../icons/corner-down-right/placeholders.scss | 2 +- .../icons/corner-down-right/property-16.scss | 2 +- .../icons/corner-down-right/property-24.scss | 2 +- .../icons/icons/corner-left-down/index.scss | 2 +- .../icons/corner-left-down/keyframes.scss | 2 +- .../icons/corner-left-down/placeholders.scss | 2 +- .../icons/corner-left-down/property-16.scss | 2 +- .../icons/corner-left-down/property-24.scss | 2 +- .../icons/icons/corner-left-up/index.scss | 2 +- .../icons/icons/corner-left-up/keyframes.scss | 2 +- .../icons/corner-left-up/placeholders.scss | 2 +- .../icons/corner-left-up/property-16.scss | 2 +- .../icons/corner-left-up/property-24.scss | 2 +- .../icons/icons/corner-right-down/index.scss | 2 +- .../icons/corner-right-down/keyframes.scss | 2 +- .../icons/corner-right-down/placeholders.scss | 2 +- .../icons/corner-right-down/property-16.scss | 2 +- .../icons/corner-right-down/property-24.scss | 2 +- .../icons/icons/corner-right-up/index.scss | 2 +- .../icons/corner-right-up/keyframes.scss | 2 +- .../icons/corner-right-up/placeholders.scss | 2 +- .../icons/corner-right-up/property-16.scss | 2 +- .../icons/corner-right-up/property-24.scss | 2 +- .../icons/icons/corner-up-left/index.scss | 2 +- .../icons/icons/corner-up-left/keyframes.scss | 2 +- .../icons/corner-up-left/placeholders.scss | 2 +- .../icons/corner-up-left/property-16.scss | 2 +- .../icons/corner-up-left/property-24.scss | 2 +- .../icons/icons/corner-up-right/index.scss | 2 +- .../icons/corner-up-right/keyframes.scss | 2 +- .../icons/corner-up-right/placeholders.scss | 2 +- .../icons/corner-up-right/property-16.scss | 2 +- .../icons/corner-up-right/property-24.scss | 2 +- .../styles/base/icons/icons/cpu/index.scss | 2 +- .../base/icons/icons/cpu/keyframes.scss | 2 +- .../base/icons/icons/cpu/placeholders.scss | 2 +- .../base/icons/icons/cpu/property-16.scss | 2 +- .../base/icons/icons/cpu/property-24.scss | 2 +- .../base/icons/icons/credit-card/index.scss | 2 +- .../icons/icons/credit-card/keyframes.scss | 2 +- .../icons/icons/credit-card/placeholders.scss | 2 +- .../icons/icons/credit-card/property-16.scss | 2 +- .../icons/icons/credit-card/property-24.scss | 2 +- .../styles/base/icons/icons/crop/index.scss | 2 +- .../base/icons/icons/crop/keyframes.scss | 2 +- .../base/icons/icons/crop/placeholders.scss | 2 +- .../base/icons/icons/crop/property-16.scss | 2 +- .../base/icons/icons/crop/property-24.scss | 2 +- .../base/icons/icons/crosshair/index.scss | 2 +- .../base/icons/icons/crosshair/keyframes.scss | 2 +- .../icons/icons/crosshair/placeholders.scss | 2 +- .../icons/icons/crosshair/property-16.scss | 2 +- .../icons/icons/crosshair/property-24.scss | 2 +- .../base/icons/icons/dashboard/index.scss | 2 +- .../base/icons/icons/dashboard/keyframes.scss | 2 +- .../icons/icons/dashboard/placeholders.scss | 2 +- .../icons/icons/dashboard/property-16.scss | 2 +- .../icons/icons/dashboard/property-24.scss | 2 +- .../base/icons/icons/database/index.scss | 2 +- .../base/icons/icons/database/keyframes.scss | 2 +- .../icons/icons/database/placeholders.scss | 2 +- .../icons/icons/database/property-16.scss | 2 +- .../icons/icons/database/property-24.scss | 2 +- .../styles/base/icons/icons/delay/index.scss | 2 +- .../base/icons/icons/delay/keyframes.scss | 2 +- .../base/icons/icons/delay/placeholders.scss | 2 +- .../base/icons/icons/delay/property-16.scss | 2 +- .../base/icons/icons/delay/property-24.scss | 2 +- .../styles/base/icons/icons/delete/index.scss | 2 +- .../base/icons/icons/delete/keyframes.scss | 2 +- .../base/icons/icons/delete/placeholders.scss | 2 +- .../base/icons/icons/delete/property-16.scss | 2 +- .../base/icons/icons/delete/property-24.scss | 2 +- .../base/icons/icons/deny-alt/index.scss | 2 +- .../base/icons/icons/deny-alt/keyframes.scss | 2 +- .../icons/icons/deny-alt/placeholders.scss | 2 +- .../base/icons/icons/deny-color/index.scss | 2 +- .../icons/icons/deny-color/keyframes.scss | 2 +- .../icons/icons/deny-color/placeholders.scss | 2 +- .../icons/icons/deny-color/property-16.scss | 2 +- .../icons/icons/deny-color/property-24.scss | 2 +- .../base/icons/icons/deny-default/index.scss | 2 +- .../icons/icons/deny-default/keyframes.scss | 2 +- .../icons/deny-default/placeholders.scss | 2 +- .../base/icons/icons/diamond-fill/index.scss | 2 +- .../icons/icons/diamond-fill/keyframes.scss | 2 +- .../icons/diamond-fill/placeholders.scss | 2 +- .../icons/icons/diamond-fill/property-16.scss | 2 +- .../icons/icons/diamond-fill/property-24.scss | 2 +- .../base/icons/icons/diamond/index.scss | 2 +- .../base/icons/icons/diamond/keyframes.scss | 2 +- .../icons/icons/diamond/placeholders.scss | 2 +- .../base/icons/icons/diamond/property-16.scss | 2 +- .../base/icons/icons/diamond/property-24.scss | 2 +- .../base/icons/icons/disabled/index.scss | 2 +- .../base/icons/icons/disabled/keyframes.scss | 2 +- .../icons/icons/disabled/placeholders.scss | 2 +- .../styles/base/icons/icons/disc/index.scss | 2 +- .../base/icons/icons/disc/keyframes.scss | 2 +- .../base/icons/icons/disc/placeholders.scss | 2 +- .../base/icons/icons/disc/property-16.scss | 2 +- .../base/icons/icons/disc/property-24.scss | 2 +- .../icons/icons/discussion-circle/index.scss | 2 +- .../icons/discussion-circle/keyframes.scss | 2 +- .../icons/discussion-circle/placeholders.scss | 2 +- .../icons/discussion-circle/property-16.scss | 2 +- .../icons/discussion-circle/property-24.scss | 2 +- .../icons/icons/discussion-square/index.scss | 2 +- .../icons/discussion-square/keyframes.scss | 2 +- .../icons/discussion-square/placeholders.scss | 2 +- .../icons/discussion-square/property-16.scss | 2 +- .../icons/discussion-square/property-24.scss | 2 +- .../base/icons/icons/docker-color/index.scss | 2 +- .../icons/icons/docker-color/keyframes.scss | 2 +- .../icons/docker-color/placeholders.scss | 2 +- .../icons/icons/docker-color/property-16.scss | 2 +- .../icons/icons/docker-color/property-24.scss | 2 +- .../styles/base/icons/icons/docker/index.scss | 2 +- .../base/icons/icons/docker/keyframes.scss | 2 +- .../base/icons/icons/docker/placeholders.scss | 2 +- .../base/icons/icons/docker/property-16.scss | 2 +- .../base/icons/icons/docker/property-24.scss | 2 +- .../base/icons/icons/docs-download/index.scss | 2 +- .../icons/icons/docs-download/keyframes.scss | 2 +- .../icons/docs-download/placeholders.scss | 2 +- .../icons/docs-download/property-16.scss | 2 +- .../icons/docs-download/property-24.scss | 2 +- .../base/icons/icons/docs-link/index.scss | 2 +- .../base/icons/icons/docs-link/keyframes.scss | 2 +- .../icons/icons/docs-link/placeholders.scss | 2 +- .../icons/icons/docs-link/property-16.scss | 2 +- .../icons/icons/docs-link/property-24.scss | 2 +- .../styles/base/icons/icons/docs/index.scss | 2 +- .../base/icons/icons/docs/keyframes.scss | 2 +- .../base/icons/icons/docs/placeholders.scss | 2 +- .../base/icons/icons/docs/property-16.scss | 2 +- .../base/icons/icons/docs/property-24.scss | 2 +- .../base/icons/icons/dollar-sign/index.scss | 2 +- .../icons/icons/dollar-sign/keyframes.scss | 2 +- .../icons/icons/dollar-sign/placeholders.scss | 2 +- .../icons/icons/dollar-sign/property-16.scss | 2 +- .../icons/icons/dollar-sign/property-24.scss | 2 +- .../base/icons/icons/dot-half/index.scss | 2 +- .../base/icons/icons/dot-half/keyframes.scss | 2 +- .../icons/icons/dot-half/placeholders.scss | 2 +- .../icons/icons/dot-half/property-16.scss | 2 +- .../icons/icons/dot-half/property-24.scss | 2 +- .../styles/base/icons/icons/dot/index.scss | 2 +- .../base/icons/icons/dot/keyframes.scss | 2 +- .../base/icons/icons/dot/placeholders.scss | 2 +- .../base/icons/icons/dot/property-16.scss | 2 +- .../base/icons/icons/dot/property-24.scss | 2 +- .../base/icons/icons/download/index.scss | 2 +- .../base/icons/icons/download/keyframes.scss | 2 +- .../icons/icons/download/placeholders.scss | 2 +- .../icons/icons/download/property-16.scss | 2 +- .../icons/icons/download/property-24.scss | 2 +- .../base/icons/icons/droplet/index.scss | 2 +- .../base/icons/icons/droplet/keyframes.scss | 2 +- .../icons/icons/droplet/placeholders.scss | 2 +- .../base/icons/icons/droplet/property-16.scss | 2 +- .../base/icons/icons/droplet/property-24.scss | 2 +- .../base/icons/icons/duplicate/index.scss | 2 +- .../base/icons/icons/duplicate/keyframes.scss | 2 +- .../icons/icons/duplicate/placeholders.scss | 2 +- .../icons/icons/duplicate/property-16.scss | 2 +- .../icons/icons/duplicate/property-24.scss | 2 +- .../styles/base/icons/icons/edit/index.scss | 2 +- .../base/icons/icons/edit/keyframes.scss | 2 +- .../base/icons/icons/edit/placeholders.scss | 2 +- .../base/icons/icons/edit/property-16.scss | 2 +- .../base/icons/icons/edit/property-24.scss | 2 +- .../base/icons/icons/enterprise/index.scss | 2 +- .../icons/icons/enterprise/keyframes.scss | 2 +- .../icons/icons/enterprise/placeholders.scss | 2 +- .../icons/icons/enterprise/property-16.scss | 2 +- .../icons/icons/enterprise/property-24.scss | 2 +- .../base/icons/icons/entry-point/index.scss | 2 +- .../icons/icons/entry-point/keyframes.scss | 2 +- .../icons/icons/entry-point/placeholders.scss | 2 +- .../icons/icons/entry-point/property-16.scss | 2 +- .../icons/icons/entry-point/property-24.scss | 2 +- .../icons/envelope-sealed-fill/index.scss | 2 +- .../icons/envelope-sealed-fill/keyframes.scss | 2 +- .../envelope-sealed-fill/placeholders.scss | 2 +- .../icons/envelope-sealed-outline/index.scss | 2 +- .../envelope-sealed-outline/keyframes.scss | 2 +- .../envelope-sealed-outline/placeholders.scss | 2 +- .../envelope-unsealed--outline/index.scss | 2 +- .../envelope-unsealed--outline/keyframes.scss | 2 +- .../placeholders.scss | 2 +- .../icons/envelope-unsealed-fill/index.scss | 2 +- .../envelope-unsealed-fill/keyframes.scss | 2 +- .../envelope-unsealed-fill/placeholders.scss | 2 +- .../styles/base/icons/icons/event/index.scss | 2 +- .../base/icons/icons/event/keyframes.scss | 2 +- .../base/icons/icons/event/placeholders.scss | 2 +- .../base/icons/icons/event/property-16.scss | 2 +- .../base/icons/icons/event/property-24.scss | 2 +- .../base/icons/icons/exit-point/index.scss | 2 +- .../icons/icons/exit-point/keyframes.scss | 2 +- .../icons/icons/exit-point/placeholders.scss | 2 +- .../icons/icons/exit-point/property-16.scss | 2 +- .../icons/icons/exit-point/property-24.scss | 2 +- .../styles/base/icons/icons/exit/index.scss | 2 +- .../base/icons/icons/exit/keyframes.scss | 2 +- .../base/icons/icons/exit/placeholders.scss | 2 +- .../base/icons/icons/expand-less/index.scss | 2 +- .../icons/icons/expand-less/keyframes.scss | 2 +- .../icons/icons/expand-less/placeholders.scss | 2 +- .../base/icons/icons/expand-more/index.scss | 2 +- .../icons/icons/expand-more/keyframes.scss | 2 +- .../icons/icons/expand-more/placeholders.scss | 2 +- .../base/icons/icons/external-link/index.scss | 2 +- .../icons/icons/external-link/keyframes.scss | 2 +- .../icons/external-link/placeholders.scss | 2 +- .../icons/external-link/property-16.scss | 2 +- .../icons/external-link/property-24.scss | 2 +- .../base/icons/icons/eye-off/index.scss | 2 +- .../base/icons/icons/eye-off/keyframes.scss | 2 +- .../icons/icons/eye-off/placeholders.scss | 2 +- .../base/icons/icons/eye-off/property-16.scss | 2 +- .../base/icons/icons/eye-off/property-24.scss | 2 +- .../styles/base/icons/icons/eye/index.scss | 2 +- .../base/icons/icons/eye/keyframes.scss | 2 +- .../base/icons/icons/eye/placeholders.scss | 2 +- .../base/icons/icons/eye/property-16.scss | 2 +- .../base/icons/icons/eye/property-24.scss | 2 +- .../base/icons/icons/f5-color/index.scss | 2 +- .../base/icons/icons/f5-color/keyframes.scss | 2 +- .../icons/icons/f5-color/placeholders.scss | 2 +- .../icons/icons/f5-color/property-16.scss | 2 +- .../icons/icons/f5-color/property-24.scss | 2 +- .../app/styles/base/icons/icons/f5/index.scss | 2 +- .../styles/base/icons/icons/f5/keyframes.scss | 2 +- .../base/icons/icons/f5/placeholders.scss | 2 +- .../base/icons/icons/f5/property-16.scss | 2 +- .../base/icons/icons/f5/property-24.scss | 2 +- .../icons/icons/facebook-color/index.scss | 2 +- .../icons/icons/facebook-color/keyframes.scss | 2 +- .../icons/facebook-color/placeholders.scss | 2 +- .../icons/facebook-color/property-16.scss | 2 +- .../icons/facebook-color/property-24.scss | 2 +- .../base/icons/icons/facebook/index.scss | 2 +- .../base/icons/icons/facebook/keyframes.scss | 2 +- .../icons/icons/facebook/placeholders.scss | 2 +- .../icons/icons/facebook/property-16.scss | 2 +- .../icons/icons/facebook/property-24.scss | 2 +- .../base/icons/icons/fast-forward/index.scss | 2 +- .../icons/icons/fast-forward/keyframes.scss | 2 +- .../icons/fast-forward/placeholders.scss | 2 +- .../icons/icons/fast-forward/property-16.scss | 2 +- .../icons/icons/fast-forward/property-24.scss | 2 +- .../base/icons/icons/file-change/index.scss | 2 +- .../icons/icons/file-change/keyframes.scss | 2 +- .../icons/icons/file-change/placeholders.scss | 2 +- .../icons/icons/file-change/property-16.scss | 2 +- .../icons/icons/file-change/property-24.scss | 2 +- .../base/icons/icons/file-check/index.scss | 2 +- .../icons/icons/file-check/keyframes.scss | 2 +- .../icons/icons/file-check/placeholders.scss | 2 +- .../icons/icons/file-check/property-16.scss | 2 +- .../icons/icons/file-check/property-24.scss | 2 +- .../base/icons/icons/file-diff/index.scss | 2 +- .../base/icons/icons/file-diff/keyframes.scss | 2 +- .../icons/icons/file-diff/placeholders.scss | 2 +- .../icons/icons/file-diff/property-16.scss | 2 +- .../icons/icons/file-diff/property-24.scss | 2 +- .../base/icons/icons/file-fill/index.scss | 2 +- .../base/icons/icons/file-fill/keyframes.scss | 2 +- .../icons/icons/file-fill/placeholders.scss | 2 +- .../base/icons/icons/file-minus/index.scss | 2 +- .../icons/icons/file-minus/keyframes.scss | 2 +- .../icons/icons/file-minus/placeholders.scss | 2 +- .../icons/icons/file-minus/property-16.scss | 2 +- .../icons/icons/file-minus/property-24.scss | 2 +- .../base/icons/icons/file-outline/index.scss | 2 +- .../icons/icons/file-outline/keyframes.scss | 2 +- .../icons/file-outline/placeholders.scss | 2 +- .../base/icons/icons/file-plus/index.scss | 2 +- .../base/icons/icons/file-plus/keyframes.scss | 2 +- .../icons/icons/file-plus/placeholders.scss | 2 +- .../icons/icons/file-plus/property-16.scss | 2 +- .../icons/icons/file-plus/property-24.scss | 2 +- .../base/icons/icons/file-source/index.scss | 2 +- .../icons/icons/file-source/keyframes.scss | 2 +- .../icons/icons/file-source/placeholders.scss | 2 +- .../icons/icons/file-source/property-16.scss | 2 +- .../icons/icons/file-source/property-24.scss | 2 +- .../base/icons/icons/file-text/index.scss | 2 +- .../base/icons/icons/file-text/keyframes.scss | 2 +- .../icons/icons/file-text/placeholders.scss | 2 +- .../icons/icons/file-text/property-16.scss | 2 +- .../icons/icons/file-text/property-24.scss | 2 +- .../styles/base/icons/icons/file-x/index.scss | 2 +- .../base/icons/icons/file-x/keyframes.scss | 2 +- .../base/icons/icons/file-x/placeholders.scss | 2 +- .../base/icons/icons/file-x/property-16.scss | 2 +- .../base/icons/icons/file-x/property-24.scss | 2 +- .../styles/base/icons/icons/file/index.scss | 2 +- .../base/icons/icons/file/keyframes.scss | 2 +- .../base/icons/icons/file/placeholders.scss | 2 +- .../base/icons/icons/file/property-16.scss | 2 +- .../base/icons/icons/file/property-24.scss | 2 +- .../styles/base/icons/icons/files/index.scss | 2 +- .../base/icons/icons/files/keyframes.scss | 2 +- .../base/icons/icons/files/placeholders.scss | 2 +- .../base/icons/icons/files/property-16.scss | 2 +- .../base/icons/icons/files/property-24.scss | 2 +- .../styles/base/icons/icons/film/index.scss | 2 +- .../base/icons/icons/film/keyframes.scss | 2 +- .../base/icons/icons/film/placeholders.scss | 2 +- .../base/icons/icons/film/property-16.scss | 2 +- .../base/icons/icons/film/property-24.scss | 2 +- .../base/icons/icons/filter-circle/index.scss | 2 +- .../icons/icons/filter-circle/keyframes.scss | 2 +- .../icons/filter-circle/placeholders.scss | 2 +- .../icons/filter-circle/property-16.scss | 2 +- .../icons/filter-circle/property-24.scss | 2 +- .../base/icons/icons/filter-fill/index.scss | 2 +- .../icons/icons/filter-fill/keyframes.scss | 2 +- .../icons/icons/filter-fill/placeholders.scss | 2 +- .../icons/icons/filter-fill/property-16.scss | 2 +- .../icons/icons/filter-fill/property-24.scss | 2 +- .../styles/base/icons/icons/filter/index.scss | 2 +- .../base/icons/icons/filter/keyframes.scss | 2 +- .../base/icons/icons/filter/placeholders.scss | 2 +- .../base/icons/icons/filter/property-16.scss | 2 +- .../base/icons/icons/filter/property-24.scss | 2 +- .../base/icons/icons/fingerprint/index.scss | 2 +- .../icons/icons/fingerprint/keyframes.scss | 2 +- .../icons/icons/fingerprint/placeholders.scss | 2 +- .../icons/icons/fingerprint/property-16.scss | 2 +- .../icons/icons/fingerprint/property-24.scss | 2 +- .../styles/base/icons/icons/flag/index.scss | 2 +- .../base/icons/icons/flag/keyframes.scss | 2 +- .../base/icons/icons/flag/placeholders.scss | 2 +- .../base/icons/icons/flag/property-16.scss | 2 +- .../base/icons/icons/flag/property-24.scss | 2 +- .../base/icons/icons/folder-fill/index.scss | 2 +- .../icons/icons/folder-fill/keyframes.scss | 2 +- .../icons/icons/folder-fill/placeholders.scss | 2 +- .../icons/icons/folder-fill/property-16.scss | 2 +- .../icons/icons/folder-fill/property-24.scss | 2 +- .../icons/icons/folder-minus-fill/index.scss | 2 +- .../icons/folder-minus-fill/keyframes.scss | 2 +- .../icons/folder-minus-fill/placeholders.scss | 2 +- .../icons/folder-minus-fill/property-16.scss | 2 +- .../icons/folder-minus-fill/property-24.scss | 2 +- .../base/icons/icons/folder-minus/index.scss | 2 +- .../icons/icons/folder-minus/keyframes.scss | 2 +- .../icons/folder-minus/placeholders.scss | 2 +- .../icons/icons/folder-minus/property-16.scss | 2 +- .../icons/icons/folder-minus/property-24.scss | 2 +- .../icons/icons/folder-outline/index.scss | 2 +- .../icons/icons/folder-outline/keyframes.scss | 2 +- .../icons/folder-outline/placeholders.scss | 2 +- .../icons/icons/folder-plus-fill/index.scss | 2 +- .../icons/folder-plus-fill/keyframes.scss | 2 +- .../icons/folder-plus-fill/placeholders.scss | 2 +- .../icons/folder-plus-fill/property-16.scss | 2 +- .../icons/folder-plus-fill/property-24.scss | 2 +- .../base/icons/icons/folder-plus/index.scss | 2 +- .../icons/icons/folder-plus/keyframes.scss | 2 +- .../icons/icons/folder-plus/placeholders.scss | 2 +- .../icons/icons/folder-plus/property-16.scss | 2 +- .../icons/icons/folder-plus/property-24.scss | 2 +- .../base/icons/icons/folder-star/index.scss | 2 +- .../icons/icons/folder-star/keyframes.scss | 2 +- .../icons/icons/folder-star/placeholders.scss | 2 +- .../icons/icons/folder-star/property-16.scss | 2 +- .../icons/icons/folder-star/property-24.scss | 2 +- .../base/icons/icons/folder-users/index.scss | 2 +- .../icons/icons/folder-users/keyframes.scss | 2 +- .../icons/folder-users/placeholders.scss | 2 +- .../icons/icons/folder-users/property-16.scss | 2 +- .../icons/icons/folder-users/property-24.scss | 2 +- .../styles/base/icons/icons/folder/index.scss | 2 +- .../base/icons/icons/folder/keyframes.scss | 2 +- .../base/icons/icons/folder/placeholders.scss | 2 +- .../base/icons/icons/folder/property-16.scss | 2 +- .../base/icons/icons/folder/property-24.scss | 2 +- .../styles/base/icons/icons/frown/index.scss | 2 +- .../base/icons/icons/frown/keyframes.scss | 2 +- .../base/icons/icons/frown/placeholders.scss | 2 +- .../base/icons/icons/frown/property-16.scss | 2 +- .../base/icons/icons/frown/property-24.scss | 2 +- .../base/icons/icons/gateway/index.scss | 2 +- .../base/icons/icons/gateway/keyframes.scss | 2 +- .../icons/icons/gateway/placeholders.scss | 2 +- .../base/icons/icons/gateway/property-16.scss | 2 +- .../base/icons/icons/gateway/property-24.scss | 2 +- .../base/icons/icons/gcp-color/index.scss | 2 +- .../base/icons/icons/gcp-color/keyframes.scss | 2 +- .../icons/icons/gcp-color/placeholders.scss | 2 +- .../icons/icons/gcp-color/property-16.scss | 2 +- .../icons/icons/gcp-color/property-24.scss | 2 +- .../styles/base/icons/icons/gcp/index.scss | 2 +- .../base/icons/icons/gcp/keyframes.scss | 2 +- .../base/icons/icons/gcp/placeholders.scss | 2 +- .../base/icons/icons/gcp/property-16.scss | 2 +- .../base/icons/icons/gcp/property-24.scss | 2 +- .../base/icons/icons/gift-fill/index.scss | 2 +- .../base/icons/icons/gift-fill/keyframes.scss | 2 +- .../icons/icons/gift-fill/placeholders.scss | 2 +- .../base/icons/icons/gift-outline/index.scss | 2 +- .../icons/icons/gift-outline/keyframes.scss | 2 +- .../icons/gift-outline/placeholders.scss | 2 +- .../styles/base/icons/icons/gift/index.scss | 2 +- .../base/icons/icons/gift/keyframes.scss | 2 +- .../base/icons/icons/gift/placeholders.scss | 2 +- .../base/icons/icons/gift/property-16.scss | 2 +- .../base/icons/icons/gift/property-24.scss | 2 +- .../base/icons/icons/git-branch/index.scss | 2 +- .../icons/icons/git-branch/keyframes.scss | 2 +- .../icons/icons/git-branch/placeholders.scss | 2 +- .../icons/icons/git-branch/property-16.scss | 2 +- .../icons/icons/git-branch/property-24.scss | 2 +- .../base/icons/icons/git-commit/index.scss | 2 +- .../icons/icons/git-commit/keyframes.scss | 2 +- .../icons/icons/git-commit/placeholders.scss | 2 +- .../icons/icons/git-commit/property-16.scss | 2 +- .../icons/icons/git-commit/property-24.scss | 2 +- .../base/icons/icons/git-merge/index.scss | 2 +- .../base/icons/icons/git-merge/keyframes.scss | 2 +- .../icons/icons/git-merge/placeholders.scss | 2 +- .../icons/icons/git-merge/property-16.scss | 2 +- .../icons/icons/git-merge/property-24.scss | 2 +- .../icons/icons/git-pull-request/index.scss | 2 +- .../icons/git-pull-request/keyframes.scss | 2 +- .../icons/git-pull-request/placeholders.scss | 2 +- .../icons/git-pull-request/property-16.scss | 2 +- .../icons/git-pull-request/property-24.scss | 2 +- .../base/icons/icons/git-repo/index.scss | 2 +- .../base/icons/icons/git-repo/keyframes.scss | 2 +- .../icons/icons/git-repo/placeholders.scss | 2 +- .../icons/icons/git-repo/property-16.scss | 2 +- .../icons/icons/git-repo/property-24.scss | 2 +- .../icons/icons/git-repository/index.scss | 2 +- .../icons/icons/git-repository/keyframes.scss | 2 +- .../icons/git-repository/placeholders.scss | 2 +- .../base/icons/icons/github-color/index.scss | 2 +- .../icons/icons/github-color/keyframes.scss | 2 +- .../icons/github-color/placeholders.scss | 2 +- .../icons/icons/github-color/property-16.scss | 2 +- .../icons/icons/github-color/property-24.scss | 2 +- .../styles/base/icons/icons/github/index.scss | 2 +- .../base/icons/icons/github/keyframes.scss | 2 +- .../base/icons/icons/github/placeholders.scss | 2 +- .../base/icons/icons/github/property-16.scss | 2 +- .../base/icons/icons/github/property-24.scss | 2 +- .../base/icons/icons/gitlab-color/index.scss | 2 +- .../icons/icons/gitlab-color/keyframes.scss | 2 +- .../icons/gitlab-color/placeholders.scss | 2 +- .../icons/icons/gitlab-color/property-16.scss | 2 +- .../icons/icons/gitlab-color/property-24.scss | 2 +- .../styles/base/icons/icons/gitlab/index.scss | 2 +- .../base/icons/icons/gitlab/keyframes.scss | 2 +- .../base/icons/icons/gitlab/placeholders.scss | 2 +- .../base/icons/icons/gitlab/property-16.scss | 2 +- .../base/icons/icons/gitlab/property-24.scss | 2 +- .../base/icons/icons/globe-private/index.scss | 2 +- .../icons/icons/globe-private/keyframes.scss | 2 +- .../icons/globe-private/placeholders.scss | 2 +- .../icons/globe-private/property-16.scss | 2 +- .../icons/globe-private/property-24.scss | 2 +- .../styles/base/icons/icons/globe/index.scss | 2 +- .../base/icons/icons/globe/keyframes.scss | 2 +- .../base/icons/icons/globe/placeholders.scss | 2 +- .../base/icons/icons/globe/property-16.scss | 2 +- .../base/icons/icons/globe/property-24.scss | 2 +- .../base/icons/icons/google-color/index.scss | 2 +- .../icons/icons/google-color/keyframes.scss | 2 +- .../icons/google-color/placeholders.scss | 2 +- .../icons/icons/google-color/property-16.scss | 2 +- .../icons/icons/google-color/property-24.scss | 2 +- .../styles/base/icons/icons/google/index.scss | 2 +- .../base/icons/icons/google/keyframes.scss | 2 +- .../base/icons/icons/google/placeholders.scss | 2 +- .../base/icons/icons/google/property-16.scss | 2 +- .../base/icons/icons/google/property-24.scss | 2 +- .../base/icons/icons/grid-alt/index.scss | 2 +- .../base/icons/icons/grid-alt/keyframes.scss | 2 +- .../icons/icons/grid-alt/placeholders.scss | 2 +- .../icons/icons/grid-alt/property-16.scss | 2 +- .../icons/icons/grid-alt/property-24.scss | 2 +- .../styles/base/icons/icons/grid/index.scss | 2 +- .../base/icons/icons/grid/keyframes.scss | 2 +- .../base/icons/icons/grid/placeholders.scss | 2 +- .../base/icons/icons/grid/property-16.scss | 2 +- .../base/icons/icons/grid/property-24.scss | 2 +- .../base/icons/icons/guide-link/index.scss | 2 +- .../icons/icons/guide-link/keyframes.scss | 2 +- .../icons/icons/guide-link/placeholders.scss | 2 +- .../icons/icons/guide-link/property-16.scss | 2 +- .../icons/icons/guide-link/property-24.scss | 2 +- .../styles/base/icons/icons/guide/index.scss | 2 +- .../base/icons/icons/guide/keyframes.scss | 2 +- .../base/icons/icons/guide/placeholders.scss | 2 +- .../base/icons/icons/guide/property-16.scss | 2 +- .../base/icons/icons/guide/property-24.scss | 2 +- .../styles/base/icons/icons/hammer/index.scss | 2 +- .../base/icons/icons/hammer/keyframes.scss | 2 +- .../base/icons/icons/hammer/placeholders.scss | 2 +- .../base/icons/icons/hammer/property-16.scss | 2 +- .../base/icons/icons/hammer/property-24.scss | 2 +- .../base/icons/icons/handshake/index.scss | 2 +- .../base/icons/icons/handshake/keyframes.scss | 2 +- .../icons/icons/handshake/placeholders.scss | 2 +- .../icons/icons/handshake/property-16.scss | 2 +- .../icons/icons/handshake/property-24.scss | 2 +- .../base/icons/icons/hard-drive/index.scss | 2 +- .../icons/icons/hard-drive/keyframes.scss | 2 +- .../icons/icons/hard-drive/placeholders.scss | 2 +- .../icons/icons/hard-drive/property-16.scss | 2 +- .../icons/icons/hard-drive/property-24.scss | 2 +- .../styles/base/icons/icons/hash/index.scss | 2 +- .../base/icons/icons/hash/keyframes.scss | 2 +- .../base/icons/icons/hash/placeholders.scss | 2 +- .../base/icons/icons/hash/property-16.scss | 2 +- .../base/icons/icons/hash/property-24.scss | 2 +- .../icons/icons/hashicorp-color/index.scss | 2 +- .../icons/hashicorp-color/keyframes.scss | 2 +- .../icons/hashicorp-color/placeholders.scss | 2 +- .../icons/hashicorp-color/property-16.scss | 2 +- .../icons/hashicorp-color/property-24.scss | 2 +- .../base/icons/icons/hashicorp/index.scss | 2 +- .../base/icons/icons/hashicorp/keyframes.scss | 2 +- .../icons/icons/hashicorp/placeholders.scss | 2 +- .../icons/icons/hashicorp/property-16.scss | 2 +- .../icons/icons/hashicorp/property-24.scss | 2 +- .../base/icons/icons/hcp-color/index.scss | 2 +- .../base/icons/icons/hcp-color/keyframes.scss | 2 +- .../icons/icons/hcp-color/placeholders.scss | 2 +- .../icons/icons/hcp-color/property-16.scss | 2 +- .../icons/icons/hcp-color/property-24.scss | 2 +- .../styles/base/icons/icons/hcp/index.scss | 2 +- .../base/icons/icons/hcp/keyframes.scss | 2 +- .../base/icons/icons/hcp/placeholders.scss | 2 +- .../base/icons/icons/hcp/property-16.scss | 2 +- .../base/icons/icons/hcp/property-24.scss | 2 +- .../base/icons/icons/headphones/index.scss | 2 +- .../icons/icons/headphones/keyframes.scss | 2 +- .../icons/icons/headphones/placeholders.scss | 2 +- .../icons/icons/headphones/property-16.scss | 2 +- .../icons/icons/headphones/property-24.scss | 2 +- .../styles/base/icons/icons/health/index.scss | 2 +- .../base/icons/icons/health/keyframes.scss | 2 +- .../base/icons/icons/health/placeholders.scss | 2 +- .../base/icons/icons/heart-fill/index.scss | 2 +- .../icons/icons/heart-fill/keyframes.scss | 2 +- .../icons/icons/heart-fill/placeholders.scss | 2 +- .../icons/icons/heart-fill/property-16.scss | 2 +- .../icons/icons/heart-fill/property-24.scss | 2 +- .../base/icons/icons/heart-off/index.scss | 2 +- .../base/icons/icons/heart-off/keyframes.scss | 2 +- .../icons/icons/heart-off/placeholders.scss | 2 +- .../icons/icons/heart-off/property-16.scss | 2 +- .../icons/icons/heart-off/property-24.scss | 2 +- .../styles/base/icons/icons/heart/index.scss | 2 +- .../base/icons/icons/heart/keyframes.scss | 2 +- .../base/icons/icons/heart/placeholders.scss | 2 +- .../base/icons/icons/heart/property-16.scss | 2 +- .../base/icons/icons/heart/property-24.scss | 2 +- .../icons/icons/help-circle-fill/index.scss | 2 +- .../icons/help-circle-fill/keyframes.scss | 2 +- .../icons/help-circle-fill/placeholders.scss | 2 +- .../icons/help-circle-outline/index.scss | 2 +- .../icons/help-circle-outline/keyframes.scss | 2 +- .../help-circle-outline/placeholders.scss | 2 +- .../styles/base/icons/icons/help/index.scss | 2 +- .../base/icons/icons/help/keyframes.scss | 2 +- .../base/icons/icons/help/placeholders.scss | 2 +- .../base/icons/icons/help/property-16.scss | 2 +- .../base/icons/icons/help/property-24.scss | 2 +- .../base/icons/icons/hexagon-fill/index.scss | 2 +- .../icons/icons/hexagon-fill/keyframes.scss | 2 +- .../icons/hexagon-fill/placeholders.scss | 2 +- .../icons/icons/hexagon-fill/property-16.scss | 2 +- .../icons/icons/hexagon-fill/property-24.scss | 2 +- .../base/icons/icons/hexagon/index.scss | 2 +- .../base/icons/icons/hexagon/keyframes.scss | 2 +- .../icons/icons/hexagon/placeholders.scss | 2 +- .../base/icons/icons/hexagon/property-16.scss | 2 +- .../base/icons/icons/hexagon/property-24.scss | 2 +- .../base/icons/icons/history/index.scss | 2 +- .../base/icons/icons/history/keyframes.scss | 2 +- .../icons/icons/history/placeholders.scss | 2 +- .../base/icons/icons/history/property-16.scss | 2 +- .../base/icons/icons/history/property-24.scss | 2 +- .../styles/base/icons/icons/home/index.scss | 2 +- .../base/icons/icons/home/keyframes.scss | 2 +- .../base/icons/icons/home/placeholders.scss | 2 +- .../base/icons/icons/home/property-16.scss | 2 +- .../base/icons/icons/home/property-24.scss | 2 +- .../base/icons/icons/hourglass/index.scss | 2 +- .../base/icons/icons/hourglass/keyframes.scss | 2 +- .../icons/icons/hourglass/placeholders.scss | 2 +- .../icons/icons/hourglass/property-16.scss | 2 +- .../icons/icons/hourglass/property-24.scss | 2 +- .../icons/icons/identity-service/index.scss | 2 +- .../icons/identity-service/keyframes.scss | 2 +- .../icons/identity-service/placeholders.scss | 2 +- .../icons/identity-service/property-16.scss | 2 +- .../icons/identity-service/property-24.scss | 2 +- .../base/icons/icons/identity-user/index.scss | 2 +- .../icons/icons/identity-user/keyframes.scss | 2 +- .../icons/identity-user/placeholders.scss | 2 +- .../icons/identity-user/property-16.scss | 2 +- .../icons/identity-user/property-24.scss | 2 +- .../styles/base/icons/icons/image/index.scss | 2 +- .../base/icons/icons/image/keyframes.scss | 2 +- .../base/icons/icons/image/placeholders.scss | 2 +- .../base/icons/icons/image/property-16.scss | 2 +- .../base/icons/icons/image/property-24.scss | 2 +- .../styles/base/icons/icons/inbox/index.scss | 2 +- .../base/icons/icons/inbox/keyframes.scss | 2 +- .../base/icons/icons/inbox/placeholders.scss | 2 +- .../base/icons/icons/inbox/property-16.scss | 2 +- .../base/icons/icons/inbox/property-24.scss | 2 +- .../app/styles/base/icons/icons/index.scss | 2 +- .../icons/icons/info-circle-fill/index.scss | 2 +- .../icons/info-circle-fill/keyframes.scss | 2 +- .../icons/info-circle-fill/placeholders.scss | 2 +- .../icons/info-circle-outline/index.scss | 2 +- .../icons/info-circle-outline/keyframes.scss | 2 +- .../info-circle-outline/placeholders.scss | 2 +- .../styles/base/icons/icons/info/index.scss | 2 +- .../base/icons/icons/info/keyframes.scss | 2 +- .../base/icons/icons/info/placeholders.scss | 2 +- .../base/icons/icons/info/property-16.scss | 2 +- .../base/icons/icons/info/property-24.scss | 2 +- .../base/icons/icons/jump-link/index.scss | 2 +- .../base/icons/icons/jump-link/keyframes.scss | 2 +- .../icons/icons/jump-link/placeholders.scss | 2 +- .../icons/icons/jump-link/property-16.scss | 2 +- .../icons/icons/jump-link/property-24.scss | 2 +- .../base/icons/icons/key-values/index.scss | 2 +- .../icons/icons/key-values/keyframes.scss | 2 +- .../icons/icons/key-values/placeholders.scss | 2 +- .../icons/icons/key-values/property-16.scss | 2 +- .../icons/icons/key-values/property-24.scss | 2 +- .../styles/base/icons/icons/key/index.scss | 2 +- .../base/icons/icons/key/keyframes.scss | 2 +- .../base/icons/icons/key/placeholders.scss | 2 +- .../base/icons/icons/key/property-16.scss | 2 +- .../base/icons/icons/key/property-24.scss | 2 +- .../base/icons/icons/keychain/index.scss | 2 +- .../base/icons/icons/keychain/keyframes.scss | 2 +- .../icons/icons/keychain/placeholders.scss | 2 +- .../icons/icons/keychain/property-16.scss | 2 +- .../icons/icons/keychain/property-24.scss | 2 +- .../icons/icons/kubernetes-color/index.scss | 2 +- .../icons/kubernetes-color/keyframes.scss | 2 +- .../icons/kubernetes-color/placeholders.scss | 2 +- .../icons/kubernetes-color/property-16.scss | 2 +- .../icons/kubernetes-color/property-24.scss | 2 +- .../base/icons/icons/kubernetes/index.scss | 2 +- .../icons/icons/kubernetes/keyframes.scss | 2 +- .../icons/icons/kubernetes/placeholders.scss | 2 +- .../icons/icons/kubernetes/property-16.scss | 2 +- .../icons/icons/kubernetes/property-24.scss | 2 +- .../base/icons/icons/labyrinth/index.scss | 2 +- .../base/icons/icons/labyrinth/keyframes.scss | 2 +- .../icons/icons/labyrinth/placeholders.scss | 2 +- .../icons/icons/labyrinth/property-16.scss | 2 +- .../icons/icons/labyrinth/property-24.scss | 2 +- .../styles/base/icons/icons/layers/index.scss | 2 +- .../base/icons/icons/layers/keyframes.scss | 2 +- .../base/icons/icons/layers/placeholders.scss | 2 +- .../base/icons/icons/layers/property-16.scss | 2 +- .../base/icons/icons/layers/property-24.scss | 2 +- .../styles/base/icons/icons/layout/index.scss | 2 +- .../base/icons/icons/layout/keyframes.scss | 2 +- .../base/icons/icons/layout/placeholders.scss | 2 +- .../base/icons/icons/layout/property-16.scss | 2 +- .../base/icons/icons/layout/property-24.scss | 2 +- .../base/icons/icons/learn-link/index.scss | 2 +- .../icons/icons/learn-link/keyframes.scss | 2 +- .../icons/icons/learn-link/placeholders.scss | 2 +- .../icons/icons/learn-link/property-16.scss | 2 +- .../icons/icons/learn-link/property-24.scss | 2 +- .../styles/base/icons/icons/learn/index.scss | 2 +- .../base/icons/icons/learn/keyframes.scss | 2 +- .../base/icons/icons/learn/placeholders.scss | 2 +- .../base/icons/icons/learn/property-16.scss | 2 +- .../base/icons/icons/learn/property-24.scss | 2 +- .../base/icons/icons/line-chart-up/index.scss | 2 +- .../icons/icons/line-chart-up/keyframes.scss | 2 +- .../icons/line-chart-up/placeholders.scss | 2 +- .../icons/line-chart-up/property-16.scss | 2 +- .../icons/line-chart-up/property-24.scss | 2 +- .../base/icons/icons/line-chart/index.scss | 2 +- .../icons/icons/line-chart/keyframes.scss | 2 +- .../icons/icons/line-chart/placeholders.scss | 2 +- .../icons/icons/line-chart/property-16.scss | 2 +- .../icons/icons/line-chart/property-24.scss | 2 +- .../styles/base/icons/icons/link/index.scss | 2 +- .../base/icons/icons/link/keyframes.scss | 2 +- .../base/icons/icons/link/placeholders.scss | 2 +- .../base/icons/icons/link/property-16.scss | 2 +- .../base/icons/icons/link/property-24.scss | 2 +- .../icons/icons/linkedin-color/index.scss | 2 +- .../icons/icons/linkedin-color/keyframes.scss | 2 +- .../icons/linkedin-color/placeholders.scss | 2 +- .../icons/linkedin-color/property-16.scss | 2 +- .../icons/linkedin-color/property-24.scss | 2 +- .../base/icons/icons/linkedin/index.scss | 2 +- .../base/icons/icons/linkedin/keyframes.scss | 2 +- .../icons/icons/linkedin/placeholders.scss | 2 +- .../icons/icons/linkedin/property-16.scss | 2 +- .../icons/icons/linkedin/property-24.scss | 2 +- .../styles/base/icons/icons/list/index.scss | 2 +- .../base/icons/icons/list/keyframes.scss | 2 +- .../base/icons/icons/list/placeholders.scss | 2 +- .../base/icons/icons/list/property-16.scss | 2 +- .../base/icons/icons/list/property-24.scss | 2 +- .../base/icons/icons/load-balancer/index.scss | 2 +- .../icons/icons/load-balancer/keyframes.scss | 2 +- .../icons/load-balancer/placeholders.scss | 2 +- .../icons/load-balancer/property-16.scss | 2 +- .../icons/load-balancer/property-24.scss | 2 +- .../icons/icons/loading-motion/index.scss | 2 +- .../icons/icons/loading-motion/keyframes.scss | 2 +- .../icons/loading-motion/placeholders.scss | 2 +- .../icons/loading-motion/property-16.scss | 2 +- .../icons/loading-motion/property-24.scss | 2 +- .../base/icons/icons/loading/index.scss | 2 +- .../base/icons/icons/loading/keyframes.scss | 2 +- .../icons/icons/loading/placeholders.scss | 2 +- .../base/icons/icons/loading/property-16.scss | 2 +- .../base/icons/icons/loading/property-24.scss | 2 +- .../icons/icons/lock-closed-fill/index.scss | 2 +- .../icons/lock-closed-fill/keyframes.scss | 2 +- .../icons/lock-closed-fill/placeholders.scss | 2 +- .../icons/lock-closed-outline/index.scss | 2 +- .../icons/lock-closed-outline/keyframes.scss | 2 +- .../lock-closed-outline/placeholders.scss | 2 +- .../base/icons/icons/lock-closed/index.scss | 2 +- .../icons/icons/lock-closed/keyframes.scss | 2 +- .../icons/icons/lock-closed/placeholders.scss | 2 +- .../base/icons/icons/lock-disabled/index.scss | 2 +- .../icons/icons/lock-disabled/keyframes.scss | 2 +- .../icons/lock-disabled/placeholders.scss | 2 +- .../base/icons/icons/lock-fill/index.scss | 2 +- .../base/icons/icons/lock-fill/keyframes.scss | 2 +- .../icons/icons/lock-fill/placeholders.scss | 2 +- .../icons/icons/lock-fill/property-16.scss | 2 +- .../icons/icons/lock-fill/property-24.scss | 2 +- .../base/icons/icons/lock-off/index.scss | 2 +- .../base/icons/icons/lock-off/keyframes.scss | 2 +- .../icons/icons/lock-off/placeholders.scss | 2 +- .../icons/icons/lock-off/property-16.scss | 2 +- .../icons/icons/lock-off/property-24.scss | 2 +- .../base/icons/icons/lock-open/index.scss | 2 +- .../base/icons/icons/lock-open/keyframes.scss | 2 +- .../icons/icons/lock-open/placeholders.scss | 2 +- .../styles/base/icons/icons/lock/index.scss | 2 +- .../base/icons/icons/lock/keyframes.scss | 2 +- .../base/icons/icons/lock/placeholders.scss | 2 +- .../base/icons/icons/lock/property-16.scss | 2 +- .../base/icons/icons/lock/property-24.scss | 2 +- .../icons/logo-alicloud-color/index.scss | 2 +- .../icons/logo-alicloud-color/keyframes.scss | 2 +- .../logo-alicloud-color/placeholders.scss | 2 +- .../icons/logo-alicloud-monochrome/index.scss | 2 +- .../logo-alicloud-monochrome/keyframes.scss | 2 +- .../placeholders.scss | 2 +- .../icons/icons/logo-auth0-color/index.scss | 2 +- .../icons/logo-auth0-color/keyframes.scss | 2 +- .../icons/logo-auth0-color/placeholders.scss | 2 +- .../icons/icons/logo-aws-color/index.scss | 2 +- .../icons/icons/logo-aws-color/keyframes.scss | 2 +- .../icons/logo-aws-color/placeholders.scss | 2 +- .../icons/logo-aws-monochrome/index.scss | 2 +- .../icons/logo-aws-monochrome/keyframes.scss | 2 +- .../logo-aws-monochrome/placeholders.scss | 2 +- .../icons/icons/logo-azure-color/index.scss | 2 +- .../icons/logo-azure-color/keyframes.scss | 2 +- .../icons/logo-azure-color/placeholders.scss | 2 +- .../icons/logo-azure-dev-ops-color/index.scss | 2 +- .../logo-azure-dev-ops-color/keyframes.scss | 2 +- .../placeholders.scss | 2 +- .../logo-azure-dev-ops-monochrome/index.scss | 2 +- .../keyframes.scss | 2 +- .../placeholders.scss | 2 +- .../icons/logo-azure-monochrome/index.scss | 2 +- .../logo-azure-monochrome/keyframes.scss | 2 +- .../logo-azure-monochrome/placeholders.scss | 2 +- .../icons/logo-bitbucket-color/index.scss | 2 +- .../icons/logo-bitbucket-color/keyframes.scss | 2 +- .../logo-bitbucket-color/placeholders.scss | 2 +- .../logo-bitbucket-monochrome/index.scss | 2 +- .../logo-bitbucket-monochrome/keyframes.scss | 2 +- .../placeholders.scss | 2 +- .../icons/logo-ember-circle-color/index.scss | 2 +- .../logo-ember-circle-color/keyframes.scss | 2 +- .../logo-ember-circle-color/placeholders.scss | 2 +- .../logo-ember-circle-color/property-16.scss | 2 +- .../logo-ember-circle-color/property-24.scss | 2 +- .../icons/icons/logo-gcp-color/index.scss | 2 +- .../icons/icons/logo-gcp-color/keyframes.scss | 2 +- .../icons/logo-gcp-color/placeholders.scss | 2 +- .../icons/logo-gcp-monochrome/index.scss | 2 +- .../icons/logo-gcp-monochrome/keyframes.scss | 2 +- .../logo-gcp-monochrome/placeholders.scss | 2 +- .../icons/icons/logo-github-color/index.scss | 2 +- .../icons/logo-github-color/keyframes.scss | 2 +- .../icons/logo-github-color/placeholders.scss | 2 +- .../icons/logo-github-monochrome/index.scss | 2 +- .../logo-github-monochrome/keyframes.scss | 2 +- .../logo-github-monochrome/placeholders.scss | 2 +- .../icons/icons/logo-gitlab-color/index.scss | 2 +- .../icons/logo-gitlab-color/keyframes.scss | 2 +- .../icons/logo-gitlab-color/placeholders.scss | 2 +- .../icons/logo-gitlab-monochrome/index.scss | 2 +- .../logo-gitlab-monochrome/keyframes.scss | 2 +- .../logo-gitlab-monochrome/placeholders.scss | 2 +- .../icons/icons/logo-glimmer-color/index.scss | 2 +- .../icons/logo-glimmer-color/keyframes.scss | 2 +- .../logo-glimmer-color/placeholders.scss | 2 +- .../icons/logo-glimmer-color/property-16.scss | 2 +- .../icons/logo-glimmer-color/property-24.scss | 2 +- .../icons/icons/logo-google-color/index.scss | 2 +- .../icons/logo-google-color/keyframes.scss | 2 +- .../icons/logo-google-color/placeholders.scss | 2 +- .../icons/logo-google-monochrome/index.scss | 2 +- .../logo-google-monochrome/keyframes.scss | 2 +- .../logo-google-monochrome/placeholders.scss | 2 +- .../icons/logo-hashicorp-color/index.scss | 2 +- .../icons/logo-hashicorp-color/keyframes.scss | 2 +- .../logo-hashicorp-color/placeholders.scss | 2 +- .../logo-hashicorp-color/property-16.scss | 2 +- .../logo-hashicorp-color/property-24.scss | 2 +- .../icons/icons/logo-jwt-color/index.scss | 2 +- .../icons/icons/logo-jwt-color/keyframes.scss | 2 +- .../icons/logo-jwt-color/placeholders.scss | 2 +- .../icons/logo-jwt-color/property-16.scss | 2 +- .../icons/logo-jwt-color/property-24.scss | 2 +- .../icons/logo-kubernetes-color/index.scss | 2 +- .../logo-kubernetes-color/keyframes.scss | 2 +- .../logo-kubernetes-color/placeholders.scss | 2 +- .../logo-kubernetes-monochrome/index.scss | 2 +- .../logo-kubernetes-monochrome/keyframes.scss | 2 +- .../placeholders.scss | 2 +- .../icons/logo-microsoft-color/index.scss | 2 +- .../icons/logo-microsoft-color/keyframes.scss | 2 +- .../logo-microsoft-color/placeholders.scss | 2 +- .../icons/icons/logo-oidc-color/index.scss | 2 +- .../icons/logo-oidc-color/keyframes.scss | 2 +- .../icons/logo-oidc-color/placeholders.scss | 2 +- .../icons/logo-oidc-color/property-16.scss | 2 +- .../icons/logo-oidc-color/property-24.scss | 2 +- .../icons/icons/logo-okta-color/index.scss | 2 +- .../icons/logo-okta-color/keyframes.scss | 2 +- .../icons/logo-okta-color/placeholders.scss | 2 +- .../icons/icons/logo-oracle-color/index.scss | 2 +- .../icons/logo-oracle-color/keyframes.scss | 2 +- .../icons/logo-oracle-color/placeholders.scss | 2 +- .../icons/logo-oracle-monochrome/index.scss | 2 +- .../logo-oracle-monochrome/keyframes.scss | 2 +- .../logo-oracle-monochrome/placeholders.scss | 2 +- .../icons/icons/logo-slack-color/index.scss | 2 +- .../icons/logo-slack-color/keyframes.scss | 2 +- .../icons/logo-slack-color/placeholders.scss | 2 +- .../icons/logo-slack-monochrome/index.scss | 2 +- .../logo-slack-monochrome/keyframes.scss | 2 +- .../logo-slack-monochrome/placeholders.scss | 2 +- .../icons/icons/logo-vmware-color/index.scss | 2 +- .../icons/logo-vmware-color/keyframes.scss | 2 +- .../icons/logo-vmware-color/placeholders.scss | 2 +- .../icons/logo-vmware-monochrome/index.scss | 2 +- .../logo-vmware-monochrome/keyframes.scss | 2 +- .../logo-vmware-monochrome/placeholders.scss | 2 +- .../base/icons/icons/mail-open/index.scss | 2 +- .../base/icons/icons/mail-open/keyframes.scss | 2 +- .../icons/icons/mail-open/placeholders.scss | 2 +- .../icons/icons/mail-open/property-16.scss | 2 +- .../icons/icons/mail-open/property-24.scss | 2 +- .../styles/base/icons/icons/mail/index.scss | 2 +- .../base/icons/icons/mail/keyframes.scss | 2 +- .../base/icons/icons/mail/placeholders.scss | 2 +- .../base/icons/icons/mail/property-16.scss | 2 +- .../base/icons/icons/mail/property-24.scss | 2 +- .../base/icons/icons/mainframe/index.scss | 2 +- .../base/icons/icons/mainframe/keyframes.scss | 2 +- .../icons/icons/mainframe/placeholders.scss | 2 +- .../icons/icons/mainframe/property-16.scss | 2 +- .../icons/icons/mainframe/property-24.scss | 2 +- .../base/icons/icons/map-pin/index.scss | 2 +- .../base/icons/icons/map-pin/keyframes.scss | 2 +- .../icons/icons/map-pin/placeholders.scss | 2 +- .../base/icons/icons/map-pin/property-16.scss | 2 +- .../base/icons/icons/map-pin/property-24.scss | 2 +- .../styles/base/icons/icons/map/index.scss | 2 +- .../base/icons/icons/map/keyframes.scss | 2 +- .../base/icons/icons/map/placeholders.scss | 2 +- .../base/icons/icons/map/property-16.scss | 2 +- .../base/icons/icons/map/property-24.scss | 2 +- .../base/icons/icons/maximize-alt/index.scss | 2 +- .../icons/icons/maximize-alt/keyframes.scss | 2 +- .../icons/maximize-alt/placeholders.scss | 2 +- .../icons/icons/maximize-alt/property-16.scss | 2 +- .../icons/icons/maximize-alt/property-24.scss | 2 +- .../base/icons/icons/maximize/index.scss | 2 +- .../base/icons/icons/maximize/keyframes.scss | 2 +- .../icons/icons/maximize/placeholders.scss | 2 +- .../icons/icons/maximize/property-16.scss | 2 +- .../icons/icons/maximize/property-24.scss | 2 +- .../styles/base/icons/icons/meh/index.scss | 2 +- .../base/icons/icons/meh/keyframes.scss | 2 +- .../base/icons/icons/meh/placeholders.scss | 2 +- .../base/icons/icons/meh/property-16.scss | 2 +- .../base/icons/icons/meh/property-24.scss | 2 +- .../styles/base/icons/icons/menu/index.scss | 2 +- .../base/icons/icons/menu/keyframes.scss | 2 +- .../base/icons/icons/menu/placeholders.scss | 2 +- .../base/icons/icons/menu/property-16.scss | 2 +- .../base/icons/icons/menu/property-24.scss | 2 +- .../styles/base/icons/icons/mesh/index.scss | 2 +- .../base/icons/icons/mesh/keyframes.scss | 2 +- .../base/icons/icons/mesh/placeholders.scss | 2 +- .../base/icons/icons/mesh/property-16.scss | 2 +- .../base/icons/icons/mesh/property-24.scss | 2 +- .../icons/message-circle-fill/index.scss | 2 +- .../icons/message-circle-fill/keyframes.scss | 2 +- .../message-circle-fill/placeholders.scss | 2 +- .../message-circle-fill/property-16.scss | 2 +- .../message-circle-fill/property-24.scss | 2 +- .../icons/icons/message-circle/index.scss | 2 +- .../icons/icons/message-circle/keyframes.scss | 2 +- .../icons/message-circle/placeholders.scss | 2 +- .../icons/message-circle/property-16.scss | 2 +- .../icons/message-circle/property-24.scss | 2 +- .../icons/message-square-fill/index.scss | 2 +- .../icons/message-square-fill/keyframes.scss | 2 +- .../message-square-fill/placeholders.scss | 2 +- .../message-square-fill/property-16.scss | 2 +- .../message-square-fill/property-24.scss | 2 +- .../icons/icons/message-square/index.scss | 2 +- .../icons/icons/message-square/keyframes.scss | 2 +- .../icons/message-square/placeholders.scss | 2 +- .../icons/message-square/property-16.scss | 2 +- .../icons/message-square/property-24.scss | 2 +- .../base/icons/icons/message/index.scss | 2 +- .../base/icons/icons/message/keyframes.scss | 2 +- .../icons/icons/message/placeholders.scss | 2 +- .../base/icons/icons/mic-off/index.scss | 2 +- .../base/icons/icons/mic-off/keyframes.scss | 2 +- .../icons/icons/mic-off/placeholders.scss | 2 +- .../base/icons/icons/mic-off/property-16.scss | 2 +- .../base/icons/icons/mic-off/property-24.scss | 2 +- .../styles/base/icons/icons/mic/index.scss | 2 +- .../base/icons/icons/mic/keyframes.scss | 2 +- .../base/icons/icons/mic/placeholders.scss | 2 +- .../base/icons/icons/mic/property-16.scss | 2 +- .../base/icons/icons/mic/property-24.scss | 2 +- .../icons/icons/microsoft-color/index.scss | 2 +- .../icons/microsoft-color/keyframes.scss | 2 +- .../icons/microsoft-color/placeholders.scss | 2 +- .../icons/microsoft-color/property-16.scss | 2 +- .../icons/microsoft-color/property-24.scss | 2 +- .../base/icons/icons/microsoft/index.scss | 2 +- .../base/icons/icons/microsoft/keyframes.scss | 2 +- .../icons/icons/microsoft/placeholders.scss | 2 +- .../icons/icons/microsoft/property-16.scss | 2 +- .../icons/icons/microsoft/property-24.scss | 2 +- .../base/icons/icons/migrate/index.scss | 2 +- .../base/icons/icons/migrate/keyframes.scss | 2 +- .../icons/icons/migrate/placeholders.scss | 2 +- .../base/icons/icons/migrate/property-16.scss | 2 +- .../base/icons/icons/migrate/property-24.scss | 2 +- .../base/icons/icons/minimize-alt/index.scss | 2 +- .../icons/icons/minimize-alt/keyframes.scss | 2 +- .../icons/minimize-alt/placeholders.scss | 2 +- .../icons/icons/minimize-alt/property-16.scss | 2 +- .../icons/icons/minimize-alt/property-24.scss | 2 +- .../base/icons/icons/minimize/index.scss | 2 +- .../base/icons/icons/minimize/keyframes.scss | 2 +- .../icons/icons/minimize/placeholders.scss | 2 +- .../icons/icons/minimize/property-16.scss | 2 +- .../icons/icons/minimize/property-24.scss | 2 +- .../icons/icons/minus-circle-fill/index.scss | 2 +- .../icons/minus-circle-fill/keyframes.scss | 2 +- .../icons/minus-circle-fill/placeholders.scss | 2 +- .../icons/minus-circle-outline/index.scss | 2 +- .../icons/minus-circle-outline/keyframes.scss | 2 +- .../minus-circle-outline/placeholders.scss | 2 +- .../base/icons/icons/minus-circle/index.scss | 2 +- .../icons/icons/minus-circle/keyframes.scss | 2 +- .../icons/minus-circle/placeholders.scss | 2 +- .../icons/icons/minus-circle/property-16.scss | 2 +- .../icons/icons/minus-circle/property-24.scss | 2 +- .../base/icons/icons/minus-plain/index.scss | 2 +- .../icons/icons/minus-plain/keyframes.scss | 2 +- .../icons/icons/minus-plain/placeholders.scss | 2 +- .../icons/icons/minus-plus-circle/index.scss | 2 +- .../icons/minus-plus-circle/keyframes.scss | 2 +- .../icons/minus-plus-circle/placeholders.scss | 2 +- .../icons/minus-plus-circle/property-16.scss | 2 +- .../icons/minus-plus-circle/property-24.scss | 2 +- .../icons/icons/minus-plus-square/index.scss | 2 +- .../icons/minus-plus-square/keyframes.scss | 2 +- .../icons/minus-plus-square/placeholders.scss | 2 +- .../icons/minus-plus-square/property-16.scss | 2 +- .../icons/minus-plus-square/property-24.scss | 2 +- .../base/icons/icons/minus-plus/index.scss | 2 +- .../icons/icons/minus-plus/keyframes.scss | 2 +- .../icons/icons/minus-plus/placeholders.scss | 2 +- .../icons/icons/minus-plus/property-16.scss | 2 +- .../icons/icons/minus-plus/property-24.scss | 2 +- .../icons/icons/minus-square-fill/index.scss | 2 +- .../icons/minus-square-fill/keyframes.scss | 2 +- .../icons/minus-square-fill/placeholders.scss | 2 +- .../base/icons/icons/minus-square/index.scss | 2 +- .../icons/icons/minus-square/keyframes.scss | 2 +- .../icons/minus-square/placeholders.scss | 2 +- .../icons/icons/minus-square/property-16.scss | 2 +- .../icons/icons/minus-square/property-24.scss | 2 +- .../styles/base/icons/icons/minus/index.scss | 2 +- .../base/icons/icons/minus/keyframes.scss | 2 +- .../base/icons/icons/minus/placeholders.scss | 2 +- .../base/icons/icons/minus/property-16.scss | 2 +- .../base/icons/icons/minus/property-24.scss | 2 +- .../styles/base/icons/icons/module/index.scss | 2 +- .../base/icons/icons/module/keyframes.scss | 2 +- .../base/icons/icons/module/placeholders.scss | 2 +- .../base/icons/icons/module/property-16.scss | 2 +- .../base/icons/icons/module/property-24.scss | 2 +- .../base/icons/icons/monitor/index.scss | 2 +- .../base/icons/icons/monitor/keyframes.scss | 2 +- .../icons/icons/monitor/placeholders.scss | 2 +- .../base/icons/icons/monitor/property-16.scss | 2 +- .../base/icons/icons/monitor/property-24.scss | 2 +- .../styles/base/icons/icons/moon/index.scss | 2 +- .../base/icons/icons/moon/keyframes.scss | 2 +- .../base/icons/icons/moon/placeholders.scss | 2 +- .../base/icons/icons/moon/property-16.scss | 2 +- .../base/icons/icons/moon/property-24.scss | 2 +- .../icons/icons/more-horizontal/index.scss | 2 +- .../icons/more-horizontal/keyframes.scss | 2 +- .../icons/more-horizontal/placeholders.scss | 2 +- .../icons/more-horizontal/property-16.scss | 2 +- .../icons/more-horizontal/property-24.scss | 2 +- .../base/icons/icons/more-vertical/index.scss | 2 +- .../icons/icons/more-vertical/keyframes.scss | 2 +- .../icons/more-vertical/placeholders.scss | 2 +- .../icons/more-vertical/property-16.scss | 2 +- .../icons/more-vertical/property-24.scss | 2 +- .../base/icons/icons/mouse-pointer/index.scss | 2 +- .../icons/icons/mouse-pointer/keyframes.scss | 2 +- .../icons/mouse-pointer/placeholders.scss | 2 +- .../icons/mouse-pointer/property-16.scss | 2 +- .../icons/mouse-pointer/property-24.scss | 2 +- .../styles/base/icons/icons/move/index.scss | 2 +- .../base/icons/icons/move/keyframes.scss | 2 +- .../base/icons/icons/move/placeholders.scss | 2 +- .../base/icons/icons/move/property-16.scss | 2 +- .../base/icons/icons/move/property-24.scss | 2 +- .../styles/base/icons/icons/music/index.scss | 2 +- .../base/icons/icons/music/keyframes.scss | 2 +- .../base/icons/icons/music/placeholders.scss | 2 +- .../base/icons/icons/music/property-16.scss | 2 +- .../base/icons/icons/music/property-24.scss | 2 +- .../icons/icons/navigation-alt/index.scss | 2 +- .../icons/icons/navigation-alt/keyframes.scss | 2 +- .../icons/navigation-alt/placeholders.scss | 2 +- .../icons/navigation-alt/property-16.scss | 2 +- .../icons/navigation-alt/property-24.scss | 2 +- .../base/icons/icons/navigation/index.scss | 2 +- .../icons/icons/navigation/keyframes.scss | 2 +- .../icons/icons/navigation/placeholders.scss | 2 +- .../icons/icons/navigation/property-16.scss | 2 +- .../icons/icons/navigation/property-24.scss | 2 +- .../base/icons/icons/network-alt/index.scss | 2 +- .../icons/icons/network-alt/keyframes.scss | 2 +- .../icons/icons/network-alt/placeholders.scss | 2 +- .../icons/icons/network-alt/property-16.scss | 2 +- .../icons/icons/network-alt/property-24.scss | 2 +- .../base/icons/icons/network/index.scss | 2 +- .../base/icons/icons/network/keyframes.scss | 2 +- .../icons/icons/network/placeholders.scss | 2 +- .../base/icons/icons/network/property-16.scss | 2 +- .../base/icons/icons/network/property-24.scss | 2 +- .../base/icons/icons/newspaper/index.scss | 2 +- .../base/icons/icons/newspaper/keyframes.scss | 2 +- .../icons/icons/newspaper/placeholders.scss | 2 +- .../icons/icons/newspaper/property-16.scss | 2 +- .../icons/icons/newspaper/property-24.scss | 2 +- .../styles/base/icons/icons/node/index.scss | 2 +- .../base/icons/icons/node/keyframes.scss | 2 +- .../base/icons/icons/node/placeholders.scss | 2 +- .../base/icons/icons/node/property-16.scss | 2 +- .../base/icons/icons/node/property-24.scss | 2 +- .../base/icons/icons/nomad-color/index.scss | 2 +- .../icons/icons/nomad-color/keyframes.scss | 2 +- .../icons/icons/nomad-color/placeholders.scss | 2 +- .../icons/icons/nomad-color/property-16.scss | 2 +- .../icons/icons/nomad-color/property-24.scss | 2 +- .../styles/base/icons/icons/nomad/index.scss | 2 +- .../base/icons/icons/nomad/keyframes.scss | 2 +- .../base/icons/icons/nomad/placeholders.scss | 2 +- .../base/icons/icons/nomad/property-16.scss | 2 +- .../base/icons/icons/nomad/property-24.scss | 2 +- .../icons/notification-disabled/index.scss | 2 +- .../notification-disabled/keyframes.scss | 2 +- .../notification-disabled/placeholders.scss | 2 +- .../icons/icons/notification-fill/index.scss | 2 +- .../icons/notification-fill/keyframes.scss | 2 +- .../icons/notification-fill/placeholders.scss | 2 +- .../icons/notification-outline/index.scss | 2 +- .../icons/notification-outline/keyframes.scss | 2 +- .../notification-outline/placeholders.scss | 2 +- .../base/icons/icons/octagon/index.scss | 2 +- .../base/icons/icons/octagon/keyframes.scss | 2 +- .../icons/icons/octagon/placeholders.scss | 2 +- .../base/icons/icons/octagon/property-16.scss | 2 +- .../base/icons/icons/octagon/property-24.scss | 2 +- .../base/icons/icons/okta-color/index.scss | 2 +- .../icons/icons/okta-color/keyframes.scss | 2 +- .../icons/icons/okta-color/placeholders.scss | 2 +- .../icons/icons/okta-color/property-16.scss | 2 +- .../icons/icons/okta-color/property-24.scss | 2 +- .../styles/base/icons/icons/okta/index.scss | 2 +- .../base/icons/icons/okta/keyframes.scss | 2 +- .../base/icons/icons/okta/placeholders.scss | 2 +- .../base/icons/icons/okta/property-16.scss | 2 +- .../base/icons/icons/okta/property-24.scss | 2 +- .../base/icons/icons/oracle-color/index.scss | 2 +- .../icons/icons/oracle-color/keyframes.scss | 2 +- .../icons/oracle-color/placeholders.scss | 2 +- .../icons/icons/oracle-color/property-16.scss | 2 +- .../icons/icons/oracle-color/property-24.scss | 2 +- .../styles/base/icons/icons/oracle/index.scss | 2 +- .../base/icons/icons/oracle/keyframes.scss | 2 +- .../base/icons/icons/oracle/placeholders.scss | 2 +- .../base/icons/icons/oracle/property-16.scss | 2 +- .../base/icons/icons/oracle/property-24.scss | 2 +- .../styles/base/icons/icons/org/index.scss | 2 +- .../base/icons/icons/org/keyframes.scss | 2 +- .../base/icons/icons/org/placeholders.scss | 2 +- .../base/icons/icons/org/property-16.scss | 2 +- .../base/icons/icons/org/property-24.scss | 2 +- .../base/icons/icons/outline/index.scss | 2 +- .../base/icons/icons/outline/keyframes.scss | 2 +- .../icons/icons/outline/placeholders.scss | 2 +- .../base/icons/icons/outline/property-16.scss | 2 +- .../base/icons/icons/outline/property-24.scss | 2 +- .../base/icons/icons/pack-color/index.scss | 2 +- .../icons/icons/pack-color/keyframes.scss | 2 +- .../icons/icons/pack-color/placeholders.scss | 2 +- .../icons/icons/pack-color/property-16.scss | 2 +- .../icons/icons/pack-color/property-24.scss | 2 +- .../styles/base/icons/icons/pack/index.scss | 2 +- .../base/icons/icons/pack/keyframes.scss | 2 +- .../base/icons/icons/pack/placeholders.scss | 2 +- .../base/icons/icons/pack/property-16.scss | 2 +- .../base/icons/icons/pack/property-24.scss | 2 +- .../base/icons/icons/package/index.scss | 2 +- .../base/icons/icons/package/keyframes.scss | 2 +- .../icons/icons/package/placeholders.scss | 2 +- .../base/icons/icons/package/property-16.scss | 2 +- .../base/icons/icons/package/property-24.scss | 2 +- .../base/icons/icons/packer-color/index.scss | 2 +- .../icons/icons/packer-color/keyframes.scss | 2 +- .../icons/packer-color/placeholders.scss | 2 +- .../icons/icons/packer-color/property-16.scss | 2 +- .../icons/icons/packer-color/property-24.scss | 2 +- .../styles/base/icons/icons/packer/index.scss | 2 +- .../base/icons/icons/packer/keyframes.scss | 2 +- .../base/icons/icons/packer/placeholders.scss | 2 +- .../base/icons/icons/packer/property-16.scss | 2 +- .../base/icons/icons/packer/property-24.scss | 2 +- .../base/icons/icons/page-outline/index.scss | 2 +- .../icons/icons/page-outline/keyframes.scss | 2 +- .../icons/page-outline/placeholders.scss | 2 +- .../base/icons/icons/paperclip/index.scss | 2 +- .../base/icons/icons/paperclip/keyframes.scss | 2 +- .../icons/icons/paperclip/placeholders.scss | 2 +- .../icons/icons/paperclip/property-16.scss | 2 +- .../icons/icons/paperclip/property-24.scss | 2 +- .../base/icons/icons/partner/index.scss | 2 +- .../base/icons/icons/partner/keyframes.scss | 2 +- .../icons/icons/partner/placeholders.scss | 2 +- .../styles/base/icons/icons/path/index.scss | 2 +- .../base/icons/icons/path/keyframes.scss | 2 +- .../base/icons/icons/path/placeholders.scss | 2 +- .../base/icons/icons/path/property-16.scss | 2 +- .../base/icons/icons/path/property-24.scss | 2 +- .../base/icons/icons/pause-circle/index.scss | 2 +- .../icons/icons/pause-circle/keyframes.scss | 2 +- .../icons/pause-circle/placeholders.scss | 2 +- .../icons/icons/pause-circle/property-16.scss | 2 +- .../icons/icons/pause-circle/property-24.scss | 2 +- .../styles/base/icons/icons/pause/index.scss | 2 +- .../base/icons/icons/pause/keyframes.scss | 2 +- .../base/icons/icons/pause/placeholders.scss | 2 +- .../base/icons/icons/pause/property-16.scss | 2 +- .../base/icons/icons/pause/property-24.scss | 2 +- .../base/icons/icons/pen-tool/index.scss | 2 +- .../base/icons/icons/pen-tool/keyframes.scss | 2 +- .../icons/icons/pen-tool/placeholders.scss | 2 +- .../icons/icons/pen-tool/property-16.scss | 2 +- .../icons/icons/pen-tool/property-24.scss | 2 +- .../base/icons/icons/pencil-tool/index.scss | 2 +- .../icons/icons/pencil-tool/keyframes.scss | 2 +- .../icons/icons/pencil-tool/placeholders.scss | 2 +- .../icons/icons/pencil-tool/property-16.scss | 2 +- .../icons/icons/pencil-tool/property-24.scss | 2 +- .../base/icons/icons/phone-call/index.scss | 2 +- .../icons/icons/phone-call/keyframes.scss | 2 +- .../icons/icons/phone-call/placeholders.scss | 2 +- .../icons/icons/phone-call/property-16.scss | 2 +- .../icons/icons/phone-call/property-24.scss | 2 +- .../base/icons/icons/phone-off/index.scss | 2 +- .../base/icons/icons/phone-off/keyframes.scss | 2 +- .../icons/icons/phone-off/placeholders.scss | 2 +- .../icons/icons/phone-off/property-16.scss | 2 +- .../icons/icons/phone-off/property-24.scss | 2 +- .../styles/base/icons/icons/phone/index.scss | 2 +- .../base/icons/icons/phone/keyframes.scss | 2 +- .../base/icons/icons/phone/placeholders.scss | 2 +- .../base/icons/icons/phone/property-16.scss | 2 +- .../base/icons/icons/phone/property-24.scss | 2 +- .../base/icons/icons/pie-chart/index.scss | 2 +- .../base/icons/icons/pie-chart/keyframes.scss | 2 +- .../icons/icons/pie-chart/placeholders.scss | 2 +- .../icons/icons/pie-chart/property-16.scss | 2 +- .../icons/icons/pie-chart/property-24.scss | 2 +- .../styles/base/icons/icons/pin/index.scss | 2 +- .../base/icons/icons/pin/keyframes.scss | 2 +- .../base/icons/icons/pin/placeholders.scss | 2 +- .../base/icons/icons/pin/property-16.scss | 2 +- .../base/icons/icons/pin/property-24.scss | 2 +- .../base/icons/icons/play-circle/index.scss | 2 +- .../icons/icons/play-circle/keyframes.scss | 2 +- .../icons/icons/play-circle/placeholders.scss | 2 +- .../icons/icons/play-circle/property-16.scss | 2 +- .../icons/icons/play-circle/property-24.scss | 2 +- .../base/icons/icons/play-fill/index.scss | 2 +- .../base/icons/icons/play-fill/keyframes.scss | 2 +- .../icons/icons/play-fill/placeholders.scss | 2 +- .../base/icons/icons/play-outline/index.scss | 2 +- .../icons/icons/play-outline/keyframes.scss | 2 +- .../icons/play-outline/placeholders.scss | 2 +- .../base/icons/icons/play-plain/index.scss | 2 +- .../icons/icons/play-plain/keyframes.scss | 2 +- .../icons/icons/play-plain/placeholders.scss | 2 +- .../styles/base/icons/icons/play/index.scss | 2 +- .../base/icons/icons/play/keyframes.scss | 2 +- .../base/icons/icons/play/placeholders.scss | 2 +- .../base/icons/icons/play/property-16.scss | 2 +- .../base/icons/icons/play/property-24.scss | 2 +- .../icons/icons/plus-circle-fill/index.scss | 2 +- .../icons/plus-circle-fill/keyframes.scss | 2 +- .../icons/plus-circle-fill/placeholders.scss | 2 +- .../icons/plus-circle-outline/index.scss | 2 +- .../icons/plus-circle-outline/keyframes.scss | 2 +- .../plus-circle-outline/placeholders.scss | 2 +- .../base/icons/icons/plus-circle/index.scss | 2 +- .../icons/icons/plus-circle/keyframes.scss | 2 +- .../icons/icons/plus-circle/placeholders.scss | 2 +- .../icons/icons/plus-circle/property-16.scss | 2 +- .../icons/icons/plus-circle/property-24.scss | 2 +- .../base/icons/icons/plus-plain/index.scss | 2 +- .../icons/icons/plus-plain/keyframes.scss | 2 +- .../icons/icons/plus-plain/placeholders.scss | 2 +- .../icons/icons/plus-square-fill/index.scss | 2 +- .../icons/plus-square-fill/keyframes.scss | 2 +- .../icons/plus-square-fill/placeholders.scss | 2 +- .../base/icons/icons/plus-square/index.scss | 2 +- .../icons/icons/plus-square/keyframes.scss | 2 +- .../icons/icons/plus-square/placeholders.scss | 2 +- .../icons/icons/plus-square/property-16.scss | 2 +- .../icons/icons/plus-square/property-24.scss | 2 +- .../styles/base/icons/icons/plus/index.scss | 2 +- .../base/icons/icons/plus/keyframes.scss | 2 +- .../base/icons/icons/plus/placeholders.scss | 2 +- .../base/icons/icons/plus/property-16.scss | 2 +- .../base/icons/icons/plus/property-24.scss | 2 +- .../styles/base/icons/icons/port/index.scss | 2 +- .../base/icons/icons/port/keyframes.scss | 2 +- .../base/icons/icons/port/placeholders.scss | 2 +- .../base/icons/icons/port/property-16.scss | 2 +- .../base/icons/icons/port/property-24.scss | 2 +- .../styles/base/icons/icons/power/index.scss | 2 +- .../base/icons/icons/power/keyframes.scss | 2 +- .../base/icons/icons/power/placeholders.scss | 2 +- .../base/icons/icons/power/property-16.scss | 2 +- .../base/icons/icons/power/property-24.scss | 2 +- .../base/icons/icons/printer/index.scss | 2 +- .../base/icons/icons/printer/keyframes.scss | 2 +- .../icons/icons/printer/placeholders.scss | 2 +- .../base/icons/icons/printer/property-16.scss | 2 +- .../base/icons/icons/printer/property-24.scss | 2 +- .../base/icons/icons/protocol/index.scss | 2 +- .../base/icons/icons/protocol/keyframes.scss | 2 +- .../icons/icons/protocol/placeholders.scss | 2 +- .../icons/icons/protocol/property-16.scss | 2 +- .../icons/icons/protocol/property-24.scss | 2 +- .../base/icons/icons/provider/index.scss | 2 +- .../base/icons/icons/provider/keyframes.scss | 2 +- .../icons/icons/provider/placeholders.scss | 2 +- .../icons/icons/provider/property-16.scss | 2 +- .../icons/icons/provider/property-24.scss | 2 +- .../icons/icons/public-default/index.scss | 2 +- .../icons/icons/public-default/keyframes.scss | 2 +- .../icons/public-default/placeholders.scss | 2 +- .../base/icons/icons/public-locked/index.scss | 2 +- .../icons/icons/public-locked/keyframes.scss | 2 +- .../icons/public-locked/placeholders.scss | 2 +- .../styles/base/icons/icons/queue/index.scss | 2 +- .../base/icons/icons/queue/keyframes.scss | 2 +- .../base/icons/icons/queue/placeholders.scss | 2 +- .../base/icons/icons/queue/property-16.scss | 2 +- .../base/icons/icons/queue/property-24.scss | 2 +- .../icons/radio-button-checked/index.scss | 2 +- .../icons/radio-button-checked/keyframes.scss | 2 +- .../radio-button-checked/placeholders.scss | 2 +- .../icons/radio-button-unchecked/index.scss | 2 +- .../radio-button-unchecked/keyframes.scss | 2 +- .../radio-button-unchecked/placeholders.scss | 2 +- .../styles/base/icons/icons/radio/index.scss | 2 +- .../base/icons/icons/radio/keyframes.scss | 2 +- .../base/icons/icons/radio/placeholders.scss | 2 +- .../base/icons/icons/radio/property-16.scss | 2 +- .../base/icons/icons/radio/property-24.scss | 2 +- .../styles/base/icons/icons/random/index.scss | 2 +- .../base/icons/icons/random/keyframes.scss | 2 +- .../base/icons/icons/random/placeholders.scss | 2 +- .../base/icons/icons/random/property-16.scss | 2 +- .../base/icons/icons/random/property-24.scss | 2 +- .../base/icons/icons/redirect/index.scss | 2 +- .../base/icons/icons/redirect/keyframes.scss | 2 +- .../icons/icons/redirect/placeholders.scss | 2 +- .../icons/icons/redirect/property-16.scss | 2 +- .../icons/icons/redirect/property-24.scss | 2 +- .../base/icons/icons/refresh-alert/index.scss | 2 +- .../icons/icons/refresh-alert/keyframes.scss | 2 +- .../icons/refresh-alert/placeholders.scss | 2 +- .../icons/icons/refresh-default/index.scss | 2 +- .../icons/refresh-default/keyframes.scss | 2 +- .../icons/refresh-default/placeholders.scss | 2 +- .../styles/base/icons/icons/reload/index.scss | 2 +- .../base/icons/icons/reload/keyframes.scss | 2 +- .../base/icons/icons/reload/placeholders.scss | 2 +- .../base/icons/icons/reload/property-16.scss | 2 +- .../base/icons/icons/reload/property-24.scss | 2 +- .../styles/base/icons/icons/remix/index.scss | 2 +- .../base/icons/icons/remix/keyframes.scss | 2 +- .../base/icons/icons/remix/placeholders.scss | 2 +- .../styles/base/icons/icons/repeat/index.scss | 2 +- .../base/icons/icons/repeat/keyframes.scss | 2 +- .../base/icons/icons/repeat/placeholders.scss | 2 +- .../base/icons/icons/repeat/property-16.scss | 2 +- .../base/icons/icons/repeat/property-24.scss | 2 +- .../icons/icons/replication-direct/index.scss | 2 +- .../icons/replication-direct/keyframes.scss | 2 +- .../replication-direct/placeholders.scss | 2 +- .../icons/replication-direct/property-16.scss | 2 +- .../icons/replication-direct/property-24.scss | 2 +- .../icons/icons/replication-perf/index.scss | 2 +- .../icons/replication-perf/keyframes.scss | 2 +- .../icons/replication-perf/placeholders.scss | 2 +- .../icons/replication-perf/property-16.scss | 2 +- .../icons/replication-perf/property-24.scss | 2 +- .../styles/base/icons/icons/rewind/index.scss | 2 +- .../base/icons/icons/rewind/keyframes.scss | 2 +- .../base/icons/icons/rewind/placeholders.scss | 2 +- .../base/icons/icons/rewind/property-16.scss | 2 +- .../base/icons/icons/rewind/property-24.scss | 2 +- .../styles/base/icons/icons/ribbon/index.scss | 2 +- .../base/icons/icons/ribbon/keyframes.scss | 2 +- .../base/icons/icons/ribbon/placeholders.scss | 2 +- .../styles/base/icons/icons/rocket/index.scss | 2 +- .../base/icons/icons/rocket/keyframes.scss | 2 +- .../base/icons/icons/rocket/placeholders.scss | 2 +- .../base/icons/icons/rocket/property-16.scss | 2 +- .../base/icons/icons/rocket/property-24.scss | 2 +- .../base/icons/icons/rotate-ccw/index.scss | 2 +- .../icons/icons/rotate-ccw/keyframes.scss | 2 +- .../icons/icons/rotate-ccw/placeholders.scss | 2 +- .../icons/icons/rotate-ccw/property-16.scss | 2 +- .../icons/icons/rotate-ccw/property-24.scss | 2 +- .../base/icons/icons/rotate-cw/index.scss | 2 +- .../base/icons/icons/rotate-cw/keyframes.scss | 2 +- .../icons/icons/rotate-cw/placeholders.scss | 2 +- .../icons/icons/rotate-cw/property-16.scss | 2 +- .../icons/icons/rotate-cw/property-24.scss | 2 +- .../styles/base/icons/icons/rss/index.scss | 2 +- .../base/icons/icons/rss/keyframes.scss | 2 +- .../base/icons/icons/rss/placeholders.scss | 2 +- .../base/icons/icons/rss/property-16.scss | 2 +- .../base/icons/icons/rss/property-24.scss | 2 +- .../styles/base/icons/icons/run/index.scss | 2 +- .../base/icons/icons/run/keyframes.scss | 2 +- .../base/icons/icons/run/placeholders.scss | 2 +- .../base/icons/icons/run/property-16.scss | 2 +- .../base/icons/icons/run/property-24.scss | 2 +- .../base/icons/icons/running/index.scss | 2 +- .../base/icons/icons/running/keyframes.scss | 2 +- .../icons/icons/running/placeholders.scss | 2 +- .../base/icons/icons/running/property-16.scss | 2 +- .../base/icons/icons/running/property-24.scss | 2 +- .../styles/base/icons/icons/save/index.scss | 2 +- .../base/icons/icons/save/keyframes.scss | 2 +- .../base/icons/icons/save/placeholders.scss | 2 +- .../base/icons/icons/save/property-16.scss | 2 +- .../base/icons/icons/save/property-24.scss | 2 +- .../base/icons/icons/scissors/index.scss | 2 +- .../base/icons/icons/scissors/keyframes.scss | 2 +- .../icons/icons/scissors/placeholders.scss | 2 +- .../icons/icons/scissors/property-16.scss | 2 +- .../icons/icons/scissors/property-24.scss | 2 +- .../base/icons/icons/search-color/index.scss | 2 +- .../icons/icons/search-color/keyframes.scss | 2 +- .../icons/search-color/placeholders.scss | 2 +- .../icons/icons/search-color/property-16.scss | 2 +- .../icons/icons/search-color/property-24.scss | 2 +- .../styles/base/icons/icons/search/index.scss | 2 +- .../base/icons/icons/search/keyframes.scss | 2 +- .../base/icons/icons/search/placeholders.scss | 2 +- .../base/icons/icons/search/property-16.scss | 2 +- .../base/icons/icons/search/property-24.scss | 2 +- .../styles/base/icons/icons/send/index.scss | 2 +- .../base/icons/icons/send/keyframes.scss | 2 +- .../base/icons/icons/send/placeholders.scss | 2 +- .../base/icons/icons/send/property-16.scss | 2 +- .../base/icons/icons/send/property-24.scss | 2 +- .../icons/icons/server-cluster/index.scss | 2 +- .../icons/icons/server-cluster/keyframes.scss | 2 +- .../icons/server-cluster/placeholders.scss | 2 +- .../icons/server-cluster/property-16.scss | 2 +- .../icons/server-cluster/property-24.scss | 2 +- .../styles/base/icons/icons/server/index.scss | 2 +- .../base/icons/icons/server/keyframes.scss | 2 +- .../base/icons/icons/server/placeholders.scss | 2 +- .../base/icons/icons/server/property-16.scss | 2 +- .../base/icons/icons/server/property-24.scss | 2 +- .../base/icons/icons/serverless/index.scss | 2 +- .../icons/icons/serverless/keyframes.scss | 2 +- .../icons/icons/serverless/placeholders.scss | 2 +- .../icons/icons/serverless/property-16.scss | 2 +- .../icons/icons/serverless/property-24.scss | 2 +- .../base/icons/icons/settings/index.scss | 2 +- .../base/icons/icons/settings/keyframes.scss | 2 +- .../icons/icons/settings/placeholders.scss | 2 +- .../icons/icons/settings/property-16.scss | 2 +- .../icons/icons/settings/property-24.scss | 2 +- .../styles/base/icons/icons/share/index.scss | 2 +- .../base/icons/icons/share/keyframes.scss | 2 +- .../base/icons/icons/share/placeholders.scss | 2 +- .../base/icons/icons/share/property-16.scss | 2 +- .../base/icons/icons/share/property-24.scss | 2 +- .../base/icons/icons/shield-alert/index.scss | 2 +- .../icons/icons/shield-alert/keyframes.scss | 2 +- .../icons/shield-alert/placeholders.scss | 2 +- .../icons/icons/shield-alert/property-16.scss | 2 +- .../icons/icons/shield-alert/property-24.scss | 2 +- .../base/icons/icons/shield-check/index.scss | 2 +- .../icons/icons/shield-check/keyframes.scss | 2 +- .../icons/shield-check/placeholders.scss | 2 +- .../icons/icons/shield-check/property-16.scss | 2 +- .../icons/icons/shield-check/property-24.scss | 2 +- .../base/icons/icons/shield-off/index.scss | 2 +- .../icons/icons/shield-off/keyframes.scss | 2 +- .../icons/icons/shield-off/placeholders.scss | 2 +- .../icons/icons/shield-off/property-16.scss | 2 +- .../icons/icons/shield-off/property-24.scss | 2 +- .../base/icons/icons/shield-x/index.scss | 2 +- .../base/icons/icons/shield-x/keyframes.scss | 2 +- .../icons/icons/shield-x/placeholders.scss | 2 +- .../icons/icons/shield-x/property-16.scss | 2 +- .../icons/icons/shield-x/property-24.scss | 2 +- .../styles/base/icons/icons/shield/index.scss | 2 +- .../base/icons/icons/shield/keyframes.scss | 2 +- .../base/icons/icons/shield/placeholders.scss | 2 +- .../base/icons/icons/shield/property-16.scss | 2 +- .../base/icons/icons/shield/property-24.scss | 2 +- .../base/icons/icons/shopping-bag/index.scss | 2 +- .../icons/icons/shopping-bag/keyframes.scss | 2 +- .../icons/shopping-bag/placeholders.scss | 2 +- .../icons/icons/shopping-bag/property-16.scss | 2 +- .../icons/icons/shopping-bag/property-24.scss | 2 +- .../base/icons/icons/shopping-cart/index.scss | 2 +- .../icons/icons/shopping-cart/keyframes.scss | 2 +- .../icons/shopping-cart/placeholders.scss | 2 +- .../icons/shopping-cart/property-16.scss | 2 +- .../icons/shopping-cart/property-24.scss | 2 +- .../base/icons/icons/shuffle/index.scss | 2 +- .../base/icons/icons/shuffle/keyframes.scss | 2 +- .../icons/icons/shuffle/placeholders.scss | 2 +- .../base/icons/icons/shuffle/property-16.scss | 2 +- .../base/icons/icons/shuffle/property-24.scss | 2 +- .../base/icons/icons/sidebar-hide/index.scss | 2 +- .../icons/icons/sidebar-hide/keyframes.scss | 2 +- .../icons/sidebar-hide/placeholders.scss | 2 +- .../icons/icons/sidebar-hide/property-16.scss | 2 +- .../icons/icons/sidebar-hide/property-24.scss | 2 +- .../base/icons/icons/sidebar-show/index.scss | 2 +- .../icons/icons/sidebar-show/keyframes.scss | 2 +- .../icons/sidebar-show/placeholders.scss | 2 +- .../icons/icons/sidebar-show/property-16.scss | 2 +- .../icons/icons/sidebar-show/property-24.scss | 2 +- .../base/icons/icons/sidebar/index.scss | 2 +- .../base/icons/icons/sidebar/keyframes.scss | 2 +- .../icons/icons/sidebar/placeholders.scss | 2 +- .../base/icons/icons/sidebar/property-16.scss | 2 +- .../base/icons/icons/sidebar/property-24.scss | 2 +- .../base/icons/icons/sign-in/index.scss | 2 +- .../base/icons/icons/sign-in/keyframes.scss | 2 +- .../icons/icons/sign-in/placeholders.scss | 2 +- .../base/icons/icons/sign-in/property-16.scss | 2 +- .../base/icons/icons/sign-in/property-24.scss | 2 +- .../base/icons/icons/sign-out/index.scss | 2 +- .../base/icons/icons/sign-out/keyframes.scss | 2 +- .../icons/icons/sign-out/placeholders.scss | 2 +- .../icons/icons/sign-out/property-16.scss | 2 +- .../icons/icons/sign-out/property-24.scss | 2 +- .../base/icons/icons/skip-back/index.scss | 2 +- .../base/icons/icons/skip-back/keyframes.scss | 2 +- .../icons/icons/skip-back/placeholders.scss | 2 +- .../icons/icons/skip-back/property-16.scss | 2 +- .../icons/icons/skip-back/property-24.scss | 2 +- .../base/icons/icons/skip-forward/index.scss | 2 +- .../icons/icons/skip-forward/keyframes.scss | 2 +- .../icons/skip-forward/placeholders.scss | 2 +- .../icons/icons/skip-forward/property-16.scss | 2 +- .../icons/icons/skip-forward/property-24.scss | 2 +- .../styles/base/icons/icons/skip/index.scss | 2 +- .../base/icons/icons/skip/keyframes.scss | 2 +- .../base/icons/icons/skip/placeholders.scss | 2 +- .../base/icons/icons/skip/property-16.scss | 2 +- .../base/icons/icons/skip/property-24.scss | 2 +- .../base/icons/icons/slack-color/index.scss | 2 +- .../icons/icons/slack-color/keyframes.scss | 2 +- .../icons/icons/slack-color/placeholders.scss | 2 +- .../icons/icons/slack-color/property-16.scss | 2 +- .../icons/icons/slack-color/property-24.scss | 2 +- .../styles/base/icons/icons/slack/index.scss | 2 +- .../base/icons/icons/slack/keyframes.scss | 2 +- .../base/icons/icons/slack/placeholders.scss | 2 +- .../base/icons/icons/slack/property-16.scss | 2 +- .../base/icons/icons/slack/property-24.scss | 2 +- .../base/icons/icons/slash-square/index.scss | 2 +- .../icons/icons/slash-square/keyframes.scss | 2 +- .../icons/slash-square/placeholders.scss | 2 +- .../icons/icons/slash-square/property-16.scss | 2 +- .../icons/icons/slash-square/property-24.scss | 2 +- .../styles/base/icons/icons/slash/index.scss | 2 +- .../base/icons/icons/slash/keyframes.scss | 2 +- .../base/icons/icons/slash/placeholders.scss | 2 +- .../base/icons/icons/slash/property-16.scss | 2 +- .../base/icons/icons/slash/property-24.scss | 2 +- .../base/icons/icons/sliders/index.scss | 2 +- .../base/icons/icons/sliders/keyframes.scss | 2 +- .../icons/icons/sliders/placeholders.scss | 2 +- .../base/icons/icons/sliders/property-16.scss | 2 +- .../base/icons/icons/sliders/property-24.scss | 2 +- .../base/icons/icons/smartphone/index.scss | 2 +- .../icons/icons/smartphone/keyframes.scss | 2 +- .../icons/icons/smartphone/placeholders.scss | 2 +- .../icons/icons/smartphone/property-16.scss | 2 +- .../icons/icons/smartphone/property-24.scss | 2 +- .../styles/base/icons/icons/smile/index.scss | 2 +- .../base/icons/icons/smile/keyframes.scss | 2 +- .../base/icons/icons/smile/placeholders.scss | 2 +- .../base/icons/icons/smile/property-16.scss | 2 +- .../base/icons/icons/smile/property-24.scss | 2 +- .../styles/base/icons/icons/socket/index.scss | 2 +- .../base/icons/icons/socket/keyframes.scss | 2 +- .../base/icons/icons/socket/placeholders.scss | 2 +- .../base/icons/icons/socket/property-16.scss | 2 +- .../base/icons/icons/socket/property-24.scss | 2 +- .../base/icons/icons/sort-asc/index.scss | 2 +- .../base/icons/icons/sort-asc/keyframes.scss | 2 +- .../icons/icons/sort-asc/placeholders.scss | 2 +- .../icons/icons/sort-asc/property-16.scss | 2 +- .../icons/icons/sort-asc/property-24.scss | 2 +- .../base/icons/icons/sort-desc/index.scss | 2 +- .../base/icons/icons/sort-desc/keyframes.scss | 2 +- .../icons/icons/sort-desc/placeholders.scss | 2 +- .../icons/icons/sort-desc/property-16.scss | 2 +- .../icons/icons/sort-desc/property-24.scss | 2 +- .../styles/base/icons/icons/sort/index.scss | 2 +- .../base/icons/icons/sort/keyframes.scss | 2 +- .../base/icons/icons/sort/placeholders.scss | 2 +- .../base/icons/icons/source-file/index.scss | 2 +- .../icons/icons/source-file/keyframes.scss | 2 +- .../icons/icons/source-file/placeholders.scss | 2 +- .../base/icons/icons/speaker/index.scss | 2 +- .../base/icons/icons/speaker/keyframes.scss | 2 +- .../icons/icons/speaker/placeholders.scss | 2 +- .../base/icons/icons/speaker/property-16.scss | 2 +- .../base/icons/icons/speaker/property-24.scss | 2 +- .../base/icons/icons/square-fill/index.scss | 2 +- .../icons/icons/square-fill/keyframes.scss | 2 +- .../icons/icons/square-fill/placeholders.scss | 2 +- .../icons/icons/square-fill/property-16.scss | 2 +- .../icons/icons/square-fill/property-24.scss | 2 +- .../styles/base/icons/icons/square/index.scss | 2 +- .../base/icons/icons/square/keyframes.scss | 2 +- .../base/icons/icons/square/placeholders.scss | 2 +- .../base/icons/icons/square/property-16.scss | 2 +- .../base/icons/icons/square/property-24.scss | 2 +- .../base/icons/icons/star-circle/index.scss | 2 +- .../icons/icons/star-circle/keyframes.scss | 2 +- .../icons/icons/star-circle/placeholders.scss | 2 +- .../icons/icons/star-circle/property-16.scss | 2 +- .../icons/icons/star-circle/property-24.scss | 2 +- .../base/icons/icons/star-fill/index.scss | 2 +- .../base/icons/icons/star-fill/keyframes.scss | 2 +- .../icons/icons/star-fill/placeholders.scss | 2 +- .../icons/icons/star-fill/property-16.scss | 2 +- .../icons/icons/star-fill/property-24.scss | 2 +- .../base/icons/icons/star-off/index.scss | 2 +- .../base/icons/icons/star-off/keyframes.scss | 2 +- .../icons/icons/star-off/placeholders.scss | 2 +- .../icons/icons/star-off/property-16.scss | 2 +- .../icons/icons/star-off/property-24.scss | 2 +- .../base/icons/icons/star-outline/index.scss | 2 +- .../icons/icons/star-outline/keyframes.scss | 2 +- .../icons/star-outline/placeholders.scss | 2 +- .../styles/base/icons/icons/star/index.scss | 2 +- .../base/icons/icons/star/keyframes.scss | 2 +- .../base/icons/icons/star/placeholders.scss | 2 +- .../base/icons/icons/star/property-16.scss | 2 +- .../base/icons/icons/star/property-24.scss | 2 +- .../base/icons/icons/stop-circle/index.scss | 2 +- .../icons/icons/stop-circle/keyframes.scss | 2 +- .../icons/icons/stop-circle/placeholders.scss | 2 +- .../icons/icons/stop-circle/property-16.scss | 2 +- .../icons/icons/stop-circle/property-24.scss | 2 +- .../base/icons/icons/sub-left/index.scss | 2 +- .../base/icons/icons/sub-left/keyframes.scss | 2 +- .../icons/icons/sub-left/placeholders.scss | 2 +- .../base/icons/icons/sub-right/index.scss | 2 +- .../base/icons/icons/sub-right/keyframes.scss | 2 +- .../icons/icons/sub-right/placeholders.scss | 2 +- .../styles/base/icons/icons/sun/index.scss | 2 +- .../base/icons/icons/sun/keyframes.scss | 2 +- .../base/icons/icons/sun/placeholders.scss | 2 +- .../base/icons/icons/sun/property-16.scss | 2 +- .../base/icons/icons/sun/property-24.scss | 2 +- .../base/icons/icons/support/index.scss | 2 +- .../base/icons/icons/support/keyframes.scss | 2 +- .../icons/icons/support/placeholders.scss | 2 +- .../base/icons/icons/support/property-16.scss | 2 +- .../base/icons/icons/support/property-24.scss | 2 +- .../icons/icons/swap-horizontal/index.scss | 2 +- .../icons/swap-horizontal/keyframes.scss | 2 +- .../icons/swap-horizontal/placeholders.scss | 2 +- .../icons/swap-horizontal/property-16.scss | 2 +- .../icons/swap-horizontal/property-24.scss | 2 +- .../base/icons/icons/swap-vertical/index.scss | 2 +- .../icons/icons/swap-vertical/keyframes.scss | 2 +- .../icons/swap-vertical/placeholders.scss | 2 +- .../icons/swap-vertical/property-16.scss | 2 +- .../icons/swap-vertical/property-24.scss | 2 +- .../base/icons/icons/switcher/index.scss | 2 +- .../base/icons/icons/switcher/keyframes.scss | 2 +- .../icons/icons/switcher/placeholders.scss | 2 +- .../icons/icons/switcher/property-16.scss | 2 +- .../icons/icons/switcher/property-24.scss | 2 +- .../base/icons/icons/sync-alert/index.scss | 2 +- .../icons/icons/sync-alert/keyframes.scss | 2 +- .../icons/icons/sync-alert/placeholders.scss | 2 +- .../icons/icons/sync-alert/property-16.scss | 2 +- .../icons/icons/sync-alert/property-24.scss | 2 +- .../base/icons/icons/sync-reverse/index.scss | 2 +- .../icons/icons/sync-reverse/keyframes.scss | 2 +- .../icons/sync-reverse/placeholders.scss | 2 +- .../icons/icons/sync-reverse/property-16.scss | 2 +- .../icons/icons/sync-reverse/property-24.scss | 2 +- .../styles/base/icons/icons/sync/index.scss | 2 +- .../base/icons/icons/sync/keyframes.scss | 2 +- .../base/icons/icons/sync/placeholders.scss | 2 +- .../base/icons/icons/sync/property-16.scss | 2 +- .../base/icons/icons/sync/property-24.scss | 2 +- .../styles/base/icons/icons/tablet/index.scss | 2 +- .../base/icons/icons/tablet/keyframes.scss | 2 +- .../base/icons/icons/tablet/placeholders.scss | 2 +- .../base/icons/icons/tablet/property-16.scss | 2 +- .../base/icons/icons/tablet/property-24.scss | 2 +- .../styles/base/icons/icons/tag/index.scss | 2 +- .../base/icons/icons/tag/keyframes.scss | 2 +- .../base/icons/icons/tag/placeholders.scss | 2 +- .../base/icons/icons/tag/property-16.scss | 2 +- .../base/icons/icons/tag/property-24.scss | 2 +- .../styles/base/icons/icons/target/index.scss | 2 +- .../base/icons/icons/target/keyframes.scss | 2 +- .../base/icons/icons/target/placeholders.scss | 2 +- .../base/icons/icons/target/property-16.scss | 2 +- .../base/icons/icons/target/property-24.scss | 2 +- .../icons/icons/terminal-screen/index.scss | 2 +- .../icons/terminal-screen/keyframes.scss | 2 +- .../icons/terminal-screen/placeholders.scss | 2 +- .../icons/terminal-screen/property-16.scss | 2 +- .../icons/terminal-screen/property-24.scss | 2 +- .../base/icons/icons/terminal/index.scss | 2 +- .../base/icons/icons/terminal/keyframes.scss | 2 +- .../icons/icons/terminal/placeholders.scss | 2 +- .../icons/icons/terminal/property-16.scss | 2 +- .../icons/icons/terminal/property-24.scss | 2 +- .../icons/icons/terraform-color/index.scss | 2 +- .../icons/terraform-color/keyframes.scss | 2 +- .../icons/terraform-color/placeholders.scss | 2 +- .../icons/terraform-color/property-16.scss | 2 +- .../icons/terraform-color/property-24.scss | 2 +- .../base/icons/icons/terraform/index.scss | 2 +- .../base/icons/icons/terraform/keyframes.scss | 2 +- .../icons/icons/terraform/placeholders.scss | 2 +- .../icons/icons/terraform/property-16.scss | 2 +- .../icons/icons/terraform/property-24.scss | 2 +- .../base/icons/icons/thumbs-down/index.scss | 2 +- .../icons/icons/thumbs-down/keyframes.scss | 2 +- .../icons/icons/thumbs-down/placeholders.scss | 2 +- .../icons/icons/thumbs-down/property-16.scss | 2 +- .../icons/icons/thumbs-down/property-24.scss | 2 +- .../base/icons/icons/thumbs-up/index.scss | 2 +- .../base/icons/icons/thumbs-up/keyframes.scss | 2 +- .../icons/icons/thumbs-up/placeholders.scss | 2 +- .../icons/icons/thumbs-up/property-16.scss | 2 +- .../icons/icons/thumbs-up/property-24.scss | 2 +- .../base/icons/icons/toggle-left/index.scss | 2 +- .../icons/icons/toggle-left/keyframes.scss | 2 +- .../icons/icons/toggle-left/placeholders.scss | 2 +- .../icons/icons/toggle-left/property-16.scss | 2 +- .../icons/icons/toggle-left/property-24.scss | 2 +- .../base/icons/icons/toggle-right/index.scss | 2 +- .../icons/icons/toggle-right/keyframes.scss | 2 +- .../icons/toggle-right/placeholders.scss | 2 +- .../icons/icons/toggle-right/property-16.scss | 2 +- .../icons/icons/toggle-right/property-24.scss | 2 +- .../styles/base/icons/icons/token/index.scss | 2 +- .../base/icons/icons/token/keyframes.scss | 2 +- .../base/icons/icons/token/placeholders.scss | 2 +- .../base/icons/icons/token/property-16.scss | 2 +- .../base/icons/icons/token/property-24.scss | 2 +- .../styles/base/icons/icons/tools/index.scss | 2 +- .../base/icons/icons/tools/keyframes.scss | 2 +- .../base/icons/icons/tools/placeholders.scss | 2 +- .../base/icons/icons/tools/property-16.scss | 2 +- .../base/icons/icons/tools/property-24.scss | 2 +- .../styles/base/icons/icons/top/index.scss | 2 +- .../base/icons/icons/top/keyframes.scss | 2 +- .../base/icons/icons/top/placeholders.scss | 2 +- .../base/icons/icons/top/property-16.scss | 2 +- .../base/icons/icons/top/property-24.scss | 2 +- .../styles/base/icons/icons/trash/index.scss | 2 +- .../base/icons/icons/trash/keyframes.scss | 2 +- .../base/icons/icons/trash/placeholders.scss | 2 +- .../base/icons/icons/trash/property-16.scss | 2 +- .../base/icons/icons/trash/property-24.scss | 2 +- .../base/icons/icons/trend-down/index.scss | 2 +- .../icons/icons/trend-down/keyframes.scss | 2 +- .../icons/icons/trend-down/placeholders.scss | 2 +- .../icons/icons/trend-down/property-16.scss | 2 +- .../icons/icons/trend-down/property-24.scss | 2 +- .../base/icons/icons/trend-up/index.scss | 2 +- .../base/icons/icons/trend-up/keyframes.scss | 2 +- .../icons/icons/trend-up/placeholders.scss | 2 +- .../icons/icons/trend-up/property-16.scss | 2 +- .../icons/icons/trend-up/property-24.scss | 2 +- .../base/icons/icons/triangle-fill/index.scss | 2 +- .../icons/icons/triangle-fill/keyframes.scss | 2 +- .../icons/triangle-fill/placeholders.scss | 2 +- .../icons/triangle-fill/property-16.scss | 2 +- .../icons/triangle-fill/property-24.scss | 2 +- .../base/icons/icons/triangle/index.scss | 2 +- .../base/icons/icons/triangle/keyframes.scss | 2 +- .../icons/icons/triangle/placeholders.scss | 2 +- .../icons/icons/triangle/property-16.scss | 2 +- .../icons/icons/triangle/property-24.scss | 2 +- .../styles/base/icons/icons/truck/index.scss | 2 +- .../base/icons/icons/truck/keyframes.scss | 2 +- .../base/icons/icons/truck/placeholders.scss | 2 +- .../base/icons/icons/truck/property-16.scss | 2 +- .../base/icons/icons/truck/property-24.scss | 2 +- .../styles/base/icons/icons/tune/index.scss | 2 +- .../base/icons/icons/tune/keyframes.scss | 2 +- .../base/icons/icons/tune/placeholders.scss | 2 +- .../app/styles/base/icons/icons/tv/index.scss | 2 +- .../styles/base/icons/icons/tv/keyframes.scss | 2 +- .../base/icons/icons/tv/placeholders.scss | 2 +- .../base/icons/icons/tv/property-16.scss | 2 +- .../base/icons/icons/tv/property-24.scss | 2 +- .../base/icons/icons/twitch-color/index.scss | 2 +- .../icons/icons/twitch-color/keyframes.scss | 2 +- .../icons/twitch-color/placeholders.scss | 2 +- .../icons/icons/twitch-color/property-16.scss | 2 +- .../icons/icons/twitch-color/property-24.scss | 2 +- .../styles/base/icons/icons/twitch/index.scss | 2 +- .../base/icons/icons/twitch/keyframes.scss | 2 +- .../base/icons/icons/twitch/placeholders.scss | 2 +- .../base/icons/icons/twitch/property-16.scss | 2 +- .../base/icons/icons/twitch/property-24.scss | 2 +- .../base/icons/icons/twitter-color/index.scss | 2 +- .../icons/icons/twitter-color/keyframes.scss | 2 +- .../icons/twitter-color/placeholders.scss | 2 +- .../icons/twitter-color/property-16.scss | 2 +- .../icons/twitter-color/property-24.scss | 2 +- .../base/icons/icons/twitter/index.scss | 2 +- .../base/icons/icons/twitter/keyframes.scss | 2 +- .../icons/icons/twitter/placeholders.scss | 2 +- .../base/icons/icons/twitter/property-16.scss | 2 +- .../base/icons/icons/twitter/property-24.scss | 2 +- .../styles/base/icons/icons/type/index.scss | 2 +- .../base/icons/icons/type/keyframes.scss | 2 +- .../base/icons/icons/type/placeholders.scss | 2 +- .../base/icons/icons/type/property-16.scss | 2 +- .../base/icons/icons/type/property-24.scss | 2 +- .../base/icons/icons/unfold-close/index.scss | 2 +- .../icons/icons/unfold-close/keyframes.scss | 2 +- .../icons/unfold-close/placeholders.scss | 2 +- .../icons/icons/unfold-close/property-16.scss | 2 +- .../icons/icons/unfold-close/property-24.scss | 2 +- .../base/icons/icons/unfold-less/index.scss | 2 +- .../icons/icons/unfold-less/keyframes.scss | 2 +- .../icons/icons/unfold-less/placeholders.scss | 2 +- .../base/icons/icons/unfold-more/index.scss | 2 +- .../icons/icons/unfold-more/keyframes.scss | 2 +- .../icons/icons/unfold-more/placeholders.scss | 2 +- .../base/icons/icons/unfold-open/index.scss | 2 +- .../icons/icons/unfold-open/keyframes.scss | 2 +- .../icons/icons/unfold-open/placeholders.scss | 2 +- .../icons/icons/unfold-open/property-16.scss | 2 +- .../icons/icons/unfold-open/property-24.scss | 2 +- .../styles/base/icons/icons/union/index.scss | 2 +- .../base/icons/icons/union/keyframes.scss | 2 +- .../base/icons/icons/union/placeholders.scss | 2 +- .../base/icons/icons/union/property-16.scss | 2 +- .../base/icons/icons/union/property-24.scss | 2 +- .../styles/base/icons/icons/unlock/index.scss | 2 +- .../base/icons/icons/unlock/keyframes.scss | 2 +- .../base/icons/icons/unlock/placeholders.scss | 2 +- .../base/icons/icons/unlock/property-16.scss | 2 +- .../base/icons/icons/unlock/property-24.scss | 2 +- .../styles/base/icons/icons/upload/index.scss | 2 +- .../base/icons/icons/upload/keyframes.scss | 2 +- .../base/icons/icons/upload/placeholders.scss | 2 +- .../base/icons/icons/upload/property-16.scss | 2 +- .../base/icons/icons/upload/property-24.scss | 2 +- .../base/icons/icons/user-add/index.scss | 2 +- .../base/icons/icons/user-add/keyframes.scss | 2 +- .../icons/icons/user-add/placeholders.scss | 2 +- .../base/icons/icons/user-check/index.scss | 2 +- .../icons/icons/user-check/keyframes.scss | 2 +- .../icons/icons/user-check/placeholders.scss | 2 +- .../icons/icons/user-check/property-16.scss | 2 +- .../icons/icons/user-check/property-24.scss | 2 +- .../icons/icons/user-circle-fill/index.scss | 2 +- .../icons/user-circle-fill/keyframes.scss | 2 +- .../icons/user-circle-fill/placeholders.scss | 2 +- .../icons/user-circle-fill/property-16.scss | 2 +- .../icons/user-circle-fill/property-24.scss | 2 +- .../base/icons/icons/user-circle/index.scss | 2 +- .../icons/icons/user-circle/keyframes.scss | 2 +- .../icons/icons/user-circle/placeholders.scss | 2 +- .../icons/icons/user-circle/property-16.scss | 2 +- .../icons/icons/user-circle/property-24.scss | 2 +- .../base/icons/icons/user-minus/index.scss | 2 +- .../icons/icons/user-minus/keyframes.scss | 2 +- .../icons/icons/user-minus/placeholders.scss | 2 +- .../icons/icons/user-minus/property-16.scss | 2 +- .../icons/icons/user-minus/property-24.scss | 2 +- .../icons/icons/user-organization/index.scss | 2 +- .../icons/user-organization/keyframes.scss | 2 +- .../icons/user-organization/placeholders.scss | 2 +- .../base/icons/icons/user-plain/index.scss | 2 +- .../icons/icons/user-plain/keyframes.scss | 2 +- .../icons/icons/user-plain/placeholders.scss | 2 +- .../base/icons/icons/user-plus/index.scss | 2 +- .../base/icons/icons/user-plus/keyframes.scss | 2 +- .../icons/icons/user-plus/placeholders.scss | 2 +- .../icons/icons/user-plus/property-16.scss | 2 +- .../icons/icons/user-plus/property-24.scss | 2 +- .../icons/icons/user-square-fill/index.scss | 2 +- .../icons/user-square-fill/keyframes.scss | 2 +- .../icons/user-square-fill/placeholders.scss | 2 +- .../icons/user-square-outline/index.scss | 2 +- .../icons/user-square-outline/keyframes.scss | 2 +- .../user-square-outline/placeholders.scss | 2 +- .../base/icons/icons/user-team/index.scss | 2 +- .../base/icons/icons/user-team/keyframes.scss | 2 +- .../icons/icons/user-team/placeholders.scss | 2 +- .../styles/base/icons/icons/user-x/index.scss | 2 +- .../base/icons/icons/user-x/keyframes.scss | 2 +- .../base/icons/icons/user-x/placeholders.scss | 2 +- .../base/icons/icons/user-x/property-16.scss | 2 +- .../base/icons/icons/user-x/property-24.scss | 2 +- .../styles/base/icons/icons/user/index.scss | 2 +- .../base/icons/icons/user/keyframes.scss | 2 +- .../base/icons/icons/user/placeholders.scss | 2 +- .../base/icons/icons/user/property-16.scss | 2 +- .../base/icons/icons/user/property-24.scss | 2 +- .../styles/base/icons/icons/users/index.scss | 2 +- .../base/icons/icons/users/keyframes.scss | 2 +- .../base/icons/icons/users/placeholders.scss | 2 +- .../base/icons/icons/users/property-16.scss | 2 +- .../base/icons/icons/users/property-24.scss | 2 +- .../base/icons/icons/vagrant-color/index.scss | 2 +- .../icons/icons/vagrant-color/keyframes.scss | 2 +- .../icons/vagrant-color/placeholders.scss | 2 +- .../icons/vagrant-color/property-16.scss | 2 +- .../icons/vagrant-color/property-24.scss | 2 +- .../base/icons/icons/vagrant/index.scss | 2 +- .../base/icons/icons/vagrant/keyframes.scss | 2 +- .../icons/icons/vagrant/placeholders.scss | 2 +- .../base/icons/icons/vagrant/property-16.scss | 2 +- .../base/icons/icons/vagrant/property-24.scss | 2 +- .../base/icons/icons/vault-color/index.scss | 2 +- .../icons/icons/vault-color/keyframes.scss | 2 +- .../icons/icons/vault-color/placeholders.scss | 2 +- .../icons/icons/vault-color/property-16.scss | 2 +- .../icons/icons/vault-color/property-24.scss | 2 +- .../styles/base/icons/icons/vault/index.scss | 2 +- .../base/icons/icons/vault/keyframes.scss | 2 +- .../base/icons/icons/vault/placeholders.scss | 2 +- .../base/icons/icons/vault/property-16.scss | 2 +- .../base/icons/icons/vault/property-24.scss | 2 +- .../base/icons/icons/verified/index.scss | 2 +- .../base/icons/icons/verified/keyframes.scss | 2 +- .../icons/icons/verified/placeholders.scss | 2 +- .../icons/icons/verified/property-16.scss | 2 +- .../icons/icons/verified/property-24.scss | 2 +- .../base/icons/icons/video-off/index.scss | 2 +- .../base/icons/icons/video-off/keyframes.scss | 2 +- .../icons/icons/video-off/placeholders.scss | 2 +- .../icons/icons/video-off/property-16.scss | 2 +- .../icons/icons/video-off/property-24.scss | 2 +- .../styles/base/icons/icons/video/index.scss | 2 +- .../base/icons/icons/video/keyframes.scss | 2 +- .../base/icons/icons/video/placeholders.scss | 2 +- .../base/icons/icons/video/property-16.scss | 2 +- .../base/icons/icons/video/property-24.scss | 2 +- .../icons/icons/visibility-hide/index.scss | 2 +- .../icons/visibility-hide/keyframes.scss | 2 +- .../icons/visibility-hide/placeholders.scss | 2 +- .../icons/icons/visibility-show/index.scss | 2 +- .../icons/visibility-show/keyframes.scss | 2 +- .../icons/visibility-show/placeholders.scss | 2 +- .../base/icons/icons/vmware-color/index.scss | 2 +- .../icons/icons/vmware-color/keyframes.scss | 2 +- .../icons/vmware-color/placeholders.scss | 2 +- .../icons/icons/vmware-color/property-16.scss | 2 +- .../icons/icons/vmware-color/property-24.scss | 2 +- .../styles/base/icons/icons/vmware/index.scss | 2 +- .../base/icons/icons/vmware/keyframes.scss | 2 +- .../base/icons/icons/vmware/placeholders.scss | 2 +- .../base/icons/icons/vmware/property-16.scss | 2 +- .../base/icons/icons/vmware/property-24.scss | 2 +- .../base/icons/icons/volume-2/index.scss | 2 +- .../base/icons/icons/volume-2/keyframes.scss | 2 +- .../icons/icons/volume-2/placeholders.scss | 2 +- .../icons/icons/volume-2/property-16.scss | 2 +- .../icons/icons/volume-2/property-24.scss | 2 +- .../base/icons/icons/volume-down/index.scss | 2 +- .../icons/icons/volume-down/keyframes.scss | 2 +- .../icons/icons/volume-down/placeholders.scss | 2 +- .../icons/icons/volume-down/property-16.scss | 2 +- .../icons/icons/volume-down/property-24.scss | 2 +- .../base/icons/icons/volume-x/index.scss | 2 +- .../base/icons/icons/volume-x/keyframes.scss | 2 +- .../icons/icons/volume-x/placeholders.scss | 2 +- .../icons/icons/volume-x/property-16.scss | 2 +- .../icons/icons/volume-x/property-24.scss | 2 +- .../styles/base/icons/icons/volume/index.scss | 2 +- .../base/icons/icons/volume/keyframes.scss | 2 +- .../base/icons/icons/volume/placeholders.scss | 2 +- .../base/icons/icons/volume/property-16.scss | 2 +- .../base/icons/icons/volume/property-24.scss | 2 +- .../styles/base/icons/icons/wall/index.scss | 2 +- .../base/icons/icons/wall/keyframes.scss | 2 +- .../base/icons/icons/wall/placeholders.scss | 2 +- .../base/icons/icons/wall/property-16.scss | 2 +- .../base/icons/icons/wall/property-24.scss | 2 +- .../styles/base/icons/icons/wand/index.scss | 2 +- .../base/icons/icons/wand/keyframes.scss | 2 +- .../base/icons/icons/wand/placeholders.scss | 2 +- .../base/icons/icons/wand/property-16.scss | 2 +- .../base/icons/icons/wand/property-24.scss | 2 +- .../styles/base/icons/icons/watch/index.scss | 2 +- .../base/icons/icons/watch/keyframes.scss | 2 +- .../base/icons/icons/watch/placeholders.scss | 2 +- .../base/icons/icons/watch/property-16.scss | 2 +- .../base/icons/icons/watch/property-24.scss | 2 +- .../icons/icons/waypoint-color/index.scss | 2 +- .../icons/icons/waypoint-color/keyframes.scss | 2 +- .../icons/waypoint-color/placeholders.scss | 2 +- .../icons/waypoint-color/property-16.scss | 2 +- .../icons/waypoint-color/property-24.scss | 2 +- .../base/icons/icons/waypoint/index.scss | 2 +- .../base/icons/icons/waypoint/keyframes.scss | 2 +- .../icons/icons/waypoint/placeholders.scss | 2 +- .../icons/icons/waypoint/property-16.scss | 2 +- .../icons/icons/waypoint/property-24.scss | 2 +- .../base/icons/icons/webhook/index.scss | 2 +- .../base/icons/icons/webhook/keyframes.scss | 2 +- .../icons/icons/webhook/placeholders.scss | 2 +- .../base/icons/icons/webhook/property-16.scss | 2 +- .../base/icons/icons/webhook/property-24.scss | 2 +- .../base/icons/icons/wifi-off/index.scss | 2 +- .../base/icons/icons/wifi-off/keyframes.scss | 2 +- .../icons/icons/wifi-off/placeholders.scss | 2 +- .../icons/icons/wifi-off/property-16.scss | 2 +- .../icons/icons/wifi-off/property-24.scss | 2 +- .../styles/base/icons/icons/wifi/index.scss | 2 +- .../base/icons/icons/wifi/keyframes.scss | 2 +- .../base/icons/icons/wifi/placeholders.scss | 2 +- .../base/icons/icons/wifi/property-16.scss | 2 +- .../base/icons/icons/wifi/property-24.scss | 2 +- .../styles/base/icons/icons/wrench/index.scss | 2 +- .../base/icons/icons/wrench/keyframes.scss | 2 +- .../base/icons/icons/wrench/placeholders.scss | 2 +- .../base/icons/icons/wrench/property-16.scss | 2 +- .../base/icons/icons/wrench/property-24.scss | 2 +- .../base/icons/icons/x-circle-fill/index.scss | 2 +- .../icons/icons/x-circle-fill/keyframes.scss | 2 +- .../icons/x-circle-fill/placeholders.scss | 2 +- .../icons/x-circle-fill/property-16.scss | 2 +- .../icons/x-circle-fill/property-24.scss | 2 +- .../base/icons/icons/x-circle/index.scss | 2 +- .../base/icons/icons/x-circle/keyframes.scss | 2 +- .../icons/icons/x-circle/placeholders.scss | 2 +- .../icons/icons/x-circle/property-16.scss | 2 +- .../icons/icons/x-circle/property-24.scss | 2 +- .../icons/icons/x-diamond-fill/index.scss | 2 +- .../icons/icons/x-diamond-fill/keyframes.scss | 2 +- .../icons/x-diamond-fill/placeholders.scss | 2 +- .../icons/x-diamond-fill/property-16.scss | 2 +- .../icons/x-diamond-fill/property-24.scss | 2 +- .../base/icons/icons/x-diamond/index.scss | 2 +- .../base/icons/icons/x-diamond/keyframes.scss | 2 +- .../icons/icons/x-diamond/placeholders.scss | 2 +- .../icons/icons/x-diamond/property-16.scss | 2 +- .../icons/icons/x-diamond/property-24.scss | 2 +- .../icons/icons/x-hexagon-fill/index.scss | 2 +- .../icons/icons/x-hexagon-fill/keyframes.scss | 2 +- .../icons/x-hexagon-fill/placeholders.scss | 2 +- .../icons/x-hexagon-fill/property-16.scss | 2 +- .../icons/x-hexagon-fill/property-24.scss | 2 +- .../base/icons/icons/x-hexagon/index.scss | 2 +- .../base/icons/icons/x-hexagon/keyframes.scss | 2 +- .../icons/icons/x-hexagon/placeholders.scss | 2 +- .../icons/icons/x-hexagon/property-16.scss | 2 +- .../icons/icons/x-hexagon/property-24.scss | 2 +- .../base/icons/icons/x-square-fill/index.scss | 2 +- .../icons/icons/x-square-fill/keyframes.scss | 2 +- .../icons/x-square-fill/placeholders.scss | 2 +- .../icons/x-square-fill/property-16.scss | 2 +- .../icons/x-square-fill/property-24.scss | 2 +- .../base/icons/icons/x-square/index.scss | 2 +- .../base/icons/icons/x-square/keyframes.scss | 2 +- .../icons/icons/x-square/placeholders.scss | 2 +- .../icons/icons/x-square/property-16.scss | 2 +- .../icons/icons/x-square/property-24.scss | 2 +- .../app/styles/base/icons/icons/x/index.scss | 2 +- .../styles/base/icons/icons/x/keyframes.scss | 2 +- .../base/icons/icons/x/placeholders.scss | 2 +- .../base/icons/icons/x/property-16.scss | 2 +- .../base/icons/icons/x/property-24.scss | 2 +- .../base/icons/icons/youtube-color/index.scss | 2 +- .../icons/icons/youtube-color/keyframes.scss | 2 +- .../icons/youtube-color/placeholders.scss | 2 +- .../icons/youtube-color/property-16.scss | 2 +- .../icons/youtube-color/property-24.scss | 2 +- .../base/icons/icons/youtube/index.scss | 2 +- .../base/icons/icons/youtube/keyframes.scss | 2 +- .../icons/icons/youtube/placeholders.scss | 2 +- .../base/icons/icons/youtube/property-16.scss | 2 +- .../base/icons/icons/youtube/property-24.scss | 2 +- .../base/icons/icons/zap-off/index.scss | 2 +- .../base/icons/icons/zap-off/keyframes.scss | 2 +- .../icons/icons/zap-off/placeholders.scss | 2 +- .../base/icons/icons/zap-off/property-16.scss | 2 +- .../base/icons/icons/zap-off/property-24.scss | 2 +- .../styles/base/icons/icons/zap/index.scss | 2 +- .../base/icons/icons/zap/keyframes.scss | 2 +- .../base/icons/icons/zap/placeholders.scss | 2 +- .../base/icons/icons/zap/property-16.scss | 2 +- .../base/icons/icons/zap/property-24.scss | 2 +- .../base/icons/icons/zoom-in/index.scss | 2 +- .../base/icons/icons/zoom-in/keyframes.scss | 2 +- .../icons/icons/zoom-in/placeholders.scss | 2 +- .../base/icons/icons/zoom-in/property-16.scss | 2 +- .../base/icons/icons/zoom-in/property-24.scss | 2 +- .../base/icons/icons/zoom-out/index.scss | 2 +- .../base/icons/icons/zoom-out/keyframes.scss | 2 +- .../icons/icons/zoom-out/placeholders.scss | 2 +- .../icons/icons/zoom-out/property-16.scss | 2 +- .../icons/icons/zoom-out/property-24.scss | 2 +- .../app/styles/base/icons/index.scss | 2 +- .../app/styles/base/icons/overrides.scss | 2 +- .../consul-ui/app/styles/base/index.scss | 2 +- .../app/styles/base/reset/base-variables.scss | 2 +- .../app/styles/base/reset/index.scss | 2 +- .../app/styles/base/reset/minireset.scss | 2 +- .../app/styles/base/reset/system.scss | 2 +- .../base/typography/base-keyframes.scss | 2 +- .../base/typography/base-placeholders.scss | 2 +- .../app/styles/base/typography/index.scss | 2 +- .../consul-ui/app/styles/components.scss | 4 +- ui/packages/consul-ui/app/styles/debug.scss | 2 +- ui/packages/consul-ui/app/styles/icons.scss | 2 +- ui/packages/consul-ui/app/styles/layout.scss | 2 +- .../consul-ui/app/styles/layouts/index.scss | 2 +- .../app/styles/prism-coldark-cold.scss | 2 +- .../app/styles/prism-coldark-dark.scss | 2 +- ui/packages/consul-ui/app/styles/routes.scss | 2 +- .../app/styles/routes/dc/acls/index.scss | 2 +- .../styles/routes/dc/intentions/index.scss | 2 +- .../app/styles/routes/dc/kv/index.scss | 2 +- .../app/styles/routes/dc/nodes/index.scss | 2 +- .../styles/routes/dc/overview/license.scss | 2 +- .../routes/dc/overview/serverstatus.scss | 2 +- .../app/styles/routes/dc/services/index.scss | 2 +- .../consul-ui/app/styles/tailwind.scss | 2 +- ui/packages/consul-ui/app/styles/themes.scss | 2 +- .../consul-ui/app/styles/typography.scss | 2 +- .../consul-ui/app/styles/variables.scss | 2 +- .../app/styles/variables/custom-query.scss | 2 +- .../app/styles/variables/layout.scss | 2 +- .../consul-ui/app/styles/variables/skin.scss | 2 +- .../consul-ui/app/templates/application.hbs | 2 +- ui/packages/consul-ui/app/templates/dc.hbs | 2 +- .../consul-ui/app/templates/dc/acls.hbs | 2 +- .../templates/dc/acls/auth-methods/index.hbs | 2 +- .../templates/dc/acls/auth-methods/show.hbs | 2 +- .../dc/acls/auth-methods/show/auth-method.hbs | 2 +- .../acls/auth-methods/show/binding-rules.hbs | 2 +- .../acls/auth-methods/show/nspace-rules.hbs | 2 +- .../consul-ui/app/templates/dc/acls/index.hbs | 2 +- .../app/templates/dc/acls/policies/-form.hbs | 2 +- .../app/templates/dc/acls/policies/edit.hbs | 2 +- .../app/templates/dc/acls/policies/index.hbs | 2 +- .../app/templates/dc/acls/roles/-form.hbs | 2 +- .../app/templates/dc/acls/roles/edit.hbs | 2 +- .../app/templates/dc/acls/roles/index.hbs | 2 +- .../dc/acls/tokens/-fieldsets-legacy.hbs | 2 +- .../templates/dc/acls/tokens/-fieldsets.hbs | 2 +- .../app/templates/dc/acls/tokens/-form.hbs | 2 +- .../app/templates/dc/acls/tokens/edit.hbs | 2 +- .../app/templates/dc/acls/tokens/index.hbs | 2 +- .../app/templates/dc/intentions/edit.hbs | 2 +- .../app/templates/dc/intentions/index.hbs | 2 +- .../consul-ui/app/templates/dc/kv/edit.hbs | 2 +- .../consul-ui/app/templates/dc/kv/index.hbs | 2 +- .../app/templates/dc/nodes/index.hbs | 2 +- .../consul-ui/app/templates/dc/nodes/show.hbs | 4 +- .../templates/dc/nodes/show/healthchecks.hbs | 2 +- .../app/templates/dc/nodes/show/index.hbs | 2 +- .../app/templates/dc/nodes/show/metadata.hbs | 2 +- .../app/templates/dc/nodes/show/rtt.hbs | 2 +- .../app/templates/dc/nodes/show/services.hbs | 2 +- .../app/templates/dc/routing-config.hbs | 2 +- .../app/templates/dc/services/index.hbs | 2 +- .../app/templates/dc/services/instance.hbs | 4 +- .../dc/services/instance/addresses.hbs | 2 +- .../dc/services/instance/exposedpaths.hbs | 2 +- .../dc/services/instance/healthchecks.hbs | 2 +- .../dc/services/instance/metadata.hbs | 2 +- .../dc/services/instance/upstreams.hbs | 2 +- .../app/templates/dc/services/show.hbs | 2 +- .../app/templates/dc/services/show/index.hbs | 2 +- .../templates/dc/services/show/instances.hbs | 2 +- .../templates/dc/services/show/intentions.hbs | 2 +- .../dc/services/show/intentions/edit.hbs | 2 +- .../dc/services/show/intentions/index.hbs | 2 +- .../templates/dc/services/show/routing.hbs | 2 +- .../templates/dc/services/show/services.hbs | 2 +- .../app/templates/dc/services/show/tags.hbs | 2 +- .../templates/dc/services/show/topology.hbs | 2 +- .../templates/dc/services/show/upstreams.hbs | 2 +- .../consul-ui/app/templates/dc/show.hbs | 2 +- .../consul-ui/app/templates/dc/show/index.hbs | 2 +- .../app/templates/dc/show/license.hbs | 2 +- .../app/templates/dc/show/serverstatus.hbs | 2 +- ui/packages/consul-ui/app/templates/debug.hbs | 2 +- ui/packages/consul-ui/app/templates/error.hbs | 2 +- ui/packages/consul-ui/app/templates/index.hbs | 2 +- .../consul-ui/app/templates/loading.hbs | 2 +- .../consul-ui/app/templates/notfound.hbs | 2 +- .../app/templates/oauth-provider-debug.hbs | 2 +- .../consul-ui/app/templates/settings.hbs | 2 +- ui/packages/consul-ui/app/utils/ascend.js | 2 +- ui/packages/consul-ui/app/utils/atob.js | 2 +- ui/packages/consul-ui/app/utils/btoa.js | 2 +- .../consul-ui/app/utils/callable-type.js | 2 +- .../app/utils/create-fingerprinter.js | 2 +- ui/packages/consul-ui/app/utils/distance.js | 2 +- .../app/utils/dom/click-first-anchor.js | 2 +- .../consul-ui/app/utils/dom/closest.js | 2 +- .../app/utils/dom/create-listeners.js | 2 +- .../app/utils/dom/event-source/blocking.js | 2 +- .../app/utils/dom/event-source/cache.js | 2 +- .../app/utils/dom/event-source/callable.js | 2 +- .../app/utils/dom/event-source/index.js | 2 +- .../app/utils/dom/event-source/openable.js | 2 +- .../app/utils/dom/event-source/proxy.js | 2 +- .../app/utils/dom/event-source/resolver.js | 2 +- .../app/utils/dom/event-source/storage.js | 2 +- .../app/utils/dom/get-component-factory.js | 2 +- .../consul-ui/app/utils/dom/is-outside.js | 2 +- .../app/utils/dom/normalize-event.js | 2 +- .../consul-ui/app/utils/dom/qsa-factory.js | 2 +- .../consul-ui/app/utils/dom/sibling.js | 2 +- .../consul-ui/app/utils/editor/lint.js | 2 +- .../consul-ui/app/utils/filter/index.js | 2 +- .../consul-ui/app/utils/form/builder.js | 2 +- .../consul-ui/app/utils/form/changeset.js | 2 +- .../consul-ui/app/utils/get-environment.js | 2 +- .../app/utils/get-form-name-property.js | 2 +- .../app/utils/helpers/call-if-type.js | 2 +- .../consul-ui/app/utils/http/consul.js | 2 +- .../app/utils/http/create-headers.js | 2 +- .../app/utils/http/create-query-params.js | 2 +- .../consul-ui/app/utils/http/create-url.js | 2 +- ui/packages/consul-ui/app/utils/http/error.js | 2 +- .../consul-ui/app/utils/http/headers.js | 2 +- .../consul-ui/app/utils/http/method.js | 2 +- .../consul-ui/app/utils/http/request.js | 2 +- .../consul-ui/app/utils/http/status.js | 2 +- ui/packages/consul-ui/app/utils/http/xhr.js | 2 +- .../app/utils/intl/missing-message.js | 2 +- ui/packages/consul-ui/app/utils/isFolder.js | 2 +- ui/packages/consul-ui/app/utils/keyToArray.js | 2 +- ui/packages/consul-ui/app/utils/left-trim.js | 2 +- ui/packages/consul-ui/app/utils/maybe-call.js | 2 +- .../consul-ui/app/utils/merge-checks.js | 2 +- .../consul-ui/app/utils/minimizeModel.js | 2 +- .../consul-ui/app/utils/non-empty-set.js | 2 +- .../consul-ui/app/utils/path/resolve.js | 2 +- .../consul-ui/app/utils/promisedTimeout.js | 2 +- ui/packages/consul-ui/app/utils/right-trim.js | 2 +- .../app/utils/routing/redirect-to.js | 2 +- .../app/utils/routing/transitionable.js | 2 +- .../consul-ui/app/utils/routing/walk.js | 2 +- .../consul-ui/app/utils/routing/wildcard.js | 2 +- .../consul-ui/app/utils/search/exact.js | 2 +- .../consul-ui/app/utils/search/fuzzy.js | 2 +- .../consul-ui/app/utils/search/predicate.js | 2 +- .../consul-ui/app/utils/search/regexp.js | 2 +- .../app/utils/storage/local-storage.js | 2 +- ui/packages/consul-ui/app/utils/templatize.js | 2 +- .../consul-ui/app/utils/ticker/index.js | 2 +- ui/packages/consul-ui/app/utils/tomography.js | 2 +- ui/packages/consul-ui/app/utils/ucfirst.js | 2 +- .../app/utils/update-array-object.js | 2 +- .../intention-permission-http-header.js | 2 +- .../app/validations/intention-permission.js | 2 +- .../consul-ui/app/validations/intention.js | 2 +- ui/packages/consul-ui/app/validations/kv.js | 2 +- .../consul-ui/app/validations/policy.js | 2 +- ui/packages/consul-ui/app/validations/role.js | 2 +- .../consul-ui/app/validations/sometimes.js | 2 +- .../consul-ui/app/validations/token.js | 2 +- .../blueprints/adapter-test/index.js | 2 +- .../__path__/integration/adapters/__test__.js | 2 +- .../__path__/unit/adapters/__test__.js | 2 +- .../files/__root__/__path__/__name__.js | 2 +- .../consul-ui/blueprints/adapter/index.js | 2 +- .../__templatepath__/__templatename__.hbs | 2 +- .../consul-ui/blueprints/component/index.js | 2 +- .../files/__root__/__path__/__name__.scss | 2 +- .../__root__/__path__/__name__/index.scss | 2 +- .../__root__/__path__/__name__/layout.scss | 2 +- .../__root__/__path__/__name__/skin.scss | 2 +- .../blueprints/css-component/index.js | 2 +- .../consul-ui/blueprints/model-test/index.js | 2 +- .../__root__/__path__/unit/models/__test__.js | 2 +- .../model/files/__root__/__path__/__name__.js | 2 +- .../consul-ui/blueprints/model/index.js | 2 +- .../blueprints/repository-test/index.js | 2 +- .../services/repository/__test__.js | 2 +- .../unit/services/repository/__test__.js | 2 +- .../files/__root__/__path__/__name__.js | 2 +- .../consul-ui/blueprints/repository/index.js | 2 +- .../consul-ui/blueprints/route-test/index.js | 2 +- .../consul-ui/blueprints/route/index.js | 2 +- .../__templatepath__/__templatename__.hbs | 2 +- .../blueprints/serializer-test/index.js | 2 +- .../integration/serializers/__test__.js | 2 +- .../__path__/unit/serializers/__test__.js | 2 +- .../files/__root__/__path__/__name__.js | 2 +- .../consul-ui/blueprints/serializer/index.js | 2 +- .../consul-ui/config/deprecation-workflow.js | 2 +- ui/packages/consul-ui/config/ember-intl.js | 2 +- ui/packages/consul-ui/config/environment.js | 2 +- ui/packages/consul-ui/config/targets.js | 2 +- ui/packages/consul-ui/config/utils.js | 2 +- ui/packages/consul-ui/ember-cli-build.js | 2 +- ui/packages/consul-ui/lib/.eslintrc.js | 2 +- .../lib/colocated-components/index.js | 2 +- .../consul-ui/lib/commands/bin/list.js | 2 +- ui/packages/consul-ui/lib/commands/index.js | 2 +- .../consul-ui/lib/commands/lib/list.js | 2 +- .../consul-ui/lib/custom-element/index.js | 2 +- ui/packages/consul-ui/lib/startup/index.js | 2 +- .../lib/startup/templates/body.html.js | 2 +- .../lib/startup/templates/head.html.js | 2 +- .../node-tests/config/environment.js | 2 +- .../consul-ui/node-tests/config/utils.js | 2 +- ui/packages/consul-ui/package.json | 18 +- ui/packages/consul-ui/server/index.js | 2 +- ui/packages/consul-ui/tailwind.config.js | 2 +- ui/packages/consul-ui/testem.js | 2 +- .../dc/intentions/filtered-select.feature | 36 + .../tests/acceptance/hcp-login-test.js | 2 +- .../acceptance/steps/api-prefix-steps.js | 2 +- .../steps/components/acl-filter-steps.js | 2 +- .../steps/components/catalog-filter-steps.js | 2 +- .../steps/components/catalog-toolbar-steps.js | 2 +- .../steps/components/copy-button-steps.js | 2 +- .../steps/components/kv-filter-steps.js | 2 +- .../steps/components/text-input-steps.js | 2 +- .../acceptance/steps/dc/acls/access-steps.js | 2 +- .../steps/dc/acls/auth-methods/index-steps.js | 2 +- .../dc/acls/auth-methods/navigation-steps.js | 2 +- .../dc/acls/auth-methods/sorting-steps.js | 2 +- .../acceptance/steps/dc/acls/index-steps.js | 2 +- .../steps/dc/acls/list-order-steps.js | 2 +- .../policies/as-many/add-existing-steps.js | 2 +- .../dc/acls/policies/as-many/add-new-steps.js | 2 +- .../dc/acls/policies/as-many/list-steps.js | 2 +- .../dc/acls/policies/as-many/nspaces-steps.js | 2 +- .../dc/acls/policies/as-many/remove-steps.js | 2 +- .../dc/acls/policies/as-many/reset-steps.js | 2 +- .../steps/dc/acls/policies/create-steps.js | 2 +- .../steps/dc/acls/policies/delete-steps.js | 2 +- .../steps/dc/acls/policies/index-steps.js | 2 +- .../dc/acls/policies/navigation-steps.js | 2 +- .../steps/dc/acls/policies/sorting-steps.js | 2 +- .../steps/dc/acls/policies/update-steps.js | 2 +- .../dc/acls/policies/view-management-steps.js | 2 +- .../dc/acls/policies/view-read-only-steps.js | 2 +- .../acls/roles/as-many/add-existing-steps.js | 2 +- .../dc/acls/roles/as-many/add-new-steps.js | 2 +- .../steps/dc/acls/roles/as-many/list-steps.js | 2 +- .../dc/acls/roles/as-many/remove-steps.js | 2 +- .../steps/dc/acls/roles/create-steps.js | 2 +- .../steps/dc/acls/roles/index-steps.js | 2 +- .../steps/dc/acls/roles/navigation-steps.js | 2 +- .../steps/dc/acls/roles/sorting-steps.js | 2 +- .../steps/dc/acls/roles/update-steps.js | 2 +- .../acls/tokens/anonymous-no-delete-steps.js | 2 +- .../steps/dc/acls/tokens/clone-steps.js | 2 +- .../steps/dc/acls/tokens/create-steps.js | 2 +- .../steps/dc/acls/tokens/index-steps.js | 2 +- .../dc/acls/tokens/legacy/update-steps.js | 2 +- .../dc/acls/tokens/login-errors-steps.js | 2 +- .../steps/dc/acls/tokens/login-steps.js | 2 +- .../steps/dc/acls/tokens/navigation-steps.js | 2 +- .../dc/acls/tokens/own-no-delete-steps.js | 2 +- .../steps/dc/acls/tokens/sorting-steps.js | 2 +- .../steps/dc/acls/tokens/update-steps.js | 2 +- .../steps/dc/acls/tokens/use-steps.js | 2 +- .../acceptance/steps/dc/acls/update-steps.js | 2 +- .../acceptance/steps/dc/acls/use-steps.js | 2 +- .../tests/acceptance/steps/dc/error-steps.js | 2 +- .../acceptance/steps/dc/forwarding-steps.js | 2 +- .../tests/acceptance/steps/dc/index-steps.js | 2 +- .../steps/dc/intentions/create-steps.js | 2 +- .../steps/dc/intentions/delete-steps.js | 2 +- .../dc/intentions/filtered-select-steps.js | 2 +- .../steps/dc/intentions/form-select-steps.js | 2 +- .../steps/dc/intentions/index-steps.js | 2 +- .../steps/dc/intentions/navigation-steps.js | 2 +- .../dc/intentions/permissions/create-steps.js | 2 +- .../dc/intentions/permissions/warn-steps.js | 2 +- .../steps/dc/intentions/read-only-steps.js | 2 +- .../steps/dc/intentions/sorting-steps.js | 2 +- .../steps/dc/intentions/update-steps.js | 2 +- .../steps/dc/kv/index/view-kvs-steps.js | 2 +- .../acceptance/steps/dc/kvs/create-steps.js | 2 +- .../acceptance/steps/dc/kvs/delete-steps.js | 2 +- .../acceptance/steps/dc/kvs/edit-steps.js | 2 +- .../acceptance/steps/dc/kvs/index-steps.js | 2 +- .../steps/dc/kvs/list-order-steps.js | 2 +- .../steps/dc/kvs/sessions/invalidate-steps.js | 2 +- .../steps/dc/kvs/trailing-slash-steps.js | 2 +- .../acceptance/steps/dc/kvs/update-steps.js | 2 +- .../steps/dc/list-blocking-steps.js | 2 +- .../tests/acceptance/steps/dc/list-steps.js | 2 +- .../steps/dc/nodes/empty-ids-steps.js | 2 +- .../acceptance/steps/dc/nodes/index-steps.js | 2 +- .../steps/dc/nodes/index/view-nodes-steps.js | 2 +- .../steps/dc/nodes/navigation-steps.js | 2 +- .../steps/dc/nodes/no-leader-steps.js | 2 +- .../steps/dc/nodes/services/list-steps.js | 2 +- .../dc/nodes/sessions/invalidate-steps.js | 2 +- .../steps/dc/nodes/sessions/list-steps.js | 2 +- .../acceptance/steps/dc/nodes/show-steps.js | 2 +- .../dc/nodes/show/health-checks-steps.js | 2 +- .../steps/dc/nodes/sorting-steps.js | 2 +- .../steps/dc/nspaces/create-steps.js | 2 +- .../steps/dc/nspaces/delete-steps.js | 2 +- .../steps/dc/nspaces/index-steps.js | 2 +- .../steps/dc/nspaces/manage-steps.js | 2 +- .../steps/dc/nspaces/sorting-steps.js | 2 +- .../steps/dc/nspaces/update-steps.js | 2 +- .../acceptance/steps/dc/peers/create-steps.js | 2 +- .../acceptance/steps/dc/peers/delete-steps.js | 2 +- .../steps/dc/peers/establish-steps.js | 2 +- .../acceptance/steps/dc/peers/index-steps.js | 2 +- .../steps/dc/peers/regenerate-steps.js | 2 +- .../acceptance/steps/dc/peers/show-steps.js | 2 +- .../steps/dc/routing-config-steps.js | 2 +- .../steps/dc/services/dc-switch-steps.js | 2 +- .../steps/dc/services/error-steps.js | 2 +- .../steps/dc/services/index-steps.js | 2 +- .../dc/services/index/view-services-steps.js | 2 +- .../dc/services/instances/error-steps.js | 2 +- .../services/instances/exposed-paths-steps.js | 2 +- .../dc/services/instances/gateway-steps.js | 2 +- .../services/instances/health-checks-steps.js | 2 +- .../dc/services/instances/navigation-steps.js | 2 +- .../dc/services/instances/proxy-steps.js | 2 +- .../steps/dc/services/instances/show-steps.js | 2 +- .../services/instances/sidecar-proxy-steps.js | 2 +- .../dc/services/instances/upstreams-steps.js | 2 +- .../dc/services/instances/with-proxy-steps.js | 2 +- .../services/instances/with-sidecar-steps.js | 2 +- .../steps/dc/services/list-blocking-steps.js | 2 +- .../steps/dc/services/list-steps.js | 2 +- .../steps/dc/services/navigation-steps.js | 2 +- .../steps/dc/services/show-routing-steps.js | 2 +- .../steps/dc/services/show-steps.js | 2 +- .../dc/services/show-with-slashes-steps.js | 2 +- .../steps/dc/services/show/dc-switch-steps.js | 2 +- .../services/show/intentions-error-steps.js | 2 +- .../services/show/intentions/create-steps.js | 2 +- .../services/show/intentions/index-steps.js | 2 +- .../dc/services/show/navigation-steps.js | 2 +- .../steps/dc/services/show/services-steps.js | 2 +- .../steps/dc/services/show/tags-steps.js | 2 +- .../dc/services/show/topology/empty-steps.js | 2 +- .../dc/services/show/topology/index-steps.js | 2 +- .../show/topology/intentions-steps.js | 2 +- .../services/show/topology/metrics-steps.js | 2 +- .../services/show/topology/notices-steps.js | 2 +- .../show/topology/routing-config-steps.js | 2 +- .../dc/services/show/topology/stats-steps.js | 2 +- .../steps/dc/services/show/upstreams-steps.js | 2 +- .../steps/dc/services/sorting-steps.js | 2 +- .../tests/acceptance/steps/deleting-steps.js | 2 +- .../steps/index-forwarding-steps.js | 2 +- .../acceptance/steps/login-errors-steps.js | 2 +- .../tests/acceptance/steps/login-steps.js | 2 +- .../steps/navigation-links-steps.js | 2 +- .../acceptance/steps/nodes/sorting-steps.js | 2 +- .../acceptance/steps/page-navigation-steps.js | 2 +- .../acceptance/steps/settings/show-steps.js | 2 +- .../acceptance/steps/settings/update-steps.js | 2 +- .../tests/acceptance/steps/startup-steps.js | 2 +- .../consul-ui/tests/acceptance/steps/steps.js | 2 +- .../acceptance/steps/submit-blank-steps.js | 2 +- .../acceptance/steps/token-header-steps.js | 2 +- ui/packages/consul-ui/tests/dictionary.js | 2 +- ui/packages/consul-ui/tests/helpers/api.js | 2 +- .../consul-ui/tests/helpers/destroy-app.js | 2 +- .../consul-ui/tests/helpers/flash-message.js | 2 +- .../tests/helpers/get-nspace-runner.js | 2 +- .../consul-ui/tests/helpers/measure.js | 2 +- .../tests/helpers/module-for-acceptance.js | 2 +- .../consul-ui/tests/helpers/normalizers.js | 2 +- ui/packages/consul-ui/tests/helpers/page.js | 2 +- ui/packages/consul-ui/tests/helpers/repo.js | 2 +- .../consul-ui/tests/helpers/set-cookies.js | 2 +- .../consul-ui/tests/helpers/stub-super.js | 2 +- .../consul-ui/tests/helpers/type-to-url.js | 2 +- .../tests/helpers/yadda-annotations.js | 2 +- ui/packages/consul-ui/tests/index.html | 2 +- .../integration/adapters/auth-method-test.js | 2 +- .../integration/adapters/binding-rule-test.js | 2 +- .../integration/adapters/coordinate-test.js | 2 +- .../adapters/discovery-chain-test.js | 2 +- .../integration/adapters/intention-test.js | 2 +- .../tests/integration/adapters/kv-test.js | 2 +- .../tests/integration/adapters/node-test.js | 2 +- .../tests/integration/adapters/nspace-test.js | 2 +- .../adapters/oidc-provider-test.js | 2 +- .../integration/adapters/partition-test.js | 2 +- .../integration/adapters/permission-test.js | 2 +- .../tests/integration/adapters/policy-test.js | 2 +- .../tests/integration/adapters/role-test.js | 2 +- .../adapters/service-instance-test.js | 2 +- .../integration/adapters/service-test.js | 2 +- .../integration/adapters/session-test.js | 2 +- .../tests/integration/adapters/token-test.js | 2 +- .../integration/adapters/topology-test.js | 2 +- .../integration/components/app-view-test.js | 2 +- .../integration/components/aria-menu-test.js | 2 +- .../components/auth-profile-test.js | 2 +- .../components/code-editor-test.js | 2 +- .../components/confirmation-dialog-test.js | 2 +- .../components/consul/bucket/list-test.js | 2 +- .../consul/datacenter/selector-test.js | 2 +- .../components/consul/discovery-chain-test.js | 2 +- .../components/consul/hcp/home-test.js | 2 +- .../consul/intention/permission/form-test.js | 2 +- .../intention/permission/header/form-test.js | 2 +- .../consul/node/agentless-notice-test.js | 2 +- .../components/data-collection-test.js | 2 +- .../components/data-source-test.js | 2 +- .../components/delete-confirmation-test.js | 2 +- .../components/event-source-test.js | 2 +- .../components/freetext-filter-test.js | 2 +- .../components/hashicorp-consul-test.js | 2 +- .../integration/components/jwt-source-test.js | 2 +- .../components/list-collection-test.js | 2 +- .../components/oidc-select-test.js | 2 +- .../components/popover-menu-test.js | 2 +- .../components/radio-group-test.js | 2 +- .../tests/integration/components/ref-test.js | 2 +- .../components/resolver-card-test.js | 2 +- .../integration/components/route-card-test.js | 2 +- .../components/splitter-card-test.js | 2 +- .../integration/components/state-test.js | 2 +- .../integration/components/tab-nav-test.js | 2 +- .../components/tabular-collection-test.js | 2 +- .../components/tabular-details-test.js | 2 +- .../integration/components/tag-list-test.js | 2 +- .../components/toggle-button-test.js | 2 +- .../integration/components/token-list-test.js | 2 +- .../tests/integration/helpers/atob-test.js | 2 +- .../integration/helpers/dom-position-test.js | 2 +- .../integration/helpers/duration-from-test.js | 2 +- .../helpers/format-short-time-test.js | 2 +- .../tests/integration/helpers/is-href-test.js | 2 +- .../tests/integration/helpers/last-test.js | 2 +- .../integration/helpers/left-trim-test.js | 2 +- .../helpers/policy/datacenters-test.js | 2 +- .../integration/helpers/policy/typeof-test.js | 2 +- .../helpers/render-template-test.js | 2 +- .../integration/helpers/right-trim-test.js | 2 +- .../integration/helpers/route-match-test.js | 2 +- .../integration/helpers/searchable-test.js | 2 +- .../helpers/service/card-permissions-test.js | 2 +- .../helpers/service/external-source-test.js | 2 +- .../helpers/service/health-percentage-test.js | 2 +- .../tests/integration/helpers/slugify-test.js | 2 +- .../tests/integration/helpers/split-test.js | 2 +- .../integration/helpers/state-matches-test.js | 2 +- .../tests/integration/helpers/substr-test.js | 2 +- .../integration/helpers/svg-curve-test.js | 2 +- .../helpers/token/is-anonymous-test.js | 2 +- .../helpers/token/is-legacy-test.js | 2 +- .../integration/helpers/tween-to-test.js | 2 +- .../serializers/auth-method-test.js | 2 +- .../serializers/binding-rule-test.js | 2 +- .../serializers/coordinate-test.js | 2 +- .../serializers/discovery-chain-test.js | 2 +- .../integration/serializers/intention-test.js | 2 +- .../tests/integration/serializers/kv-test.js | 2 +- .../integration/serializers/node-test.js | 2 +- .../integration/serializers/nspace-test.js | 2 +- .../serializers/oidc-provider-test.js | 2 +- .../integration/serializers/partition-test.js | 2 +- .../integration/serializers/policy-test.js | 2 +- .../integration/serializers/role-test.js | 2 +- .../serializers/service-instance-test.js | 2 +- .../integration/serializers/service-test.js | 2 +- .../integration/serializers/session-test.js | 2 +- .../integration/serializers/token-test.js | 2 +- .../integration/serializers/topology-test.js | 2 +- .../services/repository/auth-method-test.js | 2 +- .../services/repository/coordinate-test.js | 2 +- .../services/repository/dc-test.js | 2 +- .../repository/discovery-chain-test.js | 2 +- .../services/repository/kv-test.js | 2 +- .../services/repository/node-test.js | 2 +- .../services/repository/policy-test.js | 2 +- .../services/repository/role-test.js | 2 +- .../services/repository/service-test.js | 2 +- .../services/repository/session-test.js | 2 +- .../services/repository/token-test.js | 2 +- .../services/repository/topology-test.js | 2 +- .../integration/services/routlet-test.js | 2 +- .../utils/dom/event-source/callable-test.js | 2 +- .../consul-ui/tests/lib/measure/getMeasure.js | 2 +- .../tests/lib/page-object/createCancelable.js | 2 +- .../tests/lib/page-object/createCreatable.js | 2 +- .../tests/lib/page-object/createDeletable.js | 2 +- .../tests/lib/page-object/createSubmitable.js | 2 +- .../consul-ui/tests/lib/page-object/index.js | 2 +- .../tests/lib/page-object/visitable.js | 2 +- ui/packages/consul-ui/tests/pages.js | 2 +- ui/packages/consul-ui/tests/pages/dc.js | 2 +- .../tests/pages/dc/acls/auth-methods/index.js | 2 +- .../consul-ui/tests/pages/dc/acls/edit.js | 2 +- .../consul-ui/tests/pages/dc/acls/index.js | 2 +- .../tests/pages/dc/acls/policies/edit.js | 2 +- .../tests/pages/dc/acls/policies/index.js | 2 +- .../tests/pages/dc/acls/roles/edit.js | 2 +- .../tests/pages/dc/acls/roles/index.js | 2 +- .../tests/pages/dc/acls/tokens/edit.js | 2 +- .../tests/pages/dc/acls/tokens/index.js | 2 +- .../tests/pages/dc/intentions/edit.js | 2 +- .../tests/pages/dc/intentions/index.js | 2 +- .../consul-ui/tests/pages/dc/kv/edit.js | 2 +- .../consul-ui/tests/pages/dc/kv/index.js | 2 +- .../consul-ui/tests/pages/dc/nodes/index.js | 2 +- .../consul-ui/tests/pages/dc/nodes/show.js | 2 +- .../consul-ui/tests/pages/dc/nspaces/edit.js | 2 +- .../consul-ui/tests/pages/dc/nspaces/index.js | 2 +- .../consul-ui/tests/pages/dc/peers/index.js | 2 +- .../consul-ui/tests/pages/dc/peers/show.js | 2 +- .../tests/pages/dc/routing-config.js | 2 +- .../tests/pages/dc/services/index.js | 2 +- .../tests/pages/dc/services/instance.js | 2 +- .../consul-ui/tests/pages/dc/services/show.js | 2 +- ui/packages/consul-ui/tests/pages/index.js | 2 +- ui/packages/consul-ui/tests/pages/settings.js | 2 +- ui/packages/consul-ui/tests/steps.js | 2 +- .../consul-ui/tests/steps/assertions/dom.js | 2 +- .../consul-ui/tests/steps/assertions/form.js | 2 +- .../consul-ui/tests/steps/assertions/http.js | 2 +- .../consul-ui/tests/steps/assertions/model.js | 2 +- .../consul-ui/tests/steps/assertions/page.js | 2 +- .../consul-ui/tests/steps/debug/index.js | 2 +- .../consul-ui/tests/steps/doubles/http.js | 2 +- .../consul-ui/tests/steps/doubles/model.js | 2 +- .../tests/steps/interactions/click.js | 2 +- .../tests/steps/interactions/form.js | 2 +- .../tests/steps/interactions/visit.js | 2 +- ui/packages/consul-ui/tests/test-helper.js | 2 +- .../consul-ui/tests/unit/abilities/-test.js | 2 +- .../tests/unit/adapters/application-test.js | 2 +- .../tests/unit/adapters/auth-method-test.js | 2 +- .../tests/unit/adapters/binding-rule-test.js | 2 +- .../tests/unit/adapters/coordinate-test.js | 2 +- .../unit/adapters/discovery-chain-test.js | 2 +- .../tests/unit/adapters/http-test.js | 2 +- .../tests/unit/adapters/intention-test.js | 2 +- .../consul-ui/tests/unit/adapters/kv-test.js | 2 +- .../tests/unit/adapters/node-test.js | 2 +- .../tests/unit/adapters/nspace-test.js | 2 +- .../tests/unit/adapters/oidc-provider-test.js | 2 +- .../tests/unit/adapters/partition-test.js | 2 +- .../tests/unit/adapters/permission-test.js | 2 +- .../tests/unit/adapters/policy-test.js | 2 +- .../tests/unit/adapters/proxy-test.js | 2 +- .../tests/unit/adapters/role-test.js | 2 +- .../unit/adapters/service-instance-test.js | 2 +- .../tests/unit/adapters/session-test.js | 2 +- .../tests/unit/adapters/token-test.js | 2 +- .../get-alternate-services-test.js | 2 +- .../discovery-chain/get-resolvers-test.js | 2 +- .../discovery-chain/get-splitters-test.js | 2 +- .../components/search-bar/filters-test.js | 2 +- .../unit/controllers/application-test.js | 2 +- .../dc/acls/policies/create-test.js | 2 +- .../controllers/dc/acls/policies/edit-test.js | 2 +- .../controllers/dc/acls/roles/create-test.js | 2 +- .../controllers/dc/acls/roles/edit-test.js | 2 +- .../controllers/dc/acls/tokens/create-test.js | 2 +- .../controllers/dc/acls/tokens/edit-test.js | 2 +- .../unit/filter/predicates/intention-test.js | 2 +- .../unit/filter/predicates/service-test.js | 2 +- .../tests/unit/helpers/document-attrs-test.js | 2 +- .../unit/helpers/policy/datacenters-test.js | 2 +- .../unit/helpers/token/is-anonymous-test.js | 2 +- .../unit/helpers/token/is-legacy-test.js | 2 +- .../tests/unit/mixins/policy/as-many-test.js | 2 +- .../tests/unit/mixins/role/as-many-test.js | 2 +- .../unit/mixins/with-blocking-actions-test.js | 2 +- .../tests/unit/models/auth-method-test.js | 2 +- .../tests/unit/models/coordinate-test.js | 2 +- .../consul-ui/tests/unit/models/dc-test.js | 2 +- .../tests/unit/models/discovery-chain-test.js | 2 +- .../tests/unit/models/intention-test.js | 2 +- .../consul-ui/tests/unit/models/kv-test.js | 2 +- .../consul-ui/tests/unit/models/node-test.js | 2 +- .../tests/unit/models/oidc-provider-test.js | 2 +- .../tests/unit/models/partition-test.js | 2 +- .../tests/unit/models/permission-test.js | 2 +- .../tests/unit/models/policy-test.js | 2 +- .../consul-ui/tests/unit/models/proxy-test.js | 2 +- .../consul-ui/tests/unit/models/role-test.js | 2 +- .../unit/models/service-instance-test.js | 2 +- .../tests/unit/models/service-test.js | 2 +- .../tests/unit/models/session-test.js | 2 +- .../consul-ui/tests/unit/models/token-test.js | 2 +- .../tests/unit/routes/application-test.js | 2 +- .../consul-ui/tests/unit/routes/dc-test.js | 2 +- .../routes/dc/acls/policies/create-test.js | 2 +- .../unit/routes/dc/acls/policies/edit-test.js | 2 +- .../routes/dc/acls/policies/index-test.js | 2 +- .../unit/routes/dc/acls/roles/create-test.js | 2 +- .../unit/routes/dc/acls/roles/edit-test.js | 2 +- .../unit/routes/dc/acls/roles/index-test.js | 2 +- .../unit/routes/dc/acls/tokens/create-test.js | 2 +- .../unit/routes/dc/acls/tokens/edit-test.js | 2 +- .../unit/routes/dc/acls/tokens/index-test.js | 2 +- .../unit/search/predicates/intention-test.js | 2 +- .../tests/unit/search/predicates/kv-test.js | 2 +- .../tests/unit/search/predicates/node-test.js | 2 +- .../unit/search/predicates/policy-test.js | 2 +- .../tests/unit/search/predicates/role-test.js | 2 +- .../unit/search/predicates/service-test.js | 2 +- .../unit/search/predicates/token-test.js | 2 +- .../unit/serializers/application-test.js | 2 +- .../unit/serializers/auth-method-test.js | 2 +- .../unit/serializers/binding-rule-test.js | 2 +- .../tests/unit/serializers/coordinate-test.js | 2 +- .../unit/serializers/discovery-chain-test.js | 2 +- .../tests/unit/serializers/intention-test.js | 2 +- .../tests/unit/serializers/kv-test.js | 2 +- .../tests/unit/serializers/node-test.js | 2 +- .../tests/unit/serializers/nspace-test.js | 2 +- .../unit/serializers/oidc-provider-test.js | 2 +- .../tests/unit/serializers/partition-test.js | 2 +- .../tests/unit/serializers/permission-test.js | 2 +- .../tests/unit/serializers/policy-test.js | 2 +- .../tests/unit/serializers/proxy-test.js | 2 +- .../tests/unit/serializers/role-test.js | 2 +- .../unit/serializers/service-instance-test.js | 2 +- .../tests/unit/serializers/service-test.js | 2 +- .../tests/unit/serializers/session-test.js | 2 +- .../tests/unit/serializers/token-test.js | 2 +- .../tests/unit/services/atob-test.js | 2 +- .../tests/unit/services/btoa-test.js | 2 +- .../unit/services/client/connections-test.js | 2 +- .../tests/unit/services/client/http-test.js | 2 +- .../services/client/transports/xhr-test.js | 2 +- .../services/clipboard/local-storage-test.js | 2 +- .../tests/unit/services/clipboard/os-test.js | 2 +- .../unit/services/code-mirror/linter-test.js | 2 +- .../data-source/protocols/http-test.js | 2 +- .../protocols/local-storage-test.js | 2 +- .../tests/unit/services/data-structs-test.js | 2 +- .../consul-ui/tests/unit/services/dom-test.js | 2 +- .../tests/unit/services/encoder-test.js | 2 +- .../consul-ui/tests/unit/services/env-test.js | 2 +- .../tests/unit/services/feedback-test.js | 2 +- .../tests/unit/services/form-test.js | 2 +- .../tests/unit/services/logger-test.js | 2 +- .../tests/unit/services/repository-test.js | 2 +- .../services/repository/auth-method-test.js | 2 +- .../services/repository/coordinate-test.js | 2 +- .../tests/unit/services/repository/dc-test.js | 2 +- .../repository/discovery-chain-test.js | 2 +- .../services/repository/intention-test.js | 2 +- .../tests/unit/services/repository/kv-test.js | 2 +- .../unit/services/repository/node-test.js | 2 +- .../unit/services/repository/nspace-test.js | 2 +- .../services/repository/oidc-provider-test.js | 2 +- .../services/repository/partition-test.js | 2 +- .../services/repository/permission-test.js | 2 +- .../unit/services/repository/policy-test.js | 2 +- .../unit/services/repository/role-test.js | 2 +- .../repository/service-instance-test.js | 2 +- .../unit/services/repository/service-test.js | 2 +- .../unit/services/repository/session-test.js | 2 +- .../unit/services/repository/token-test.js | 2 +- .../tests/unit/services/search-test.js | 2 +- .../tests/unit/services/settings-test.js | 2 +- .../tests/unit/services/sort-test.js | 2 +- .../tests/unit/services/state-test.js | 2 +- .../tests/unit/services/store-test.js | 2 +- .../tests/unit/services/temporal-test.js | 2 +- .../tests/unit/services/ticker-test.js | 2 +- .../tests/unit/services/timeout-test.js | 2 +- .../tests/unit/sort/comparators/node-test.js | 2 +- .../unit/sort/comparators/service-test.js | 2 +- .../consul-ui/tests/unit/utils/ascend-test.js | 2 +- .../consul-ui/tests/unit/utils/atob-test.js | 2 +- .../consul-ui/tests/unit/utils/btoa-test.js | 2 +- .../tests/unit/utils/callable-type-test.js | 2 +- .../unit/utils/create-fingerprinter-test.js | 2 +- .../unit/utils/dom/click-first-anchor-test.js | 2 +- .../tests/unit/utils/dom/closest-test.js | 2 +- .../unit/utils/dom/create-listeners-test.js | 2 +- .../utils/dom/event-source/blocking-test.js | 2 +- .../unit/utils/dom/event-source/cache-test.js | 2 +- .../utils/dom/event-source/callable-test.js | 2 +- .../unit/utils/dom/event-source/index-test.js | 2 +- .../utils/dom/event-source/openable-test.js | 2 +- .../unit/utils/dom/event-source/proxy-test.js | 2 +- .../utils/dom/event-source/resolver-test.js | 2 +- .../utils/dom/event-source/storage-test.js | 2 +- .../unit/utils/dom/event-target/rsvp-test.js | 2 +- .../utils/dom/get-component-factory-test.js | 2 +- .../tests/unit/utils/dom/is-outside-test.js | 2 +- .../unit/utils/dom/normalize-event-test.js | 2 +- .../tests/unit/utils/dom/qsa-factory-test.js | 2 +- .../tests/unit/utils/dom/sibling-test.js | 2 +- .../tests/unit/utils/get-environment-test.js | 2 +- .../unit/utils/get-form-name-property-test.js | 2 +- .../unit/utils/helpers/call-if-type-test.js | 2 +- .../unit/utils/http/create-headers-test.js | 2 +- .../utils/http/create-query-params-test.js | 2 +- .../tests/unit/utils/http/create-url-test.js | 2 +- .../tests/unit/utils/http/error-test.js | 2 +- .../tests/unit/utils/http/request-test.js | 2 +- .../tests/unit/utils/http/xhr-test.js | 2 +- .../tests/unit/utils/isFolder-test.js | 2 +- .../tests/unit/utils/keyToArray-test.js | 2 +- .../tests/unit/utils/left-trim-test.js | 2 +- .../tests/unit/utils/maybe-call-test.js | 2 +- .../tests/unit/utils/merge-checks-test.js | 2 +- .../tests/unit/utils/non-empty-set-test.js | 2 +- .../tests/unit/utils/path/resolve-test.js | 2 +- .../tests/unit/utils/promisedTimeout-test.js | 2 +- .../tests/unit/utils/right-trim-test.js | 2 +- .../unit/utils/routing/transitionable-test.js | 2 +- .../tests/unit/utils/routing/walk-test.js | 2 +- .../tests/unit/utils/routing/wildcard-test.js | 2 +- .../unit/utils/storage/local-storage-test.js | 2 +- .../tests/unit/utils/templatize-test.js | 2 +- .../tests/unit/utils/ticker/index-test.js | 2 +- .../tests/unit/utils/ucfirst-test.js | 2 +- .../unit/utils/update-array-object-test.js | 2 +- .../consul-ui/translations/common/en-us.yaml | 2 +- .../translations/components/app/en-us.yaml | 2 +- .../translations/components/consul/en-us.yaml | 2 +- .../en-us.yaml | 2 +- .../consul-ui/translations/models/en-us.yaml | 2 +- .../consul-ui/translations/routes/en-us.yaml | 2 +- .../vendor/consul-ui/routes-debug.js | 2 +- .../consul-ui/vendor/consul-ui/routes.js | 2 +- .../vendor/consul-ui/services-debug.js | 2 +- .../consul-ui/vendor/consul-ui/services.js | 2 +- ui/packages/consul-ui/vendor/init.js | 2 +- .../vendor/metrics-providers/consul.js | 2 +- .../vendor/metrics-providers/prometheus.js | 2 +- ui/yarn.lock | 4382 ++++++++--------- version/VERSION | 2 +- version/fips.go | 3 - version/version.go | 2 +- version/version_test.go | 2 +- website/.eslintrc.js | 2 +- website/.stylelintrc.js | 2 +- website/content/api-docs/acl/auth-methods.mdx | 8 +- .../content/api-docs/acl/binding-rules.mdx | 99 +- website/content/api-docs/acl/index.mdx | 10 +- website/content/api-docs/acl/policies.mdx | 2 +- website/content/api-docs/acl/roles.mdx | 81 +- .../api-docs/acl/templated-policies.mdx | 189 - website/content/api-docs/acl/tokens.mdx | 33 +- website/content/api-docs/agent/check.mdx | 2 +- website/content/api-docs/agent/connect.mdx | 2 +- website/content/api-docs/agent/service.mdx | 2 +- website/content/api-docs/catalog.mdx | 4 +- website/content/api-docs/config.mdx | 2 +- .../content/api-docs/connect/intentions.mdx | 2 +- website/content/api-docs/discovery-chain.mdx | 8 +- website/content/api-docs/health.mdx | 2 +- website/content/api-docs/kv.mdx | 2 +- website/content/api-docs/session.mdx | 2 +- website/content/api-docs/status.mdx | 2 +- .../commands/acl/templated-policy/index.mdx | 72 - .../commands/acl/templated-policy/list.mdx | 43 - .../commands/acl/templated-policy/preview.mdx | 130 - .../commands/acl/templated-policy/read.mdx | 46 - website/content/commands/connect/envoy.mdx | 2 +- website/content/commands/debug.mdx | 4 +- website/content/commands/snapshot/agent.mdx | 2 +- website/content/commands/watch.mdx | 5 - .../content/docs/agent/config/cli-flags.mdx | 6 +- .../docs/agent/config/config-files.mdx | 24 +- website/content/docs/agent/index.mdx | 3 + .../usage/limit-request-rates-from-ips.mdx | 6 +- .../usage/set-global-traffic-rate-limits.mdx | 2 +- website/content/docs/agent/rpc.mdx | 260 + website/content/docs/agent/telemetry.mdx | 4 +- .../api-gateway/configuration/gateway.mdx | 4 +- .../configuration/gatewayclass.mdx | 2 +- .../configuration/gatewayclassconfig.mdx | 0 .../docs/api-gateway/configuration/index.mdx | 24 + .../api-gateway/configuration/meshservice.mdx | 0 .../api-gateway/configuration/routes.mdx | 343 +- website/content/docs/api-gateway/index.mdx | 45 + .../install.mdx} | 16 +- .../content/docs/api-gateway/tech-specs.mdx | 71 + .../upgrades.mdx} | 8 +- .../usage}/errors.mdx | 2 +- .../usage}/reroute-http-requests.mdx | 10 +- .../usage}/route-to-peered-services.mdx | 18 +- .../content/docs/api-gateway/usage/usage.mdx | 87 + website/content/docs/connect/ca/index.mdx | 21 +- website/content/docs/connect/ca/vault.mdx | 40 +- .../docs/connect/cluster-peering/index.mdx | 2 +- .../usage/create-sameness-groups.mdx | 115 +- .../usage/peering-traffic-management.mdx | 2 +- .../control-plane-request-limit.mdx | 2 +- .../connect/config-entries/http-route.mdx | 1128 ----- .../config-entries/ingress-gateway.mdx | 17 +- .../connect/config-entries/proxy-defaults.mdx | 60 +- .../connect/config-entries/sameness-group.mdx | 70 +- .../config-entries/service-defaults.mdx | 978 ++-- .../config-entries/service-resolver.mdx | 39 +- .../connect/config-entries/service-router.mdx | 2 +- .../content/docs/connect/dataplane/index.mdx | 71 +- .../{manage-traffic => }/failover/index.mdx | 27 +- .../configuration}/api-gateway.mdx | 235 +- .../configuration/gatewaypolicy.mdx | 259 - .../api-gateway/configuration/http-route.mdx | 684 +++ .../api-gateway/configuration/index.mdx | 44 - .../configuration}/inline-certificate.mdx | 2 +- .../configuration/routeauthfilter.mdx | 139 - .../configuration/routeretryfilter.mdx | 206 - .../configuration/routetimeoutfilter.mdx | 114 - .../api-gateway/configuration}/tcp-route.mdx | 2 +- .../api-gateway/define-routes/routes-k8s.mdx | 68 - .../api-gateway/define-routes/routes-vms.mdx | 121 - .../api-gateway/deploy/listeners-k8s.mdx | 74 - .../api-gateway/deploy/listeners-vms.mdx | 113 - .../connect/gateways/api-gateway/index.mdx | 73 +- .../secure-traffic/encrypt-vms.mdx | 66 - .../secure-traffic/verify-jwts-k8s.mdx | 72 - .../secure-traffic/verify-jwts-vms.mdx | 43 - .../gateways/api-gateway/tech-specs.mdx | 157 - .../connect/gateways/api-gateway/usage.mdx | 211 + .../content/docs/connect/gateways/index.mdx | 4 +- .../connect/gateways/terminating-gateway.mdx | 2 +- .../discovery-chain.mdx | 0 .../{manage-traffic => l7-traffic}/index.mdx | 8 +- .../manage-traffic/failover/sameness.mdx | 205 - .../manage-traffic/limit-request-rates.mdx | 78 - .../route-to-local-upstreams.mdx | 113 - .../proxies/deploy-sidecar-services.mdx | 2 +- .../configuration/ext-authz.mdx | 13 - .../configuration/otel-access-logging.mdx | 390 -- .../envoy-extensions/configuration/wasm.mdx | 4 +- .../proxies/envoy-extensions/index.mdx | 5 - .../envoy-extensions/usage/ext-authz.mdx | 29 +- .../proxies/envoy-extensions/usage/lua.mdx | 12 +- .../usage/otel-access-logging.mdx | 148 - .../content/docs/connect/proxies/envoy.mdx | 12 +- .../content/docs/connect/proxies/index.mdx | 12 +- .../docs/connect/proxies/integrate.mdx | 4 +- .../proxies/proxy-config-reference.mdx | 4 +- .../consul-vs-other/service-mesh-compare.mdx | 2 +- .../content/docs/dynamic-app-config/kv.mdx | 2 +- website/content/docs/ecs/architecture.mdx | 280 +- .../ecs/{reference => }/compatibility.mdx | 0 .../configuration-reference.mdx | 2 +- .../docs/ecs/deploy/bind-addresses.mdx | 47 - .../docs/ecs/deploy/configure-routes.mdx | 79 - website/content/docs/ecs/deploy/manual.mdx | 342 -- .../ecs/deploy/migrate-existing-tasks.mdx | 99 - website/content/docs/ecs/deploy/terraform.mdx | 478 -- website/content/docs/ecs/enterprise.mdx | 4 +- website/content/docs/ecs/index.mdx | 58 +- .../docs/ecs/manual/acl-controller.mdx | 190 + website/content/docs/ecs/manual/install.mdx | 556 +++ .../docs/ecs/manual/secure-configuration.mdx | 545 ++ .../docs/ecs/reference/consul-server-json.mdx | 120 - website/content/docs/ecs/requirements.mdx | 32 + .../content/docs/ecs/task-resource-usage.mdx | 37 + website/content/docs/ecs/tech-specs.mdx | 52 - .../content/docs/ecs/terraform/install.mdx | 452 ++ .../ecs/terraform/migrate-existing-tasks.mdx | 115 + .../ecs/terraform/secure-configuration.mdx | 177 + .../docs/ecs/upgrade-to-dataplanes.mdx | 68 - website/content/docs/internals/index.mdx | 2 +- .../docs/k8s/annotations-and-labels.mdx | 7 +- website/content/docs/k8s/compatibility.mdx | 13 +- .../usage/create-sameness-groups.mdx | 126 +- .../usage/establish-peering.mdx | 2 +- .../cluster-peering/usage/l7-traffic.mdx | 2 +- .../cluster-peering/usage/manage-peering.mdx | 4 +- website/content/docs/k8s/connect/index.mdx | 16 +- .../enable-transparent-proxy.mdx | 2 - .../multi-cluster/index.mdx | 2 +- .../multi-cluster/vms-and-kubernetes.mdx | 1 + website/content/docs/k8s/helm.mdx | 144 +- .../docs/k8s/installation/install-cli.mdx | 19 - .../content/docs/k8s/installation/install.mdx | 23 +- .../docs/k8s/l7-traffic/failover-tproxy.mdx | 2 +- .../l7-traffic/route-to-virtual-services.mdx | 2 +- .../content/docs/k8s/multiport/configure.mdx | 489 -- website/content/docs/k8s/multiport/index.mdx | 69 - website/content/docs/k8s/upgrade/index.mdx | 2 +- website/content/docs/nia/configuration.mdx | 2 +- website/content/docs/nia/usage/errors-ref.mdx | 2 +- .../consul-api-gateway/v0_1_x.mdx | 2 +- .../consul-api-gateway/v0_2_x.mdx | 2 +- .../consul-api-gateway/v0_3_x.mdx | 2 +- .../consul-api-gateway/v0_4_x.mdx | 6 +- .../consul-api-gateway/v0_5_x.mdx | 4 +- .../docs/release-notes/consul-ecs/v0_5_x.mdx | 4 +- .../docs/release-notes/consul-k8s/v1_2_x.mdx | 2 +- .../docs/release-notes/consul/v1_16_x.mdx | 4 +- .../docs/release-notes/consul/v1_17_x.mdx | 82 - .../content/docs/security/acl/acl-roles.mdx | 121 +- .../docs/security/acl/auth-methods/index.mdx | 2 +- website/content/docs/security/acl/index.mdx | 24 +- .../tokens/create/create-a-service-token.mdx | 52 +- .../docs/security/acl/tokens/index.mdx | 41 +- .../docs/security/security-models/core.mdx | 6 + .../checks-configuration-reference.mdx | 4 +- .../services-configuration-reference.mdx | 101 +- .../services/discovery/dns-configuration.mdx | 2 +- .../services/discovery/dns-static-lookups.mdx | 4 +- .../docs/upgrading/upgrade-specific.mdx | 20 +- website/data/api-docs-nav-data.json | 4 - website/data/commands-nav-data.json | 21 - website/data/docs-nav-data.json | 365 +- website/prettier.config.js | 2 +- website/public/ie-warning.js | 2 +- ...ul-on-ecs-architecture-dataplanes-dark.jpg | Bin 68588 -> 0 bytes .../consul-on-ecs-architecture-dataplanes.jpg | Bin 67505 -> 0 bytes website/redirects.js | 122 +- website/scripts/should-build.sh | 2 +- website/scripts/website-build.sh | 2 +- website/scripts/website-start.sh | 2 +- 8536 files changed, 44427 insertions(+), 202994 deletions(-) delete mode 100644 .changelog/17107.txt delete mode 100644 .changelog/17155.txt delete mode 100644 .changelog/17481.txt delete mode 100644 .changelog/17593.txt delete mode 100644 .changelog/17694.txt delete mode 100644 .changelog/17831.txt delete mode 100644 .changelog/17936.txt delete mode 100644 .changelog/18007.txt delete mode 100644 .changelog/18300.txt create mode 100644 .changelog/18303.txt delete mode 100644 .changelog/18324.txt delete mode 100644 .changelog/18336.txt delete mode 100644 .changelog/18367.txt delete mode 100644 .changelog/18439.txt delete mode 100644 .changelog/18504.txt delete mode 100644 .changelog/18560.txt delete mode 100644 .changelog/18573.txt delete mode 100644 .changelog/18583.txt delete mode 100644 .changelog/18646.txt delete mode 100644 .changelog/18668.txt delete mode 100644 .changelog/18708.txt delete mode 100644 .changelog/18719.txt delete mode 100644 .changelog/18769.txt delete mode 100644 .changelog/18813.txt delete mode 100644 .changelog/18816.txt delete mode 100644 .changelog/18943.txt delete mode 100644 .changelog/18983.txt delete mode 100644 .changelog/18994.txt delete mode 100644 .changelog/19077.txt create mode 100644 .changelog/19120.txt delete mode 100644 .changelog/19218.txt create mode 100644 .changelog/19273.txt delete mode 100644 .changelog/19306.txt delete mode 100644 .changelog/19311.txt delete mode 100644 .changelog/19314.txt delete mode 100644 .changelog/19389.txt delete mode 100644 .changelog/_18366.txt delete mode 100644 .changelog/_18422.txt delete mode 100644 .changelog/_6074.txt delete mode 100644 .changelog/_6870.txt delete mode 100755 .github/scripts/get_runner_classes_windows.sh rename .github/workflows/{nightly-test-1.16.x.yaml => nightly-test-1.12.x.yaml} (75%) rename .github/workflows/{nightly-test-1.17.x.yaml => nightly-test-1.13.x.yaml} (73%) delete mode 100644 .github/workflows/nightly-test-integrations-1.15.x.yml delete mode 100644 .github/workflows/nightly-test-integrations-1.16.x.yml delete mode 100644 .github/workflows/nightly-test-integrations-1.17.x.yml delete mode 100644 .github/workflows/reusable-dev-build-windows.yml delete mode 100644 .github/workflows/test-integrations-windows.yml delete mode 100644 .release/docker/docker-entrypoint-windows.sh delete mode 100644 Dockerfile-windows rename Makefile => GNUmakefile (71%) create mode 100644 NOTICE.md delete mode 100644 agent/cacheshim/cache.go delete mode 100644 agent/connect/uri_workload_identity.go delete mode 100644 agent/connect/uri_workload_identity_ce.go delete mode 100644 agent/connect/uri_workload_identity_ce_test.go create mode 100644 agent/connect_auth.go delete mode 100644 agent/consul/fsm/decode_ce.go delete mode 100644 agent/consul/fsm/decode_downgrade.go delete mode 100644 agent/consul/gateways/controller_gateways_ce.go delete mode 100644 agent/consul/tenancy_bridge.go delete mode 100644 agent/consul/tenancy_bridge_ce.go delete mode 100644 agent/consul/testdata/v2-resource-dependencies.md delete mode 100644 agent/consul/type_registry.go delete mode 100644 agent/envoyextensions/builtin/otel-access-logging/otel_access_logging.go delete mode 100644 agent/envoyextensions/builtin/otel-access-logging/otel_access_logging_test.go delete mode 100644 agent/envoyextensions/builtin/otel-access-logging/structs.go delete mode 100644 agent/envoyextensions/registered_extensions_ce.go delete mode 100644 agent/grpc-external/services/resource/mock_TenancyBridge.go delete mode 100644 agent/grpc-external/services/resource/server_ce.go delete mode 100644 agent/grpc-external/services/resource/server_ce_test.go delete mode 100644 agent/grpc-external/services/resource/testing/testing_ce.go rename agent/leafcert/{leafcert_test_helpers.go => signer_test.go} (56%) delete mode 100644 agent/proxycfg-sources/catalog/config_source_oss.go delete mode 100644 agent/proxycfg/api_gateway_ce.go delete mode 100644 agent/proxycfg/config_snapshot_glue.go delete mode 100644 agent/proxycfg/config_snapshot_glue_test.go delete mode 100644 agent/structs/acl_templated_policy.go delete mode 100644 agent/structs/acl_templated_policy_ce.go delete mode 100644 agent/structs/acl_templated_policy_ce_test.go delete mode 100644 agent/structs/acl_templated_policy_test.go delete mode 100644 agent/structs/acltemplatedpolicy/policies/ce/dns.hcl delete mode 100644 agent/structs/acltemplatedpolicy/policies/ce/node.hcl delete mode 100644 agent/structs/acltemplatedpolicy/policies/ce/nomad-server.hcl delete mode 100644 agent/structs/acltemplatedpolicy/policies/ce/service.hcl delete mode 100644 agent/structs/acltemplatedpolicy/policies/ce/workload-identity.hcl delete mode 100644 agent/structs/acltemplatedpolicy/schemas/node.json delete mode 100644 agent/structs/acltemplatedpolicy/schemas/service.json delete mode 100644 agent/structs/acltemplatedpolicy/schemas/workload-identity.json delete mode 100644 agent/structs/config_entry_apigw_jwt_ce.go delete mode 100644 agent/structs/structs.deepcopy_ce.go rename agent/xds/{config => }/config.go (98%) rename agent/xds/{config => }/config_test.go (99%) delete mode 100644 agent/xds/configfetcher/config_fetcher.go delete mode 100644 agent/xds/gw_per_route_filters_ce.go delete mode 100644 agent/xds/jwt_authn_ce.go delete mode 100644 agent/xds/locality_policy.go delete mode 100644 agent/xds/locality_policy_ce.go create mode 100644 agent/xds/naming.go delete mode 100644 agent/xds/naming/naming.go create mode 100644 agent/xds/net_fallback.go rename agent/xds/{platform => }/net_linux.go (85%) delete mode 100644 agent/xds/platform/net_fallback.go delete mode 100644 agent/xds/proxystateconverter/clusters.go delete mode 100644 agent/xds/proxystateconverter/converter.go delete mode 100644 agent/xds/proxystateconverter/endpoints.go delete mode 100644 agent/xds/proxystateconverter/failover_policy.go delete mode 100644 agent/xds/proxystateconverter/failover_policy_ce.go delete mode 100644 agent/xds/proxystateconverter/listeners.go delete mode 100644 agent/xds/proxystateconverter/locality_policy.go delete mode 100644 agent/xds/proxystateconverter/locality_policy_ce.go delete mode 100644 agent/xds/proxystateconverter/routes.go rename agent/xds/{response => }/response.go (80%) delete mode 100644 agent/xds/testdata/builtin_extension/clusters/otel-access-logging-http.latest.golden delete mode 100644 agent/xds/testdata/builtin_extension/endpoints/otel-access-logging-http.latest.golden delete mode 100644 agent/xds/testdata/builtin_extension/listeners/otel-access-logging-http.latest.golden delete mode 100644 agent/xds/testdata/builtin_extension/routes/otel-access-logging-http.latest.golden create mode 100644 agent/xds/testdata/clusters/api-gateway-with-http-route-and-inline-certificate.latest.golden delete mode 100644 agent/xds/testdata/clusters/api-gateway-with-http-route.latest.golden rename agent/xds/testdata/clusters/{api-gateway-with-multiple-inline-certificates.latest.golden => api-gateway-with-tcp-route-and-inline-certificate.envoy-1-21-x.golden} (59%) delete mode 100644 agent/xds/testdata/clusters/connect-proxy-with-chain-http2.latest.golden delete mode 100644 agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden delete mode 100644 agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams-http2.latest.golden delete mode 100644 agent/xds/testdata/clusters/custom-passive-healthcheck-zero-consecutive_5xx.latest.golden delete mode 100644 agent/xds/testdata/clusters/custom-upstream-with-prepared-query.latest.golden delete mode 100644 agent/xds/testdata/clusters/expose-checks.latest.golden rename agent/xds/testdata/clusters/{api-gateway-with-http-route-timeoutfilter-one-set.latest.golden => ingress-with-overwrite-defaults-service-passive-health-check.latest.golden} (79%) delete mode 100644 agent/xds/testdata/clusters/mesh-gateway-using-federation-control-plane.latest.golden rename agent/{xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports.golden => xds/testdata/endpoints/api-gateway-with-http-route-and-inline-certificate.latest.golden} (60%) delete mode 100644 agent/xds/testdata/endpoints/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden delete mode 100644 agent/xds/testdata/endpoints/api-gateway-with-http-route.latest.golden delete mode 100644 agent/xds/testdata/endpoints/api-gateway-with-multiple-inline-certificates.latest.golden delete mode 100644 agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden delete mode 100644 agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams-http2.latest.golden delete mode 100644 agent/xds/testdata/endpoints/mesh-gateway-using-federation-control-plane.latest.golden create mode 100644 agent/xds/testdata/listeners/api-gateway-tcp-listeners.latest.golden create mode 100644 agent/xds/testdata/listeners/api-gateway-with-http-route-and-inline-certificate.latest.golden delete mode 100644 agent/xds/testdata/listeners/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden delete mode 100644 agent/xds/testdata/listeners/api-gateway-with-http-route.latest.golden delete mode 100644 agent/xds/testdata/listeners/api-gateway-with-multiple-inline-certificates.latest.golden delete mode 100644 agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden delete mode 100644 agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams-http2.latest.golden delete mode 100644 agent/xds/testdata/listeners/custom-upstream-with-prepared-query.latest.golden delete mode 100644 agent/xds/testdata/listeners/expose-checks-grpc.latest.golden delete mode 100644 agent/xds/testdata/listeners/expose-checks-http-with-bind-override.latest.golden rename agent/xds/testdata/listeners/{expose-checks-http.latest.golden => expose-checks.latest.golden} (97%) delete mode 100644 agent/xds/testdata/listeners/ingress-with-tls-mixed-cipher-suites-listeners.latest.golden delete mode 100644 agent/xds/testdata/listeners/ingress-with-tls-mixed-max-version-listeners.latest.golden delete mode 100644 agent/xds/testdata/listeners/mesh-gateway-using-federation-control-plane.latest.golden delete mode 100644 agent/xds/testdata/listeners/terminating-gateway-custom-trace-listener.latest.golden delete mode 100644 agent/xds/testdata/rbac/v2-default-allow.golden delete mode 100644 agent/xds/testdata/rbac/v2-default-deny.golden delete mode 100644 agent/xds/testdata/rbac/v2-ignore-empty-permissions.golden delete mode 100644 agent/xds/testdata/rbac/v2-kitchen-sink.golden rename agent/xds/testdata/routes/{api-gateway-with-http-route-timeoutfilter-one-set.latest.golden => api-gateway-with-http-route-and-inline-certificate.latest.golden} (76%) delete mode 100644 agent/xds/testdata/routes/api-gateway-with-http-route.latest.golden delete mode 100644 agent/xds/testdata/routes/api-gateway-with-multiple-inline-certificates.latest.golden delete mode 100644 agent/xds/testdata/routes/connect-proxy-resolver-with-lb.latest.golden delete mode 100644 agent/xds/testdata/routes/connect-proxy-route-to-lb-resolver.latest.golden delete mode 100644 agent/xds/testdata/routes/connect-proxy-splitter-overweight.latest.golden delete mode 100644 agent/xds/testdata/routes/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden delete mode 100644 agent/xds/testdata/routes/connect-proxy-with-peered-upstreams-http2.latest.golden delete mode 100644 agent/xds/testdata/secrets/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden delete mode 100644 agent/xds/testdata/secrets/api-gateway-with-http-route.latest.golden delete mode 100644 agent/xds/testdata/secrets/api-gateway-with-multiple-inline-certificates.latest.golden delete mode 100644 agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden delete mode 100644 agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-http2.latest.golden delete mode 100644 agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-listener-override.latest.golden delete mode 100644 agent/xdsv2/cluster_resources.go delete mode 100644 agent/xdsv2/endpoint_resources.go delete mode 100644 agent/xdsv2/listener_resources.go delete mode 100644 agent/xdsv2/rbac_resources.go delete mode 100644 agent/xdsv2/resources.go delete mode 100644 agent/xdsv2/resources_test.go delete mode 100644 agent/xdsv2/route_resources.go delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multi-destination.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden delete mode 100644 agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/l4-single-workload-address-without-ports.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/l7-expose-paths.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/local-and-inbound-connections.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multi-destination.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden delete mode 100644 agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/l4-single-workload-address-without-ports.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/l7-expose-paths.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multi-destination.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden delete mode 100644 agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/l4-single-workload-address-without-ports.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/l7-expose-paths.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/local-and-inbound-connections.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multi-destination.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/mixed-multi-destination.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden delete mode 100644 agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden delete mode 100644 agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/routes/source/l4-single-workload-address-without-ports.golden delete mode 100644 agent/xdsv2/testdata/routes/source/l7-expose-paths.golden delete mode 100644 agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden delete mode 100644 api/.copywrite.hcl delete mode 100644 api/LICENSE delete mode 100644 api/config_entry_routes_test.go delete mode 100755 build-support/scripts/check-allowed-imports.sh delete mode 100755 build-support/scripts/copywrite-exceptions.sh delete mode 100644 build-support/windows/Dockerfile-consul-dev-windows delete mode 100644 build-support/windows/Dockerfile-consul-local-windows delete mode 100644 build-support/windows/Dockerfile-openzipkin-windows delete mode 100644 build-support/windows/build-consul-dev-image.sh delete mode 100644 build-support/windows/build-consul-local-images.sh delete mode 100644 build-support/windows/build-test-sds-server-image.sh delete mode 100644 build-support/windows/windows-test.md delete mode 100644 command/acl/templatedpolicy/formatter.go delete mode 100644 command/acl/templatedpolicy/formatter_ce_test.go delete mode 100644 command/acl/templatedpolicy/formatter_test.go delete mode 100644 command/acl/templatedpolicy/list/templated_policy_list.go delete mode 100644 command/acl/templatedpolicy/list/templated_policy_list_test.go delete mode 100644 command/acl/templatedpolicy/preview/templated_policy_preview.go delete mode 100644 command/acl/templatedpolicy/preview/templated_policy_preview_test.go delete mode 100644 command/acl/templatedpolicy/read/templated_policy_read.go delete mode 100644 command/acl/templatedpolicy/read/templated_policy_read_test.go delete mode 100644 command/acl/templatedpolicy/templated_policy.go delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.json.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.pretty-meta.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.pretty.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.json.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.pretty-meta.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.pretty.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.json.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.pretty-meta.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.pretty.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.json.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.pretty-meta.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.pretty.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicyList/ce/list.json.golden delete mode 100644 command/acl/templatedpolicy/testdata/FormatTemplatedPolicyList/ce/list.pretty.golden delete mode 100644 command/connect/envoy/exec_supported.go delete mode 100644 command/connect/envoy/exec_windows.go delete mode 100644 command/resource/apply/apply.go delete mode 100644 command/resource/apply/apply_test.go delete mode 100644 command/resource/client/client.go delete mode 100644 command/resource/delete/delete.go delete mode 100644 command/resource/delete/delete_test.go delete mode 100644 command/resource/helper.go delete mode 100644 command/resource/helper_test.go delete mode 100644 command/resource/list/list.go delete mode 100644 command/resource/list/list_test.go delete mode 100644 command/resource/read/read.go delete mode 100644 command/resource/read/read_test.go delete mode 100644 command/resource/resource.go delete mode 100644 command/resource/testdata/demo.hcl delete mode 100644 command/resource/testdata/invalid.hcl delete mode 100644 command/resource/testdata/invalid_type.hcl delete mode 100644 command/resource/testdata/nested_data.hcl create mode 100644 fixup_acl_move.sh delete mode 100644 grafana/consul-k8s-control-plane-monitoring.json delete mode 100644 internal/auth/exports.go delete mode 100644 internal/auth/internal/controllers/register.go delete mode 100644 internal/auth/internal/controllers/trafficpermissions/controller.go delete mode 100644 internal/auth/internal/controllers/trafficpermissions/controller_test.go delete mode 100644 internal/auth/internal/controllers/trafficpermissions/status.go delete mode 100644 internal/auth/internal/mappers/trafficpermissionsmapper/traffic_permissions_mapper.go delete mode 100644 internal/auth/internal/types/computed_traffic_permissions.go delete mode 100644 internal/auth/internal/types/computed_traffic_permissions_test.go delete mode 100644 internal/auth/internal/types/errors.go delete mode 100644 internal/auth/internal/types/traffic_permissions.go delete mode 100644 internal/auth/internal/types/traffic_permissions_test.go delete mode 100644 internal/auth/internal/types/types.go delete mode 100644 internal/auth/internal/types/workload_identity.go delete mode 100644 internal/auth/internal/types/workload_identity_test.go delete mode 100644 internal/catalog/catalogtest/helpers/acl_hooks_test_helpers.go rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-service.json (87%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-1-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-1.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-10-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-10.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-11-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-11.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-12-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-12.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-13-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-13.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-14-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-14.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-15-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-15.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-16-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-16.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-17-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-17.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-18-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-18.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-19-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-19.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-2-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-2.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-20-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-20.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-3-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-3.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-4-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-4.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-5-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-5.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-6-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-6.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-7-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-7.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-8-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-8.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-9-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/api-workload-9.json (89%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/foo-service-endpoints.json (86%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/foo-service.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/grpc-api-service.json (88%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/http-api-service.json (82%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/node-1-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/node-1.json (82%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/node-2-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/node-2.json (82%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/node-3-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/node-3.json (82%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/node-4-health.json (80%) rename internal/catalog/catalogtest/integration_test_data/{v2beta1 => v1alpha1}/node-4.json (82%) rename internal/catalog/catalogtest/{test_integration_v2beta1.go => test_integration_v1alpha1.go} (66%) delete mode 100644 internal/catalog/catalogtest/test_lifecycle_v2beta1.go delete mode 100644 internal/catalog/internal/controllers/failover/controller.go delete mode 100644 internal/catalog/internal/controllers/failover/controller_test.go delete mode 100644 internal/catalog/internal/controllers/failover/status.go delete mode 100644 internal/catalog/internal/mappers/failovermapper/failover_mapper.go delete mode 100644 internal/catalog/internal/mappers/failovermapper/failover_mapper_test.go rename internal/{resource => catalog/internal}/mappers/selectiontracker/selection_tracker.go (55%) create mode 100644 internal/catalog/internal/mappers/selectiontracker/selection_tracker_test.go delete mode 100644 internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go delete mode 100644 internal/catalog/internal/types/acl_hooks.go delete mode 100644 internal/catalog/internal/types/failover_policy.go delete mode 100644 internal/catalog/internal/types/failover_policy_test.go delete mode 100644 internal/catalog/internal/types/workload_selecting.go delete mode 100644 internal/controller/dependencies.go delete mode 100644 internal/controller/dependencies_test.go delete mode 100644 internal/controller/helper.go delete mode 100644 internal/controller/helper_test.go delete mode 100644 internal/controller/testdata/dependencies.golden delete mode 100644 internal/mesh/internal/controllers/explicitdestinations/controller.go delete mode 100644 internal/mesh/internal/controllers/explicitdestinations/controller_test.go delete mode 100644 internal/mesh/internal/controllers/explicitdestinations/mapper/mapper.go delete mode 100644 internal/mesh/internal/controllers/explicitdestinations/status.go delete mode 100644 internal/mesh/internal/controllers/proxyconfiguration/controller.go delete mode 100644 internal/mesh/internal/controllers/proxyconfiguration/controller_test.go delete mode 100644 internal/mesh/internal/controllers/proxyconfiguration/sort.go delete mode 100644 internal/mesh/internal/controllers/proxyconfiguration/sort_test.go delete mode 100644 internal/mesh/internal/controllers/register.go delete mode 100644 internal/mesh/internal/controllers/routes/bound_refs.go delete mode 100644 internal/mesh/internal/controllers/routes/controller.go delete mode 100644 internal/mesh/internal/controllers/routes/controller_test.go delete mode 100644 internal/mesh/internal/controllers/routes/generate.go delete mode 100644 internal/mesh/internal/controllers/routes/generate_test.go delete mode 100644 internal/mesh/internal/controllers/routes/intermediate.go delete mode 100644 internal/mesh/internal/controllers/routes/loader/loader.go delete mode 100644 internal/mesh/internal/controllers/routes/loader/loader_test.go delete mode 100644 internal/mesh/internal/controllers/routes/loader/memoized.go delete mode 100644 internal/mesh/internal/controllers/routes/loader/related.go delete mode 100644 internal/mesh/internal/controllers/routes/pending_status.go delete mode 100644 internal/mesh/internal/controllers/routes/ref_validation.go delete mode 100644 internal/mesh/internal/controllers/routes/ref_validation_test.go delete mode 100644 internal/mesh/internal/controllers/routes/routestest/routestest.go delete mode 100644 internal/mesh/internal/controllers/routes/sort_rules.go delete mode 100644 internal/mesh/internal/controllers/routes/sort_rules_test.go delete mode 100644 internal/mesh/internal/controllers/routes/status.go delete mode 100644 internal/mesh/internal/controllers/routes/util.go delete mode 100644 internal/mesh/internal/controllers/routes/xroutemapper/util.go delete mode 100644 internal/mesh/internal/controllers/routes/xroutemapper/xroutemapper.go delete mode 100644 internal/mesh/internal/controllers/routes/xroutemapper/xroutemapper_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/builder.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/builder_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/destinations_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/local_app_multiport_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/naming.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/routes.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-single-workload-address-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/cache/cache.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/cache/cache_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/controller.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/controller_test.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/fetcher/data_fetcher.go delete mode 100644 internal/mesh/internal/controllers/sidecarproxy/fetcher/data_fetcher_test.go delete mode 100644 internal/mesh/internal/controllers/xds/controller.go delete mode 100644 internal/mesh/internal/controllers/xds/controller_test.go delete mode 100644 internal/mesh/internal/controllers/xds/endpoint_builder.go delete mode 100644 internal/mesh/internal/controllers/xds/endpoint_builder_test.go delete mode 100644 internal/mesh/internal/controllers/xds/leaf_cancels.go delete mode 100644 internal/mesh/internal/controllers/xds/leaf_mapper.go delete mode 100644 internal/mesh/internal/controllers/xds/mock_updater.go delete mode 100644 internal/mesh/internal/controllers/xds/proxy_tracker_watch.go delete mode 100644 internal/mesh/internal/controllers/xds/reconciliation_data.go delete mode 100644 internal/mesh/internal/controllers/xds/status/status.go delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/l4-single-workload-address-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-single-workload-address-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden delete mode 100644 internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-single-workload-address-without-ports.golden delete mode 100644 internal/mesh/internal/mappers/common/workload_selector_util.go delete mode 100644 internal/mesh/internal/mappers/common/workload_selector_util_test.go delete mode 100644 internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper.go delete mode 100644 internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper_test.go delete mode 100644 internal/mesh/internal/types/computed_explicit_destinations.go delete mode 100644 internal/mesh/internal/types/computed_proxy_configuration.go delete mode 100644 internal/mesh/internal/types/computed_routes.go delete mode 100644 internal/mesh/internal/types/computed_routes_test.go delete mode 100644 internal/mesh/internal/types/decoded.go delete mode 100644 internal/mesh/internal/types/destination_policy.go delete mode 100644 internal/mesh/internal/types/destination_policy_test.go delete mode 100644 internal/mesh/internal/types/destinations.go delete mode 100644 internal/mesh/internal/types/destinations_configuration.go delete mode 100644 internal/mesh/internal/types/destinations_configuration_test.go delete mode 100644 internal/mesh/internal/types/destinations_test.go delete mode 100644 internal/mesh/internal/types/errors.go delete mode 100644 internal/mesh/internal/types/grpc_route.go delete mode 100644 internal/mesh/internal/types/grpc_route_test.go delete mode 100644 internal/mesh/internal/types/http_route.go delete mode 100644 internal/mesh/internal/types/http_route_test.go delete mode 100644 internal/mesh/internal/types/intermediate/types.go delete mode 100644 internal/mesh/internal/types/proxy_configuration_test.go delete mode 100644 internal/mesh/internal/types/proxy_state_template.go delete mode 100644 internal/mesh/internal/types/proxy_state_template_test.go delete mode 100644 internal/mesh/internal/types/tcp_route.go delete mode 100644 internal/mesh/internal/types/tcp_route_test.go create mode 100644 internal/mesh/internal/types/upstreams.go delete mode 100644 internal/mesh/internal/types/util.go delete mode 100644 internal/mesh/internal/types/xroute.go delete mode 100644 internal/mesh/internal/types/xroute_test.go delete mode 100644 internal/mesh/proxy-snapshot/proxy_snapshot.go delete mode 100644 internal/mesh/proxy-tracker/mock_SessionLimiter.go delete mode 100644 internal/mesh/proxy-tracker/proxy_state_exports.go delete mode 100644 internal/mesh/proxy-tracker/proxy_state_exports_test.go delete mode 100644 internal/mesh/proxy-tracker/proxy_tracker.go delete mode 100644 internal/mesh/proxy-tracker/proxy_tracker_test.go delete mode 100644 internal/multicluster/exports.go delete mode 100644 internal/multicluster/internal/types/computed_exported_services.go delete mode 100644 internal/multicluster/internal/types/computed_exported_services_test.go delete mode 100644 internal/multicluster/internal/types/exported_services.go delete mode 100644 internal/multicluster/internal/types/exported_services_test.go delete mode 100644 internal/multicluster/internal/types/helpers.go delete mode 100644 internal/multicluster/internal/types/helpers_ce.go delete mode 100644 internal/multicluster/internal/types/namespace_exported_services.go delete mode 100644 internal/multicluster/internal/types/namespace_exported_services_test.go delete mode 100644 internal/multicluster/internal/types/partition_exported_services.go delete mode 100644 internal/multicluster/internal/types/partition_exported_services_test.go delete mode 100644 internal/multicluster/internal/types/types.go delete mode 100644 internal/protohcl/any.go delete mode 100644 internal/protohcl/attributes.go delete mode 100644 internal/protohcl/blocks.go delete mode 100644 internal/protohcl/cty.go delete mode 100644 internal/protohcl/decoder.go delete mode 100644 internal/protohcl/doc.go delete mode 100644 internal/protohcl/naming.go delete mode 100644 internal/protohcl/oneof.go delete mode 100644 internal/protohcl/primitives.go delete mode 100644 internal/protohcl/testproto/buf.gen.yaml delete mode 100644 internal/protohcl/testproto/example.pb.go delete mode 100644 internal/protohcl/testproto/example.proto delete mode 100644 internal/protohcl/unmarshal.go delete mode 100644 internal/protohcl/unmarshal_test.go delete mode 100644 internal/protohcl/well_known_types.go delete mode 100644 internal/protoutil/protoutil.go delete mode 100644 internal/resource/acls.go delete mode 100644 internal/resource/authz.go delete mode 100644 internal/resource/authz_ce.go delete mode 100644 internal/resource/authz_ce_test.go delete mode 100644 internal/resource/decode.go delete mode 100644 internal/resource/decode_test.go delete mode 100644 internal/resource/filter.go delete mode 100644 internal/resource/filter_test.go delete mode 100644 internal/resource/hooks.go delete mode 100644 internal/resource/hooks_test.go delete mode 100644 internal/resource/http/http.go delete mode 100644 internal/resource/http/http_test.go delete mode 100644 internal/resource/mappers/bimapper/bimapper.go delete mode 100644 internal/resource/mappers/bimapper/bimapper_test.go delete mode 100644 internal/resource/mappers/selectiontracker/selection_tracker_test.go delete mode 100644 internal/resource/protoc-gen-deepcopy/internal/generate/generate.go delete mode 100644 internal/resource/protoc-gen-deepcopy/main.go delete mode 100644 internal/resource/protoc-gen-json-shim/internal/generate/generate.go delete mode 100644 internal/resource/protoc-gen-json-shim/main.go delete mode 100644 internal/resource/protoc-gen-resource-types/internal/generate/generate.go delete mode 100644 internal/resource/protoc-gen-resource-types/main.go delete mode 100644 internal/resource/refkey.go delete mode 100644 internal/resource/refkey_test.go delete mode 100644 internal/resource/resource.go delete mode 100644 internal/resource/resourcetest/acls.go delete mode 100644 internal/resource/resourcetest/decode.go delete mode 100644 internal/resource/resourcetest/tenancy.go delete mode 100644 internal/resource/resourcetest/validation.go delete mode 100644 internal/resource/sort.go delete mode 100644 internal/resource/sort_test.go delete mode 100644 internal/resource/stringer.go delete mode 100644 internal/resource/tenancy.go delete mode 100644 internal/resource/tenancy_test.go delete mode 100644 internal/resourcehcl/any.go delete mode 100644 internal/resourcehcl/naming.go delete mode 100644 internal/resourcehcl/testdata/destinations.golden delete mode 100644 internal/resourcehcl/testdata/destinations.hcl delete mode 100644 internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/0e4b8ec300611dbc delete mode 100644 internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/c800420b7494c6d1 delete mode 100644 internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/eaba8205942c3f31 delete mode 100644 internal/resourcehcl/testdata/gvk-no-arguments.error delete mode 100644 internal/resourcehcl/testdata/gvk-no-arguments.hcl delete mode 100644 internal/resourcehcl/testdata/invalid-group.error delete mode 100644 internal/resourcehcl/testdata/invalid-group.hcl delete mode 100644 internal/resourcehcl/testdata/invalid-gvk.error delete mode 100644 internal/resourcehcl/testdata/invalid-gvk.hcl delete mode 100644 internal/resourcehcl/testdata/invalid-metadata.error delete mode 100644 internal/resourcehcl/testdata/invalid-metadata.hcl delete mode 100644 internal/resourcehcl/testdata/invalid-name.error delete mode 100644 internal/resourcehcl/testdata/invalid-name.hcl delete mode 100644 internal/resourcehcl/testdata/no-blocks-any-first.golden delete mode 100644 internal/resourcehcl/testdata/no-blocks-any-first.hcl delete mode 100644 internal/resourcehcl/testdata/no-blocks.golden delete mode 100644 internal/resourcehcl/testdata/no-blocks.hcl delete mode 100644 internal/resourcehcl/testdata/owner.golden delete mode 100644 internal/resourcehcl/testdata/owner.hcl delete mode 100644 internal/resourcehcl/testdata/simple-gvk.golden delete mode 100644 internal/resourcehcl/testdata/simple-gvk.hcl delete mode 100644 internal/resourcehcl/testdata/type-block.golden delete mode 100644 internal/resourcehcl/testdata/type-block.hcl delete mode 100644 internal/resourcehcl/testdata/unknown-field-block.error delete mode 100644 internal/resourcehcl/testdata/unknown-field-block.hcl delete mode 100644 internal/resourcehcl/testdata/unknown-field-object.error delete mode 100644 internal/resourcehcl/testdata/unknown-field-object.hcl delete mode 100644 internal/resourcehcl/testdata/unknown-type.error delete mode 100644 internal/resourcehcl/testdata/unknown-type.hcl delete mode 100644 internal/resourcehcl/unmarshal.go delete mode 100644 internal/resourcehcl/unmarshal_test.go delete mode 100644 internal/tenancy/exports.go delete mode 100644 internal/tenancy/internal/bridge/tenancy_bridge.go delete mode 100644 internal/tenancy/internal/bridge/tenancy_bridge_ce.go delete mode 100644 internal/tenancy/internal/controllers/register_ce.go delete mode 100644 internal/tenancy/internal/types/errors.go delete mode 100644 internal/tenancy/internal/types/namespace.go delete mode 100644 internal/tenancy/internal/types/types.go delete mode 100644 internal/tenancy/internal/types/types_ce.go delete mode 100644 internal/tenancy/internal/types/types_test.go delete mode 100644 internal/tenancy/tenancytest/namespace_test.go delete mode 100644 proto-public/LICENSE delete mode 100644 proto-public/annotations/ratelimit/ratelimit_deepcopy.gen.go delete mode 100644 proto-public/annotations/ratelimit/ratelimit_json.gen.go delete mode 100644 proto-public/pbacl/acl_deepcopy.gen.go delete mode 100644 proto-public/pbacl/acl_json.gen.go delete mode 100644 proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.binary.go delete mode 100644 proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.go delete mode 100644 proto-public/pbauth/v2beta1/computed_traffic_permissions.proto delete mode 100644 proto-public/pbauth/v2beta1/computed_traffic_permissions_deepcopy.gen.go delete mode 100644 proto-public/pbauth/v2beta1/computed_traffic_permissions_json.gen.go delete mode 100644 proto-public/pbauth/v2beta1/resource_types.gen.go delete mode 100644 proto-public/pbauth/v2beta1/traffic_permissions.pb.binary.go delete mode 100644 proto-public/pbauth/v2beta1/traffic_permissions.pb.go delete mode 100644 proto-public/pbauth/v2beta1/traffic_permissions.proto delete mode 100644 proto-public/pbauth/v2beta1/traffic_permissions_addon.go delete mode 100644 proto-public/pbauth/v2beta1/traffic_permissions_deepcopy.gen.go delete mode 100644 proto-public/pbauth/v2beta1/traffic_permissions_json.gen.go delete mode 100644 proto-public/pbauth/v2beta1/workload_identity.pb.binary.go delete mode 100644 proto-public/pbauth/v2beta1/workload_identity.pb.go delete mode 100644 proto-public/pbauth/v2beta1/workload_identity.proto delete mode 100644 proto-public/pbauth/v2beta1/workload_identity_deepcopy.gen.go delete mode 100644 proto-public/pbauth/v2beta1/workload_identity_json.gen.go rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/dns.pb.binary.go (91%) create mode 100644 proto-public/pbcatalog/v1alpha1/dns.pb.go rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/dns.proto (54%) rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/health.pb.binary.go (97%) rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/health.pb.go (53%) rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/health.proto (81%) rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/node.pb.binary.go (91%) create mode 100644 proto-public/pbcatalog/v1alpha1/node.pb.go rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/node.proto (57%) create mode 100644 proto-public/pbcatalog/v1alpha1/protocol.pb.go create mode 100644 proto-public/pbcatalog/v1alpha1/protocol.proto rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/selector.pb.binary.go (85%) create mode 100644 proto-public/pbcatalog/v1alpha1/selector.pb.go rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/selector.proto (80%) rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/service.pb.binary.go (90%) create mode 100644 proto-public/pbcatalog/v1alpha1/service.pb.go rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/service.proto (82%) rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/service_endpoints.pb.binary.go (89%) create mode 100644 proto-public/pbcatalog/v1alpha1/service_endpoints.pb.go rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/service_endpoints.proto (72%) rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/vip.pb.binary.go (91%) create mode 100644 proto-public/pbcatalog/v1alpha1/vip.pb.go rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/vip.proto (72%) rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/workload.pb.binary.go (94%) create mode 100644 proto-public/pbcatalog/v1alpha1/workload.pb.go rename proto-public/pbcatalog/{v2beta1 => v1alpha1}/workload.proto (91%) delete mode 100644 proto-public/pbcatalog/v2beta1/dns.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/dns_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/dns_json.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/failover_policy.pb.binary.go delete mode 100644 proto-public/pbcatalog/v2beta1/failover_policy.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/failover_policy.proto delete mode 100644 proto-public/pbcatalog/v2beta1/failover_policy_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/failover_policy_extras.go delete mode 100644 proto-public/pbcatalog/v2beta1/failover_policy_extras_test.go delete mode 100644 proto-public/pbcatalog/v2beta1/failover_policy_json.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/health_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/health_json.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/node.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/node_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/node_json.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/protocol.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/protocol.proto delete mode 100644 proto-public/pbcatalog/v2beta1/resource_types.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/selector.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/selector_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/selector_json.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/service.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_addon.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_addon_test.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_endpoints.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_endpoints_addon.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_endpoints_addon_test.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_endpoints_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_endpoints_json.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/service_json.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/vip.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/vip_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/vip_json.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/workload.pb.go delete mode 100644 proto-public/pbcatalog/v2beta1/workload_addon.go delete mode 100644 proto-public/pbcatalog/v2beta1/workload_addon_test.go delete mode 100644 proto-public/pbcatalog/v2beta1/workload_deepcopy.gen.go delete mode 100644 proto-public/pbcatalog/v2beta1/workload_json.gen.go delete mode 100644 proto-public/pbconnectca/ca_deepcopy.gen.go delete mode 100644 proto-public/pbconnectca/ca_json.gen.go delete mode 100644 proto-public/pbdataplane/dataplane_deepcopy.gen.go delete mode 100644 proto-public/pbdataplane/dataplane_json.gen.go delete mode 100644 proto-public/pbdns/dns_deepcopy.gen.go delete mode 100644 proto-public/pbdns/dns_json.gen.go rename proto-public/pbmesh/{v2beta1 => v1alpha1}/connection.pb.binary.go (91%) create mode 100644 proto-public/pbmesh/v1alpha1/connection.pb.go create mode 100644 proto-public/pbmesh/v1alpha1/connection.proto rename proto-public/pbmesh/{v2beta1 => v1alpha1}/expose.pb.binary.go (91%) create mode 100644 proto-public/pbmesh/v1alpha1/expose.pb.go create mode 100644 proto-public/pbmesh/v1alpha1/expose.proto rename proto-public/pbmesh/{v2beta1/proxy_configuration.pb.binary.go => v1alpha1/proxy.pb.binary.go} (66%) create mode 100644 proto-public/pbmesh/v1alpha1/proxy.pb.go create mode 100644 proto-public/pbmesh/v1alpha1/proxy.proto create mode 100644 proto-public/pbmesh/v1alpha1/routing.pb.go rename proto-public/pbmesh/{v2beta1 => v1alpha1}/routing.proto (84%) rename proto-public/pbmesh/{v2beta1/pbproxystate/listener.pb.binary.go => v1alpha1/upstreams.pb.binary.go} (59%) create mode 100644 proto-public/pbmesh/v1alpha1/upstreams.pb.go create mode 100644 proto-public/pbmesh/v1alpha1/upstreams.proto delete mode 100644 proto-public/pbmesh/v2beta1/common.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/common.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/common.proto delete mode 100644 proto-public/pbmesh/v2beta1/common_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/common_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_explicit_destinations.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_explicit_destinations.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_explicit_destinations.proto delete mode 100644 proto-public/pbmesh/v2beta1/computed_explicit_destinations_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_explicit_destinations_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_proxy_configuration.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_proxy_configuration.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_proxy_configuration.proto delete mode 100644 proto-public/pbmesh/v2beta1/computed_proxy_configuration_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_proxy_configuration_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_routes.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_routes.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_routes.proto delete mode 100644 proto-public/pbmesh/v2beta1/computed_routes_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/computed_routes_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/connection.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/connection.proto delete mode 100644 proto-public/pbmesh/v2beta1/connection_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/connection_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/destination_policy.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/destination_policy.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/destination_policy.proto delete mode 100644 proto-public/pbmesh/v2beta1/destination_policy_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/destination_policy_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/destinations.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/destinations.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/destinations.proto delete mode 100644 proto-public/pbmesh/v2beta1/destinations_configuration.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/destinations_configuration.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/destinations_configuration.proto delete mode 100644 proto-public/pbmesh/v2beta1/destinations_configuration_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/destinations_configuration_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/destinations_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/destinations_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/expose.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/expose.proto delete mode 100644 proto-public/pbmesh/v2beta1/expose_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/expose_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/grpc_route.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/grpc_route.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/grpc_route.proto delete mode 100644 proto-public/pbmesh/v2beta1/grpc_route_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/grpc_route_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route.proto delete mode 100644 proto-public/pbmesh/v2beta1/http_route_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_retries.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_retries.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_retries.proto delete mode 100644 proto-public/pbmesh/v2beta1/http_route_retries_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_retries_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_timeouts.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_timeouts.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_timeouts.proto delete mode 100644 proto-public/pbmesh/v2beta1/http_route_timeouts_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/http_route_timeouts_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/access_logs.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/access_logs.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/access_logs.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/access_logs_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/access_logs_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/address.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/address.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/address.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/address_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/address_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/cluster.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/cluster_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/cluster_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/endpoints.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/endpoints.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/endpoints.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/endpoints_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/endpoints_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/intentions.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/listener.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/listener.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/listener_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/listener_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/protocol.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/protocol.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/protocol_test.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/references.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/references.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/references.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/references_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/references_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/route.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/route.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/route.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/route_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/route_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.proto delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_configuration.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_configuration.proto delete mode 100644 proto-public/pbmesh/v2beta1/proxy_configuration_addon.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_configuration_addon_test.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_configuration_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_configuration_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_state.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_state.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_state.proto delete mode 100644 proto-public/pbmesh/v2beta1/proxy_state_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/proxy_state_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/resource_types.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/routing.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/tcp_route.pb.binary.go delete mode 100644 proto-public/pbmesh/v2beta1/tcp_route.pb.go delete mode 100644 proto-public/pbmesh/v2beta1/tcp_route.proto delete mode 100644 proto-public/pbmesh/v2beta1/tcp_route_deepcopy.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/tcp_route_json.gen.go delete mode 100644 proto-public/pbmesh/v2beta1/xroute_addons.go delete mode 100644 proto-public/pbmesh/v2beta1/xroute_addons_test.go delete mode 100644 proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.binary.go delete mode 100644 proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.go delete mode 100644 proto-public/pbmulticluster/v2beta1/computed_exported_services.proto delete mode 100644 proto-public/pbmulticluster/v2beta1/computed_exported_services_deepcopy.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/computed_exported_services_json.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services.pb.binary.go delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services.pb.go delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services.proto delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.binary.go delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.go delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services_consumer.proto delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services_consumer_deepcopy.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services_consumer_json.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services_deepcopy.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/exported_services_json.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.binary.go delete mode 100644 proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.go delete mode 100644 proto-public/pbmulticluster/v2beta1/namespace_exported_services.proto delete mode 100644 proto-public/pbmulticluster/v2beta1/namespace_exported_services_deepcopy.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/namespace_exported_services_json.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.binary.go delete mode 100644 proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.go delete mode 100644 proto-public/pbmulticluster/v2beta1/partition_exported_services.proto delete mode 100644 proto-public/pbmulticluster/v2beta1/partition_exported_services_deepcopy.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/partition_exported_services_json.gen.go delete mode 100644 proto-public/pbmulticluster/v2beta1/resource_types.gen.go delete mode 100644 proto-public/pbresource/annotations.pb.binary.go delete mode 100644 proto-public/pbresource/annotations.pb.go delete mode 100644 proto-public/pbresource/annotations.proto delete mode 100644 proto-public/pbresource/annotations_deepcopy.gen.go delete mode 100644 proto-public/pbresource/annotations_json.gen.go delete mode 100644 proto-public/pbresource/resource_deepcopy.gen.go delete mode 100644 proto-public/pbresource/resource_json.gen.go delete mode 100644 proto-public/pbserverdiscovery/serverdiscovery_deepcopy.gen.go delete mode 100644 proto-public/pbserverdiscovery/serverdiscovery_json.gen.go delete mode 100644 proto-public/pbtenancy/v2beta1/namespace.pb.binary.go delete mode 100644 proto-public/pbtenancy/v2beta1/namespace.pb.go delete mode 100644 proto-public/pbtenancy/v2beta1/namespace.proto delete mode 100644 proto-public/pbtenancy/v2beta1/namespace_deepcopy.gen.go delete mode 100644 proto-public/pbtenancy/v2beta1/namespace_json.gen.go delete mode 100644 proto-public/pbtenancy/v2beta1/resource_types.gen.go delete mode 100644 proto/private/pbconfigentry/config_entry_ce.go delete mode 100644 proto/private/prototest/golden_json.go delete mode 100644 sdk/.copywrite.hcl delete mode 100644 sdk/LICENSE delete mode 100644 sdk/testutil/retry/counter.go delete mode 100644 sdk/testutil/retry/timer.go delete mode 100644 test-integ/README.md delete mode 100644 test-integ/connect/snapshot_test.go delete mode 100644 test-integ/go.mod delete mode 100644 test-integ/go.sum delete mode 100644 test-integ/peering_commontopo/README.md delete mode 100644 test-integ/peering_commontopo/ac1_basic_test.go delete mode 100644 test-integ/peering_commontopo/ac2_disco_chain_test.go delete mode 100644 test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go delete mode 100644 test-integ/peering_commontopo/ac4_proxy_defaults_test.go delete mode 100644 test-integ/peering_commontopo/ac5_1_no_svc_mesh_test.go delete mode 100644 test-integ/peering_commontopo/ac5_2_pq_failover_test.go delete mode 100644 test-integ/peering_commontopo/ac6_failovers_test.go delete mode 100644 test-integ/peering_commontopo/ac7_1_rotate_gw_test.go delete mode 100644 test-integ/peering_commontopo/ac7_2_rotate_leader_test.go delete mode 100644 test-integ/peering_commontopo/asserter.go delete mode 100644 test-integ/peering_commontopo/commontopo.go delete mode 100644 test-integ/peering_commontopo/sharedtopology_test.go delete mode 100644 test/integration/connect/envoy/Dockerfile-consul-envoy-windows delete mode 100644 test/integration/connect/envoy/Dockerfile-tcpdump-windows delete mode 100644 test/integration/connect/envoy/Dockerfile-test-sds-server-windows delete mode 100644 test/integration/connect/envoy/WINDOWS-TEST.md delete mode 100644 test/integration/connect/envoy/case-wanfed-gw/global-setup-windows.sh delete mode 100644 test/integration/connect/envoy/docker-windows.md delete mode 100644 test/integration/connect/envoy/docs/img/linux-arch.png delete mode 100644 test/integration/connect/envoy/docs/img/windows-arch-singlecontainer.png delete mode 100644 test/integration/connect/envoy/docs/img/windows-linux-arch.png delete mode 100644 test/integration/connect/envoy/docs/windows-testing-architecture.md delete mode 100644 test/integration/connect/envoy/helpers.windows.bash delete mode 100644 test/integration/connect/envoy/run-tests.windows.sh delete mode 100644 test/integration/connect/envoy/windows-troubleshooting.md delete mode 100644 test/integration/consul-container/assets/Dockerfile-consul-dataplane delete mode 100644 test/integration/consul-container/libs/cluster/dataplane.go delete mode 100644 test/integration/consul-container/test/catalog/catalog_test.go delete mode 100644 test/integration/consul-container/test/debugging.md delete mode 100644 test/integration/consul-container/test/envoy_extensions/otel_access_logging_test.go delete mode 100644 test/integration/consul-container/test/envoy_extensions/testdata/otel/config.yaml delete mode 100644 test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/Dockerfile delete mode 100644 test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/README.md delete mode 100755 test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/build.sh delete mode 100644 test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/go.mod delete mode 100644 test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/go.sum delete mode 100644 test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/nginx.conf delete mode 100644 test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/wasm_add_header.go delete mode 100755 test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/wasm_add_header.wasm delete mode 100644 test/integration/consul-container/test/envoy_extensions/wasm_test.go delete mode 100644 test/integration/consul-container/test/gateways/terminating_gateway_test.go delete mode 100644 test/integration/consul-container/test/multiport/explicit_destination_test.go delete mode 100644 test/integration/consul-container/test/resource/http_api/acl_enabled_test.go delete mode 100644 test/integration/consul-container/test/resource/http_api/client/client.go delete mode 100644 test/integration/consul-container/test/resource/http_api/helper.go delete mode 100644 test/integration/consul-container/test/trafficpermissions/tcp_test.go delete mode 100644 test/integration/consul-container/test/upgrade/catalog/catalog_test.go delete mode 100644 test/integration/consul-container/test/util/test_debug_breakpoint_hit.png delete mode 100644 test/integration/consul-container/test/util/test_debug_configuration.png delete mode 100644 test/integration/consul-container/test/util/test_debug_info.png delete mode 100644 test/integration/consul-container/test/util/test_debug_remote_configuration.png delete mode 100644 test/integration/consul-container/test/util/test_debug_remote_connected.png delete mode 100644 test/integration/consul-container/test/util/test_debug_resume_program.png delete mode 100644 testing/deployer/.gitignore delete mode 100644 testing/deployer/README.md delete mode 100644 testing/deployer/TODO.md delete mode 100644 testing/deployer/go.mod delete mode 100644 testing/deployer/go.sum delete mode 100644 testing/deployer/sprawl/acl.go delete mode 100644 testing/deployer/sprawl/acl_rules.go delete mode 100644 testing/deployer/sprawl/boot.go delete mode 100644 testing/deployer/sprawl/catalog.go delete mode 100644 testing/deployer/sprawl/configentries.go delete mode 100644 testing/deployer/sprawl/consul.go delete mode 100644 testing/deployer/sprawl/debug.go delete mode 100644 testing/deployer/sprawl/details.go delete mode 100644 testing/deployer/sprawl/ent.go delete mode 100644 testing/deployer/sprawl/helpers.go delete mode 100644 testing/deployer/sprawl/internal/build/docker.go delete mode 100644 testing/deployer/sprawl/internal/runner/exec.go delete mode 100644 testing/deployer/sprawl/internal/secrets/store.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/agent.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/digest.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/dns.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/docker.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/docker_test.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/gen.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/io.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/nodes.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/prelude.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/proxy.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/res.go delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-app-sidecar.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-app.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-consul.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-mgw-dataplane.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-mgw.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl delete mode 100644 testing/deployer/sprawl/internal/tfgen/tfgen.go delete mode 100644 testing/deployer/sprawl/peering.go delete mode 100644 testing/deployer/sprawl/sprawl.go delete mode 100644 testing/deployer/sprawl/sprawltest/sprawltest.go delete mode 100644 testing/deployer/sprawl/sprawltest/test_test.go delete mode 100644 testing/deployer/sprawl/tls.go delete mode 100644 testing/deployer/topology/compile.go delete mode 100644 testing/deployer/topology/default_cdp.go delete mode 100644 testing/deployer/topology/default_consul.go delete mode 100644 testing/deployer/topology/default_envoy.go delete mode 100644 testing/deployer/topology/ids.go delete mode 100644 testing/deployer/topology/images.go delete mode 100644 testing/deployer/topology/images_test.go delete mode 100644 testing/deployer/topology/topology.go delete mode 100644 testing/deployer/topology/util.go delete mode 100644 testing/deployer/topology/util_test.go delete mode 100644 testing/deployer/util/consul.go delete mode 100644 testing/deployer/util/files.go delete mode 100644 testing/deployer/util/internal/ipamutils/doc.go delete mode 100644 testing/deployer/util/internal/ipamutils/utils.go delete mode 100644 testing/deployer/util/internal/ipamutils/utils_test.go delete mode 100644 testing/deployer/util/net.go rename ui/packages/consul-ui/app/components/{consul-copy-button => copy-button}/README.mdx (93%) rename ui/packages/consul-ui/app/components/{consul-copy-button => copy-button}/chart.xstate.js (92%) rename ui/packages/consul-ui/app/components/{consul-copy-button => copy-button}/index.hbs (72%) rename ui/packages/consul-ui/app/components/{consul-copy-button => copy-button}/index.js (67%) rename ui/packages/consul-ui/app/components/{consul-copy-button => copy-button}/index.scss (93%) rename ui/packages/consul-ui/app/components/{consul-copy-button => copy-button}/layout.scss (94%) rename ui/packages/consul-ui/app/components/{consul-copy-button => copy-button}/skin.scss (94%) rename ui/packages/consul-ui/translations/components/{consul-copy-button => copy-button}/en-us.yaml (76%) delete mode 100644 website/content/api-docs/acl/templated-policies.mdx delete mode 100644 website/content/commands/acl/templated-policy/index.mdx delete mode 100644 website/content/commands/acl/templated-policy/list.mdx delete mode 100644 website/content/commands/acl/templated-policy/preview.mdx delete mode 100644 website/content/commands/acl/templated-policy/read.mdx create mode 100644 website/content/docs/agent/rpc.mdx rename website/content/docs/{connect/gateways => }/api-gateway/configuration/gateway.mdx (95%) rename website/content/docs/{connect/gateways => }/api-gateway/configuration/gatewayclass.mdx (95%) rename website/content/docs/{connect/gateways => }/api-gateway/configuration/gatewayclassconfig.mdx (100%) create mode 100644 website/content/docs/api-gateway/configuration/index.mdx rename website/content/docs/{connect/gateways => }/api-gateway/configuration/meshservice.mdx (100%) rename website/content/docs/{connect/gateways => }/api-gateway/configuration/routes.mdx (55%) create mode 100644 website/content/docs/api-gateway/index.mdx rename website/content/docs/{connect/gateways/api-gateway/install-k8s.mdx => api-gateway/install.mdx} (78%) create mode 100644 website/content/docs/api-gateway/tech-specs.mdx rename website/content/docs/{connect/gateways/api-gateway/upgrades-k8s.mdx => api-gateway/upgrades.mdx} (98%) rename website/content/docs/{connect/gateways/api-gateway => api-gateway/usage}/errors.mdx (96%) rename website/content/docs/{connect/gateways/api-gateway/define-routes => api-gateway/usage}/reroute-http-requests.mdx (66%) rename website/content/docs/{connect/gateways/api-gateway/define-routes => api-gateway/usage}/route-to-peered-services.mdx (57%) create mode 100644 website/content/docs/api-gateway/usage/usage.mdx delete mode 100644 website/content/docs/connect/config-entries/http-route.mdx rename website/content/docs/connect/{manage-traffic => }/failover/index.mdx (61%) rename website/content/docs/connect/{config-entries => gateways/api-gateway/configuration}/api-gateway.mdx (52%) delete mode 100644 website/content/docs/connect/gateways/api-gateway/configuration/gatewaypolicy.mdx create mode 100644 website/content/docs/connect/gateways/api-gateway/configuration/http-route.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/configuration/index.mdx rename website/content/docs/connect/{config-entries => gateways/api-gateway/configuration}/inline-certificate.mdx (97%) delete mode 100644 website/content/docs/connect/gateways/api-gateway/configuration/routeauthfilter.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/configuration/routeretryfilter.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/configuration/routetimeoutfilter.mdx rename website/content/docs/connect/{config-entries => gateways/api-gateway/configuration}/tcp-route.mdx (98%) delete mode 100644 website/content/docs/connect/gateways/api-gateway/define-routes/routes-k8s.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/define-routes/routes-vms.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/deploy/listeners-k8s.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/deploy/listeners-vms.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/secure-traffic/encrypt-vms.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-k8s.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/secure-traffic/verify-jwts-vms.mdx delete mode 100644 website/content/docs/connect/gateways/api-gateway/tech-specs.mdx create mode 100644 website/content/docs/connect/gateways/api-gateway/usage.mdx rename website/content/docs/connect/{manage-traffic => l7-traffic}/discovery-chain.mdx (100%) rename website/content/docs/connect/{manage-traffic => l7-traffic}/index.mdx (90%) delete mode 100644 website/content/docs/connect/manage-traffic/failover/sameness.mdx delete mode 100644 website/content/docs/connect/manage-traffic/limit-request-rates.mdx delete mode 100644 website/content/docs/connect/manage-traffic/route-to-local-upstreams.mdx delete mode 100644 website/content/docs/connect/proxies/envoy-extensions/configuration/otel-access-logging.mdx delete mode 100644 website/content/docs/connect/proxies/envoy-extensions/usage/otel-access-logging.mdx rename website/content/docs/ecs/{reference => }/compatibility.mdx (100%) rename website/content/docs/ecs/{reference => }/configuration-reference.mdx (99%) delete mode 100644 website/content/docs/ecs/deploy/bind-addresses.mdx delete mode 100644 website/content/docs/ecs/deploy/configure-routes.mdx delete mode 100644 website/content/docs/ecs/deploy/manual.mdx delete mode 100644 website/content/docs/ecs/deploy/migrate-existing-tasks.mdx delete mode 100644 website/content/docs/ecs/deploy/terraform.mdx create mode 100644 website/content/docs/ecs/manual/acl-controller.mdx create mode 100644 website/content/docs/ecs/manual/install.mdx create mode 100644 website/content/docs/ecs/manual/secure-configuration.mdx delete mode 100644 website/content/docs/ecs/reference/consul-server-json.mdx create mode 100644 website/content/docs/ecs/requirements.mdx create mode 100644 website/content/docs/ecs/task-resource-usage.mdx delete mode 100644 website/content/docs/ecs/tech-specs.mdx create mode 100644 website/content/docs/ecs/terraform/install.mdx create mode 100644 website/content/docs/ecs/terraform/migrate-existing-tasks.mdx create mode 100644 website/content/docs/ecs/terraform/secure-configuration.mdx delete mode 100644 website/content/docs/ecs/upgrade-to-dataplanes.mdx delete mode 100644 website/content/docs/k8s/multiport/configure.mdx delete mode 100644 website/content/docs/k8s/multiport/index.mdx delete mode 100644 website/content/docs/release-notes/consul/v1_17_x.mdx delete mode 100644 website/public/img/ecs/consul-on-ecs-architecture-dataplanes-dark.jpg delete mode 100644 website/public/img/ecs/consul-on-ecs-architecture-dataplanes.jpg diff --git a/.changelog/17107.txt b/.changelog/17107.txt deleted file mode 100644 index 5694fca2c9cc8..0000000000000 --- a/.changelog/17107.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:breaking-change -api: RaftLeaderTransfer now requires an id string. An empty string can be specified to keep the old behavior. -``` diff --git a/.changelog/17155.txt b/.changelog/17155.txt deleted file mode 100644 index 03cec33e991af..0000000000000 --- a/.changelog/17155.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -config: Add new `tls.defaults.verify_server_hostname` configuration option. This specifies the default value for any interfaces that support the `verify_server_hostname` option. -``` diff --git a/.changelog/17481.txt b/.changelog/17481.txt deleted file mode 100644 index 89ad16998e836..0000000000000 --- a/.changelog/17481.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -tlsutil: Default setting of ServerName field in outgoing TLS configuration for checks now handled by crypto/tls. -``` diff --git a/.changelog/17593.txt b/.changelog/17593.txt deleted file mode 100644 index 1f84e75f57427..0000000000000 --- a/.changelog/17593.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -docs: fix list of telemetry metrics -``` diff --git a/.changelog/17694.txt b/.changelog/17694.txt deleted file mode 100644 index 703b100d1d3a3..0000000000000 --- a/.changelog/17694.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -Windows: support consul connect envoy command on Windows -``` diff --git a/.changelog/17754.txt b/.changelog/17754.txt index 32272ec1ae911..56ab20dc213ef 100644 --- a/.changelog/17754.txt +++ b/.changelog/17754.txt @@ -1,3 +1,3 @@ ```release-note:feature -ui: Display the Consul agent version in the nodes list, and allow filtering and sorting of nodes based on versions. -``` \ No newline at end of file +ui: consul version is displayed in nodes list with filtering and sorting based on versions +``` diff --git a/.changelog/17831.txt b/.changelog/17831.txt deleted file mode 100644 index 2833bda1d5765..0000000000000 --- a/.changelog/17831.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -ca: Vault CA provider config no longer requires root_pki_path for secondary datacenters -``` diff --git a/.changelog/17936.txt b/.changelog/17936.txt deleted file mode 100644 index 61f5117d8712f..0000000000000 --- a/.changelog/17936.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -acl: Add new `acl.tokens.dns` config field which specifies the token used implicitly during dns checks. -``` diff --git a/.changelog/18007.txt b/.changelog/18007.txt deleted file mode 100644 index b963d2f77fcd6..0000000000000 --- a/.changelog/18007.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -Windows: Integration tests for Consul Windows VMs -``` diff --git a/.changelog/18300.txt b/.changelog/18300.txt deleted file mode 100644 index 717a697777e26..0000000000000 --- a/.changelog/18300.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -connect: update supported envoy versions to 1.24.10, 1.25.9, 1.26.4, 1.27.0 -``` diff --git a/.changelog/18303.txt b/.changelog/18303.txt new file mode 100644 index 0000000000000..4afc4473b7c90 --- /dev/null +++ b/.changelog/18303.txt @@ -0,0 +1,3 @@ +```release-note:improvement +connect: update supported envoy versions to 1.23.12, 1.24.10, 1.25.9, 1.26.4 +``` diff --git a/.changelog/18324.txt b/.changelog/18324.txt deleted file mode 100644 index 6d1f11a92e969..0000000000000 --- a/.changelog/18324.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -api-gateway: add retry and timeout filters -``` \ No newline at end of file diff --git a/.changelog/18336.txt b/.changelog/18336.txt deleted file mode 100644 index 5d91046ec5efd..0000000000000 --- a/.changelog/18336.txt +++ /dev/null @@ -1,7 +0,0 @@ -```release-note:feature -xds: Add a built-in Envoy extension that appends OpenTelemetry Access Logging (otel-access-logging) to the HTTP Connection Manager filter. -``` - -```release-note:feature -xds: Add support for patching outbound listeners to the built-in Envoy External Authorization extension. -``` diff --git a/.changelog/18367.txt b/.changelog/18367.txt deleted file mode 100644 index 578cf7091853f..0000000000000 --- a/.changelog/18367.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -dev-mode: Fix dev mode has new line in responses. Now new line is added only when url has pretty query parameter. -``` diff --git a/.changelog/18439.txt b/.changelog/18439.txt deleted file mode 100644 index dd12738d5c387..0000000000000 --- a/.changelog/18439.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -Support custom watches on the Consul Controller framework. -``` diff --git a/.changelog/18504.txt b/.changelog/18504.txt deleted file mode 100644 index 6df042237a93c..0000000000000 --- a/.changelog/18504.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -dataplane: Allow getting bootstrap parameters when using V2 APIs -``` \ No newline at end of file diff --git a/.changelog/18560.txt b/.changelog/18560.txt deleted file mode 100644 index 118fad95306d7..0000000000000 --- a/.changelog/18560.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -ui: Use Community verbiage -``` \ No newline at end of file diff --git a/.changelog/18573.txt b/.changelog/18573.txt deleted file mode 100644 index ce03f1c55baf7..0000000000000 --- a/.changelog/18573.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:enhancement -xds: Use downstream protocol when connecting to local app -``` diff --git a/.changelog/18583.txt b/.changelog/18583.txt deleted file mode 100644 index 8121e01ced0db..0000000000000 --- a/.changelog/18583.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -mesh: **(Enterprise only)** Adds rate limiting config to service-defaults -``` diff --git a/.changelog/18646.txt b/.changelog/18646.txt deleted file mode 100644 index 93da75819901a..0000000000000 --- a/.changelog/18646.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -api-gateway: Add support for response header modifiers on http-route configuration entry -``` diff --git a/.changelog/18668.txt b/.changelog/18668.txt deleted file mode 100644 index fdd63e1c6d4b6..0000000000000 --- a/.changelog/18668.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:breaking-change -audit-logging: **(Enterprise only)** allowing timestamp based filename only on rotation. initially the filename will be just file.json -``` diff --git a/.changelog/18708.txt b/.changelog/18708.txt deleted file mode 100644 index 66a34da789703..0000000000000 --- a/.changelog/18708.txt +++ /dev/null @@ -1,7 +0,0 @@ -```release-note:feature -acl: Added ACL Templated policies to simplify getting the right ACL token. -``` - -```release-note:improvement -cli: Added `-templated-policy`, `-templated-policy-file`, `-replace-templated-policy`, `-append-templated-policy`, `-replace-templated-policy-file`, `-append-templated-policy-file` and `-var` flags for creating or updating tokens/roles. -``` diff --git a/.changelog/18719.txt b/.changelog/18719.txt deleted file mode 100644 index 4da370b91b90f..0000000000000 --- a/.changelog/18719.txt +++ /dev/null @@ -1,7 +0,0 @@ -```release-note:feature -acl: Add BindRule support for templated policies. Add new BindType: templated-policy and BindVar field for templated policy variables. -``` - -```release-note:feature -cli: Add `bind-var` flag to `consul acl binding-rule` for templated policy variables. -``` \ No newline at end of file diff --git a/.changelog/18769.txt b/.changelog/18769.txt deleted file mode 100644 index b9cf8aa207465..0000000000000 --- a/.changelog/18769.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -acl: Adds a new ACL rule for workload identities -``` diff --git a/.changelog/18813.txt b/.changelog/18813.txt deleted file mode 100644 index 3dcb4612915b0..0000000000000 --- a/.changelog/18813.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -acl: Use templated policy to generate synthetic policies for tokens/roles with node and/or service identities -``` \ No newline at end of file diff --git a/.changelog/18816.txt b/.changelog/18816.txt deleted file mode 100644 index ef8989ee705b3..0000000000000 --- a/.changelog/18816.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -cli: Add `consul acl templated-policy` commands to read, list and preview templated policies. -``` \ No newline at end of file diff --git a/.changelog/18943.txt b/.changelog/18943.txt deleted file mode 100644 index adb027dee9fd9..0000000000000 --- a/.changelog/18943.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -api: added `CheckRegisterOpts` to Agent API -``` diff --git a/.changelog/18983.txt b/.changelog/18983.txt deleted file mode 100644 index 8a49a850eb356..0000000000000 --- a/.changelog/18983.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -api: added `Token` field to `ServiceRegisterOpts` type in Agent API -``` diff --git a/.changelog/18994.txt b/.changelog/18994.txt deleted file mode 100644 index f28381721d54b..0000000000000 --- a/.changelog/18994.txt +++ /dev/null @@ -1,26 +0,0 @@ -```release-note:feature -# Catalog v2 feature preview -This release provides the ability to preview Consul's v2 Catalog and Resource API if enabled. The new model supports -multi-port application deployments with only a single Envoy proxy. Note that the v1 and v2 catalogs are not cross -compatible, and not all Consul features are available within this v2 feature preview. See the [v2 Catalog and Resource -API documentation](https://developer.hashicorp.com/consul/docs/architecture/v2) for more information. The v2 Catalog and -Resources API should be considered a feature preview within this release and should not be used in production -environments. - -### Limitations -* The v2 catalog API feature preview does not support connections with client agents. As a result, it is only available for Kubernetes deployments, which use [Consul dataplanes](consul/docs/connect/dataplane) instead of client agents. -* The v1 and v2 catalog APIs cannot run concurrently. -* The Consul UI does not support multi-port services or the v2 catalog API in this release. -* HCP Consul does not support multi-port services or the v2 catalog API in this release. -* The v2 API only supports transparent proxy mode where services that have permissions to connect to each other can use - Kube DNS to connect. - -### Known Issues -* When using the v2 API with transparent proxy, Kubernetes pods cannot use L7 liveness, readiness, or startup probes. - - -[[Catalog resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/catalog/internal/controllers) -[[Mesh resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/mesh/internal/controllers) -[[Auth resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/auth/internal) -[[V2 Protobufs]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/proto-public) -``` \ No newline at end of file diff --git a/.changelog/19077.txt b/.changelog/19077.txt deleted file mode 100644 index d7c9b0483c7c4..0000000000000 --- a/.changelog/19077.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -acl: Adds workload identity templated policy -``` diff --git a/.changelog/19120.txt b/.changelog/19120.txt new file mode 100644 index 0000000000000..e7e5d3274fa1d --- /dev/null +++ b/.changelog/19120.txt @@ -0,0 +1,3 @@ +```release-note:bug +api-gateway: fix matching for different hostnames on the same listener +``` diff --git a/.changelog/19218.txt b/.changelog/19218.txt deleted file mode 100644 index a3dde32317b47..0000000000000 --- a/.changelog/19218.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -resource: lowercase names enforced for v2 resources only. -``` \ No newline at end of file diff --git a/.changelog/19273.txt b/.changelog/19273.txt new file mode 100644 index 0000000000000..b5264e101980b --- /dev/null +++ b/.changelog/19273.txt @@ -0,0 +1,3 @@ +```release-note:security +connect: update supported envoy versions to 1.24.12, 1.25.11, 1.26.6 to address [CVE-2023-44487](https://github.com/envoyproxy/envoy/security/advisories/GHSA-jhv4-f7mr-xx76) +``` diff --git a/.changelog/19306.txt b/.changelog/19306.txt deleted file mode 100644 index 81c0b638b9587..0000000000000 --- a/.changelog/19306.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:security -connect: update supported envoy versions to 1.24.12, 1.25.11, 1.26.6, 1.27.2 to address [CVE-2023-44487](https://github.com/envoyproxy/envoy/security/advisories/GHSA-jhv4-f7mr-xx76) -``` diff --git a/.changelog/19311.txt b/.changelog/19311.txt deleted file mode 100644 index e53536f44d32b..0000000000000 --- a/.changelog/19311.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -raft: Fix panic during downgrade from enterprise to oss. -``` \ No newline at end of file diff --git a/.changelog/19314.txt b/.changelog/19314.txt deleted file mode 100644 index c5f1346f3bfe0..0000000000000 --- a/.changelog/19314.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:enhancement -raft: upgrade raft-wal library version to 0.4.1. -``` diff --git a/.changelog/19389.txt b/.changelog/19389.txt deleted file mode 100644 index 1fe521b853812..0000000000000 --- a/.changelog/19389.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -cli: stop simultaneous usage of -templated-policy and -templated-policy-file when creating a role or token. -``` \ No newline at end of file diff --git a/.changelog/_18366.txt b/.changelog/_18366.txt deleted file mode 100644 index 02a3599c2c27c..0000000000000 --- a/.changelog/_18366.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -config-entry(api-gateway): (Enterprise only) Add GatewayPolicy to APIGateway Config Entry listeners -``` diff --git a/.changelog/_18422.txt b/.changelog/_18422.txt deleted file mode 100644 index 4f0efbbe3b278..0000000000000 --- a/.changelog/_18422.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -config-entry(api-gateway): (Enterprise only) Add JWTFilter to HTTPRoute Filters -``` diff --git a/.changelog/_6074.txt b/.changelog/_6074.txt deleted file mode 100644 index 6539fa6a4fa19..0000000000000 --- a/.changelog/_6074.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -connect: **(Enterprise only)** Fix bug where incorrect service-defaults entries were fetched to determine an upstream's protocol whenever the upstream did not explicitly define the namespace / partition. When this bug occurs, upstreams would use the protocol from a service-default entry in the default namespace / partition, rather than their own namespace / partition. -``` diff --git a/.changelog/_6870.txt b/.changelog/_6870.txt deleted file mode 100644 index b4c52f7d67554..0000000000000 --- a/.changelog/_6870.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -gateway: **(Enterprise only)** Add JWT authentication and authorization to APIGateway Listeners and HTTPRoutes. -``` diff --git a/.copywrite.hcl b/.copywrite.hcl index 243a0a730722b..fa06f76e2ac69 100644 --- a/.copywrite.hcl +++ b/.copywrite.hcl @@ -1,8 +1,8 @@ schema_version = 1 project { - license = "BUSL-1.1" - copyright_year = 2023 + license = "MPL-2.0" + copyright_year = 2013 # (OPTIONAL) A list of globs that should not have copyright/license headers. # Supports doublestar glob patterns for more flexibility in defining which @@ -19,21 +19,11 @@ project { # ignore specific test data files "agent/uiserver/testdata/**", - "internal/resourcehcl/testdata/**", # generated files "agent/structs/structs.deepcopy.go", "agent/proxycfg/proxycfg.deepcopy.go", "agent/grpc-middleware/rate_limit_mappings.gen.go", "agent/uiserver/dist/**", - - # ignoring policy embedded files - "agent/structs/acltemplatedpolicy/policies/ce/**", - - # licensed under MPL - ignoring for now until the copywrite tool can support - # multiple licenses per repo. - "sdk/**", - "api/**", - "proto-public/**", ] } diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 16480bb6f4f94..36f9456693ff3 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 blank_issues_enabled: false contact_links: diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d618028e100bd..05387a7c9b803 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 version: 2 updates: diff --git a/.github/pr-labeler.yml b/.github/pr-labeler.yml index fd39f2ccab423..e10f3c1376ef0 100644 --- a/.github/pr-labeler.yml +++ b/.github/pr-labeler.yml @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 pr/dependencies: - vendor/**/* diff --git a/.github/scripts/changelog_checker.sh b/.github/scripts/changelog_checker.sh index a214ef2477979..e6b4d7f85dcc0 100755 --- a/.github/scripts/changelog_checker.sh +++ b/.github/scripts/changelog_checker.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/.github/scripts/get_runner_classes.sh b/.github/scripts/get_runner_classes.sh index 603ed20ec7257..2e66a4e344c6c 100755 --- a/.github/scripts/get_runner_classes.sh +++ b/.github/scripts/get_runner_classes.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # # This script generates tag-sets that can be used as runs-on: values to select runners. diff --git a/.github/scripts/get_runner_classes_windows.sh b/.github/scripts/get_runner_classes_windows.sh deleted file mode 100755 index ae75625974cf2..0000000000000 --- a/.github/scripts/get_runner_classes_windows.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -# -# This script generates tag-sets that can be used as runs-on: values to select runners. - -set -euo pipefail - -case "$GITHUB_REPOSITORY" in -*-enterprise) - # shellcheck disable=SC2129 - echo "compute-small=['self-hosted', 'ondemand', 'os=windows-2019', 'type=m6a.2xlarge']" >>"$GITHUB_OUTPUT" - echo "compute-medium=['self-hosted', 'ondemand', 'os=windows-2019', 'type=m6a.4xlarge']" >>"$GITHUB_OUTPUT" - echo "compute-large=['self-hosted', 'ondemand', 'os=windows-2019', 'type=m6a.8xlarge']" >>"$GITHUB_OUTPUT" - # m5d.8xlarge is equivalent to our xl custom runner in CE - echo "compute-xl=['self-hosted', 'ondemand', 'os=windows-2019', 'type=m6a.12xlarge']" >>"$GITHUB_OUTPUT" - ;; -*) - # shellcheck disable=SC2129 - echo "compute-small=['windows-2019']" >>"$GITHUB_OUTPUT" - echo "compute-medium=['windows-2019']" >>"$GITHUB_OUTPUT" - echo "compute-large=['windows-2019']" >>"$GITHUB_OUTPUT" - echo "compute-xl=['windows-2019']" >>"$GITHUB_OUTPUT" - ;; -esac diff --git a/.github/scripts/metrics_checker.sh b/.github/scripts/metrics_checker.sh index 37659de4df8bd..a34cdf12fbec3 100755 --- a/.github/scripts/metrics_checker.sh +++ b/.github/scripts/metrics_checker.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -uo pipefail diff --git a/.github/scripts/notify_slack.sh b/.github/scripts/notify_slack.sh index 8df3f3f648766..eacefaa91a439 100755 --- a/.github/scripts/notify_slack.sh +++ b/.github/scripts/notify_slack.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 + set -uo pipefail @@ -12,8 +13,8 @@ if [[ $GITHUB_REF_NAME == "main" ]]; then COMMIT_MESSAGE=$(git log -1 --pretty=%B | head -n1) SHORT_REF=$(git rev-parse --short "${GITHUB_SHA}") curl -X POST -H 'Content-type: application/json' \ - --data \ - "{ \ + --data \ + "{ \ \"attachments\": [ \ { \ \"fallback\": \"GitHub Actions workflow failed!\", \ diff --git a/.github/scripts/rerun_fails_report.sh b/.github/scripts/rerun_fails_report.sh index 90bae7a03a59d..ac6b7cf2ff9da 100755 --- a/.github/scripts/rerun_fails_report.sh +++ b/.github/scripts/rerun_fails_report.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # # Add a comment on the github PR if there were any rerun tests. diff --git a/.github/scripts/set_test_package_matrix.sh b/.github/scripts/set_test_package_matrix.sh index da8b6d563c37a..5608a83974024 100755 --- a/.github/scripts/set_test_package_matrix.sh +++ b/.github/scripts/set_test_package_matrix.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail export RUNNER_COUNT=$1 diff --git a/.github/scripts/verify_artifact.sh b/.github/scripts/verify_artifact.sh index 3aa9e0848dfb3..48bfede1cb33f 100755 --- a/.github/scripts/verify_artifact.sh +++ b/.github/scripts/verify_artifact.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/.github/scripts/verify_bin.sh b/.github/scripts/verify_bin.sh index dc5ac9f9f0e34..ff572d87fae9e 100755 --- a/.github/scripts/verify_bin.sh +++ b/.github/scripts/verify_bin.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/.github/scripts/verify_deb.sh b/.github/scripts/verify_deb.sh index c6b6926c5d1a2..84a9a10c85639 100755 --- a/.github/scripts/verify_deb.sh +++ b/.github/scripts/verify_deb.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/.github/scripts/verify_docker.sh b/.github/scripts/verify_docker.sh index ea9180920f8ae..fbbeb7dff464a 100755 --- a/.github/scripts/verify_docker.sh +++ b/.github/scripts/verify_docker.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/.github/scripts/verify_envoy_version.sh b/.github/scripts/verify_envoy_version.sh index 4bcbea4cabeeb..bfbd969d4baab 100755 --- a/.github/scripts/verify_envoy_version.sh +++ b/.github/scripts/verify_envoy_version.sh @@ -1,10 +1,10 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail -current_branch=$GITHUB_REF_NAME +current_branch=$GITHUB_REF GITHUB_DEFAULT_BRANCH='main' if [ -z "$GITHUB_TOKEN" ]; then @@ -13,7 +13,7 @@ if [ -z "$GITHUB_TOKEN" ]; then fi if [ -z "$current_branch" ]; then - echo "GITHUB_REF_NAME must be set" + echo "GITHUB_REF must be set" exit 1 fi @@ -81,6 +81,7 @@ released_envoy_version=$(get_latest_envoy_version) major_released_envoy_version="${released_envoy_version[@]:1:4}" validate_envoy_version_main(){ + echo "verify "main" GitHub branch has latest envoy version" # Get envoy version for current branch ENVOY_VERSIONS=$(sanitize_consul_envoy_version | awk '{print $2}' | tr ',' ' ') envoy_version_main_branch=$(get_major_version ${ENVOY_VERSIONS}) @@ -122,8 +123,8 @@ echo checking out branch: "${current_branch}" git checkout "${current_branch}" echo -echo "Branch ${current_branch} => Consul version: ${CONSUL_VERSION}; Envoy Version: ${ENVOY_VERSIONS}" -echo "Branch ${GITHUB_DEFAULT_BRANCH} => Consul version: ${CONSUL_VERSION_DEFAULT_BRANCH}; Envoy Version: ${ENVOY_VERSIONS_DEFAULT_BRANCH}" +echo "Branch ${current_branch} =>Consul version: ${CONSUL_VERSION}; Envoy Version: ${ENVOY_VERSIONS}" +echo "Branch ${GITHUB_DEFAULT_BRANCH} =>Consul version: ${CONSUL_VERSION_DEFAULT_BRANCH}; Envoy Version: ${ENVOY_VERSIONS_DEFAULT_BRANCH}" ## Get major Consul and Envoy versions on release and default branch MAJOR_CONSUL_VERSION=$(get_major_version ${CONSUL_VERSION}) diff --git a/.github/scripts/verify_rpm.sh b/.github/scripts/verify_rpm.sh index 96cd658eef3d5..17709a1d90e1b 100755 --- a/.github/scripts/verify_rpm.sh +++ b/.github/scripts/verify_rpm.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/.github/workflows/bot-auto-approve.yaml b/.github/workflows/bot-auto-approve.yaml index 911fc27f46968..2b652388999c2 100644 --- a/.github/workflows/bot-auto-approve.yaml +++ b/.github/workflows/bot-auto-approve.yaml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest if: github.actor == 'hc-github-team-consul-core' steps: - - uses: hmarr/auto-approve-action@44888193675f29a83e04faf4002fa8c0b537b1e4 # v3.2.1 + - uses: hmarr/auto-approve-action@v3 with: review-message: "Auto approved Consul Bot automated PR" github-token: ${{ secrets.MERGE_APPROVE_TOKEN }} diff --git a/.github/workflows/broken-link-check.yml b/.github/workflows/broken-link-check.yml index 2a8d77c5880fd..b7c89ff3e75dc 100644 --- a/.github/workflows/broken-link-check.yml +++ b/.github/workflows/broken-link-check.yml @@ -12,11 +12,11 @@ jobs: linkChecker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v3 - name: Run lychee link checker id: lychee - uses: lycheeverse/lychee-action@ec3ed119d4f44ad2673a7232460dc7dff59d2421 # v1.8.0 + uses: lycheeverse/lychee-action@v1.6.1 with: args: ./website/content/docs/ --base https://developer.hashicorp.com/ --exclude-all-private --exclude '\.(svg|gif|jpg|png)' --exclude 'manage\.auth0\.com' --accept 403 --max-concurrency=24 --no-progress --verbose # Fail GitHub action when broken links are found? @@ -26,7 +26,7 @@ jobs: - name: Create GitHub Issue From lychee output file if: env.lychee_exit_code != 0 - uses: peter-evans/create-issue-from-file@433e51abf769039ee20ba1293a088ca19d573b7f # v4.0.1 + uses: peter-evans/create-issue-from-file@v4 with: title: Link Checker Report content-filepath: ./lychee/out.md diff --git a/.github/workflows/build-artifacts.yml b/.github/workflows/build-artifacts.yml index 2977a73b6eb07..f57ea3527d485 100644 --- a/.github/workflows/build-artifacts.yml +++ b/.github/workflows/build-artifacts.yml @@ -13,7 +13,7 @@ permissions: contents: read env: - GOPRIVATE: github.com/hashicorp # Required for enterprise deps + GOPRIVATE: github.com/hashicorp jobs: setup: @@ -25,7 +25,7 @@ jobs: compute-large: ${{ steps.setup-outputs.outputs.compute-large }} compute-xl: ${{ steps.setup-outputs.outputs.compute-xl }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -56,14 +56,14 @@ jobs: kv/data/github/${{ github.repository }}/dockerhub username | DOCKERHUB_USERNAME; kv/data/github/${{ github.repository }}/dockerhub token | DOCKERHUB_TOKEN; - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 # NOTE: ENT specific step as we need to set elevated GitHub permissions. - name: Setup Git if: ${{ endsWith(github.repository, '-enterprise') }} run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # pin@v3.5.0 with: go-version-file: 'go.mod' @@ -78,17 +78,17 @@ jobs: echo "GITHUB_BUILD_URL=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_ENV - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0 + uses: docker/setup-buildx-action@f03ac48505955848960e80bbb68046aa35c7b9e7 # pin@v2.4.1 # NOTE: conditional specific logic as we store secrets in Vault in ENT and use GHA secrets in CE. - name: Login to Docker Hub - uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 + uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # pin@v2.1.0 with: username: ${{ endsWith(github.repository, '-enterprise') && steps.secrets.outputs.DOCKERHUB_USERNAME || secrets.DOCKERHUB_USERNAME }} password: ${{ endsWith(github.repository, '-enterprise') && steps.secrets.outputs.DOCKERHUB_TOKEN || secrets.DOCKERHUB_TOKEN }} - name: Docker build and push - uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1 + uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 # pin@v4.0.0 with: context: ./bin file: ./build-support/docker/Consul-Dev.dockerfile diff --git a/.github/workflows/build-distros.yml b/.github/workflows/build-distros.yml index 4d8799a5643d8..10c5208933412 100644 --- a/.github/workflows/build-distros.yml +++ b/.github/workflows/build-distros.yml @@ -17,10 +17,6 @@ env: GOTAGS: ${{ endsWith(github.repository, '-enterprise') && 'consulent' || '' }} GOPRIVATE: github.com/hashicorp # Required for enterprise deps -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} - cancel-in-progress: true - jobs: setup: name: Setup @@ -31,7 +27,7 @@ jobs: compute-large: ${{ steps.setup-outputs.outputs.compute-large }} compute-xl: ${{ steps.setup-outputs.outputs.compute-xl }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -54,7 +50,7 @@ jobs: XC_OS: "freebsd linux windows" runs-on: ${{ fromJSON(needs.setup.outputs.compute-xl) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git @@ -78,7 +74,7 @@ jobs: XC_OS: "darwin freebsd linux solaris windows" runs-on: ${{ fromJSON(needs.setup.outputs.compute-xl) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git @@ -103,7 +99,7 @@ jobs: CGO_ENABLED: 1 GOOS: linux steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git @@ -129,7 +125,7 @@ jobs: - check-go-mod runs-on: ${{ fromJSON(needs.setup.outputs.compute-xl) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cc2e2437a0502..d2af7841cafb5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -67,7 +67,7 @@ jobs: filepath: ${{ steps.generate-metadata-file.outputs.filepath }} steps: - name: 'Checkout directory' - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Generate metadata file id: generate-metadata-file uses: hashicorp/actions-generate-metadata@v1 @@ -99,12 +99,12 @@ jobs: name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Setup with node and yarn - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: '18' + node-version: '14' cache: 'yarn' cache-dependency-path: 'ui/yarn.lock' @@ -188,12 +188,12 @@ jobs: name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Setup with node and yarn - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: '18' + node-version: '14' cache: 'yarn' cache-dependency-path: 'ui/yarn.lock' @@ -239,12 +239,12 @@ jobs: name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Setup with node and yarn - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 with: - node-version: '18' + node-version: '14' cache: 'yarn' cache-dependency-path: 'ui/yarn.lock' @@ -294,7 +294,7 @@ jobs: version: ${{needs.set-product-version.outputs.product-version}} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # Strip everything but MAJOR.MINOR from the version string and add a `-dev` suffix # This naming convention will be used ONLY for per-commit dev images @@ -332,7 +332,7 @@ jobs: version: ${{needs.set-product-version.outputs.product-version}} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: hashicorp/actions-docker-build@v1 with: version: ${{env.version}} @@ -352,7 +352,7 @@ jobs: version: ${{needs.set-product-version.outputs.product-version}} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # Strip everything but MAJOR.MINOR from the version string and add a `-dev` suffix # This naming convention will be used ONLY for per-commit dev images @@ -397,7 +397,7 @@ jobs: name: Verify ${{ matrix.arch }} linux binary steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 if: ${{ endsWith(github.repository, '-enterprise') || matrix.arch != 's390x' }} - name: Download ${{ matrix.arch }} zip @@ -407,7 +407,7 @@ jobs: name: ${{ env.zip_name }} - name: Set up QEMU - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 + uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.1.0 if: ${{ matrix.arch == 'arm' || matrix.arch == 'arm64' }} with: # this should be a comma-separated string as opposed to an array @@ -430,7 +430,7 @@ jobs: name: Verify amd64 darwin binary steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Download amd64 darwin zip uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 @@ -461,7 +461,7 @@ jobs: name: Verify ${{ matrix.arch }} debian package steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set package version run: | @@ -477,7 +477,7 @@ jobs: name: ${{ env.pkg_name }} - name: Set up QEMU - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 + uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.1.0 with: platforms: all @@ -502,7 +502,7 @@ jobs: name: Verify ${{ matrix.arch }} rpm steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Set package version run: | @@ -518,7 +518,7 @@ jobs: name: ${{ env.pkg_name }} - name: Set up QEMU - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 + uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.1.0 with: platforms: all diff --git a/.github/workflows/ce-merge-trigger.yml b/.github/workflows/ce-merge-trigger.yml index 30a6b5fd90dff..4de4751660d1c 100644 --- a/.github/workflows/ce-merge-trigger.yml +++ b/.github/workflows/ce-merge-trigger.yml @@ -8,7 +8,7 @@ on: - closed branches: - main - - release/** + - 'release/*.*.x' jobs: trigger-ce-merge: diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml index 62b906eda3e66..d00717e2f0492 100644 --- a/.github/workflows/changelog-checker.yml +++ b/.github/workflows/changelog-checker.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 # by default the checkout action doesn't checkout all branches diff --git a/.github/workflows/embedded-asset-checker.yml b/.github/workflows/embedded-asset-checker.yml index 38879945e209c..4bb07771bd68f 100644 --- a/.github/workflows/embedded-asset-checker.yml +++ b/.github/workflows/embedded-asset-checker.yml @@ -20,7 +20,7 @@ jobs: if: "! ( contains(github.event.pull_request.labels.*.name, 'pr/update-ui-assets') || github.event.pull_request.user.login == 'hc-github-team-consul-core' )" runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 # by default the checkout action doesn't checkout all branches diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index 550fddd5d15ff..ed1e0c2088f84 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -21,7 +21,7 @@ jobs: compute-large: ${{ steps.setup-outputs.outputs.compute-large }} compute-xl: ${{ steps.setup-outputs.outputs.compute-xl }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -33,14 +33,14 @@ jobs: run: working-directory: ui steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # pin@v3.6.0 with: - node-version: '18' + node-version: '16' - name: Install Yarn - run: corepack enable + run: npm install -g yarn # Install dependencies. - name: install yarn packages @@ -53,14 +53,14 @@ jobs: needs: setup runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # pin@v3.6.0 with: - node-version: '18' + node-version: '16' - name: Install Yarn - run: corepack enable + run: npm install -g yarn # Install dependencies. - name: install yarn packages @@ -72,7 +72,7 @@ jobs: ember-build-test: needs: setup - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large ) }} + runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} strategy: matrix: partition: [1, 2, 3, 4] @@ -82,17 +82,17 @@ jobs: CONSUL_NSPACES_ENABLED: ${{ endsWith(github.repository, '-enterprise') && 1 || 0 }} # NOTE: this should be 1 in ENT. JOBS: 2 # limit parallelism for broccoli-babel-transpiler steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # pin@v3.6.0 with: - node-version: '18' + node-version: '16' - name: Install Yarn - run: corepack enable + run: npm install -g yarn - name: Install Chrome - uses: browser-actions/setup-chrome@c485fa3bab6be59dce18dbc18ef6ab7cbc8ff5f1 # v1.2.0 + uses: browser-actions/setup-chrome@29abc1a83d1d71557708563b4bc962d0f983a376 # pin@v1.2.1 - name: Install dependencies working-directory: ui diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index 20452515740f4..abb910b29e677 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -54,7 +54,7 @@ jobs: compute-large: ${{ steps.setup-outputs.outputs.compute-large }} compute-xl: ${{ steps.setup-outputs.outputs.compute-xl }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - id: setup-outputs name: Setup outputs run: ./.github/scripts/get_runner_classes.sh @@ -74,7 +74,7 @@ jobs: - setup runs-on: ${{ fromJSON(needs.setup.outputs.compute-medium) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(github.repository, '-enterprise') }} @@ -97,35 +97,35 @@ jobs: - name: Notify Slack if: ${{ failure() }} run: .github/scripts/notify_slack.sh - check-codegen: - needs: - - setup - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(github.repository, '-enterprise') }} - run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - run: make --always-make codegen - - run: | - if ! git diff --exit-code; then - echo "Generated code was not updated correctly" - exit 1 - fi - - name: Notify Slack - if: ${{ failure() }} - run: .github/scripts/notify_slack.sh + check-generated-deep-copy: + needs: + - setup + runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} + steps: + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. + - name: Setup Git + if: ${{ endsWith(github.repository, '-enterprise') }} + run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" + - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + with: + go-version-file: 'go.mod' + - run: make --always-make deep-copy + - run: | + if ! git diff --exit-code; then + echo "Generated code was not updated correctly" + exit 1 + fi + - name: Notify Slack + if: ${{ failure() }} + run: .github/scripts/notify_slack.sh lint-enums: needs: - setup runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(github.repository, '-enterprise') }} @@ -143,7 +143,7 @@ jobs: - setup runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" @@ -160,7 +160,7 @@ jobs: - setup runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(github.repository, '-enterprise') }} @@ -486,7 +486,7 @@ jobs: needs: - conditional-skip - setup - - check-codegen + - check-generated-deep-copy - check-generated-protobuf - check-go-mod - lint-consul-retry diff --git a/.github/workflows/issue-comment-created.yml b/.github/workflows/issue-comment-created.yml index 42483d92b1645..01e7e13f8bc44 100644 --- a/.github/workflows/issue-comment-created.yml +++ b/.github/workflows/issue-comment-created.yml @@ -11,8 +11,8 @@ jobs: triage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1.3.0 + - uses: actions/checkout@v2 + - uses: actions-ecosystem/action-remove-labels@v1 with: labels: | waiting-reply diff --git a/.github/workflows/jira-issues.yaml b/.github/workflows/jira-issues.yaml index c136dfd69a78c..d595e5f5af8c6 100644 --- a/.github/workflows/jira-issues.yaml +++ b/.github/workflows/jira-issues.yaml @@ -16,7 +16,7 @@ jobs: name: Jira Community Issue sync steps: - name: Login - uses: atlassian/gajira-login@ca13f8850ea309cf44a6e4e0c49d9aa48ac3ca4c # v3 + uses: atlassian/gajira-login@v3.0.0 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} @@ -40,7 +40,7 @@ jobs: - name: Create ticket if an issue is filed, or if PR not by a team member is opened if: github.event.action == 'opened' - uses: tomhjp/gh-action-jira-create@3ed1789cad3521292e591a7cfa703215ec1348bf # v0.2.1 + uses: tomhjp/gh-action-jira-create@v0.2.1 with: project: NET issuetype: "${{ steps.set-ticket-type.outputs.TYPE }}" @@ -60,7 +60,7 @@ jobs: # Education Jira - name: Create ticket in Education board an issue is filed, or if PR not by a team member is opened if: github.event.action == 'opened' && contains(github.event.issue.labels.*.name, 'type/docs') - uses: tomhjp/gh-action-jira-create@3ed1789cad3521292e591a7cfa703215ec1348bf # v0.2.1 + uses: tomhjp/gh-action-jira-create@v0.2.1 with: project: CE issuetype: "${{ steps.set-ticket-type.outputs.TYPE }}" @@ -77,28 +77,28 @@ jobs: - name: Search if: github.event.action != 'opened' id: search - uses: tomhjp/gh-action-jira-search@04700b457f317c3e341ce90da5a3ff4ce058f2fa # v0.2.2 + uses: tomhjp/gh-action-jira-search@v0.2.2 with: # cf[10089] is Issue Link (use JIRA API to retrieve) jql: 'issuetype = "${{ steps.set-ticket-type.outputs.TYPE }}" and cf[10089] = "${{ github.event.issue.html_url || github.event.pull_request.html_url }}"' - name: Sync comment if: github.event.action == 'created' && steps.search.outputs.issue - uses: tomhjp/gh-action-jira-comment@6eb6b9ead70221916b6badd118c24535ed220bd9 # v0.2.0 + uses: tomhjp/gh-action-jira-comment@v0.2.0 with: issue: ${{ steps.search.outputs.issue }} comment: "${{ github.actor }} ${{ github.event.review.state || 'commented' }}:\n\n${{ github.event.comment.body || github.event.review.body }}\n\n${{ github.event.comment.html_url || github.event.review.html_url }}" - name: Close ticket if: ( github.event.action == 'closed' || github.event.action == 'deleted' ) && steps.search.outputs.issue - uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 + uses: atlassian/gajira-transition@v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "Closed" - name: Reopen ticket if: github.event.action == 'reopened' && steps.search.outputs.issue - uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 + uses: atlassian/gajira-transition@v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "To Do" diff --git a/.github/workflows/jira-pr.yaml b/.github/workflows/jira-pr.yaml index a40bb0ae0f829..cadbfef1b2b8c 100644 --- a/.github/workflows/jira-pr.yaml +++ b/.github/workflows/jira-pr.yaml @@ -14,7 +14,7 @@ jobs: name: Jira sync steps: - name: Login - uses: atlassian/gajira-login@ca13f8850ea309cf44a6e4e0c49d9aa48ac3ca4c # v3 + uses: atlassian/gajira-login@v3.0.0 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} @@ -59,7 +59,7 @@ jobs: - name: Create ticket if an issue is filed, or if PR not by a team member is opened if: ( github.event.action == 'opened' && steps.is-team-member.outputs.MESSAGE == 'false' ) - uses: tomhjp/gh-action-jira-create@3ed1789cad3521292e591a7cfa703215ec1348bf # v0.2.1 + uses: tomhjp/gh-action-jira-create@v0.2.1 with: project: NET issuetype: "${{ steps.set-ticket-type.outputs.TYPE }}" @@ -79,7 +79,7 @@ jobs: # Education Jira - name: Create ticket in Education board an issue is filed, or if PR not by a team member is opened if: github.event.action == 'opened' && steps.is-team-member.outputs.MESSAGE == 'false' && contains(github.event.issue.labels.*.name, 'type/docs') - uses: tomhjp/gh-action-jira-create@3ed1789cad3521292e591a7cfa703215ec1348bf # v0.2.1 + uses: tomhjp/gh-action-jira-create@v0.2.1 with: project: CE issuetype: "${{ steps.set-ticket-type.outputs.TYPE }}" @@ -91,28 +91,28 @@ jobs: - name: Search if: github.event.action != 'opened' id: search - uses: tomhjp/gh-action-jira-search@04700b457f317c3e341ce90da5a3ff4ce058f2fa # v0.2.2 + uses: tomhjp/gh-action-jira-search@v0.2.2 with: # cf[10089] is Issue Link (use JIRA API to retrieve) jql: 'issuetype = "${{ steps.set-ticket-type.outputs.TYPE }}" and cf[10089] = "${{ github.event.issue.html_url || github.event.pull_request.html_url }}"' - name: Sync comment if: github.event.action == 'created' && steps.search.outputs.issue - uses: tomhjp/gh-action-jira-comment@6eb6b9ead70221916b6badd118c24535ed220bd9 # v0.2.0 + uses: tomhjp/gh-action-jira-comment@v0.2.0 with: issue: ${{ steps.search.outputs.issue }} comment: "${{ github.actor }} ${{ github.event.review.state || 'commented' }}:\n\n${{ github.event.comment.body || github.event.review.body }}\n\n${{ github.event.comment.html_url || github.event.review.html_url }}" - name: Close ticket if: ( github.event.action == 'closed' || github.event.action == 'deleted' ) && steps.search.outputs.issue - uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 + uses: atlassian/gajira-transition@v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "Closed" - name: Reopen ticket if: github.event.action == 'reopened' && steps.search.outputs.issue - uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 + uses: atlassian/gajira-transition@v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "To Do" diff --git a/.github/workflows/nightly-test-1.16.x.yaml b/.github/workflows/nightly-test-1.12.x.yaml similarity index 75% rename from .github/workflows/nightly-test-1.16.x.yaml rename to .github/workflows/nightly-test-1.12.x.yaml index b441eca5d0f59..c09cc4864b89d 100644 --- a/.github/workflows/nightly-test-1.16.x.yaml +++ b/.github/workflows/nightly-test-1.12.x.yaml @@ -1,28 +1,27 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -name: Nightly Frontend Test 1.16.x +name: Nightly Test 1.12.x on: schedule: - cron: '0 4 * * *' workflow_dispatch: {} env: - EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition - BRANCH: "release/1.16.x" - BRANCH_NAME: "release-1.16.x" # Used for naming artifacts - GOPRIVATE: github.com/hashicorp # Required for enterprise deps + EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition + BRANCH: "release/1.12.x" + BRANCH_NAME: "release-1.12.x" # Used for naming artifacts jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -49,12 +48,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -71,7 +70,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,12 +87,12 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -105,7 +104,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,12 +120,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -143,7 +142,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,12 +159,12 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -177,7 +176,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,12 +190,12 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -208,7 +207,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +223,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@v1.19 with: payload: | { diff --git a/.github/workflows/nightly-test-1.17.x.yaml b/.github/workflows/nightly-test-1.13.x.yaml similarity index 73% rename from .github/workflows/nightly-test-1.17.x.yaml rename to .github/workflows/nightly-test-1.13.x.yaml index 9a063001e402c..6139eb4bc1e1a 100644 --- a/.github/workflows/nightly-test-1.17.x.yaml +++ b/.github/workflows/nightly-test-1.13.x.yaml @@ -1,30 +1,29 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -name: Nightly Frontend Test 1.17.x +name: Nightly Test 1.13.x on: schedule: - cron: '0 4 * * *' workflow_dispatch: {} env: - EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition - BRANCH: "release/1.17.x" - BRANCH_NAME: "release-1.17.x" # Used for naming artifacts - GOPRIVATE: github.com/hashicorp # Required for enterprise deps + EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition + BRANCH: "release/1.13.x" + BRANCH_NAME: "release-1.13.x" # Used for naming artifacts jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -49,14 +48,14 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -71,7 +70,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,14 +87,14 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -105,7 +104,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,14 +120,14 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -143,7 +142,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,14 +159,14 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -177,7 +176,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,14 +190,14 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -208,7 +207,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +223,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@v1.19 with: payload: | { diff --git a/.github/workflows/nightly-test-1.14.x.yaml b/.github/workflows/nightly-test-1.14.x.yaml index 11fb011d13571..9b310f59065dc 100644 --- a/.github/workflows/nightly-test-1.14.x.yaml +++ b/.github/workflows/nightly-test-1.14.x.yaml @@ -1,28 +1,27 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -name: Nightly Frontend Test 1.14.x +name: Nightly Test 1.14.x on: schedule: - cron: '0 4 * * *' workflow_dispatch: {} env: - EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition + EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition BRANCH: "release/1.14.x" - BRANCH_NAME: "release-1.14.x" # Used for naming artifacts - GOPRIVATE: github.com/hashicorp # Required for enterprise deps + BRANCH_NAME: "release-1.14.x" # Used for naming artifacts jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -49,12 +48,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -71,7 +70,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,12 +87,12 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -105,7 +104,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,12 +120,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -143,7 +142,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,12 +159,12 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -177,7 +176,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,12 +190,12 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -208,7 +207,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +223,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@v1.19 with: payload: | { diff --git a/.github/workflows/nightly-test-1.15.x.yaml b/.github/workflows/nightly-test-1.15.x.yaml index a98eb73070b36..9048abb4a04e4 100644 --- a/.github/workflows/nightly-test-1.15.x.yaml +++ b/.github/workflows/nightly-test-1.15.x.yaml @@ -1,28 +1,27 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -name: Nightly Frontend Test 1.15.x +name: Nightly Test 1.15.x on: schedule: - cron: '0 4 * * *' workflow_dispatch: {} env: - EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition + EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition BRANCH: "release/1.15.x" - BRANCH_NAME: "release-1.15.x" # Used for naming artifacts - GOPRIVATE: github.com/hashicorp # Required for enterprise deps + BRANCH_NAME: "release-1.15.x" # Used for naming artifacts jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -49,12 +48,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -71,7 +70,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,12 +87,12 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -105,7 +104,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,12 +120,12 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -143,7 +142,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,12 +159,12 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -177,7 +176,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,12 +190,12 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: node-version: 14 cache: 'yarn' @@ -208,7 +207,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +223,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@v1.19 with: payload: | { diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml deleted file mode 100644 index c570a541abd11..0000000000000 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ /dev/null @@ -1,320 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -name: Nightly test-integrations 1.15.x - -on: - schedule: - # Run nightly at 1AM UTC/9PM EST/6PM PST - - cron: '* 1 * * *' - workflow_dispatch: {} - -env: - TEST_RESULTS_DIR: /tmp/test-results - TEST_RESULTS_ARTIFACT_NAME: test-results - CONSUL_LICENSE: ${{ secrets.CONSUL_LICENSE }} - GOTAGS: ${{ endsWith(github.repository, '-enterprise') && 'consulent' || '' }} - GOTESTSUM_VERSION: "1.10.1" - CONSUL_BINARY_UPLOAD_NAME: consul-bin - # strip the hashicorp/ off the front of github.repository for consul - CONSUL_LATEST_IMAGE_NAME: ${{ endsWith(github.repository, '-enterprise') && github.repository || 'hashicorp/consul' }} - GOPRIVATE: github.com/hashicorp # Required for enterprise deps - BRANCH: "release/1.15.x" - BRANCH_NAME: "release-1.15.x" # Used for naming artifacts - -jobs: - setup: - runs-on: ubuntu-latest - name: Setup - outputs: - compute-small: ${{ steps.runners.outputs.compute-small }} - compute-medium: ${{ steps.runners.outputs.compute-medium }} - compute-large: ${{ steps.runners.outputs.compute-large }} - compute-xl: ${{ steps.runners.outputs.compute-xl }} - enterprise: ${{ steps.runners.outputs.enterprise }} - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - id: runners - run: .github/scripts/get_runner_classes.sh - - dev-build: - needs: [setup] - uses: ./.github/workflows/reusable-dev-build.yml - with: - runs-on: ${{ needs.setup.outputs.compute-large }} - repository-name: ${{ github.repository }} - uploaded-binary-name: 'consul-bin' - branch-name: "release/1.15.x" - secrets: - elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - - generate-envoy-job-matrices: - needs: [setup] - runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - name: Generate Envoy Job Matrices - outputs: - envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - name: Generate Envoy Job Matrix - id: set-matrix - env: - # this is further going to multiplied in envoy-integration tests by the - # other dimensions in the matrix. Currently TOTAL_RUNNERS would be - # multiplied by 8 based on these values: - # envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 4 - JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' - run: | - NUM_RUNNERS=$TOTAL_RUNNERS - NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) - - if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then - echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." - NUM_RUNNERS=$((NUM_DIRS-1)) - fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) - { - echo -n "envoy-matrix=" - find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ - | xargs -0 -n 1 basename \ - | jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ - | jq --compact-output 'map(join("|"))' - } >> "$GITHUB_OUTPUT" - - envoy-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - needs: - - setup - - generate-envoy-job-matrices - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11"] - xds-target: ["server", "client"] - test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} - env: - ENVOY_VERSION: ${{ matrix.envoy-version }} - XDS_TARGET: ${{ matrix.xds-target }} - AWS_LAMBDA_REGION: us-west-2 - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: ./bin - - name: restore mode+x - run: chmod +x ./bin/consul - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0 - - name: Docker build - run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - - name: Envoy Integration Tests - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running $(sed 's,|, ,g' <<< "${{ matrix.test-cases }}" |wc -w) subtests" - # shellcheck disable=SC2001 - sed 's,|,\n,g' <<< "${{ matrix.test-cases }}" - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --debug \ - --rerun-fails \ - --rerun-fails-report=/tmp/gotestsum-rerun-fails \ - --jsonfile /tmp/jsonfile/go-test.log \ - --packages=./test/integration/connect/envoy \ - -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - upgrade-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - needs: - - setup - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - consul-version: ["1.14", "1.15"] - env: - CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.24.6" - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(github.repository, '-enterprise') }} - run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - run: go env - - # Get go binary from workspace - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: . - - name: restore mode+x - run: chmod +x consul - - name: Build consul:local image - run: docker build -t ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local -f ./build-support/docker/Consul-Dev.dockerfile . - - name: Configure GH workaround for ipv6 loopback - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - cat /etc/hosts && echo "-----------" - sudo sed -i 's/::1 *localhost ip6-localhost ip6-loopback/::1 ip6-localhost ip6-loopback/g' /etc/hosts - cat /etc/hosts - - name: Upgrade Integration Tests - run: | - mkdir -p "${{ env.TEST_RESULTS_DIR }}" - cd ./test/integration/consul-container/test/upgrade - docker run --rm ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local consul version - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --raw-command \ - --format=short-verbose \ - --debug \ - --rerun-fails=2 \ - --packages="./..." \ - -- \ - go test \ - -p=4 \ - -tags "${{ env.GOTAGS }}" \ - -timeout=30m \ - -json \ - ./... \ - --follow-log=false \ - --target-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --target-version local \ - --latest-image docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --latest-version "${{ env.CONSUL_LATEST_VERSION }}" - ls -lrt - env: - # this is needed because of incompatibility between RYUK container and GHA - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - # tput complains if this isn't set to something. - TERM: ansi - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - test-integrations-success: - needs: - - setup - - dev-build - - generate-envoy-job-matrices - - envoy-integration-test - - upgrade-integration-test - runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - if: ${{ always() }} - steps: - - name: evaluate upstream job results - run: | - # exit 1 if failure or cancelled result for any upstream job - if printf '${{ toJSON(needs) }}' | grep -E -i '\"result\": \"(failure|cancelled)\"'; then - printf "Tests failed or workflow cancelled:\n\n${{ toJSON(needs) }}" - exit 1 - fi - - name: Notify Slack - if: ${{ failure() }} - id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 - with: - payload: | - { - "message": "One or more nightly integration tests have failed on branch ${{ env.BRANCH }} for Consul. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.CONSUL_NIGHTLY_INTEG_TEST_SLACK_WEBHOOK }} diff --git a/.github/workflows/nightly-test-integrations-1.16.x.yml b/.github/workflows/nightly-test-integrations-1.16.x.yml deleted file mode 100644 index d9a771c3fe133..0000000000000 --- a/.github/workflows/nightly-test-integrations-1.16.x.yml +++ /dev/null @@ -1,342 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -name: Nightly test-integrations 1.16.x - -on: - schedule: - # Run nightly at 1AM UTC/9PM EST/6PM PST - - cron: '* 1 * * *' - workflow_dispatch: {} - -env: - TEST_RESULTS_DIR: /tmp/test-results - TEST_RESULTS_ARTIFACT_NAME: test-results - CONSUL_LICENSE: ${{ secrets.CONSUL_LICENSE }} - GOTAGS: ${{ endsWith(github.repository, '-enterprise') && 'consulent' || '' }} - GOTESTSUM_VERSION: "1.10.1" - CONSUL_BINARY_UPLOAD_NAME: consul-bin - # strip the hashicorp/ off the front of github.repository for consul - CONSUL_LATEST_IMAGE_NAME: ${{ endsWith(github.repository, '-enterprise') && github.repository || 'hashicorp/consul' }} - GOPRIVATE: github.com/hashicorp # Required for enterprise deps - BRANCH: "release/1.16.x" - BRANCH_NAME: "release-1.16.x" # Used for naming artifacts - -jobs: - setup: - runs-on: ubuntu-latest - name: Setup - outputs: - compute-small: ${{ steps.runners.outputs.compute-small }} - compute-medium: ${{ steps.runners.outputs.compute-medium }} - compute-large: ${{ steps.runners.outputs.compute-large }} - compute-xl: ${{ steps.runners.outputs.compute-xl }} - enterprise: ${{ steps.runners.outputs.enterprise }} - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - id: runners - run: .github/scripts/get_runner_classes.sh - - dev-build: - needs: [setup] - uses: ./.github/workflows/reusable-dev-build.yml - with: - runs-on: ${{ needs.setup.outputs.compute-large }} - repository-name: ${{ github.repository }} - uploaded-binary-name: 'consul-bin' - branch-name: "release/1.16.x" - secrets: - elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - - generate-envoy-job-matrices: - needs: [setup] - runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - name: Generate Envoy Job Matrices - outputs: - envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - name: Generate Envoy Job Matrix - id: set-matrix - env: - # this is further going to multiplied in envoy-integration tests by the - # other dimensions in the matrix. Currently TOTAL_RUNNERS would be - # multiplied by 8 based on these values: - # envoy-version: ["1.23.12", "1.24.12", "1.25.11", "1.26.6"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 4 - JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' - run: | - NUM_RUNNERS=$TOTAL_RUNNERS - NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) - - if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then - echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." - NUM_RUNNERS=$((NUM_DIRS-1)) - fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) - { - echo -n "envoy-matrix=" - find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ - | xargs -0 -n 1 basename \ - | jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ - | jq --compact-output 'map(join("|"))' - } >> "$GITHUB_OUTPUT" - - envoy-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - needs: - - setup - - generate-envoy-job-matrices - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - envoy-version: ["1.23.12", "1.24.12", "1.25.11", "1.26.6"] - xds-target: ["server", "client"] - test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} - env: - ENVOY_VERSION: ${{ matrix.envoy-version }} - XDS_TARGET: ${{ matrix.xds-target }} - AWS_LAMBDA_REGION: us-west-2 - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: ./bin - - name: restore mode+x - run: chmod +x ./bin/consul - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0 - - - name: Docker build - run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - - - name: Envoy Integration Tests - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running $(sed 's,|, ,g' <<< "${{ matrix.test-cases }}" |wc -w) subtests" - # shellcheck disable=SC2001 - sed 's,|,\n,g' <<< "${{ matrix.test-cases }}" - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --debug \ - --rerun-fails \ - --rerun-fails-report=/tmp/gotestsum-rerun-fails \ - --jsonfile /tmp/jsonfile/go-test.log \ - --packages=./test/integration/connect/envoy \ - -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - upgrade-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - needs: - - setup - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - consul-version: ["1.14", "1.15", "1.16"] - env: - CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.24.6" - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(github.repository, '-enterprise') }} - run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - run: go env - - # Get go binary from workspace - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: . - - name: restore mode+x - run: chmod +x consul - - name: Build consul:local image - run: docker build -t ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local -f ./build-support/docker/Consul-Dev.dockerfile . - - name: Build consul-envoy:latest-version image - id: buildConsulEnvoyLatestImage - run: | - if ${{ endsWith(github.repository, '-enterprise') }} == 'true' - then - docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }}-ent --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - else - docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }} --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - fi - - name: Build consul-envoy:target-version image - id: buildConsulEnvoyTargetImage - continue-on-error: true - run: docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=${{ env.CONSUL_LATEST_IMAGE_NAME }}:local --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - - name: Retry Build consul-envoy:target-version image - if: steps.buildConsulEnvoyTargetImage.outcome == 'failure' - run: docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=${{ env.CONSUL_LATEST_IMAGE_NAME }}:local --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - - name: Build sds image - run: docker build -t consul-sds-server ./test/integration/connect/envoy/test-sds-server/ - - name: Configure GH workaround for ipv6 loopback - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - cat /etc/hosts && echo "-----------" - sudo sed -i 's/::1 *localhost ip6-localhost ip6-loopback/::1 ip6-localhost ip6-loopback/g' /etc/hosts - cat /etc/hosts - - name: Upgrade Integration Tests - run: | - mkdir -p "${{ env.TEST_RESULTS_DIR }}" - cd ./test/integration/consul-container/test/upgrade - docker run --rm ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local consul version - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --raw-command \ - --format=short-verbose \ - --debug \ - --rerun-fails=2 \ - --packages="./..." \ - -- \ - go test \ - -p=4 \ - -tags "${{ env.GOTAGS }}" \ - -timeout=30m \ - -json \ - ./... \ - --follow-log=false \ - --target-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --target-version local \ - --latest-image docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --latest-version "${{ env.CONSUL_LATEST_VERSION }}" - ls -lrt - env: - # this is needed because of incompatibility between RYUK container and GHA - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - # tput complains if this isn't set to something. - TERM: ansi - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - - test-integrations-success: - needs: - - setup - - dev-build - - generate-envoy-job-matrices - - envoy-integration-test - - upgrade-integration-test - runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - if: ${{ always() }} - steps: - - name: evaluate upstream job results - run: | - # exit 1 if failure or cancelled result for any upstream job - if printf '${{ toJSON(needs) }}' | grep -E -i '\"result\": \"(failure|cancelled)\"'; then - printf "Tests failed or workflow cancelled:\n\n${{ toJSON(needs) }}" - exit 1 - fi - - name: Notify Slack - if: ${{ failure() }} - id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 - with: - payload: | - { - "message": "One or more nightly integration tests have failed on branch ${{ env.BRANCH }} for Consul. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.CONSUL_NIGHTLY_INTEG_TEST_SLACK_WEBHOOK }} diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml deleted file mode 100644 index 660a28374b783..0000000000000 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ /dev/null @@ -1,342 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -name: Nightly test-integrations 1.17.x - -on: - schedule: - # Run nightly at 1AM UTC/9PM EST/6PM PST - - cron: '* 1 * * *' - workflow_dispatch: {} - -env: - TEST_RESULTS_DIR: /tmp/test-results - TEST_RESULTS_ARTIFACT_NAME: test-results - CONSUL_LICENSE: ${{ secrets.CONSUL_LICENSE }} - GOTAGS: ${{ endsWith(github.repository, '-enterprise') && 'consulent' || '' }} - GOTESTSUM_VERSION: "1.10.1" - CONSUL_BINARY_UPLOAD_NAME: consul-bin - # strip the hashicorp/ off the front of github.repository for consul - CONSUL_LATEST_IMAGE_NAME: ${{ endsWith(github.repository, '-enterprise') && github.repository || 'hashicorp/consul' }} - GOPRIVATE: github.com/hashicorp # Required for enterprise deps - BRANCH: "release/1.17.x" - BRANCH_NAME: "release-1.17.x" # Used for naming artifacts - -jobs: - setup: - runs-on: ubuntu-latest - name: Setup - outputs: - compute-small: ${{ steps.runners.outputs.compute-small }} - compute-medium: ${{ steps.runners.outputs.compute-medium }} - compute-large: ${{ steps.runners.outputs.compute-large }} - compute-xl: ${{ steps.runners.outputs.compute-xl }} - enterprise: ${{ steps.runners.outputs.enterprise }} - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - id: runners - run: .github/scripts/get_runner_classes.sh - - dev-build: - needs: [setup] - uses: ./.github/workflows/reusable-dev-build.yml - with: - runs-on: ${{ needs.setup.outputs.compute-large }} - repository-name: ${{ github.repository }} - uploaded-binary-name: 'consul-bin' - branch-name: "release/1.17.x" - secrets: - elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - - generate-envoy-job-matrices: - needs: [setup] - runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - name: Generate Envoy Job Matrices - outputs: - envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - name: Generate Envoy Job Matrix - id: set-matrix - env: - # this is further going to multiplied in envoy-integration tests by the - # other dimensions in the matrix. Currently TOTAL_RUNNERS would be - # multiplied by 8 based on these values: - # envoy-version: ["1.24.12", "1.25.11", "1.26.6", "1.27.2"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 4 - JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' - run: | - NUM_RUNNERS=$TOTAL_RUNNERS - NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) - - if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then - echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." - NUM_RUNNERS=$((NUM_DIRS-1)) - fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) - { - echo -n "envoy-matrix=" - find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ - | xargs -0 -n 1 basename \ - | jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ - | jq --compact-output 'map(join("|"))' - } >> "$GITHUB_OUTPUT" - - envoy-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - needs: - - setup - - generate-envoy-job-matrices - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.6", "1.27.2"] - xds-target: ["server", "client"] - test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} - env: - ENVOY_VERSION: ${{ matrix.envoy-version }} - XDS_TARGET: ${{ matrix.xds-target }} - AWS_LAMBDA_REGION: us-west-2 - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: ./bin - - name: restore mode+x - run: chmod +x ./bin/consul - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0 - - - name: Docker build - run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - - - name: Envoy Integration Tests - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running $(sed 's,|, ,g' <<< "${{ matrix.test-cases }}" |wc -w) subtests" - # shellcheck disable=SC2001 - sed 's,|,\n,g' <<< "${{ matrix.test-cases }}" - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --debug \ - --rerun-fails \ - --rerun-fails-report=/tmp/gotestsum-rerun-fails \ - --jsonfile /tmp/jsonfile/go-test.log \ - --packages=./test/integration/connect/envoy \ - -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - upgrade-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - needs: - - setup - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - consul-version: ["1.15", "1.16", "1.17"] - env: - CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.24.6" - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(github.repository, '-enterprise') }} - run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - run: go env - - # Get go binary from workspace - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: . - - name: restore mode+x - run: chmod +x consul - - name: Build consul:local image - run: docker build -t ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local -f ./build-support/docker/Consul-Dev.dockerfile . - - name: Build consul-envoy:latest-version image - id: buildConsulEnvoyLatestImage - run: | - if ${{ endsWith(github.repository, '-enterprise') }} == 'true' - then - docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }}-ent --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - else - docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }} --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - fi - - name: Build consul-envoy:target-version image - id: buildConsulEnvoyTargetImage - continue-on-error: true - run: docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=${{ env.CONSUL_LATEST_IMAGE_NAME }}:local --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - - name: Retry Build consul-envoy:target-version image - if: steps.buildConsulEnvoyTargetImage.outcome == 'failure' - run: docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=${{ env.CONSUL_LATEST_IMAGE_NAME }}:local --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - - name: Build sds image - run: docker build -t consul-sds-server ./test/integration/connect/envoy/test-sds-server/ - - name: Configure GH workaround for ipv6 loopback - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - cat /etc/hosts && echo "-----------" - sudo sed -i 's/::1 *localhost ip6-localhost ip6-loopback/::1 ip6-localhost ip6-loopback/g' /etc/hosts - cat /etc/hosts - - name: Upgrade Integration Tests - run: | - mkdir -p "${{ env.TEST_RESULTS_DIR }}" - cd ./test/integration/consul-container/test/upgrade - docker run --rm ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local consul version - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --raw-command \ - --format=short-verbose \ - --debug \ - --rerun-fails=2 \ - --packages="./..." \ - -- \ - go test \ - -p=4 \ - -tags "${{ env.GOTAGS }}" \ - -timeout=30m \ - -json \ - ./... \ - --follow-log=false \ - --target-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --target-version local \ - --latest-image docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --latest-version "${{ env.CONSUL_LATEST_VERSION }}" - ls -lrt - env: - # this is needed because of incompatibility between RYUK container and GHA - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - # tput complains if this isn't set to something. - TERM: ansi - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - - test-integrations-success: - needs: - - setup - - dev-build - - generate-envoy-job-matrices - - envoy-integration-test - - upgrade-integration-test - runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - if: ${{ always() }} - steps: - - name: evaluate upstream job results - run: | - # exit 1 if failure or cancelled result for any upstream job - if printf '${{ toJSON(needs) }}' | grep -E -i '\"result\": \"(failure|cancelled)\"'; then - printf "Tests failed or workflow cancelled:\n\n${{ toJSON(needs) }}" - exit 1 - fi - - name: Notify Slack - if: ${{ failure() }} - id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 - with: - payload: | - { - "message": "One or more nightly integration tests have failed on branch ${{ env.BRANCH }} for Consul. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.CONSUL_NIGHTLY_INTEG_TEST_SLACK_WEBHOOK }} diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index 7fa1ec1f48daa..d4432f27ba86b 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -65,7 +65,7 @@ jobs: # this is further going to multiplied in envoy-integration tests by the # other dimensions in the matrix. Currently TOTAL_RUNNERS would be # multiplied by 8 based on these values: - # envoy-version: ["1.24.12", "1.25.11", "1.26.6", "1.27.2"] + # envoy-version: ["1.24.10", "1.25.9", "1.26.4", "1.27.0"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -88,7 +88,7 @@ jobs: } >> "$GITHUB_OUTPUT" envoy-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large ) }} + runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} needs: - setup - generate-envoy-job-matrices @@ -99,7 +99,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.6", "1.27.2"] + envoy-version: ["1.23.12", "1.24.10", "1.25.9", "1.26.4"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -183,7 +183,7 @@ jobs: run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml upgrade-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large ) }} + runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} needs: - setup - dev-build @@ -193,7 +193,7 @@ jobs: strategy: fail-fast: false matrix: - consul-version: [ "1.15", "1.16"] + consul-version: ["1.14", "1.15", "1.16"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} ENVOY_VERSION: "1.24.6" @@ -223,13 +223,11 @@ jobs: run: docker build -t ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local -f ./build-support/docker/Consul-Dev.dockerfile . - name: Build consul-envoy:latest-version image id: buildConsulEnvoyLatestImage - run: | - if ${{ endsWith(github.repository, '-enterprise') }} == 'true' - then - docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }}-ent --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - else - docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }} --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - fi + continue-on-error: true + run: docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }} --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets + - name: Retry Build consul-envoy:latest-version image + if: steps.buildConsulEnvoyLatestImage.outcome == 'failure' + run: docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }} --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - name: Build consul-envoy:target-version image id: buildConsulEnvoyTargetImage continue-on-error: true @@ -309,99 +307,6 @@ jobs: run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - peering_commontopo-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large ) }} - needs: - - setup - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - env: - ENVOY_VERSION: "1.24.6" - steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(github.repository, '-enterprise') }} - run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - run: go env - - # Get go binary from workspace - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: . - - name: restore mode+x - run: chmod +x consul - - name: Build consul:local image - run: docker build -t ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local -f ./build-support/docker/Consul-Dev.dockerfile . - - name: Peering commonTopo Integration Tests - run: | - mkdir -p "${{ env.TEST_RESULTS_DIR }}" - cd ./test-integ/peering_commontopo - docker run --rm ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local consul version - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --raw-command \ - --format=short-verbose \ - --debug \ - --packages="./..." \ - -- \ - go test \ - -tags "${{ env.GOTAGS }}" \ - -timeout=30m \ - -json . \ - --target-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --target-version local \ - --latest-image docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --latest-version latest - ls -lrt - env: - # this is needed because of incompatibility between RYUK container and GHA - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - # tput complains if this isn't set to something. - TERM: ansi - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - test-integrations-success: needs: - setup @@ -409,7 +314,6 @@ jobs: - generate-envoy-job-matrices - envoy-integration-test - upgrade-integration-test - - peering_commontopo-integration-test runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} if: ${{ always() }} steps: @@ -420,14 +324,3 @@ jobs: printf "Tests failed or workflow cancelled:\n\n${{ toJSON(needs) }}" exit 1 fi - - name: Notify Slack - if: ${{ failure() }} - id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 - with: - payload: | - { - "message": "One or more nightly integration tests have failed. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.CONSUL_NIGHTLY_INTEG_TEST_SLACK_WEBHOOK }} diff --git a/.github/workflows/nightly-test-main.yaml b/.github/workflows/nightly-test-main.yaml index a089121cc8c66..16160175b6815 100644 --- a/.github/workflows/nightly-test-main.yaml +++ b/.github/workflows/nightly-test-main.yaml @@ -1,30 +1,29 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -name: Nightly Frontend Test Main +name: Nightly Test Main on: schedule: - cron: '0 4 * * *' workflow_dispatch: {} env: - EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition + EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition BRANCH: "main" - BRANCH_NAME: "main" # Used for naming artifacts - GOPRIVATE: github.com/hashicorp # Required for enterprise deps + BRANCH_NAME: "main" # Used for naming artifacts jobs: frontend-test-workspace-node: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -49,14 +48,14 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 0 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -71,7 +70,7 @@ jobs: run: make build-ci - name: Upload CE Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -88,14 +87,14 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -105,7 +104,7 @@ jobs: run: make deps - name: Download CE Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ce-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -121,14 +120,14 @@ jobs: JOBS: 2 CONSUL_NSPACES_ENABLED: 1 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -143,7 +142,7 @@ jobs: run: make build-ci - name: Upload ENT Frontend - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -160,14 +159,14 @@ jobs: EMBER_TEST_REPORT: test-results/report-ce.xml #outputs test report for CI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -177,7 +176,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -191,14 +190,14 @@ jobs: runs-on: ubuntu-latest needs: [frontend-build-ent] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ env.BRANCH }} # Not necessary to use yarn, but enables caching - - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 + - uses: actions/setup-node@v3 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -208,7 +207,7 @@ jobs: run: make deps - name: Download ENT Frontend - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@v3 with: name: frontend-ent-${{ env.BRANCH_NAME }} path: ./ui/packages/consul-ui/dist @@ -224,7 +223,7 @@ jobs: steps: - name: Slack Notification id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 + uses: slackapi/slack-github-action@v1.19 with: payload: | { diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 0d6b71c9f0618..a29cadcb685b4 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -10,7 +10,7 @@ jobs: triage: runs-on: ubuntu-latest steps: - - uses: actions/labeler@0967ca812e7fdc8f5f71402a1b486d5bd061fe20 # v4.2.0 + - uses: actions/labeler@main with: repo-token: "${{ secrets.GITHUB_TOKEN }}" configuration-path: .github/pr-labeler.yml diff --git a/.github/workflows/pr-metrics-test-checker.yml b/.github/workflows/pr-metrics-test-checker.yml index d0bdac04f7e3f..a73f4fbb3ff5a 100644 --- a/.github/workflows/pr-metrics-test-checker.yml +++ b/.github/workflows/pr-metrics-test-checker.yml @@ -14,7 +14,7 @@ jobs: if: "! ( contains(github.event.pull_request.labels.*.name, 'pr/no-metrics-test') || github.event.pull_request.user.login == 'hc-github-team-consul-core' )" runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 name: "checkout repo" with: ref: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/reusable-check-go-mod.yml b/.github/workflows/reusable-check-go-mod.yml index 7fffb616879ef..2078b0c3217d6 100644 --- a/.github/workflows/reusable-check-go-mod.yml +++ b/.github/workflows/reusable-check-go-mod.yml @@ -18,12 +18,12 @@ jobs: runs-on: ${{ fromJSON(inputs.runs-on) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(inputs.repository-name, '-enterprise') }} run: git config --global url."https://${{ secrets.elevated-github-token }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # pin@v3.5.0 with: go-version-file: 'go.mod' - run: go mod tidy diff --git a/.github/workflows/reusable-dev-build-windows.yml b/.github/workflows/reusable-dev-build-windows.yml deleted file mode 100644 index 01247c477878c..0000000000000 --- a/.github/workflows/reusable-dev-build-windows.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: reusable-dev-build-windows - -on: - workflow_call: - inputs: - uploaded-binary-name: - required: false - type: string - default: "consul.exe" - runs-on: - description: An expression indicating which kind of runners to use. - required: true - type: string - repository-name: - required: true - type: string - go-arch: - required: false - type: string - default: "" - secrets: - elevated-github-token: - required: true -jobs: - build: - runs-on: 'windows-2019' - steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(inputs.repository-name, '-enterprise') }} - run: git config --global url."https://${{ secrets.elevated-github-token }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - name: Build - env: - GOARCH: ${{ inputs.goarch }} - run: go build . - # save dev build to pass to downstream jobs - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 - with: - name: ${{inputs.uploaded-binary-name}} - path: consul.exe - - name: Notify Slack - if: ${{ failure() }} - run: .github/scripts/notify_slack.sh diff --git a/.github/workflows/reusable-dev-build.yml b/.github/workflows/reusable-dev-build.yml index 99bcb96592c3a..2db9670655e46 100644 --- a/.github/workflows/reusable-dev-build.yml +++ b/.github/workflows/reusable-dev-build.yml @@ -14,10 +14,6 @@ on: repository-name: required: true type: string - branch-name: - required: false - type: string - default: "" go-arch: required: false type: string @@ -29,15 +25,7 @@ jobs: build: runs-on: ${{ fromJSON(inputs.runs-on) }} steps: - # NOTE: This is used for nightly job of building release branch. - - name: Checkout branch ${{ inputs.branch-name }} - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ inputs.branch-name }} - if: inputs.branch-name != '' - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - if: inputs.branch-name == '' + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(inputs.repository-name, '-enterprise') }} diff --git a/.github/workflows/reusable-lint.yml b/.github/workflows/reusable-lint.yml index 902ff1867144f..f7032f9866633 100644 --- a/.github/workflows/reusable-lint.yml +++ b/.github/workflows/reusable-lint.yml @@ -20,7 +20,6 @@ on: env: GOTAGS: "${{ github.event.repository.name == 'consul-enterprise' && 'consulent consulprem consuldev' || '' }}" GOARCH: ${{inputs.go-arch}} - GOPRIVATE: github.com/hashicorp # Required for enterprise deps jobs: lint: @@ -34,22 +33,20 @@ jobs: - "envoyextensions" - "troubleshoot" - "test/integration/consul-container" - - "test-integ" - - "testing/deployer" fail-fast: true name: lint ${{ matrix.directory }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(inputs.repository-name, '-enterprise') }} run: git config --global url."https://${{ secrets.elevated-github-token }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # pin@v3.5.0 with: go-version-file: 'go.mod' - run: go env - name: lint-${{ matrix.directory }} - uses: golangci/golangci-lint-action@639cd343e1d3b897ff35927a75193d57cfcba299 # v3.6.0 + uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5 # pin@v3.4.0 with: working-directory: ${{ matrix.directory }} version: v1.51.1 diff --git a/.github/workflows/reusable-unit-split.yml b/.github/workflows/reusable-unit-split.yml index 3d959d168beda..6c13670e742ed 100644 --- a/.github/workflows/reusable-unit-split.yml +++ b/.github/workflows/reusable-unit-split.yml @@ -51,7 +51,6 @@ env: TOTAL_RUNNERS: ${{inputs.runner-count}} CONSUL_LICENSE: ${{secrets.consul-license}} GOTAGS: ${{ inputs.go-tags}} - GOPRIVATE: github.com/hashicorp # Required for enterprise deps DATADOG_API_KEY: ${{secrets.datadog-api-key}} jobs: @@ -60,8 +59,8 @@ jobs: outputs: package-matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # pin@v3.5.0 with: go-version-file: 'go.mod' - id: set-matrix @@ -83,12 +82,12 @@ jobs: ulimit -Sa echo "Hard limits" ulimit -Ha - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(inputs.repository-name, '-enterprise') }} run: git config --global url."https://${{ secrets.elevated-github-token }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # pin@v3.5.0 with: go-version-file: 'go.mod' cache: true @@ -97,7 +96,7 @@ jobs: working-directory: ${{inputs.directory}} run: go mod download - name: Download consul - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # pin@v3.0.2 with: name: ${{inputs.uploaded-binary-name}} path: ${{inputs.directory}} @@ -129,9 +128,9 @@ jobs: --rerun-fails-report=/tmp/gotestsum-rerun-fails \ --packages="$PACKAGE_NAMES" \ --junitfile ${{env.TEST_RESULTS}}/gotestsum-report.xml -- \ - -tags="${{env.GOTAGS}}" \ - -cover -coverprofile=coverage.txt \ - -timeout=30m + -tags="${{env.GOTAGS}}" -p 2 \ + ${GO_TEST_FLAGS-} \ + -cover -coverprofile=coverage.txt # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault @@ -164,11 +163,11 @@ jobs: DD_ENV: ci run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" ${{env.TEST_RESULTS}}/gotestsum-report.xml - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin@v3.1.2 with: name: test-results path: ${{env.TEST_RESULTS}} - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin@v3.1.2 with: name: jsonfile path: /tmp/jsonfile diff --git a/.github/workflows/reusable-unit.yml b/.github/workflows/reusable-unit.yml index 3b50bfa7e3887..c49a6291fa2e2 100644 --- a/.github/workflows/reusable-unit.yml +++ b/.github/workflows/reusable-unit.yml @@ -50,14 +50,13 @@ env: GOARCH: ${{inputs.go-arch}} CONSUL_LICENSE: ${{secrets.consul-license}} GOTAGS: ${{ inputs.go-tags}} - GOPRIVATE: github.com/hashicorp # Required for enterprise deps DATADOG_API_KEY: ${{secrets.datadog-api-key}} jobs: go-test: runs-on: ${{ fromJSON(inputs.runs-on) }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # pin@v3.3.0 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(inputs.repository-name, '-enterprise') }} @@ -77,7 +76,7 @@ jobs: working-directory: ${{inputs.directory}} run: go mod download - name: Download consul - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # pin@v3.0.2 with: name: ${{inputs.uploaded-binary-name}} path: ${{inputs.directory}} @@ -109,8 +108,7 @@ jobs: --junitfile ${{env.TEST_RESULTS}}/gotestsum-report.xml -- \ -tags="${{env.GOTAGS}}" \ ${GO_TEST_FLAGS-} \ - -cover -coverprofile=coverage.txt \ - -timeout=30m + -cover -coverprofile=coverage.txt # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault @@ -143,11 +141,11 @@ jobs: DD_ENV: ci run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" ${{env.TEST_RESULTS}}/gotestsum-report.xml - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin@v3.1.2 with: name: test-results path: ${{env.TEST_RESULTS}} - - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # pin@v3.1.2 with: name: jsonfile path: /tmp/jsonfile diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index ff07a961a4e48..f3da6d422b6b1 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -12,7 +12,7 @@ jobs: permissions: pull-requests: write steps: - - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8.0.0 + - uses: actions/stale@v4 with: days-before-stale: -1 days-before-close: -1 diff --git a/.github/workflows/test-integrations-windows.yml b/.github/workflows/test-integrations-windows.yml deleted file mode 100644 index 16f7b26fdc67a..0000000000000 --- a/.github/workflows/test-integrations-windows.yml +++ /dev/null @@ -1,1211 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -name: test-integrations-windows - -on: - workflow_dispatch: - -env: - TEST_RESULTS_DIR: /tmp/test-results - TEST_RESULTS_ARTIFACT_NAME: test-results - CONSUL_LICENSE: ${{ secrets.CONSUL_LICENSE }} - GOTAGS: ${{ endsWith(github.repository, '-enterprise') && 'consulent' || '' }} - GOTESTSUM_VERSION: "1.9.0" - CONSUL_BINARY_UPLOAD_NAME: consul.exe - # strip the hashicorp/ off the front of github.repository for consul - CONSUL_LATEST_IMAGE_NAME: ${{ endsWith(github.repository, '-enterprise') && github.repository || 'consul' }} - GOPRIVATE: github.com/hashicorp # Required for enterprise deps - -jobs: - setup: - runs-on: ubuntu-latest - name: Setup - outputs: - compute-small: ${{ steps.runners.outputs.compute-small }} - compute-medium: ${{ steps.runners.outputs.compute-medium }} - compute-large: ${{ steps.runners.outputs.compute-large }} - compute-xl: ${{ steps.runners.outputs.compute-xl }} - enterprise: ${{ steps.runners.outputs.enterprise }} - steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - id: runners - run: .github/scripts/get_runner_classes_windows.sh - - dev-build: - uses: ./.github/workflows/reusable-dev-build-windows.yml - with: - runs-on: ${{ needs.setup.outputs.compute-large }} - repository-name: ${{ github.repository }} - uploaded-binary-name: 'consul.exe' - secrets: - elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - - # NOTE: Jobs needs to be added here manually. Jobs when run together on windows fails intermittently. - # So they are run independently of each other. - envoy-integration-test: - needs: - - setup - - dev-build - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - envoy-version: [ "1.27.2" ] - xds-target: [ "server", "client" ] - env: - ENVOY_VERSION: ${{ matrix.envoy-version }} - XDS_TARGET: ${{ matrix.xds-target }} - AWS_LAMBDA_REGION: us-west-2 - steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - - name: Fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: ${{ github.workspace }} - - - name: Create dist folder and copy binary - run: | - mkdir dist - cp ${{ github.workspace }}\consul.exe dist\ - - - name: Restore mode+x - run: icacls ${{ github.workspace }}\consul.exe /grant:rx Everyone:RX - - - name: Setup TcpDump Docker Image - shell: bash - run: | - cd test/integration/connect/envoy - curl -sSL "https://asheshvidyut-bucket.s3.ap-southeast-2.amazonaws.com/tcpdump.exe" -o tcpdump.exe - docker build -t envoy-tcpdump -f Dockerfile-tcpdump-windows . - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0 - - - name: Docker build consul - run: docker build -t windows/consul -f Dockerfile-windows . - - - name: Docker build consul local - shell: bash - run: cd build-support/windows && ./build-consul-local-images.sh - - - name: Docker build consul dev - shell: bash - run: cd build-support/windows && ./build-consul-dev-image.sh - - # https://hashicorp.atlassian.net/browse/NET-4973 - # ^ Ticket to figure out why grouping test case is failing on Windows Machine - -# - name: Envoy Integration Tests for windows case-api-gateway-http-hostnames -# shell: bash -# if: always() -# env: -# GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml -# GOTESTSUM_FORMAT: standard-verbose -# COMPOSE_INTERACTIVE_NO_CLI: 1 -# LAMBDA_TESTS_ENABLED: "true" -# # tput complains if this isn't set to something. -# TERM: ansi -# run: | -# # shellcheck disable=SC2001 -# echo "Running Integration Test case-api-gateway-http-hostnames" -# # shellcheck disable=SC2001 -# go test -v -timeout=45m -tags integration \ -# ./test/integration/connect/envoy -run="TestEnvoy/case-api-gateway-http-hostnames" -win=true - - - name: Envoy Integration Tests for windows case-api-gateway-http-simple - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-api-gateway-http-simple" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-api-gateway-http-simple" -win=true - - - name: Envoy Integration Tests for windows case-api-gateway-http-splitter-targets - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-api-gateway-http-splitter-targets" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-api-gateway-http-splitter-targets" -win=true - - - name: Envoy Integration Tests for windows case-api-gateway-http-tls-overlapping-hosts - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-api-gateway-http-tls-overlapping-hosts" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-api-gateway-http-tls-overlapping-hosts" -win=true - - - name: Envoy Integration Tests for windows case-api-gateway-tcp-conflicted - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-api-gateway-tcp-conflicted" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-api-gateway-tcp-conflicted" -win=true - - - name: Envoy Integration Tests for windows case-api-gateway-tcp-simple - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-api-gateway-tcp-simple" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-api-gateway-tcp-simple" -win=true - - - name: Envoy Integration Tests for windows case-api-gateway-tcp-tls-overlapping-hosts - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-api-gateway-tcp-tls-overlapping-hosts" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-api-gateway-tcp-tls-overlapping-hosts" -win=true - - - name: Envoy Integration Tests for windows case-badauthz - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-badauthz" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-badauthz" -win=true - - - name: Envoy Integration Tests for windows case-basic - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-basic" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-basic" -win=true - - - name: Envoy Integration Tests for windows case-centralconf - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-centralconf" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-centralconf" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-cluster-peering-failover - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-cluster-peering-failover" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-cluster-peering-failover" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-dc-failover-gateways-none - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-dc-failover-gateways-none" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-dc-failover-gateways-none" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-dc-failover-gateways-remote - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-dc-failover-gateways-remote" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-dc-failover-gateways-remote" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-defaultsubset - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-defaultsubset" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-defaultsubset" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-features - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-features" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-features" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-subset-onlypassing - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-subset-onlypassing" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-subset-onlypassing" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-subset-redirect - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-subset-redirect" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-subset-redirect" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-svc-failover - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-svc-failover" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-svc-failover" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-svc-redirect-http - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-svc-redirect-http" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-svc-redirect-http" -win=true - - - name: Envoy Integration Tests for windows case-cfg-resolver-svc-redirect-tcp - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-resolver-svc-redirect-tcp" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-resolver-svc-redirect-tcp" -win=true - - - name: Envoy Integration Tests for windows case-cfg-router-features - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-router-features" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-router-features" -win=true - - - name: Envoy Integration Tests for windows case-cfg-splitter-cluster-peering - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-splitter-cluster-peering" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-splitter-cluster-peering" -win=true - - - name: Envoy Integration Tests for windows case-cfg-splitter-features - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-splitter-features" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-splitter-features" -win=true - - - name: Envoy Integration Tests for windows case-cfg-splitter-peering-ingress-gateways - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cfg-splitter-peering-ingress-gateways" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cfg-splitter-peering-ingress-gateways" -win=true - - # This test runs fine on windows machine but fails on CI - # Task to be picked later on - https://hashicorp.atlassian.net/browse/NET-4972 - # - name: Envoy Integration Tests for windows case-consul-exec - # if: always() - # shell: bash - # env: - # GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - # GOTESTSUM_FORMAT: standard-verbose - # COMPOSE_INTERACTIVE_NO_CLI: 1 - # LAMBDA_TESTS_ENABLED: "true" - # # tput complains if this isn't set to something. - # TERM: ansi - # run: | - # #shellcheck disable=SC2001 - # echo "Running Integration Test case-consul-exec" - # # shellcheck disable=SC2001 - # go test -v -timeout=45m -tags integration \ - # ./test/integration/connect/envoy -run="TestEnvoy/case-consul-exec" -win=true - - - name: Envoy Integration Tests for windows case-cross-peer-control-plane-mgw - if: always() - shell: bash - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cross-peer-control-plane-mgw" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cross-peer-control-plane-mgw" -win=true - - - name: Envoy Integration Tests for windows case-cross-peers - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cross-peers" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cross-peers" -win=true - - - name: Envoy Integration Tests for windows case-cross-peers-http - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cross-peers-http" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cross-peers-http" -win=true - - - name: Envoy Integration Tests for windows case-cross-peers-http-router - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cross-peers-http-router" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cross-peers-http-router" -win=true - - - name: Envoy Integration Tests for windows case-cross-peers-resolver-redirect-tcp - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-cross-peers-resolver-redirect-tcp" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-cross-peers-resolver-redirect-tcp" -win=true - - - name: Envoy Integration Tests for windows case-dogstatsd-udp - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-dogstatsd-udp" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-dogstatsd-udp" -win=true - - - name: Envoy Integration Tests for windows case-envoyext-ratelimit - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-envoyext-ratelimit" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-envoyext-ratelimit" -win=true - - - name: Envoy Integration Tests for windows case-expose-checks - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-expose-checks" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-expose-checks" -win=true - - - name: Envoy Integration Tests for windows case-gateway-without-services - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-gateway-without-services" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-gateway-without-services" -win=true - - - name: Envoy Integration Tests for windows case-gateways-local - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-gateways-local" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-gateways-local" -win=true - - - name: Envoy Integration Tests for windows case-gateways-remote - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-gateways-remote" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-gateways-remote" -win=true - - - name: Envoy Integration Tests for windows case-grpc - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-grpc" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-grpc" -win=true - - - name: Envoy Integration Tests for windows case-http - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-http" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-http" -win=true - - - name: Envoy Integration Tests for windows case-http-badauthz - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-http-badauthz" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-http-badauthz" -win=true - - - name: Envoy Integration Tests for windows case-ingress-gateway-grpc - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-ingress-gateway-grpc" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-ingress-gateway-grpc" -win=true - - - name: Envoy Integration Tests for windows case-ingress-gateway-http - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-ingress-gateway-http" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-ingress-gateway-http" -win=true - - - name: Envoy Integration Tests for windows case-ingress-gateway-multiple-services - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-ingress-gateway-multiple-services" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-ingress-gateway-multiple-services" -win=true - - - name: Envoy Integration Tests for windows case-ingress-gateway-peering-failover - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-ingress-gateway-peering-failover" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-ingress-gateway-peering-failover" -win=true - - - name: Envoy Integration Tests for windows case-ingress-gateway-simple - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-ingress-gateway-simple" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-ingress-gateway-simple" -win=true - - - name: Envoy Integration Tests for windows case-ingress-mesh-gateways-resolver - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-ingress-mesh-gateways-resolver" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-ingress-mesh-gateways-resolver" -win=true - - - name: Envoy Integration Tests for windows case-l7-intentions - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-l7-intentions" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-l7-intentions" -win=true - - - name: Envoy Integration Tests for windows case-multidc-rsa-ca - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-multidc-rsa-ca" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-multidc-rsa-ca" -win=true - - - name: Envoy Integration Tests for windows case-prometheus - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-prometheus" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-prometheus" -win=true - - - name: Envoy Integration Tests for windows case-property-override - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-property-override" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-property-override" -win=true - - - name: Envoy Integration Tests for windows case-stats-proxy - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-stats-proxy" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-stats-proxy" -win=true - - - name: Envoy Integration Tests for windows case-statsd-udp - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-statsd-udp" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-statsd-udp" -win=true - - - name: Envoy Integration Tests for windows case-terminating-gateway-hostnames - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-terminating-gateway-hostnames" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-terminating-gateway-hostnames" -win=true - - - name: Envoy Integration Tests for windows case-terminating-gateway-simple - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-terminating-gateway-simple" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-terminating-gateway-simple" -win=true - - - name: Envoy Integration Tests for windows case-terminating-gateway-without-services - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-terminating-gateway-without-services" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-terminating-gateway-without-services" -win=true - - - name: Envoy Integration Tests for windows case-upstream-config - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-upstream-config" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-upstream-config" -win=true - - - name: Envoy Integration Tests for windows case-wanfed-gw - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-wanfed-gw" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-wanfed-gw" -win=true - - - name: Envoy Integration Tests for windows case-ingress-gateway-sds - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-ingress-gateway-sds" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-ingress-gateway-sds" -win=true - - - name: Envoy Integration Tests for windows case-lua - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-lua" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-lua" -win=true - - - name: Envoy Integration Tests for windows case-terminating-gateway-subsets - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-terminating-gateway-subsets" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-terminating-gateway-subsets" -win=true - - # Skipping this because - https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/wasm_filter - # - name: Envoy Integration Tests for windows case-wasm - # shell: bash - # env: - # GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - # GOTESTSUM_FORMAT: standard-verbose - # COMPOSE_INTERACTIVE_NO_CLI: 1 - # LAMBDA_TESTS_ENABLED: "true" - # # tput complains if this isn't set to something. - # TERM: ansi - # run: | - # # shellcheck disable=SC2001 - # echo "Running Integration Test case-wasm" - # # shellcheck disable=SC2001 - # go test -v -timeout=45m -tags integration \ - # ./test/integration/connect/envoy -run="TestEnvoy/case-wasm" -win=true - - # Skipping because of - cacert is not available in curl windows - # https://www.phillipsj.net/posts/windows-curl-and-self-signed-certs/ - # - name: Envoy Integration Tests for windows case-ingress-gateway-tls - # shell: bash - # if: always() - # env: - # GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - # GOTESTSUM_FORMAT: standard-verbose - # COMPOSE_INTERACTIVE_NO_CLI: 1 - # LAMBDA_TESTS_ENABLED: "true" - # # tput complains if this isn't set to something. - # TERM: ansi - # run: | - # # shellcheck disable=SC2001 - # echo "Running Integration Test case-ingress-gateway-tls" - # # shellcheck disable=SC2001 - # go test -v -timeout=45m -tags integration \ - # ./test/integration/connect/envoy -run="TestEnvoy/case-ingress-gateway-tls" -win=true - - - name: Envoy Integration Tests for windows case-mesh-to-lambda - shell: bash - if: always() - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running Integration Test case-mesh-to-lambda" - # shellcheck disable=SC2001 - go test -v -timeout=45m -tags integration \ - ./test/integration/connect/envoy -run="TestEnvoy/case-mesh-to-lambda" -win=true - - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: Prepare datadog-ci - shell: bash - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/download/v2.17.2/datadog-ci_win-x64.exe" --output "C:/datadog-ci" - icacls C:/datadog-ci /grant:rx Everyone:RX - - - name: Upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: C:/datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - test-integrations-success: - needs: - - envoy-integration-test - runs-on: 'ubuntu-latest' - if: ${{ always() }} - steps: - - name: evaluate upstream job results - run: | - # exit 1 if failure or cancelled result for any upstream job - if printf '${{ toJSON(needs) }}' | grep -E -i '\"result\": \"(failure|cancelled)\"'; then - printf "Tests failed or workflow cancelled:\n\n${{ toJSON(needs) }}" - exit 1 - fi diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index ef89176536fde..3ffc42e1b648f 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -32,14 +32,14 @@ concurrency: jobs: conditional-skip: - runs-on: ubuntu-latest + runs-on: ubuntu-latest name: Get files changed and conditionally skip CI outputs: skip-ci: ${{ steps.read-files.outputs.skip-ci }} steps: - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 with: - fetch-depth: 0 + fetch-depth: 0 - name: Get changed files id: read-files run: ./.github/scripts/filter_changed_files_go_test.sh @@ -56,7 +56,7 @@ jobs: compute-xl: ${{ steps.runners.outputs.compute-xl }} enterprise: ${{ steps.runners.outputs.enterprise }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 - id: runners run: .github/scripts/get_runner_classes.sh @@ -80,16 +80,16 @@ jobs: contents: read strategy: matrix: - nomad-version: ['v1.6.2', 'v1.5.9', 'v1.4.13'] + nomad-version: ['v1.3.3', 'v1.2.10', 'v1.1.16'] steps: - name: Checkout Nomad - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 with: repository: hashicorp/nomad ref: ${{ matrix.nomad-version }} - name: Install Go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: go-version-file: 'go.mod' @@ -116,7 +116,7 @@ jobs: --packages="./command/agent/consul" \ --junitfile $TEST_RESULTS_DIR/results.xml -- \ -run TestConsul - + # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault if: ${{ endsWith(github.repository, '-enterprise') }} @@ -159,18 +159,18 @@ jobs: contents: read strategy: matrix: - vault-version: ["1.15.0", "1.14.4", "1.13.8", "1.12.11"] + vault-version: ["1.13.1", "1.12.5", "1.11.9", "1.10.11"] env: VAULT_BINARY_VERSION: ${{ matrix.vault-version }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - name: Setup Git if: ${{ endsWith(github.repository, '-enterprise') }} run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: go-version-file: 'go.mod' @@ -253,16 +253,16 @@ jobs: outputs: envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 - name: Generate Envoy Job Matrix id: set-matrix env: - # this is further going to multiplied in envoy-integration tests by the + # this is further going to multiplied in envoy-integration tests by the # other dimensions in the matrix. Currently TOTAL_RUNNERS would be - # multiplied by 2 based on these values: - # envoy-version: ["1.27.2"] + # multiplied by 8 based on these values: + # envoy-version: ["1.23.12", "1.24.12", "1.25.11", "1.26.6"] # xds-target: ["server", "client"] - TOTAL_RUNNERS: 4 + TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' run: | NUM_RUNNERS=$TOTAL_RUNNERS @@ -281,7 +281,7 @@ jobs: | jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ | jq --compact-output 'map(join("|"))' } >> "$GITHUB_OUTPUT" - + envoy-integration-test: runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} needs: @@ -294,7 +294,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.27.2"] + envoy-version: ["1.26.6"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -302,8 +302,8 @@ jobs: XDS_TARGET: ${{ matrix.xds-target }} AWS_LAMBDA_REGION: us-west-2 steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: go-version-file: 'go.mod' @@ -316,7 +316,7 @@ jobs: run: chmod +x ./bin/consul - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0 + uses: docker/setup-buildx-action@f03ac48505955848960e80bbb68046aa35c7b9e7 # v2.4.1 - name: Docker build run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin @@ -375,7 +375,7 @@ jobs: run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml compatibility-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-xl) }} # NOTE: do not change without tuning the -p and -parallel flags in go test. + runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} needs: - setup - dev-build @@ -384,14 +384,9 @@ jobs: contents: read env: ENVOY_VERSION: "1.25.4" - CONSUL_DATAPLANE_IMAGE: "docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi" steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(github.repository, '-enterprise') }} - run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3.5.0 with: go-version-file: 'go.mod' - run: go env @@ -416,8 +411,6 @@ jobs: - name: Retry Build consul-envoy:target-version image if: steps.buildConsulEnvoyImage.outcome == 'failure' run: docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=${{ env.CONSUL_LATEST_IMAGE_NAME }}:local --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - - name: Build consul-dataplane:local image - run: docker build -t consul-dataplane:local --build-arg CONSUL_IMAGE=${{ env.CONSUL_LATEST_IMAGE_NAME }}:local --build-arg CONSUL_DATAPLANE_IMAGE=${{ env.CONSUL_DATAPLANE_IMAGE }} -f ./test/integration/consul-container/assets/Dockerfile-consul-dataplane ./test/integration/consul-container/assets - name: Configure GH workaround for ipv6 loopback if: ${{ !endsWith(github.repository, '-enterprise') }} run: | @@ -431,7 +424,7 @@ jobs: docker run --rm ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local consul version go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ --raw-command \ - --format=pkgname-and-test-fails \ + --format=standard-verbose \ --debug \ --rerun-fails=3 \ -- \ @@ -441,7 +434,7 @@ jobs: -tags "${{ env.GOTAGS }}" \ -timeout=30m \ -json \ - `go list -tags "${{ env.GOTAGS }}" ./... | grep -v upgrade | grep -v peering_commontopo` \ + `go list ./... | grep -v upgrade` \ --target-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ --target-version local \ --latest-image docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }} \ @@ -487,87 +480,8 @@ jobs: DD_ENV: ci run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - integration-test-with-deployer: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large ) }} - needs: - - setup - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(github.repository, '-enterprise') }} - run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - run: go env - - name: Build image - run: make test-compat-integ-setup - - name: Integration Tests - run: | - mkdir -p "${{ env.TEST_RESULTS_DIR }}" - export NOLOGBUFFER=1 - cd ./test-integ/connect - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --raw-command \ - --format=standard-verbose \ - --debug \ - --packages="./..." \ - -- \ - go test \ - -tags "${{ env.GOTAGS }}" \ - -timeout=20m \ - -parallel=2 \ - -json . \ - --target-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --target-version local - env: - # this is needed because of incompatibility between RYUK container and GHA - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - # tput complains if this isn't set to something. - TERM: ansi - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - test-integrations-success: - needs: + needs: - conditional-skip - setup - dev-build @@ -576,7 +490,6 @@ jobs: - generate-envoy-job-matrices - envoy-integration-test - compatibility-integration-test - - integration-test-with-deployer runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} if: always() && needs.conditional-skip.outputs.skip-ci != 'true' steps: diff --git a/.github/workflows/verify-envoy-version.yml b/.github/workflows/verify-envoy-version.yml index dafa9db6f22a6..7c46453aec128 100644 --- a/.github/workflows/verify-envoy-version.yml +++ b/.github/workflows/verify-envoy-version.yml @@ -13,7 +13,7 @@ on: branches: - main - release/** - + env: SKIP_VERIFY_ENVOY_VERSION: ${{ vars.SKIP_VERIFY_ENVOY_VERSION }} @@ -21,11 +21,11 @@ jobs: verify-envoy-version: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@v2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 # by default the checkout action doesn't checkout all branches - name: Run Envoy Version Verification for main and release branches run: ./.github/scripts/verify_envoy_version.sh env: - GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 793354db02d52..a48d19b74cc22 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ .vagrant/ /pkg bin/ -workdir/ changelog.tmp exit-code Thumbs.db @@ -69,4 +68,3 @@ override.tf.json terraform.rc /go.work /go.work.sum -.docker diff --git a/.golangci.yml b/.golangci.yml index 0d426b34cd024..3e45ef464c14c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 linters: disable-all: true @@ -28,11 +28,6 @@ issues: - linters: [staticcheck] text: 'SA1019: "io/ioutil" has been deprecated since Go 1.16' - # Allow usage of deprecated values. - - linters: [ staticcheck ] - text: 'SA1019:' - path: "(agent/grpc-external)" - # An argument that always receives the same value is often not a problem. - linters: [unparam] text: "always receives" diff --git a/.release/ci.hcl b/.release/ci.hcl index d11983b460574..dfe69d2fc1ebd 100644 --- a/.release/ci.hcl +++ b/.release/ci.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 schema = "1" diff --git a/.release/docker/docker-entrypoint-ubi.sh b/.release/docker/docker-entrypoint-ubi.sh index 96e70df925672..a932ad7286e28 100755 --- a/.release/docker/docker-entrypoint-ubi.sh +++ b/.release/docker/docker-entrypoint-ubi.sh @@ -1,6 +1,6 @@ #!/usr/bin/dumb-init /bin/sh # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -e diff --git a/.release/docker/docker-entrypoint-windows.sh b/.release/docker/docker-entrypoint-windows.sh deleted file mode 100644 index f6aac9afaeca7..0000000000000 --- a/.release/docker/docker-entrypoint-windows.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/dumb-init /bin/sh -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -set -e - -# Note above that we run dumb-init as PID 1 in order to reap zombie processes -# as well as forward signals to all processes in its session. Normally, sh -# wouldn't do either of these functions so we'd leak zombies as well as do -# unclean termination of all our sub-processes. -# As of docker 1.13, using docker run --init achieves the same outcome. - -# You can set CONSUL_BIND_INTERFACE to the name of the interface you'd like to -# bind to and this will look up the IP and pass the proper -bind= option along -# to Consul. -CONSUL_BIND= -if [ -n "$CONSUL_BIND_INTERFACE" ]; then - CONSUL_BIND_ADDRESS=$(ip -o -4 addr list $CONSUL_BIND_INTERFACE | head -n1 | awk '{print $4}' | cut -d/ -f1) - if [ -z "$CONSUL_BIND_ADDRESS" ]; then - echo "Could not find IP for interface '$CONSUL_BIND_INTERFACE', exiting" - exit 1 - fi - - CONSUL_BIND="-bind=$CONSUL_BIND_ADDRESS" - echo "==> Found address '$CONSUL_BIND_ADDRESS' for interface '$CONSUL_BIND_INTERFACE', setting bind option..." -fi - -# You can set CONSUL_CLIENT_INTERFACE to the name of the interface you'd like to -# bind client intefaces (HTTP, DNS, and RPC) to and this will look up the IP and -# pass the proper -client= option along to Consul. -CONSUL_CLIENT= -if [ -n "$CONSUL_CLIENT_INTERFACE" ]; then - CONSUL_CLIENT_ADDRESS=$(ip -o -4 addr list $CONSUL_CLIENT_INTERFACE | head -n1 | awk '{print $4}' | cut -d/ -f1) - if [ -z "$CONSUL_CLIENT_ADDRESS" ]; then - echo "Could not find IP for interface '$CONSUL_CLIENT_INTERFACE', exiting" - exit 1 - fi - - CONSUL_CLIENT="-client=$CONSUL_CLIENT_ADDRESS" - echo "==> Found address '$CONSUL_CLIENT_ADDRESS' for interface '$CONSUL_CLIENT_INTERFACE', setting client option..." -fi - -# CONSUL_DATA_DIR is exposed as a volume for possible persistent storage. The -# CONSUL_CONFIG_DIR isn't exposed as a volume but you can compose additional -# config files in there if you use this image as a base, or use CONSUL_LOCAL_CONFIG -# below. -CONSUL_DATA_DIR=C:\\consul\\data -CONSUL_CONFIG_DIR=C:\\consul\\config - -# You can also set the CONSUL_LOCAL_CONFIG environemnt variable to pass some -# Consul configuration JSON without having to bind any volumes. -if [ -n "$CONSUL_LOCAL_CONFIG" ]; then - echo "$CONSUL_LOCAL_CONFIG" > "$CONSUL_CONFIG_DIR/local.json" -fi - -# If the user is trying to run Consul directly with some arguments, then -# pass them to Consul. -if [ "${1:0:1}" = '-' ]; then - set -- consul "$@" -fi - -# Look for Consul subcommands. -if [ "$1" = 'agent' ]; then - shift - set -- consul agent \ - -data-dir="$CONSUL_DATA_DIR" \ - -config-dir="$CONSUL_CONFIG_DIR" \ - $CONSUL_BIND \ - $CONSUL_CLIENT \ - "$@" -elif [ "$1" = 'version' ]; then - # This needs a special case because there's no help output. - set -- consul "$@" -elif consul --help "$1" 2>&1 | grep -q "consul $1"; then - # We can't use the return code to check for the existence of a subcommand, so - # we have to use grep to look for a pattern in the help output. - set -- consul "$@" -fi - -# NOTE: Unlike in the regular Consul Docker image, we don't have code here -# for changing data-dir directory ownership or using su-exec because OpenShift -# won't run this container as root and so we can't change data dir ownership, -# and there's no need to use su-exec. - -exec "$@" \ No newline at end of file diff --git a/.release/docker/docker-entrypoint.sh b/.release/docker/docker-entrypoint.sh index a544809643e00..c169576b6cf85 100755 --- a/.release/docker/docker-entrypoint.sh +++ b/.release/docker/docker-entrypoint.sh @@ -1,6 +1,6 @@ #!/usr/bin/dumb-init /bin/sh # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -e diff --git a/.release/linux/package/etc/consul.d/consul.hcl b/.release/linux/package/etc/consul.d/consul.hcl index b25f186858564..b54644b2f9ccd 100644 --- a/.release/linux/package/etc/consul.d/consul.hcl +++ b/.release/linux/package/etc/consul.d/consul.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # Full configuration options can be found at https://www.consul.io/docs/agent/config diff --git a/.release/release-metadata.hcl b/.release/release-metadata.hcl index 963192fc4b80e..8de2623fdee4e 100644 --- a/.release/release-metadata.hcl +++ b/.release/release-metadata.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 url_docker_registry_dockerhub = "https://hub.docker.com/r/hashicorp/consul" url_docker_registry_ecr = "https://gallery.ecr.aws/hashicorp/consul" diff --git a/.release/security-scan.hcl b/.release/security-scan.hcl index 0dd5116c6ecef..3029b33273b06 100644 --- a/.release/security-scan.hcl +++ b/.release/security-scan.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 container { dependencies = true diff --git a/CHANGELOG.md b/CHANGELOG.md index f72f27cb912dd..48e70b99523df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,64 +35,6 @@ BUG FIXES: * gateways: Fix a bug where gateway to service mappings weren't being cleaned up properly when externally registered proxies were being deregistered. [[GH-18831](https://github.com/hashicorp/consul/issues/18831)] * telemetry: emit consul version metric on a regular interval. [[GH-18724](https://github.com/hashicorp/consul/issues/18724)] -## 1.15.6 (September 19, 2023) - -SECURITY: - -* Upgrade to use Go 1.20.8. This resolves CVEs -[CVE-2023-39320](https://github.com/advisories/GHSA-rxv8-v965-v333) (`cmd/go`), -[CVE-2023-39318](https://github.com/advisories/GHSA-vq7j-gx56-rxjh) (`html/template`), -[CVE-2023-39319](https://github.com/advisories/GHSA-vv9m-32rr-3g55) (`html/template`), -[CVE-2023-39321](https://github.com/advisories/GHSA-9v7r-x7cv-v437) (`crypto/tls`), and -[CVE-2023-39322](https://github.com/advisories/GHSA-892h-r6cr-53g4) (`crypto/tls`) [[GH-18742](https://github.com/hashicorp/consul/issues/18742)] - -IMPROVEMENTS: - -* Adds flag -append-filename (which works on values version, dc, node and status) to consul snapshot save command. -Adding the flag -append-filename version,dc,node,status will add consul version, consul datacenter, node name and leader/follower -(status) in the file name given in the snapshot save command before the file extension. [[GH-18625](https://github.com/hashicorp/consul/issues/18625)] -* Reduce the frequency of metric exports from Consul to HCP from every 10s to every 1m [[GH-18584](https://github.com/hashicorp/consul/issues/18584)] -* api: Add support for listing ACL tokens by service name. [[GH-18667](https://github.com/hashicorp/consul/issues/18667)] -* command: Adds -since flag in consul debug command which internally calls hcdiag for debug information in the past. [[GH-18797](https://github.com/hashicorp/consul/issues/18797)] -* log: Currently consul logs files like this consul-{timestamp}.log. This change makes sure that there is always -consul.log file with the latest logs in it. [[GH-18617](https://github.com/hashicorp/consul/issues/18617)] - -BUG FIXES: - -* api: Fix `/v1/agent/self` not returning latest configuration [[GH-18681](https://github.com/hashicorp/consul/issues/18681)] -* ca: Vault provider now cleans up the previous Vault issuer and key when generating a new leaf signing certificate [[GH-18779](https://github.com/hashicorp/consul/issues/18779)] [[GH-18773](https://github.com/hashicorp/consul/issues/18773)] -* check: prevent go routine leakage when existing Defercheck of same check id is not nil [[GH-18558](https://github.com/hashicorp/consul/issues/18558)] -* gateways: Fix a bug where gateway to service mappings weren't being cleaned up properly when externally registered proxies were being deregistered. [[GH-18831](https://github.com/hashicorp/consul/issues/18831)] -* telemetry: emit consul version metric on a regular interval. [[GH-18724](https://github.com/hashicorp/consul/issues/18724)] - -## 1.14.10 (September 19, 2023) - -SECURITY: - -* Upgrade to use Go 1.20.8. This resolves CVEs -[CVE-2023-39320](https://github.com/advisories/GHSA-rxv8-v965-v333) (`cmd/go`), -[CVE-2023-39318](https://github.com/advisories/GHSA-vq7j-gx56-rxjh) (`html/template`), -[CVE-2023-39319](https://github.com/advisories/GHSA-vv9m-32rr-3g55) (`html/template`), -[CVE-2023-39321](https://github.com/advisories/GHSA-9v7r-x7cv-v437) (`crypto/tls`), and -[CVE-2023-39322](https://github.com/advisories/GHSA-892h-r6cr-53g4) (`crypto/tls`) [[GH-18742](https://github.com/hashicorp/consul/issues/18742)] - -IMPROVEMENTS: - -* Adds flag -append-filename (which works on values version, dc, node and status) to consul snapshot save command. -Adding the flag -append-filename version,dc,node,status will add consul version, consul datacenter, node name and leader/follower -(status) in the file name given in the snapshot save command before the file extension. [[GH-18625](https://github.com/hashicorp/consul/issues/18625)] -* api: Add support for listing ACL tokens by service name. [[GH-18667](https://github.com/hashicorp/consul/issues/18667)] -* command: Adds -since flag in consul debug command which internally calls hcdiag for debug information in the past. [[GH-18797](https://github.com/hashicorp/consul/issues/18797)] -* log: Currently consul logs files like this consul-{timestamp}.log. This change makes sure that there is always -consul.log file with the latest logs in it. [[GH-18617](https://github.com/hashicorp/consul/issues/18617)] - -BUG FIXES: - -* api: Fix `/v1/agent/self` not returning latest configuration [[GH-18681](https://github.com/hashicorp/consul/issues/18681)] -* ca: Vault provider now cleans up the previous Vault issuer and key when generating a new leaf signing certificate [[GH-18779](https://github.com/hashicorp/consul/issues/18779)] [[GH-18773](https://github.com/hashicorp/consul/issues/18773)] -* gateways: Fix a bug where gateway to service mappings weren't being cleaned up properly when externally registered proxies were being deregistered. [[GH-18831](https://github.com/hashicorp/consul/issues/18831)] -* telemetry: emit consul version metric on a regular interval. [[GH-18724](https://github.com/hashicorp/consul/issues/18724)] - ## 1.16.1 (August 8, 2023) KNOWN ISSUES: @@ -156,83 +98,6 @@ we now reject those earlier in the process when we validate the certificate. [[G https://github.com/rboyer/safeio/pull/3 [[GH-18302](https://github.com/hashicorp/consul/issues/18302)] * xds: Prevent partial application of non-Required Envoy extensions in the case of failure. [[GH-18068](https://github.com/hashicorp/consul/issues/18068)] -## 1.15.5 (August 8, 2023) - -SECURITY: - -* Update `golang.org/x/net` to v0.13.0 to address [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978). [[GH-18358](https://github.com/hashicorp/consul/issues/18358)] -* Upgrade golang.org/x/net to address [CVE-2023-29406](https://nvd.nist.gov/vuln/detail/CVE-2023-29406) [[GH-18186](https://github.com/hashicorp/consul/issues/18186)] -* Upgrade to use Go 1.20.6. -This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`) for uses of the standard library. -A separate change updates dependencies on `golang.org/x/net` to use `0.12.0`. [[GH-18190](https://github.com/hashicorp/consul/issues/18190)] -* Upgrade to use Go 1.20.7. -This resolves vulnerability [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`). [[GH-18358](https://github.com/hashicorp/consul/issues/18358)] - -FEATURES: - -* cli: `consul members` command uses `-filter` expression to filter members based on bexpr. [[GH-18223](https://github.com/hashicorp/consul/issues/18223)] -* cli: `consul watch` command uses `-filter` expression to filter response from checks, services, nodes, and service. [[GH-17780](https://github.com/hashicorp/consul/issues/17780)] -* reloadable config: Made enable_debug config reloadable and enable pprof command to work when config toggles to true [[GH-17565](https://github.com/hashicorp/consul/issues/17565)] - -IMPROVEMENTS: - -* Fix some typos in metrics docs [[GH-18080](https://github.com/hashicorp/consul/issues/18080)] -* acl: added builtin ACL policy that provides global read-only access (builtin/global-read-only) [[GH-18319](https://github.com/hashicorp/consul/issues/18319)] -* acl: allow for a single slash character in policy names [[GH-18319](https://github.com/hashicorp/consul/issues/18319)] -* connect: Add capture group labels from Envoy cluster FQDNs to Envoy exported metric labels [[GH-17888](https://github.com/hashicorp/consul/issues/17888)] -* connect: update supported envoy versions to 1.22.11, 1.23.12, 1.24.10, 1.25.9 [[GH-18304](https://github.com/hashicorp/consul/issues/18304)] -* hcp: Add dynamic configuration support for the export of server metrics to HCP. [[GH-18168](https://github.com/hashicorp/consul/issues/18168)] -* hcp: Removes requirement for HCP to provide a management token [[GH-18140](https://github.com/hashicorp/consul/issues/18140)] -* xds: Explicitly enable WebSocket connection upgrades in HTTP connection manager [[GH-18150](https://github.com/hashicorp/consul/issues/18150)] - -BUG FIXES: - -* Fix a bug that wrongly trims domains when there is an overlap with DC name. [[GH-17160](https://github.com/hashicorp/consul/issues/17160)] -* api-gateway: fix race condition in proxy config generation when Consul is notified of the bound-api-gateway config entry before it is notified of the api-gateway config entry. [[GH-18291](https://github.com/hashicorp/consul/issues/18291)] -* connect/ca: Fixes a bug preventing CA configuration updates in secondary datacenters [[GH-17846](https://github.com/hashicorp/consul/issues/17846)] -* connect: Fix incorrect protocol config merging for transparent proxy implicit upstreams. [[GH-17894](https://github.com/hashicorp/consul/issues/17894)] -* connect: Removes the default health check from the `consul connect envoy` command when starting an API Gateway. -This health check would always fail. [[GH-18011](https://github.com/hashicorp/consul/issues/18011)] -* connect: fix a bug with Envoy potentially starting with incomplete configuration by not waiting enough for initial xDS configuration. [[GH-18024](https://github.com/hashicorp/consul/issues/18024)] -* snapshot: fix access denied and handle is invalid when we call snapshot save on windows - skip sync() for folders in windows in -https://github.com/rboyer/safeio/pull/3 [[GH-18302](https://github.com/hashicorp/consul/issues/18302)] - -## 1.14.9 (August 8, 2023) - -SECURITY: - -* Update `golang.org/x/net` to v0.13.0 to address [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978). [[GH-18358](https://github.com/hashicorp/consul/issues/18358)] -* Upgrade golang.org/x/net to address [CVE-2023-29406](https://nvd.nist.gov/vuln/detail/CVE-2023-29406) [[GH-18186](https://github.com/hashicorp/consul/issues/18186)] -* Upgrade to use Go 1.20.6. -This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`) for uses of the standard library. -A separate change updates dependencies on `golang.org/x/net` to use `0.12.0`. [[GH-18190](https://github.com/hashicorp/consul/issues/18190)] -* Upgrade to use Go 1.20.7. -This resolves vulnerability [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`). [[GH-18358](https://github.com/hashicorp/consul/issues/18358)] - -FEATURES: - -* cli: `consul members` command uses `-filter` expression to filter members based on bexpr. [[GH-18223](https://github.com/hashicorp/consul/issues/18223)] -* cli: `consul watch` command uses `-filter` expression to filter response from checks, services, nodes, and service. [[GH-17780](https://github.com/hashicorp/consul/issues/17780)] -* reloadable config: Made enable_debug config reloadable and enable pprof command to work when config toggles to true [[GH-17565](https://github.com/hashicorp/consul/issues/17565)] - -IMPROVEMENTS: - -* Fix some typos in metrics docs [[GH-18080](https://github.com/hashicorp/consul/issues/18080)] -* acl: added builtin ACL policy that provides global read-only access (builtin/global-read-only) [[GH-18319](https://github.com/hashicorp/consul/issues/18319)] -* acl: allow for a single slash character in policy names [[GH-18319](https://github.com/hashicorp/consul/issues/18319)] -* connect: update supported envoy versions to 1.21.6, 1.22.11, 1.23.12, 1.24.10 [[GH-18305](https://github.com/hashicorp/consul/issues/18305)] -* hcp: Removes requirement for HCP to provide a management token [[GH-18140](https://github.com/hashicorp/consul/issues/18140)] -* xds: Explicitly enable WebSocket connection upgrades in HTTP connection manager [[GH-18150](https://github.com/hashicorp/consul/issues/18150)] - -BUG FIXES: - -* Fix a bug that wrongly trims domains when there is an overlap with DC name. [[GH-17160](https://github.com/hashicorp/consul/issues/17160)] -* connect/ca: Fixes a bug preventing CA configuration updates in secondary datacenters [[GH-17846](https://github.com/hashicorp/consul/issues/17846)] -* connect: Fix incorrect protocol config merging for transparent proxy implicit upstreams. [[GH-17894](https://github.com/hashicorp/consul/issues/17894)] -* connect: fix a bug with Envoy potentially starting with incomplete configuration by not waiting enough for initial xDS configuration. [[GH-18024](https://github.com/hashicorp/consul/issues/18024)] -* snapshot: fix access denied and handle is invalid when we call snapshot save on windows - skip sync() for folders in windows in -https://github.com/rboyer/safeio/pull/3 [[GH-18302](https://github.com/hashicorp/consul/issues/18302)] - ## 1.16.0 (June 26, 2023) KNOWN ISSUES: @@ -310,100 +175,6 @@ BUG FIXES: * ui: fixes ui tests run on CI [[GH-16428](https://github.com/hashicorp/consul/issues/16428)] * xds: Fixed a bug where modifying ACLs on a token being actively used for an xDS connection caused all xDS updates to fail. [[GH-17566](https://github.com/hashicorp/consul/issues/17566)] -## 1.15.4 (June 26, 2023) -FEATURES: - -* cli: `consul operator raft list-peers` command shows the number of commits each follower is trailing the leader by to aid in troubleshooting. [[GH-17582](https://github.com/hashicorp/consul/issues/17582)] -* server: **(Enterprise Only)** allow automatic license utilization reporting. [[GH-5102](https://github.com/hashicorp/consul/issues/5102)] - -IMPROVEMENTS: - -* connect: update supported envoy versions to 1.22.11, 1.23.9, 1.24.7, 1.25.6 [[GH-17545](https://github.com/hashicorp/consul/issues/17545)] -* debug: change default setting of consul debug command. now default duration is 5ms and default log level is 'TRACE' [[GH-17596](https://github.com/hashicorp/consul/issues/17596)] -* fix metric names in /docs/agent/telemetry [[GH-17577](https://github.com/hashicorp/consul/issues/17577)] -* gateway: Change status condition reason for invalid certificate on a listener from "Accepted" to "ResolvedRefs". [[GH-17115](https://github.com/hashicorp/consul/issues/17115)] -* systemd: set service type to notify. [[GH-16845](https://github.com/hashicorp/consul/issues/16845)] - -BUG FIXES: - -* cache: fix a few minor goroutine leaks in leaf certs and the agent cache [[GH-17636](https://github.com/hashicorp/consul/issues/17636)] -* docs: fix list of telemetry metrics [[GH-17593](https://github.com/hashicorp/consul/issues/17593)] -* gateways: **(Enterprise only)** Fixed a bug in API gateways where gateway configuration objects in non-default partitions did not reconcile properly. [[GH-17581](https://github.com/hashicorp/consul/issues/17581)] -* gateways: Fixed a bug in API gateways where binding a route that only targets a service imported from a peer results - in the programmed gateway having no routes. [[GH-17609](https://github.com/hashicorp/consul/issues/17609)] -* gateways: Fixed a bug where API gateways were not being taken into account in determining xDS rate limits. [[GH-17631](https://github.com/hashicorp/consul/issues/17631)] -* http: fixed API endpoint `PUT /acl/token/:AccessorID` (update token), no longer requires `AccessorID` in the request body. Web UI can now update tokens. [[GH-17739](https://github.com/hashicorp/consul/issues/17739)] -* namespaces: **(Enterprise only)** fixes a bug where agent health checks stop syncing for all services on a node if the namespace of any service has been removed from the server. -* namespaces: **(Enterprise only)** fixes a bug where namespaces are stuck in a deferred deletion state indefinitely under some conditions. - Also fixes the Consul query metadata present in the HTTP headers of the namespace read and list endpoints. -* peering: Fix a bug that caused server agents to continue cleaning up peering resources even after loss of leadership. [[GH-17483](https://github.com/hashicorp/consul/issues/17483)] -* xds: Fixed a bug where modifying ACLs on a token being actively used for an xDS connection caused all xDS updates to fail. [[GH-17566](https://github.com/hashicorp/consul/issues/17566)] - -## 1.14.8 (June 26, 2023) - -SECURITY: - -* Update to UBI base image to 9.2. [[GH-17513](https://github.com/hashicorp/consul/issues/17513)] - -FEATURES: - -* cli: `consul operator raft list-peers` command shows the number of commits each follower is trailing the leader by to aid in troubleshooting. [[GH-17582](https://github.com/hashicorp/consul/issues/17582)] -* server: **(Enterprise Only)** allow automatic license utilization reporting. [[GH-5102](https://github.com/hashicorp/consul/issues/5102)] - -IMPROVEMENTS: - -* connect: update supported envoy versions to 1.21.6, 1.22.11, 1.23.9, 1.24.7 [[GH-17547](https://github.com/hashicorp/consul/issues/17547)] -* debug: change default setting of consul debug command. now default duration is 5ms and default log level is 'TRACE' [[GH-17596](https://github.com/hashicorp/consul/issues/17596)] -* fix metric names in /docs/agent/telemetry [[GH-17577](https://github.com/hashicorp/consul/issues/17577)] -* peering: gRPC queries for TrustBundleList, TrustBundleRead, PeeringList, and PeeringRead now support blocking semantics, - reducing network and CPU demand. - The HTTP APIs for Peering List and Read have been updated to support blocking. [[GH-17426](https://github.com/hashicorp/consul/issues/17426)] -* raft: Remove expensive reflection from raft/mesh hot path [[GH-16552](https://github.com/hashicorp/consul/issues/16552)] -* systemd: set service type to notify. [[GH-16845](https://github.com/hashicorp/consul/issues/16845)] - -BUG FIXES: - -* cache: fix a few minor goroutine leaks in leaf certs and the agent cache [[GH-17636](https://github.com/hashicorp/consul/issues/17636)] -* connect: reverts #17317 fix that caused a downstream error for Ingress/Mesh/Terminating GWs when their respective config entry does not already exist. [[GH-17541](https://github.com/hashicorp/consul/issues/17541)] -* namespaces: **(Enterprise only)** fixes a bug where agent health checks stop syncing for all services on a node if the namespace of any service has been removed from the server. -* namespaces: **(Enterprise only)** fixes a bug where namespaces are stuck in a deferred deletion state indefinitely under some conditions. - Also fixes the Consul query metadata present in the HTTP headers of the namespace read and list endpoints. -* namespaces: adjusts the return type from HTTP list API to return the `api` module representation of a namespace. - This fixes an error with the `consul namespace list` command when a namespace has a deferred deletion timestamp. -* peering: Fix a bug that caused server agents to continue cleaning up peering resources even after loss of leadership. [[GH-17483](https://github.com/hashicorp/consul/issues/17483)] -* peering: Fix issue where modifying the list of exported services did not correctly replicate changes for services that exist in a non-default namespace. [[GH-17456](https://github.com/hashicorp/consul/issues/17456)] - -## 1.13.9 (June 26, 2023) -BREAKING CHANGES: - -* connect: Disable peering by default in connect proxies for Consul 1.13. This change was made to prevent inefficient polling - queries from having a negative impact on server performance. Peering in Consul 1.13 is an experimental feature and is not - recommended for use in production environments. If you still wish to use the experimental peering feature, ensure - [`peering.enabled = true`](https://developer.hashicorp.com/consul/docs/v1.13.x/agent/config/config-files#peering_enabled) - is set on all clients and servers. [[GH-17731](https://github.com/hashicorp/consul/issues/17731)] - -SECURITY: - -* Update to UBI base image to 9.2. [[GH-17513](https://github.com/hashicorp/consul/issues/17513)] - -FEATURES: - -* server: **(Enterprise Only)** allow automatic license utilization reporting. [[GH-5102](https://github.com/hashicorp/consul/issues/5102)] - -IMPROVEMENTS: - -* debug: change default setting of consul debug command. now default duration is 5ms and default log level is 'TRACE' [[GH-17596](https://github.com/hashicorp/consul/issues/17596)] -* systemd: set service type to notify. [[GH-16845](https://github.com/hashicorp/consul/issues/16845)] - -BUG FIXES: - -* cache: fix a few minor goroutine leaks in leaf certs and the agent cache [[GH-17636](https://github.com/hashicorp/consul/issues/17636)] -* namespaces: **(Enterprise only)** fixes a bug where namespaces are stuck in a deferred deletion state indefinitely under some conditions. - Also fixes the Consul query metadata present in the HTTP headers of the namespace read and list endpoints. -* namespaces: adjusts the return type from HTTP list API to return the `api` module representation of a namespace. - This fixes an error with the `consul namespace list` command when a namespace has a deferred deletion timestamp. -* peering: Fix a bug that caused server agents to continue cleaning up peering resources even after loss of leadership. [[GH-17483](https://github.com/hashicorp/consul/issues/17483)] - ## 1.16.0-rc1 (June 12, 2023) BREAKING CHANGES: diff --git a/Dockerfile b/Dockerfile index 1926c521299a7..7599ec7b35b80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # This Dockerfile contains multiple targets. # Use 'docker build --target= .' to build one. diff --git a/Dockerfile-windows b/Dockerfile-windows deleted file mode 100644 index 14582908db550..0000000000000 --- a/Dockerfile-windows +++ /dev/null @@ -1,51 +0,0 @@ -FROM mcr.microsoft.com/windows/servercore:ltsc2019 -ARG VERSION=1.16.0 - -ENV chocolateyVersion=1.4.0 - -LABEL org.opencontainers.image.authors="Consul Team " \ - org.opencontainers.image.url="https://www.consul.io/" \ - org.opencontainers.image.documentation="https://www.consul.io/docs" \ - org.opencontainers.image.source="https://github.com/hashicorp/consul" \ - org.opencontainers.image.version=$VERSION \ - org.opencontainers.image.vendor="HashiCorp" \ - org.opencontainers.image.title="consul" \ - org.opencontainers.image.description="Consul is a datacenter runtime that provides service discovery, configuration, and orchestration." \ - version=${VERSION} - -RUN ["powershell", "Set-ExecutionPolicy", "Bypass", "-Scope", "Process", "-Force;"] -RUN ["powershell", "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"] - -RUN choco install git.install -yf -RUN SETX /M path "%PATH%;C:\Program Files\Git\bin" - -RUN mkdir C:\\consul -RUN mkdir C:\\consul\\data -RUN mkdir C:\\consul\\config - -# Server RPC is used for communication between Consul clients and servers for internal -# request forwarding. -EXPOSE 8300 - -# Serf LAN and WAN (WAN is used only by Consul servers) are used for gossip between -# Consul agents. LAN is within the datacenter and WAN is between just the Consul -# servers in all datacenters. -EXPOSE 8301 8301/udp 8302 8302/udp - -# HTTP and DNS (both TCP and UDP) are the primary interfaces that applications -# use to interact with Consul. -EXPOSE 8500 8600 8600/udp - -#ENV CONSUL_URL=https://releases.hashicorp.com/consul/${VERSION}/consul_${VERSION}_windows_amd64.zip -#RUN curl %CONSUL_URL% -L -o consul.zip -#RUN tar -xf consul.zip -C consul - -COPY consul.exe C:\\consul - -COPY .release/docker/docker-entrypoint-windows.sh C:\\docker-entrypoint-windows.sh -ENTRYPOINT ["bash.exe", "docker-entrypoint-windows.sh"] - -# By default you'll get an insecure single-node development server that stores -# everything in RAM, exposes a web UI and HTTP endpoints, and bootstraps itself. -# Don't use this configuration for production. -CMD ["agent", "-dev", "-client", "0.0.0.0"] diff --git a/Makefile b/GNUmakefile similarity index 71% rename from Makefile rename to GNUmakefile index a7c275511c510..2b5aaf29a5315 100644 --- a/Makefile +++ b/GNUmakefile @@ -3,7 +3,6 @@ SHELL = bash - GO_MODULES := $(shell find . -name go.mod -exec dirname {} \; | grep -v "proto-gen-rpc-glue/e2e" | sort) ### @@ -12,14 +11,13 @@ GO_MODULES := $(shell find . -name go.mod -exec dirname {} \; | grep -v "proto-g ### GOLANGCI_LINT_VERSION='v1.51.1' MOCKERY_VERSION='v2.20.0' -BUF_VERSION='v1.26.0' +BUF_VERSION='v1.14.0' PROTOC_GEN_GO_GRPC_VERSION="v1.2.0" -MOG_VERSION='v0.4.1' +MOG_VERSION='v0.4.0' PROTOC_GO_INJECT_TAG_VERSION='v1.3.0' PROTOC_GEN_GO_BINARY_VERSION="v0.1.0" DEEP_COPY_VERSION='bc3f5aa5735d8a54961580a3a24422c308c831c2' -COPYWRITE_TOOL_VERSION='v0.16.4' MOCKED_PB_DIRS= pbdns @@ -66,9 +64,14 @@ UI_BUILD_TAG?=consul-build-ui BUILD_CONTAINER_NAME?=consul-builder CONSUL_IMAGE_VERSION?=latest ENVOY_VERSION?='1.25.4' -CONSUL_DATAPLANE_IMAGE := $(or $(CONSUL_DATAPLANE_IMAGE),"docker.io/hashicorppreview/consul-dataplane:1.3-dev-ubi") -CONSUL_VERSION?=$(shell cat version/VERSION) +################ +# CI Variables # +################ +CI_DEV_DOCKER_NAMESPACE?=hashicorpdev +CI_DEV_DOCKER_IMAGE_NAME?=consul +CI_DEV_DOCKER_WORKDIR?=bin/ +################ TEST_MODCACHE?=1 TEST_BUILDCACHE?=1 @@ -148,27 +151,23 @@ ifdef SKIP_DOCKER_BUILD ENVOY_INTEG_DEPS=noop endif -##@ Build - -.PHONY: all -all: dev-build ## Command running by default +all: dev-build # used to make integration dependencies conditional noop: ; -.PHONY: dev -dev: dev-build ## Dev creates binaries for testing locally - these are put into ./bin +# dev creates binaries for testing locally - these are put into ./bin +dev: dev-build -.PHONY: dev-build -dev-build: ## Same as dev +dev-build: mkdir -p bin CGO_ENABLED=0 go install -ldflags "$(GOLDFLAGS)" -tags "$(GOTAGS)" # rm needed due to signature caching (https://apple.stackexchange.com/a/428388) rm -f ./bin/consul cp ${MAIN_GOPATH}/bin/consul ./bin/consul -.PHONY: dev-docker-dbg -dev-docker-dbg: dev-docker ## Build containers for debug mode + +dev-docker-dbg: dev-docker @echo "Pulling consul container image - $(CONSUL_IMAGE_VERSION)" @docker pull hashicorp/consul:$(CONSUL_IMAGE_VERSION) >/dev/null @echo "Building Consul Development container - $(CONSUL_DEV_IMAGE)" @@ -180,8 +179,7 @@ dev-docker-dbg: dev-docker ## Build containers for debug mode --load \ -f $(CURDIR)/build-support/docker/Consul-Dev-Dbg.dockerfile $(CURDIR)/pkg/bin/ -.PHONY: dev-docker -dev-docker: linux dev-build ## Build and tag docker images in dev env +dev-docker: linux dev-build @echo "Pulling consul container image - $(CONSUL_IMAGE_VERSION)" @docker pull hashicorp/consul:$(CONSUL_IMAGE_VERSION) >/dev/null @echo "Building Consul Development container - $(CONSUL_DEV_IMAGE)" @@ -190,20 +188,15 @@ dev-docker: linux dev-build ## Build and tag docker images in dev env @docker buildx use default && docker buildx build -t 'consul:local' -t '$(CONSUL_DEV_IMAGE)' \ --platform linux/$(GOARCH) \ --build-arg CONSUL_IMAGE_VERSION=$(CONSUL_IMAGE_VERSION) \ - --label org.opencontainers.image.version=$(CONSUL_VERSION) \ - --label version=$(CONSUL_VERSION) \ --load \ -f $(CURDIR)/build-support/docker/Consul-Dev-Multiarch.dockerfile $(CURDIR)/pkg/bin/ - docker tag 'consul:local' '$(CONSUL_COMPAT_TEST_IMAGE):local' -.PHONY: check-remote-dev-image-env -check-remote-dev-image-env: ## Check remote dev image env +check-remote-dev-image-env: ifndef REMOTE_DEV_IMAGE $(error REMOTE_DEV_IMAGE is undefined: set this image to /:, e.g. hashicorp/consul-k8s-dev:latest) endif -.PHONY: remote-docker -remote-docker: check-remote-dev-image-env ## Remote docker +remote-docker: check-remote-dev-image-env $(MAKE) GOARCH=amd64 linux $(MAKE) GOARCH=arm64 linux @echo "Pulling consul container image - $(CONSUL_IMAGE_VERSION)" @@ -215,64 +208,39 @@ remote-docker: check-remote-dev-image-env ## Remote docker @docker buildx use consul-builder && docker buildx build -t '$(REMOTE_DEV_IMAGE)' \ --platform linux/amd64,linux/arm64 \ --build-arg CONSUL_IMAGE_VERSION=$(CONSUL_IMAGE_VERSION) \ - --label org.opencontainers.image.version=$(CONSUL_VERSION) \ - --label version=$(CONSUL_VERSION) \ --push \ -f $(CURDIR)/build-support/docker/Consul-Dev-Multiarch.dockerfile $(CURDIR)/pkg/bin/ -linux: ## Linux builds a linux binary compatible with the source platform +# In CI, the linux binary will be attached from a previous step at bin/. This make target +# should only run in CI and not locally. +ci.dev-docker: + @echo "Pulling consul container image - $(CONSUL_IMAGE_VERSION)" + @docker pull hashicorp/consul:$(CONSUL_IMAGE_VERSION) >/dev/null + @echo "Building Consul Development container - $(CI_DEV_DOCKER_IMAGE_NAME)" + @docker build $(NOCACHE) $(QUIET) -t '$(CI_DEV_DOCKER_NAMESPACE)/$(CI_DEV_DOCKER_IMAGE_NAME):$(GIT_COMMIT)' \ + --build-arg CONSUL_IMAGE_VERSION=$(CONSUL_IMAGE_VERSION) \ + --label COMMIT_SHA=$(CIRCLE_SHA1) \ + --label PULL_REQUEST=$(CIRCLE_PULL_REQUEST) \ + --label CIRCLE_BUILD_URL=$(CIRCLE_BUILD_URL) \ + $(CI_DEV_DOCKER_WORKDIR) -f $(CURDIR)/build-support/docker/Consul-Dev.dockerfile + @echo $(DOCKER_PASS) | docker login -u="$(DOCKER_USER)" --password-stdin + @echo "Pushing dev image to: https://cloud.docker.com/u/hashicorpdev/repository/docker/hashicorpdev/consul" + @docker push $(CI_DEV_DOCKER_NAMESPACE)/$(CI_DEV_DOCKER_IMAGE_NAME):$(GIT_COMMIT) +ifeq ($(CIRCLE_BRANCH), main) + @docker tag $(CI_DEV_DOCKER_NAMESPACE)/$(CI_DEV_DOCKER_IMAGE_NAME):$(GIT_COMMIT) $(CI_DEV_DOCKER_NAMESPACE)/$(CI_DEV_DOCKER_IMAGE_NAME):latest + @docker push $(CI_DEV_DOCKER_NAMESPACE)/$(CI_DEV_DOCKER_IMAGE_NAME):latest +endif + +# linux builds a linux binary compatible with the source platform +linux: @mkdir -p ./pkg/bin/linux_$(GOARCH) CGO_ENABLED=0 GOOS=linux GOARCH=$(GOARCH) go build -o ./pkg/bin/linux_$(GOARCH) -ldflags "$(GOLDFLAGS)" -tags "$(GOTAGS)" -.PHONY: go-mod-tidy -go-mod-tidy: $(foreach mod,$(GO_MODULES),go-mod-tidy/$(mod)) ## Run go mod tidy in every module - -.PHONY: mod-tidy/% -go-mod-tidy/%: - @echo "--> Running go mod tidy ($*)" - @cd $* && go mod tidy - -##@ Checks - -.PHONY: fmt -fmt: $(foreach mod,$(GO_MODULES),fmt/$(mod)) ## Format go modules - -.PHONY: fmt/% -fmt/%: - @echo "--> Running go fmt ($*)" - @cd $* && gofmt -s -l -w . - -.PHONY: lint -lint: $(foreach mod,$(GO_MODULES),lint/$(mod)) lint-container-test-deps ## Lint go modules and test deps - -.PHONY: lint/% -lint/%: - @echo "--> Running golangci-lint ($*)" - @cd $* && GOWORK=off golangci-lint run --build-tags '$(GOTAGS)' - @echo "--> Running lint-consul-retry ($*)" - @cd $* && GOWORK=off lint-consul-retry - @echo "--> Running enumcover ($*)" - @cd $* && GOWORK=off enumcover ./... - -# check that the test-container module only imports allowlisted packages -# from the root consul module. Generally we don't want to allow these imports. -# In a few specific instances though it is okay to import test definitions and -# helpers from some of the packages in the root module. -.PHONY: lint-container-test-deps -lint-container-test-deps: ## Check that the test-container module only imports allowlisted packages from the root consul module. - @echo "--> Checking container tests for bad dependencies" - @cd test/integration/consul-container && \ - $(CURDIR)/build-support/scripts/check-allowed-imports.sh \ - github.com/hashicorp/consul \ - "internal/catalog/catalogtest" \ - "internal/resource/resourcetest" - -##@ Testing - -.PHONY: cover -cover: cov ## Run tests and generate coverage report +# dist builds binaries for all platforms and packages them for distribution +dist: + @$(SHELL) $(CURDIR)/build-support/scripts/release.sh -t '$(DIST_TAG)' -b '$(DIST_BUILD)' -S '$(DIST_SIGN)' $(DIST_VERSION_ARG) $(DIST_DATE_ARG) $(DIST_REL_ARG) -.PHONY: cov +cover: cov cov: other-consul dev-build go test -tags '$(GOTAGS)' ./... -coverprofile=coverage.out cd sdk && go test -tags '$(GOTAGS)' ./... -coverprofile=../coverage.sdk.part @@ -281,11 +249,17 @@ cov: other-consul dev-build rm -f coverage.{sdk,api}.part go tool cover -html=coverage.out -.PHONY: test test: other-consul dev-build lint test-internal -.PHONY: test-internal -test-internal: ## Test internal +.PHONY: go-mod-tidy +go-mod-tidy: $(foreach mod,$(GO_MODULES),go-mod-tidy/$(mod)) + +.PHONY: mod-tidy/% +go-mod-tidy/%: + @echo "--> Running go mod tidy ($*)" + @cd $* && go mod tidy + +test-internal: @echo "--> Running go test" @rm -f test.log exit-code @# Dump verbose output to test.log so we can surface test names on failure but @@ -314,148 +288,113 @@ test-internal: ## Test internal @grep '^FAIL' test.log || true @if [ "$$(cat exit-code)" == "0" ] ; then echo "PASS" ; exit 0 ; else exit 1 ; fi -.PHONY: test-all -test-all: other-consul dev-build lint $(foreach mod,$(GO_MODULES),test-module/$(mod)) ## Test all +test-all: other-consul dev-build lint $(foreach mod,$(GO_MODULES),test-module/$(mod)) -.PHONY: test-module/% test-module/%: @echo "--> Running go test ($*)" cd $* && go test $(GOTEST_FLAGS) -tags '$(GOTAGS)' ./... -.PHONY: test-race -test-race: ## Test race +test-race: $(MAKE) GOTEST_FLAGS=-race -.PHONY: other-consul -other-consul: ## Checking for other consul instances +test-docker: linux go-build-image + @# -ti run in the foreground showing stdout + @# --rm removes the container once its finished running + @# GO_MODCACHE_VOL - args for mapping in the go module cache + @# GO_BUILD_CACHE_VOL - args for mapping in the go build cache + @# All the env vars are so we pass through all the relevant bits of information + @# Needed for running the tests + @# We map in our local linux_amd64 bin directory as thats where the linux dep + @# target dropped the binary. We could build the binary in the container too + @# but that might take longer as caching gets weird + @# Lastly we map the source dir here to the /consul workdir + @echo "Running tests within a docker container" + @docker run -ti --rm \ + -e 'GOTEST_FLAGS=$(GOTEST_FLAGS)' \ + -e 'GOTAGS=$(GOTAGS)' \ + -e 'GIT_COMMIT=$(GIT_COMMIT)' \ + -e 'GIT_COMMIT_YEAR=$(GIT_COMMIT_YEAR)' \ + -e 'GIT_DIRTY=$(GIT_DIRTY)' \ + $(TEST_PARALLELIZATION) \ + $(TEST_DOCKER_RESOURCE_CONSTRAINTS) \ + $(TEST_MODCACHE_VOL) \ + $(TEST_BUILDCACHE_VOL) \ + -v $(MAIN_GOPATH)/bin/linux_amd64/:/go/bin \ + -v $(shell pwd):/consul \ + $(GO_BUILD_TAG) \ + make test-internal + +other-consul: @echo "--> Checking for other consul instances" @if ps -ef | grep 'consul agent' | grep -v grep ; then \ echo "Found other running consul agents. This may affect your tests." ; \ exit 1 ; \ fi + +.PHONY: fmt +fmt: $(foreach mod,$(GO_MODULES),fmt/$(mod)) -# Use GO_TEST_FLAGS to run specific tests: -# make test-envoy-integ GO_TEST_FLAGS="-run TestEnvoy/case-basic" -# NOTE: Always uses amd64 images, even when running on M1 macs, to match CI/CD environment. -# You can also specify the envoy version (example: 1.27.0) setting the environment variable: ENVOY_VERSION=1.27.0 -.PHONY: test-envoy-integ -test-envoy-integ: $(ENVOY_INTEG_DEPS) ## Run integration tests. - @go test -v -timeout=30m -tags integration $(GO_TEST_FLAGS) ./test/integration/connect/envoy - -# NOTE: Use DOCKER_BUILDKIT=0, if docker build fails to resolve consul:local base image -.PHONY: test-compat-integ-setup -test-compat-integ-setup: dev-docker - @docker tag consul-dev:latest $(CONSUL_COMPAT_TEST_IMAGE):local - @docker run --rm -t $(CONSUL_COMPAT_TEST_IMAGE):local consul version - @# 'consul-envoy:target-version' is needed by compatibility integ test - @docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=$(CONSUL_COMPAT_TEST_IMAGE):local --build-arg ENVOY_VERSION=${ENVOY_VERSION} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - @docker build -t consul-dataplane:local --build-arg CONSUL_IMAGE=$(CONSUL_COMPAT_TEST_IMAGE):local --build-arg CONSUL_DATAPLANE_IMAGE=${CONSUL_DATAPLANE_IMAGE} -f ./test/integration/consul-container/assets/Dockerfile-consul-dataplane ./test/integration/consul-container/assets - -.PHONY: test-compat-integ -test-compat-integ: test-compat-integ-setup ## Test compat integ -ifeq ("$(GOTESTSUM_PATH)","") - @cd ./test/integration/consul-container && \ - go test \ - -v \ - -timeout=30m \ - ./... \ - --tags $(GOTAGS) \ - --target-image $(CONSUL_COMPAT_TEST_IMAGE) \ - --target-version local \ - --latest-image $(CONSUL_COMPAT_TEST_IMAGE) \ - --latest-version latest -else - @cd ./test/integration/consul-container && \ - gotestsum \ - --format=short-verbose \ - --debug \ - --rerun-fails=3 \ - --packages="./..." \ - -- \ - --tags $(GOTAGS) \ - -timeout=30m \ - ./... \ - --target-image $(CONSUL_COMPAT_TEST_IMAGE) \ - --target-version local \ - --latest-image $(CONSUL_COMPAT_TEST_IMAGE) \ - --latest-version latest -endif +.PHONY: fmt/% +fmt/%: + @echo "--> Running go fmt ($*)" + @cd $* && gofmt -s -l -w . -.PHONY: test-metrics-integ -test-metrics-integ: test-compat-integ-setup ## Test metrics integ - @cd ./test/integration/consul-container && \ - go test -v -timeout=7m ./test/metrics \ - --target-image $(CONSUL_COMPAT_TEST_IMAGE) \ - --target-version local \ - --latest-image $(CONSUL_COMPAT_TEST_IMAGE) \ - --latest-version latest +.PHONY: lint +lint: $(foreach mod,$(GO_MODULES),lint/$(mod)) lint-container-test-deps -.PHONY: test-connect-ca-providers -test-connect-ca-providers: ## Running /agent/connect/ca tests in verbose mode - @echo "Running /agent/connect/ca tests in verbose mode" - @go test -v ./agent/connect/ca - @go test -v ./agent/consul -run Vault - @go test -v ./agent -run Vault +.PHONY: lint/% +lint/%: + @echo "--> Running golangci-lint ($*)" + @cd $* && GOWORK=off golangci-lint run --build-tags '$(GOTAGS)' + @echo "--> Running lint-consul-retry ($*)" + @cd $* && GOWORK=off lint-consul-retry + @echo "--> Running enumcover ($*)" + @cd $* && GOWORK=off enumcover ./... -##@ UI +.PHONY: lint-container-test-deps +lint-container-test-deps: + @echo "--> Checking container tests for bad dependencies" + @cd test/integration/consul-container && ( \ + found="$$(go list -m all | grep -c '^github.com/hashicorp/consul ')" ; \ + if [[ "$$found" != "0" ]]; then \ + echo "test/integration/consul-container: This project should not depend on the root consul module" >&2 ; \ + exit 1 ; \ + fi \ + ) -.PHONY: ui -ui: ui-docker ## Build the static web ui inside a Docker container. For local testing only; do not commit these assets. +# Build the static web ui inside a Docker container. For local testing only; do not commit these assets. +ui: ui-docker +# Build the static web ui with yarn. This is the version to commit. .PHONY: ui-regen -ui-regen: ## Build the static web ui with yarn. This is the version to commit. +ui-regen: cd $(CURDIR)/ui && make && cd .. rm -rf $(CURDIR)/agent/uiserver/dist mv $(CURDIR)/ui/packages/consul-ui/dist $(CURDIR)/agent/uiserver/ -.PHONY: ui-build-image -ui-build-image: ## Building UI build container - @echo "Building UI build container" - @docker build $(NOCACHE) $(QUIET) -t $(UI_BUILD_TAG) - < build-support/docker/Build-UI.dockerfile - -.PHONY: ui-docker -ui-docker: ui-build-image ## Builds ui within docker container and copy all the relevant artifacts out of the containers back to the source - @$(SHELL) $(CURDIR)/build-support/scripts/build-docker.sh ui - -##@ Tools - -.PHONY: tools -tools: ## Installs various supporting Go tools. +tools: @$(SHELL) $(CURDIR)/build-support/scripts/devtools.sh .PHONY: lint-tools -lint-tools: ## Install tools for linting +lint-tools: @$(SHELL) $(CURDIR)/build-support/scripts/devtools.sh -lint +.PHONY: proto-tools +proto-tools: + @$(SHELL) $(CURDIR)/build-support/scripts/devtools.sh -protobuf + .PHONY: codegen-tools -codegen-tools: ## Install tools for codegen +codegen-tools: @$(SHELL) $(CURDIR)/build-support/scripts/devtools.sh -codegen -.PHONY: codegen -codegen: codegen-tools ## Deep copy +.PHONY: deep-copy +deep-copy: codegen-tools @$(SHELL) $(CURDIR)/agent/structs/deep-copy.sh @$(SHELL) $(CURDIR)/agent/proxycfg/deep-copy.sh @$(SHELL) $(CURDIR)/agent/consul/state/deep-copy.sh @$(SHELL) $(CURDIR)/agent/config/deep-copy.sh - copywrite headers - # Special case for MPL headers in /api and /sdk - cd api && $(CURDIR)/build-support/scripts/copywrite-exceptions.sh - cd sdk && $(CURDIR)/build-support/scripts/copywrite-exceptions.sh - -print-% : ; @echo $($*) ## utility to echo a makefile variable (i.e. 'make print-GOPATH') - -.PHONY: module-versions -module-versions: ## Print a list of modules which can be updated. Columns are: module current_version date_of_current_version latest_version - @go list -m -u -f '{{if .Update}} {{printf "%-50v %-40s" .Path .Version}} {{with .Time}} {{ .Format "2006-01-02" -}} {{else}} {{printf "%9s" ""}} {{end}} {{ .Update.Version}} {{end}}' all - -.PHONY: docs -docs: ## Point your web browser to http://localhost:3000/consul to live render docs from ./website/ - make -C website -##@ Release - -.PHONY: version -version: ## Current Consul version +version: @echo -n "Version: " @$(SHELL) $(CURDIR)/build-support/scripts/version.sh @echo -n "Version + release: " @@ -465,20 +404,26 @@ version: ## Current Consul version @echo -n "Version + release + git: " @$(SHELL) $(CURDIR)/build-support/scripts/version.sh -r -g -.PHONY: docker-images + docker-images: go-build-image ui-build-image -.PHONY: go-build-image -go-build-image: ## Building Golang build container +go-build-image: @echo "Building Golang build container" @docker build $(NOCACHE) $(QUIET) -t $(GO_BUILD_TAG) - < build-support/docker/Build-Go.dockerfile -.PHONY: consul-docker -consul-docker: go-build-image ## Builds consul in a docker container and then dumps executable into ./pkg/bin/... +ui-build-image: + @echo "Building UI build container" + @docker build $(NOCACHE) $(QUIET) -t $(UI_BUILD_TAG) - < build-support/docker/Build-UI.dockerfile + +# Builds consul in a docker container and then dumps executable into ./pkg/bin/... +consul-docker: go-build-image @$(SHELL) $(CURDIR)/build-support/scripts/build-docker.sh consul -.PHONY: docker-envoy-integ -docker-envoy-integ: ## Build image used to run integration tests locally. +ui-docker: ui-build-image + @$(SHELL) $(CURDIR)/build-support/scripts/build-docker.sh ui + +# Build image used to run integration tests locally. +docker-envoy-integ: $(MAKE) GOARCH=amd64 linux docker build \ --platform linux/amd64 $(NOCACHE) $(QUIET) \ @@ -487,21 +432,75 @@ docker-envoy-integ: ## Build image used to run integration tests locally. $(CURDIR)/pkg/bin/linux_amd64 \ -f $(CURDIR)/build-support/docker/Consul-Dev.dockerfile -##@ Proto +# Run integration tests. +# Use GO_TEST_FLAGS to run specific tests: +# make test-envoy-integ GO_TEST_FLAGS="-run TestEnvoy/case-basic" +# NOTE: Always uses amd64 images, even when running on M1 macs, to match CI/CD environment. +test-envoy-integ: $(ENVOY_INTEG_DEPS) + @go test -v -timeout=30m -tags integration $(GO_TEST_FLAGS) ./test/integration/connect/envoy -.PHONY: proto -proto: proto-tools proto-gen proto-mocks ## Protobuf setup command +.PHONY: test-compat-integ +test-compat-integ: test-compat-integ-setup +ifeq ("$(GOTESTSUM_PATH)","") + @cd ./test/integration/consul-container && \ + go test \ + -v \ + -timeout=30m \ + ./... \ + --tags $(GOTAGS) \ + --target-image $(CONSUL_COMPAT_TEST_IMAGE) \ + --target-version local \ + --latest-image $(CONSUL_COMPAT_TEST_IMAGE) \ + --latest-version latest +else + @cd ./test/integration/consul-container && \ + gotestsum \ + --format=short-verbose \ + --debug \ + --rerun-fails=3 \ + --packages="./..." \ + -- \ + --tags $(GOTAGS) \ + -timeout=30m \ + ./... \ + --target-image $(CONSUL_COMPAT_TEST_IMAGE) \ + --target-version local \ + --latest-image $(CONSUL_COMPAT_TEST_IMAGE) \ + --latest-version latest +endif -.PHONY: proto-tools -proto-tools: ## Install tools for protobuf - @$(SHELL) $(CURDIR)/build-support/scripts/devtools.sh -protobuf +# NOTE: Use DOCKER_BUILDKIT=0, if docker build fails to resolve consul:local base image +.PHONY: test-compat-integ-setup +test-compat-integ-setup: dev-docker + @docker tag consul-dev:latest $(CONSUL_COMPAT_TEST_IMAGE):local + @docker run --rm -t $(CONSUL_COMPAT_TEST_IMAGE):local consul version + @# 'consul-envoy:target-version' is needed by compatibility integ test + @docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=$(CONSUL_COMPAT_TEST_IMAGE):local --build-arg ENVOY_VERSION=${ENVOY_VERSION} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets + +.PHONY: test-metrics-integ +test-metrics-integ: test-compat-integ-setup + @cd ./test/integration/consul-container && \ + go test -v -timeout=7m ./test/metrics \ + --target-image $(CONSUL_COMPAT_TEST_IMAGE) \ + --target-version local \ + --latest-image $(CONSUL_COMPAT_TEST_IMAGE) \ + --latest-version latest + +test-connect-ca-providers: + @echo "Running /agent/connect/ca tests in verbose mode" + @go test -v ./agent/connect/ca + @go test -v ./agent/consul -run Vault + @go test -v ./agent -run Vault + +.PHONY: proto +proto: proto-tools proto-gen proto-mocks .PHONY: proto-gen -proto-gen: proto-tools ## Regenerates all Go files from protobuf definitions +proto-gen: proto-tools @$(SHELL) $(CURDIR)/build-support/scripts/protobuf.sh .PHONY: proto-mocks -proto-mocks: ## Proto mocks +proto-mocks: for dir in $(MOCKED_PB_DIRS) ; do \ cd proto-public && \ rm -f $$dir/mock*.go && \ @@ -509,11 +508,11 @@ proto-mocks: ## Proto mocks done .PHONY: proto-format -proto-format: proto-tools ## Proto format +proto-format: proto-tools @buf format -w .PHONY: proto-lint -proto-lint: proto-tools ## Proto lint +proto-lint: proto-tools @buf lint @for fn in $$(find proto -name '*.proto'); do \ if [[ "$$fn" = "proto/private/pbsubscribe/subscribe.proto" ]]; then \ @@ -528,14 +527,21 @@ proto-lint: proto-tools ## Proto lint fi \ done -##@ Envoy +# utility to echo a makefile variable (i.e. 'make print-PROTOC_VERSION') +print-% : ; @echo $($*) + +.PHONY: module-versions +# Print a list of modules which can be updated. +# Columns are: module current_version date_of_current_version latest_version +module-versions: + @go list -m -u -f '{{if .Update}} {{printf "%-50v %-40s" .Path .Version}} {{with .Time}} {{ .Format "2006-01-02" -}} {{else}} {{printf "%9s" ""}} {{end}} {{ .Update.Version}} {{end}}' all .PHONY: envoy-library -envoy-library: ## Ensures that all of the protobuf packages present in the github.com/envoyproxy/go-control-plane library are referenced in the consul codebase +envoy-library: @$(SHELL) $(CURDIR)/build-support/scripts/envoy-library-references.sh .PHONY: envoy-regen -envoy-regen: ## Regenerating envoy golden files +envoy-regen: $(info regenerating envoy golden files) @for d in endpoints listeners routes clusters rbac; do \ if [[ -d "agent/xds/testdata/$${d}" ]]; then \ @@ -546,18 +552,17 @@ envoy-regen: ## Regenerating envoy golden files @find "command/connect/envoy/testdata" -name '*.golden' -delete @go test -tags '$(GOTAGS)' ./command/connect/envoy -update -##@ Help - -# The help target prints out all targets with their descriptions organized -# beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk commands is responsible for reading the -# entire set of makefiles included in this invocation, looking for lines of the -# file as xyz: ## something, and then pretty-format the target and help. Then, -# if there's a line with ##@ something, that gets pretty-printed as a category. -# More info on the usage of ANSI control characters for terminal formatting: -# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters -# More info on the awk command: -# http://linuxcommand.org/lc3_adv_awk.php +# Point your web browser to http://localhost:3000/consul to live render docs from ./website/ +.PHONY: docs +docs: + make -C website + .PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) +help: + $(info available make targets) + $(info ----------------------) + @grep "^[a-z0-9-][a-z0-9.-]*:" GNUmakefile | cut -d':' -f1 | sort + +.PHONY: all bin dev dist cov test test-internal cover lint ui tools +.PHONY: docker-images go-build-image ui-build-image consul-docker ui-docker +.PHONY: version test-envoy-integ diff --git a/LICENSE b/LICENSE index 1f38fcdd11e2d..c72625e4cc88b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,61 +1,356 @@ -License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved. -“Business Source License” is a trademark of MariaDB Corporation Ab. - -Parameters - -Licensor: HashiCorp, Inc. -Licensed Work: Consul 1.17.0. The Licensed Work is (c) 2023 HashiCorp, Inc. -Additional Use Grant: You may make production use of the Licensed Work, - provided such use does not include offering the Licensed Work - to third parties on a hosted or embedded basis which is - competitive with HashiCorp's products. -Change Date: Four years from the date the Licensed Work is published. -Change License: MPL 2.0 - -For information about alternative licensing arrangements for the Licensed Work, -please contact licensing@hashicorp.com. - -Notice - -Business Source License 1.1 - -Terms - -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited production use. - -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. - -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND -TITLE. +Copyright (c) 2013 HashiCorp, Inc. + +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. + diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 0000000000000..fe34b5e571555 --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,3 @@ +Copyright © 2014-2018 HashiCorp, Inc. + +This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/README.md b/README.md index c23053f0e1f7d..93e3176cc048a 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,6 @@ Consul provides several key features: can use sidecar proxies in a service mesh configuration to establish TLS connections for inbound and outbound connections with Transparent Proxy. -* **API Gateway** - Consul API Gateway manages access to services within Consul Service Mesh, - allow users to define traffic and authorization policies to services deployed within the mesh. - * **Service Discovery** - Consul makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. External services such as SaaS providers can be registered as well. @@ -35,8 +32,7 @@ Consul provides several key features: discovery prevents routing traffic to unhealthy hosts and enables service level circuit breakers. -* **Dynamic App Configuration** - An HTTP API that allows users to store indexed objects within Consul, - for storing configuration parameters and application metadata. +* **Dynamic App Configuration** - An HTTP API that allows users to store indexed objects, like configuration parameters and application metadata, within Consul. Consul runs on Linux, macOS, FreeBSD, Solaris, and Windows and includes an optional [browser based UI](https://demo.consul.io). A commercial version diff --git a/acl/MockAuthorizer.go b/acl/MockAuthorizer.go index 9941f81e3f052..01afb5fea6654 100644 --- a/acl/MockAuthorizer.go +++ b/acl/MockAuthorizer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -59,31 +59,6 @@ func (m *MockAuthorizer) EventWrite(segment string, ctx *AuthorizerContext) Enfo return ret.Get(0).(EnforcementDecision) } -// IdentityRead checks for permission to read a given workload identity. -func (m *MockAuthorizer) IdentityRead(segment string, ctx *AuthorizerContext) EnforcementDecision { - ret := m.Called(segment, ctx) - return ret.Get(0).(EnforcementDecision) -} - -// IdentityReadAll checks for permission to read all workload identities. -func (m *MockAuthorizer) IdentityReadAll(ctx *AuthorizerContext) EnforcementDecision { - ret := m.Called(ctx) - return ret.Get(0).(EnforcementDecision) -} - -// IdentityWrite checks for permission to create or update a given -// workload identity. -func (m *MockAuthorizer) IdentityWrite(segment string, ctx *AuthorizerContext) EnforcementDecision { - ret := m.Called(segment, ctx) - return ret.Get(0).(EnforcementDecision) -} - -// IdentityWriteAny checks for write permission on any workload identity. -func (m *MockAuthorizer) IdentityWriteAny(ctx *AuthorizerContext) EnforcementDecision { - ret := m.Called(ctx) - return ret.Get(0).(EnforcementDecision) -} - // IntentionDefaultAllow determines the default authorized behavior // when no intentions match a Connect request. func (m *MockAuthorizer) IntentionDefaultAllow(ctx *AuthorizerContext) EnforcementDecision { @@ -224,11 +199,6 @@ func (m *MockAuthorizer) ServiceReadAll(ctx *AuthorizerContext) EnforcementDecis return ret.Get(0).(EnforcementDecision) } -func (m *MockAuthorizer) ServiceReadPrefix(prefix string, ctx *AuthorizerContext) EnforcementDecision { - ret := m.Called(ctx) - return ret.Get(0).(EnforcementDecision) -} - // ServiceWrite checks for permission to create or update a given // service func (m *MockAuthorizer) ServiceWrite(segment string, ctx *AuthorizerContext) EnforcementDecision { @@ -261,19 +231,6 @@ func (m *MockAuthorizer) Snapshot(ctx *AuthorizerContext) EnforcementDecision { return ret.Get(0).(EnforcementDecision) } -// TrafficPermissionsRead determines if specific traffic permissions can be read. -func (m *MockAuthorizer) TrafficPermissionsRead(segment string, ctx *AuthorizerContext) EnforcementDecision { - ret := m.Called(segment, ctx) - return ret.Get(0).(EnforcementDecision) -} - -// TrafficPermissionsWrite determines if specific traffic permissions can be -// created, modified, or deleted. -func (m *MockAuthorizer) TrafficPermissionsWrite(segment string, ctx *AuthorizerContext) EnforcementDecision { - ret := m.Called(segment, ctx) - return ret.Get(0).(EnforcementDecision) -} - func (p *MockAuthorizer) ToAllowAuthorizer() AllowAuthorizer { return AllowAuthorizer{Authorizer: p} } diff --git a/acl/acl.go b/acl/acl.go index 753db01516e8c..75789dd17498c 100644 --- a/acl/acl.go +++ b/acl/acl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/acl/acl_ce.go b/acl/acl_ce.go index 7d2b8513b8327..58f92022ba55b 100644 --- a/acl/acl_ce.go +++ b/acl/acl_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package acl diff --git a/acl/acl_test.go b/acl/acl_test.go index 28542024e9567..3734eb1572fd3 100644 --- a/acl/acl_test.go +++ b/acl/acl_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -40,22 +40,6 @@ func checkAllowEventWrite(t *testing.T, authz Authorizer, prefix string, entCtx require.Equal(t, Allow, authz.EventWrite(prefix, entCtx)) } -func checkAllowIdentityRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Allow, authz.IdentityRead(prefix, entCtx)) -} - -func checkAllowIdentityReadAll(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) { - require.Equal(t, Allow, authz.IdentityReadAll(entCtx)) -} - -func checkAllowIdentityWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Allow, authz.IdentityWrite(prefix, entCtx)) -} - -func checkAllowIdentityWriteAny(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) { - require.Equal(t, Allow, authz.IdentityWriteAny(entCtx)) -} - func checkAllowIntentionDefaultAllow(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Allow, authz.IntentionDefaultAllow(entCtx)) } @@ -164,14 +148,6 @@ func checkAllowSnapshot(t *testing.T, authz Authorizer, prefix string, entCtx *A require.Equal(t, Allow, authz.Snapshot(entCtx)) } -func checkAllowTrafficPermissionsRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Allow, authz.TrafficPermissionsRead(prefix, entCtx)) -} - -func checkAllowTrafficPermissionsWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Allow, authz.TrafficPermissionsWrite(prefix, entCtx)) -} - func checkDenyACLRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Deny, authz.ACLRead(entCtx)) } @@ -196,22 +172,6 @@ func checkDenyEventWrite(t *testing.T, authz Authorizer, prefix string, entCtx * require.Equal(t, Deny, authz.EventWrite(prefix, entCtx)) } -func checkDenyIdentityRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Deny, authz.IdentityRead(prefix, entCtx)) -} - -func checkDenyIdentityReadAll(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) { - require.Equal(t, Deny, authz.IdentityReadAll(entCtx)) -} - -func checkDenyIdentityWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Deny, authz.IdentityWrite(prefix, entCtx)) -} - -func checkDenyIdentityWriteAny(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) { - require.Equal(t, Deny, authz.IdentityWriteAny(entCtx)) -} - func checkDenyIntentionDefaultAllow(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Deny, authz.IntentionDefaultAllow(entCtx)) } @@ -300,14 +260,6 @@ func checkDenyServiceReadAll(t *testing.T, authz Authorizer, _ string, entCtx *A require.Equal(t, Deny, authz.ServiceReadAll(entCtx)) } -func checkAllowServiceReadPrefix(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Allow, authz.ServiceReadPrefix(prefix, entCtx)) -} - -func checkDenyServiceReadPrefix(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Deny, authz.ServiceReadPrefix(prefix, entCtx)) -} - func checkDenyServiceWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Deny, authz.ServiceWrite(prefix, entCtx)) } @@ -328,14 +280,6 @@ func checkDenySnapshot(t *testing.T, authz Authorizer, prefix string, entCtx *Au require.Equal(t, Deny, authz.Snapshot(entCtx)) } -func checkDenyTrafficPermissionsRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Deny, authz.TrafficPermissionsRead(prefix, entCtx)) -} - -func checkDenyTrafficPermissionsWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Deny, authz.TrafficPermissionsWrite(prefix, entCtx)) -} - func checkDefaultACLRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Default, authz.ACLRead(entCtx)) } @@ -360,22 +304,6 @@ func checkDefaultEventWrite(t *testing.T, authz Authorizer, prefix string, entCt require.Equal(t, Default, authz.EventWrite(prefix, entCtx)) } -func checkDefaultIdentityRead(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Default, authz.IdentityRead(prefix, entCtx)) -} - -func checkDefaultIdentityReadAll(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) { - require.Equal(t, Default, authz.IdentityReadAll(entCtx)) -} - -func checkDefaultIdentityWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Default, authz.IdentityWrite(prefix, entCtx)) -} - -func checkDefaultIdentityWriteAny(t *testing.T, authz Authorizer, _ string, entCtx *AuthorizerContext) { - require.Equal(t, Default, authz.IdentityWriteAny(entCtx)) -} - func checkDefaultIntentionDefaultAllow(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Default, authz.IntentionDefaultAllow(entCtx)) } @@ -464,10 +392,6 @@ func checkDefaultServiceReadAll(t *testing.T, authz Authorizer, _ string, entCtx require.Equal(t, Default, authz.ServiceReadAll(entCtx)) } -func checkDefaultServiceReadPrefix(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { - require.Equal(t, Default, authz.ServiceReadPrefix(prefix, entCtx)) -} - func checkDefaultServiceWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Default, authz.ServiceWrite(prefix, entCtx)) } @@ -516,10 +440,6 @@ func TestACL(t *testing.T) { {name: "DenyIntentionDefaultAllow", check: checkDenyIntentionDefaultAllow}, {name: "DenyIntentionRead", check: checkDenyIntentionRead}, {name: "DenyIntentionWrite", check: checkDenyIntentionWrite}, - {name: "DenyIdentityRead", check: checkDenyIdentityRead}, - {name: "DenyIdentityReadAll", check: checkDenyIdentityReadAll}, - {name: "DenyIdentityWrite", check: checkDenyIdentityWrite}, - {name: "DenyIdentityWriteAny", check: checkDenyIdentityWriteAny}, {name: "DenyKeyRead", check: checkDenyKeyRead}, {name: "DenyKeyringRead", check: checkDenyKeyringRead}, {name: "DenyKeyringWrite", check: checkDenyKeyringWrite}, @@ -538,7 +458,6 @@ func TestACL(t *testing.T) { {name: "DenyServiceRead", check: checkDenyServiceRead}, {name: "DenyServiceReadAll", check: checkDenyServiceReadAll}, {name: "DenyServiceWrite", check: checkDenyServiceWrite}, - {name: "DenyServiceWriteAny", check: checkDenyServiceWriteAny}, {name: "DenySessionRead", check: checkDenySessionRead}, {name: "DenySessionWrite", check: checkDenySessionWrite}, {name: "DenySnapshot", check: checkDenySnapshot}, @@ -554,10 +473,6 @@ func TestACL(t *testing.T) { {name: "AllowAgentWrite", check: checkAllowAgentWrite}, {name: "AllowEventRead", check: checkAllowEventRead}, {name: "AllowEventWrite", check: checkAllowEventWrite}, - {name: "AllowIdentityRead", check: checkAllowIdentityRead}, - {name: "AllowIdentityReadAll", check: checkAllowIdentityReadAll}, - {name: "AllowIdentityWrite", check: checkAllowIdentityWrite}, - {name: "AllowIdentityWriteAny", check: checkAllowIdentityWriteAny}, {name: "AllowIntentionDefaultAllow", check: checkAllowIntentionDefaultAllow}, {name: "AllowIntentionRead", check: checkAllowIntentionRead}, {name: "AllowIntentionWrite", check: checkAllowIntentionWrite}, @@ -579,12 +494,9 @@ func TestACL(t *testing.T) { {name: "AllowServiceRead", check: checkAllowServiceRead}, {name: "AllowServiceReadAll", check: checkAllowServiceReadAll}, {name: "AllowServiceWrite", check: checkAllowServiceWrite}, - {name: "AllowServiceWriteAny", check: checkAllowServiceWriteAny}, {name: "AllowSessionRead", check: checkAllowSessionRead}, {name: "AllowSessionWrite", check: checkAllowSessionWrite}, {name: "DenySnapshot", check: checkDenySnapshot}, - {name: "AllowTrafficPermissionsRead", check: checkAllowTrafficPermissionsRead}, - {name: "AllowTrafficPermissionsWrite", check: checkAllowTrafficPermissionsWrite}, }, }, { @@ -597,10 +509,6 @@ func TestACL(t *testing.T) { {name: "AllowAgentWrite", check: checkAllowAgentWrite}, {name: "AllowEventRead", check: checkAllowEventRead}, {name: "AllowEventWrite", check: checkAllowEventWrite}, - {name: "AllowIdentityRead", check: checkAllowIdentityRead}, - {name: "AllowIdentityReadAll", check: checkAllowIdentityReadAll}, - {name: "AllowIdentityWrite", check: checkAllowIdentityWrite}, - {name: "AllowIdentityWriteAny", check: checkAllowIdentityWriteAny}, {name: "AllowIntentionDefaultAllow", check: checkAllowIntentionDefaultAllow}, {name: "AllowIntentionRead", check: checkAllowIntentionRead}, {name: "AllowIntentionWrite", check: checkAllowIntentionWrite}, @@ -622,12 +530,9 @@ func TestACL(t *testing.T) { {name: "AllowServiceRead", check: checkAllowServiceRead}, {name: "AllowServiceReadAll", check: checkAllowServiceReadAll}, {name: "AllowServiceWrite", check: checkAllowServiceWrite}, - {name: "AllowServiceWriteAny", check: checkAllowServiceWriteAny}, {name: "AllowSessionRead", check: checkAllowSessionRead}, {name: "AllowSessionWrite", check: checkAllowSessionWrite}, {name: "AllowSnapshot", check: checkAllowSnapshot}, - {name: "AllowTrafficPermissionsRead", check: checkAllowTrafficPermissionsRead}, - {name: "AllowTrafficPermissionsWrite", check: checkAllowTrafficPermissionsWrite}, }, }, { @@ -1000,134 +905,6 @@ func TestACL(t *testing.T) { {name: "ChildOverrideWriteAllowed", prefix: "override", check: checkAllowAgentWrite}, }, }, - { - name: "IdentityDefaultAllowPolicyDeny", - defaultPolicy: AllowAll(), - policyStack: []*Policy{ - { - PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: PolicyDeny, - }, - }, - IdentityPrefixes: []*IdentityRule{ - { - Name: "prefix", - Policy: PolicyDeny, - }, - }, - }, - }, - }, - checks: []aclCheck{ - {name: "IdentityFooReadDenied", prefix: "foo", check: checkDenyIdentityRead}, - {name: "IdentityFooWriteDenied", prefix: "foo", check: checkDenyIdentityWrite}, - {name: "IdentityPrefixReadDenied", prefix: "prefix", check: checkDenyIdentityRead}, - {name: "IdentityPrefixWriteDenied", prefix: "prefix", check: checkDenyIdentityWrite}, - {name: "IdentityBarReadAllowed", prefix: "fail", check: checkAllowIdentityRead}, - {name: "IdentityBarWriteAllowed", prefix: "fail", check: checkAllowIdentityWrite}, - }, - }, - { - name: "IdentityDefaultDenyPolicyAllow", - defaultPolicy: DenyAll(), - policyStack: []*Policy{ - { - PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: PolicyWrite, - }, - }, - IdentityPrefixes: []*IdentityRule{ - { - Name: "prefix", - Policy: PolicyRead, - }, - }, - }, - }, - }, - checks: []aclCheck{ - {name: "IdentityFooReadAllowed", prefix: "foo", check: checkAllowIdentityRead}, - {name: "IdentityFooWriteAllowed", prefix: "foo", check: checkAllowIdentityWrite}, - {name: "IdentityPrefixReadAllowed", prefix: "prefix", check: checkAllowIdentityRead}, - {name: "IdentityPrefixWriteDenied", prefix: "prefix", check: checkDenyIdentityWrite}, - {name: "IdentityBarReadDenied", prefix: "fail", check: checkDenyIdentityRead}, - {name: "IdentityBarWriteDenied", prefix: "fail", check: checkDenyIdentityWrite}, - }, - }, - { - name: "IdentityDefaultDenyPolicyComplex", - defaultPolicy: DenyAll(), - policyStack: []*Policy{ - { - PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "football", - Policy: PolicyRead, - }, - { - Name: "prefix-forbidden", - Policy: PolicyDeny, - Intentions: PolicyDeny, - }, - }, - IdentityPrefixes: []*IdentityRule{ - { - Name: "foo", - Policy: PolicyWrite, - Intentions: PolicyWrite, - }, - { - Name: "prefix", - Policy: PolicyRead, - Intentions: PolicyWrite, - }, - }, - }, - }, - { - PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "foozball", - Policy: PolicyWrite, - Intentions: PolicyRead, - }, - }, - }, - }, - }, - checks: []aclCheck{ - {name: "IdentityReadAllowed", prefix: "foo", check: checkAllowIdentityRead}, - {name: "IdentityWriteAllowed", prefix: "foo", check: checkAllowIdentityWrite}, - {name: "TrafficPermissionsReadAllowed", prefix: "foo", check: checkAllowTrafficPermissionsRead}, - {name: "TrafficPermissionsWriteAllowed", prefix: "foo", check: checkAllowTrafficPermissionsWrite}, - {name: "IdentityReadAllowed", prefix: "football", check: checkAllowIdentityRead}, - {name: "IdentityWriteDenied", prefix: "football", check: checkDenyIdentityWrite}, - {name: "TrafficPermissionsReadAllowed", prefix: "football", check: checkAllowTrafficPermissionsRead}, - // This might be surprising but omitting intention rule gives at most intention:read - // if we have identity:write perms. This matches services as well. - {name: "TrafficPermissionsWriteDenied", prefix: "football", check: checkDenyTrafficPermissionsWrite}, - {name: "IdentityReadAllowed", prefix: "prefix", check: checkAllowIdentityRead}, - {name: "IdentityWriteDenied", prefix: "prefix", check: checkDenyIdentityWrite}, - {name: "TrafficPermissionsReadAllowed", prefix: "prefix", check: checkAllowTrafficPermissionsRead}, - {name: "TrafficPermissionsWriteDenied", prefix: "prefix", check: checkAllowTrafficPermissionsWrite}, - {name: "IdentityReadDenied", prefix: "prefix-forbidden", check: checkDenyIdentityRead}, - {name: "IdentityWriteDenied", prefix: "prefix-forbidden", check: checkDenyIdentityWrite}, - {name: "TrafficPermissionsReadDenied", prefix: "prefix-forbidden", check: checkDenyTrafficPermissionsRead}, - {name: "TrafficPermissionsWriteDenied", prefix: "prefix-forbidden", check: checkDenyTrafficPermissionsWrite}, - {name: "IdentityReadAllowed", prefix: "foozball", check: checkAllowIdentityRead}, - {name: "IdentityWriteAllowed", prefix: "foozball", check: checkAllowIdentityWrite}, - {name: "TrafficPermissionsReadAllowed", prefix: "foozball", check: checkAllowTrafficPermissionsRead}, - {name: "TrafficPermissionsWriteDenied", prefix: "foozball", check: checkDenyTrafficPermissionsWrite}, - }, - }, { name: "KeyringDefaultAllowPolicyDeny", defaultPolicy: AllowAll(), diff --git a/acl/authorizer.go b/acl/authorizer.go index 9e5bacc25e863..f4515f11c92ac 100644 --- a/acl/authorizer.go +++ b/acl/authorizer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -43,7 +43,6 @@ const ( ResourceACL Resource = "acl" ResourceAgent Resource = "agent" ResourceEvent Resource = "event" - ResourceIdentity Resource = "identity" ResourceIntention Resource = "intention" ResourceKey Resource = "key" ResourceKeyring Resource = "keyring" @@ -78,19 +77,6 @@ type Authorizer interface { // EventWrite determines if a specific event may be fired. EventWrite(string, *AuthorizerContext) EnforcementDecision - // IdentityRead checks for permission to read a given workload identity. - IdentityRead(string, *AuthorizerContext) EnforcementDecision - - // IdentityReadAll checks for permission to read all workload identities. - IdentityReadAll(*AuthorizerContext) EnforcementDecision - - // IdentityWrite checks for permission to create or update a given - // workload identity. - IdentityWrite(string, *AuthorizerContext) EnforcementDecision - - // IdentityWriteAny checks for write permission on any workload identity. - IdentityWriteAny(*AuthorizerContext) EnforcementDecision - // IntentionDefaultAllow determines the default authorized behavior // when no intentions match a Connect request. IntentionDefaultAllow(*AuthorizerContext) EnforcementDecision @@ -171,9 +157,6 @@ type Authorizer interface { // ServiceReadAll checks for permission to read all services ServiceReadAll(*AuthorizerContext) EnforcementDecision - // ServiceReadPrefix checks for permission to read services within the given prefix. - ServiceReadPrefix(string, *AuthorizerContext) EnforcementDecision - // ServiceWrite checks for permission to create or update a given // service ServiceWrite(string, *AuthorizerContext) EnforcementDecision @@ -191,13 +174,6 @@ type Authorizer interface { // Snapshot checks for permission to take and restore snapshots. Snapshot(*AuthorizerContext) EnforcementDecision - // TrafficPermissionsRead determines if specific traffic permissions can be read. - TrafficPermissionsRead(string, *AuthorizerContext) EnforcementDecision - - // TrafficPermissionsWrite determines if specific traffic permissions can be - // created, modified, or deleted. - TrafficPermissionsWrite(string, *AuthorizerContext) EnforcementDecision - // Embedded Interface for Consul Enterprise specific ACL enforcement enterpriseAuthorizer @@ -263,40 +239,6 @@ func (a AllowAuthorizer) EventWriteAllowed(name string, ctx *AuthorizerContext) return nil } -// IdentityReadAllowed checks for permission to read a given workload identity, -func (a AllowAuthorizer) IdentityReadAllowed(name string, ctx *AuthorizerContext) error { - if a.Authorizer.IdentityRead(name, ctx) != Allow { - return PermissionDeniedByACL(a, ctx, ResourceIdentity, AccessRead, name) - } - return nil -} - -// IdentityReadAllAllowed checks for permission to read all workload identities. -func (a AllowAuthorizer) IdentityReadAllAllowed(ctx *AuthorizerContext) error { - if a.Authorizer.IdentityReadAll(ctx) != Allow { - // This is only used to gate certain UI functions right now (e.g metrics) - return PermissionDeniedByACL(a, ctx, ResourceIdentity, AccessRead, "all identities") // read - } - return nil -} - -// IdentityWriteAllowed checks for permission to create or update a given -// workload identity. -func (a AllowAuthorizer) IdentityWriteAllowed(name string, ctx *AuthorizerContext) error { - if a.Authorizer.IdentityWrite(name, ctx) != Allow { - return PermissionDeniedByACL(a, ctx, ResourceIdentity, AccessWrite, name) - } - return nil -} - -// IdentityWriteAnyAllowed checks for write permission on any workload identity -func (a AllowAuthorizer) IdentityWriteAnyAllowed(ctx *AuthorizerContext) error { - if a.Authorizer.IdentityWriteAny(ctx) != Allow { - return PermissionDeniedByACL(a, ctx, ResourceIdentity, AccessWrite, "any identity") - } - return nil -} - // IntentionDefaultAllowAllowed determines the default authorized behavior // when no intentions match a Connect request. func (a AllowAuthorizer) IntentionDefaultAllowAllowed(ctx *AuthorizerContext) error { @@ -325,23 +267,6 @@ func (a AllowAuthorizer) IntentionWriteAllowed(name string, ctx *AuthorizerConte return nil } -// TrafficPermissionsReadAllowed determines if specific traffic permissions can be read. -func (a AllowAuthorizer) TrafficPermissionsReadAllowed(name string, ctx *AuthorizerContext) error { - if a.Authorizer.TrafficPermissionsRead(name, ctx) != Allow { - return PermissionDeniedByACL(a, ctx, ResourceIntention, AccessRead, name) - } - return nil -} - -// TrafficPermissionsWriteAllowed determines if specific traffic permissions can be -// created, modified, or deleted. -func (a AllowAuthorizer) TrafficPermissionsWriteAllowed(name string, ctx *AuthorizerContext) error { - if a.Authorizer.TrafficPermissionsWrite(name, ctx) != Allow { - return PermissionDeniedByACL(a, ctx, ResourceIntention, AccessWrite, name) - } - return nil -} - // KeyListAllowed checks for permission to list keys under a prefix func (a AllowAuthorizer) KeyListAllowed(name string, ctx *AuthorizerContext) error { if a.Authorizer.KeyList(name, ctx) != Allow { @@ -510,14 +435,6 @@ func (a AllowAuthorizer) ServiceReadAllAllowed(ctx *AuthorizerContext) error { return nil } -// ServiceReadPrefixAllowed checks for permission to read services within the given prefix -func (a AllowAuthorizer) ServiceReadPrefixAllowed(prefix string, ctx *AuthorizerContext) error { - if a.Authorizer.ServiceReadPrefix(prefix, ctx) != Allow { - return PermissionDeniedByACL(a, ctx, ResourceService, AccessRead, prefix) // read - } - return nil -} - // ServiceWriteAllowed checks for permission to create or update a given // service func (a AllowAuthorizer) ServiceWriteAllowed(name string, ctx *AuthorizerContext) error { @@ -586,13 +503,6 @@ func Enforce(authz Authorizer, rsc Resource, segment string, access string, ctx case "write": return authz.EventWrite(segment, ctx), nil } - case ResourceIdentity: - switch lowerAccess { - case "read": - return authz.IdentityRead(segment, ctx), nil - case "write": - return authz.IdentityWrite(segment, ctx), nil - } case ResourceIntention: switch lowerAccess { case "read": diff --git a/acl/authorizer_ce.go b/acl/authorizer_ce.go index dafac8692a9a3..ed77d5e81d3f7 100644 --- a/acl/authorizer_ce.go +++ b/acl/authorizer_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package acl diff --git a/acl/authorizer_test.go b/acl/authorizer_test.go index d538a04ad7152..20774841ba8dc 100644 --- a/acl/authorizer_test.go +++ b/acl/authorizer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -188,34 +188,6 @@ func TestACL_Enforce(t *testing.T) { ret: Deny, err: "Invalid access level", }, - { - method: "IdentityRead", - resource: ResourceIdentity, - segment: "foo", - access: "read", - ret: Deny, - }, - { - method: "IdentityRead", - resource: ResourceIdentity, - segment: "foo", - access: "read", - ret: Allow, - }, - { - method: "IdentityWrite", - resource: ResourceIdentity, - segment: "foo", - access: "write", - ret: Deny, - }, - { - method: "IdentityWrite", - resource: ResourceIdentity, - segment: "foo", - access: "write", - ret: Allow, - }, { method: "IntentionRead", resource: ResourceIntention, diff --git a/acl/chained_authorizer.go b/acl/chained_authorizer.go index 76e973d2e9eda..9a681187bc1ed 100644 --- a/acl/chained_authorizer.go +++ b/acl/chained_authorizer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -80,35 +80,6 @@ func (c *ChainedAuthorizer) EventWrite(name string, entCtx *AuthorizerContext) E }) } -// IdentityRead checks for permission to read a given workload identity. -func (c *ChainedAuthorizer) IdentityRead(name string, entCtx *AuthorizerContext) EnforcementDecision { - return c.executeChain(func(authz Authorizer) EnforcementDecision { - return authz.IdentityRead(name, entCtx) - }) -} - -// IdentityReadAll checks for permission to read all workload identities. -func (c *ChainedAuthorizer) IdentityReadAll(entCtx *AuthorizerContext) EnforcementDecision { - return c.executeChain(func(authz Authorizer) EnforcementDecision { - return authz.IdentityReadAll(entCtx) - }) -} - -// IdentityWrite checks for permission to create or update a given -// workload identity. -func (c *ChainedAuthorizer) IdentityWrite(name string, entCtx *AuthorizerContext) EnforcementDecision { - return c.executeChain(func(authz Authorizer) EnforcementDecision { - return authz.IdentityWrite(name, entCtx) - }) -} - -// IdentityWriteAny checks for write permission on any workload identity. -func (c *ChainedAuthorizer) IdentityWriteAny(entCtx *AuthorizerContext) EnforcementDecision { - return c.executeChain(func(authz Authorizer) EnforcementDecision { - return authz.IdentityWriteAny(entCtx) - }) -} - // IntentionDefaultAllow determines the default authorized behavior // when no intentions match a Connect request. func (c *ChainedAuthorizer) IntentionDefaultAllow(entCtx *AuthorizerContext) EnforcementDecision { @@ -275,12 +246,6 @@ func (c *ChainedAuthorizer) ServiceReadAll(entCtx *AuthorizerContext) Enforcemen }) } -func (c *ChainedAuthorizer) ServiceReadPrefix(prefix string, entCtx *AuthorizerContext) EnforcementDecision { - return c.executeChain(func(authz Authorizer) EnforcementDecision { - return authz.ServiceReadPrefix(prefix, entCtx) - }) -} - // ServiceWrite checks for permission to create or update a given // service func (c *ChainedAuthorizer) ServiceWrite(name string, entCtx *AuthorizerContext) EnforcementDecision { @@ -318,21 +283,6 @@ func (c *ChainedAuthorizer) Snapshot(entCtx *AuthorizerContext) EnforcementDecis }) } -// TrafficPermissionsRead determines if specific traffic permissions can be read. -func (c *ChainedAuthorizer) TrafficPermissionsRead(prefix string, entCtx *AuthorizerContext) EnforcementDecision { - return c.executeChain(func(authz Authorizer) EnforcementDecision { - return authz.TrafficPermissionsRead(prefix, entCtx) - }) -} - -// TrafficPermissionsWrite determines if specific traffic permissions can be -// created, modified, or deleted. -func (c *ChainedAuthorizer) TrafficPermissionsWrite(prefix string, entCtx *AuthorizerContext) EnforcementDecision { - return c.executeChain(func(authz Authorizer) EnforcementDecision { - return authz.TrafficPermissionsWrite(prefix, entCtx) - }) -} - func (c *ChainedAuthorizer) ToAllowAuthorizer() AllowAuthorizer { return AllowAuthorizer{Authorizer: c} } diff --git a/acl/chained_authorizer_test.go b/acl/chained_authorizer_test.go index 01d33a029204e..c17cbc907bf50 100644 --- a/acl/chained_authorizer_test.go +++ b/acl/chained_authorizer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -29,18 +29,6 @@ func (authz testAuthorizer) EventRead(string, *AuthorizerContext) EnforcementDec func (authz testAuthorizer) EventWrite(string, *AuthorizerContext) EnforcementDecision { return EnforcementDecision(authz) } -func (authz testAuthorizer) IdentityRead(string, *AuthorizerContext) EnforcementDecision { - return EnforcementDecision(authz) -} -func (authz testAuthorizer) IdentityReadAll(*AuthorizerContext) EnforcementDecision { - return EnforcementDecision(authz) -} -func (authz testAuthorizer) IdentityWrite(string, *AuthorizerContext) EnforcementDecision { - return EnforcementDecision(authz) -} -func (authz testAuthorizer) IdentityWriteAny(*AuthorizerContext) EnforcementDecision { - return EnforcementDecision(authz) -} func (authz testAuthorizer) IntentionDefaultAllow(*AuthorizerContext) EnforcementDecision { return EnforcementDecision(authz) } @@ -107,9 +95,6 @@ func (authz testAuthorizer) ServiceRead(string, *AuthorizerContext) EnforcementD func (authz testAuthorizer) ServiceReadAll(*AuthorizerContext) EnforcementDecision { return EnforcementDecision(authz) } -func (authz testAuthorizer) ServiceReadPrefix(string, *AuthorizerContext) EnforcementDecision { - return EnforcementDecision(authz) -} func (authz testAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision { return EnforcementDecision(authz) } @@ -125,12 +110,6 @@ func (authz testAuthorizer) SessionWrite(string, *AuthorizerContext) Enforcement func (authz testAuthorizer) Snapshot(*AuthorizerContext) EnforcementDecision { return EnforcementDecision(authz) } -func (authz testAuthorizer) TrafficPermissionsRead(string, *AuthorizerContext) EnforcementDecision { - return EnforcementDecision(authz) -} -func (authz testAuthorizer) TrafficPermissionsWrite(string, *AuthorizerContext) EnforcementDecision { - return EnforcementDecision(authz) -} func (authz testAuthorizer) ToAllowAuthorizer() AllowAuthorizer { return AllowAuthorizer{Authorizer: &authz} diff --git a/acl/enterprisemeta_ce.go b/acl/enterprisemeta_ce.go index 7262e79b6dc6f..8b93fd6807968 100644 --- a/acl/enterprisemeta_ce.go +++ b/acl/enterprisemeta_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package acl diff --git a/acl/errors.go b/acl/errors.go index 7f4548ed95d62..7302e0392f178 100644 --- a/acl/errors.go +++ b/acl/errors.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/acl/errors_ce.go b/acl/errors_ce.go index e342137b534e0..8c2e84ac5c415 100644 --- a/acl/errors_ce.go +++ b/acl/errors_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package acl diff --git a/acl/errors_test.go b/acl/errors_test.go index b4e645c073122..4988f695994f6 100644 --- a/acl/errors_test.go +++ b/acl/errors_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/acl/policy.go b/acl/policy.go index 0c88a9041b289..e26c8871314c3 100644 --- a/acl/policy.go +++ b/acl/policy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -59,8 +59,6 @@ type PolicyRules struct { ACL string `hcl:"acl,expand"` Agents []*AgentRule `hcl:"agent,expand"` AgentPrefixes []*AgentRule `hcl:"agent_prefix,expand"` - Identities []*IdentityRule `hcl:"identity,expand"` - IdentityPrefixes []*IdentityRule `hcl:"identity_prefix,expand"` Keys []*KeyRule `hcl:"key,expand"` KeyPrefixes []*KeyRule `hcl:"key_prefix,expand"` Nodes []*NodeRule `hcl:"node,expand"` @@ -92,19 +90,6 @@ type AgentRule struct { Policy string } -// IdentityRule represents a policy for a workload identity -type IdentityRule struct { - Name string `hcl:",key"` - Policy string - - // Intentions is the policy for intentions where this workload identity - // is the destination. This may be empty, in which case the Policy determines - // the intentions policy. - Intentions string - - EnterpriseRule `hcl:",squash"` -} - // KeyRule represents a rule for a key type KeyRule struct { Prefix string `hcl:",key"` @@ -183,30 +168,6 @@ func (pr *PolicyRules) Validate(conf *Config) error { } } - // Validate the identity policies - for _, id := range pr.Identities { - if !isPolicyValid(id.Policy, false) { - return fmt.Errorf("Invalid identity policy: %#v", id) - } - if id.Intentions != "" && !isPolicyValid(id.Intentions, false) { - return fmt.Errorf("Invalid identity intentions policy: %#v", id) - } - if err := id.EnterpriseRule.Validate(id.Policy, conf); err != nil { - return fmt.Errorf("Invalid identity enterprise policy: %#v, got error: %v", id, err) - } - } - for _, id := range pr.IdentityPrefixes { - if !isPolicyValid(id.Policy, false) { - return fmt.Errorf("Invalid identity_prefix policy: %#v", id) - } - if id.Intentions != "" && !isPolicyValid(id.Intentions, false) { - return fmt.Errorf("Invalid identity_prefix intentions policy: %#v", id) - } - if err := id.EnterpriseRule.Validate(id.Policy, conf); err != nil { - return fmt.Errorf("Invalid identity_prefix enterprise policy: %#v, got error: %v", id, err) - } - } - // Validate the key policy for _, kp := range pr.Keys { if !isPolicyValid(kp.Policy, true) { diff --git a/acl/policy_authorizer.go b/acl/policy_authorizer.go index 11d19609efde9..e87635a036df1 100644 --- a/acl/policy_authorizer.go +++ b/acl/policy_authorizer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -14,15 +14,9 @@ type policyAuthorizer struct { // agentRules contain the exact-match agent policies agentRules *radix.Tree - // identityRules contains the identity exact-match policies - identityRules *radix.Tree - // intentionRules contains the service intention exact-match policies intentionRules *radix.Tree - // trafficPermissionsRules contains the service intention exact-match policies - trafficPermissionsRules *radix.Tree - // keyRules contains the key exact-match policies keyRules *radix.Tree @@ -186,48 +180,6 @@ func (p *policyAuthorizer) loadRules(policy *PolicyRules) error { } } - // Load the identity policy (exact matches) - for _, id := range policy.Identities { - if err := insertPolicyIntoRadix(id.Name, id.Policy, &id.EnterpriseRule, p.identityRules, false); err != nil { - return err - } - - intention := id.Intentions - if intention == "" { - switch id.Policy { - case PolicyRead, PolicyWrite: - intention = PolicyRead - default: - intention = PolicyDeny - } - } - - if err := insertPolicyIntoRadix(id.Name, intention, &id.EnterpriseRule, p.trafficPermissionsRules, false); err != nil { - return err - } - } - - // Load the identity policy (prefix matches) - for _, id := range policy.IdentityPrefixes { - if err := insertPolicyIntoRadix(id.Name, id.Policy, &id.EnterpriseRule, p.identityRules, true); err != nil { - return err - } - - intention := id.Intentions - if intention == "" { - switch id.Policy { - case PolicyRead, PolicyWrite: - intention = PolicyRead - default: - intention = PolicyDeny - } - } - - if err := insertPolicyIntoRadix(id.Name, intention, &id.EnterpriseRule, p.trafficPermissionsRules, true); err != nil { - return err - } - } - // Load the key policy (exact matches) for _, kp := range policy.Keys { if err := insertPolicyIntoRadix(kp.Prefix, kp.Policy, &kp.EnterpriseRule, p.keyRules, false); err != nil { @@ -396,16 +348,14 @@ func newPolicyAuthorizer(policies []*Policy, ent *Config) (*policyAuthorizer, er func newPolicyAuthorizerFromRules(rules *PolicyRules, ent *Config) (*policyAuthorizer, error) { p := &policyAuthorizer{ - agentRules: radix.New(), - identityRules: radix.New(), - intentionRules: radix.New(), - trafficPermissionsRules: radix.New(), - keyRules: radix.New(), - nodeRules: radix.New(), - serviceRules: radix.New(), - sessionRules: radix.New(), - eventRules: radix.New(), - preparedQueryRules: radix.New(), + agentRules: radix.New(), + intentionRules: radix.New(), + keyRules: radix.New(), + nodeRules: radix.New(), + serviceRules: radix.New(), + sessionRules: radix.New(), + eventRules: radix.New(), + preparedQueryRules: radix.New(), } p.enterprisePolicyAuthorizer.init(ent) @@ -578,33 +528,6 @@ func (p *policyAuthorizer) EventWrite(name string, _ *AuthorizerContext) Enforce return Default } -// IdentityRead checks for permission to read a given workload identity. -func (p *policyAuthorizer) IdentityRead(name string, _ *AuthorizerContext) EnforcementDecision { - if rule, ok := getPolicy(name, p.identityRules); ok { - return enforce(rule.access, AccessRead) - } - return Default -} - -// IdentityReadAll checks for permission to read all workload identities. -func (p *policyAuthorizer) IdentityReadAll(_ *AuthorizerContext) EnforcementDecision { - return p.allAllowed(p.identityRules, AccessRead) -} - -// IdentityWrite checks for permission to create or update a given -// workload identity. -func (p *policyAuthorizer) IdentityWrite(name string, _ *AuthorizerContext) EnforcementDecision { - if rule, ok := getPolicy(name, p.identityRules); ok { - return enforce(rule.access, AccessWrite) - } - return Default -} - -// IdentityWriteAny checks for write permission on any workload identity. -func (p *policyAuthorizer) IdentityWriteAny(_ *AuthorizerContext) EnforcementDecision { - return p.anyAllowed(p.identityRules, AccessWrite) -} - // IntentionDefaultAllow returns whether the default behavior when there are // no matching intentions is to allow or deny. func (p *policyAuthorizer) IntentionDefaultAllow(_ *AuthorizerContext) EnforcementDecision { @@ -612,7 +535,8 @@ func (p *policyAuthorizer) IntentionDefaultAllow(_ *AuthorizerContext) Enforceme return Default } -// IntentionRead checks if reading an intention is allowed. +// IntentionRead checks if writing (creating, updating, or deleting) of an +// intention is allowed. func (p *policyAuthorizer) IntentionRead(prefix string, _ *AuthorizerContext) EnforcementDecision { if prefix == "*" { return p.anyAllowed(p.intentionRules, AccessRead) @@ -637,31 +561,6 @@ func (p *policyAuthorizer) IntentionWrite(prefix string, _ *AuthorizerContext) E return Default } -// TrafficPermissionsRead checks if reading of traffic permissions is allowed. -func (p *policyAuthorizer) TrafficPermissionsRead(prefix string, _ *AuthorizerContext) EnforcementDecision { - if prefix == "*" { - return p.anyAllowed(p.trafficPermissionsRules, AccessRead) - } - - if rule, ok := getPolicy(prefix, p.trafficPermissionsRules); ok { - return enforce(rule.access, AccessRead) - } - return Default -} - -// TrafficPermissionsWrite checks if writing (creating, updating, or deleting) of traffic -// permissions is allowed. -func (p *policyAuthorizer) TrafficPermissionsWrite(prefix string, _ *AuthorizerContext) EnforcementDecision { - if prefix == "*" { - return p.allAllowed(p.trafficPermissionsRules, AccessWrite) - } - - if rule, ok := getPolicy(prefix, p.trafficPermissionsRules); ok { - return enforce(rule.access, AccessWrite) - } - return Default -} - // KeyRead returns if a key is allowed to be read func (p *policyAuthorizer) KeyRead(key string, _ *AuthorizerContext) EnforcementDecision { if rule, ok := getPolicy(key, p.keyRules); ok { @@ -712,7 +611,7 @@ func (p *policyAuthorizer) KeyWritePrefix(prefix string, _ *AuthorizerContext) E // that do NOT grant AccessWrite. // // Conditions for Default: - // * There is no prefix match rule that would apply to the given prefix. + // * There is no prefix match rule that would appy to the given prefix. // AND // * There are no rules (exact or prefix match) within/under the given prefix // that would NOT grant AccessWrite. @@ -916,62 +815,6 @@ func (p *policyAuthorizer) ServiceReadAll(_ *AuthorizerContext) EnforcementDecis return p.allAllowed(p.serviceRules, AccessRead) } -// ServiceReadPrefix determines whether service read is allowed within the given prefix. -// -// Access is allowed iff all the following are true: -// - There's a read policy for the longest prefix that's shorter or equal to the provided prefix. -// - There's no deny policy for any prefix that's longer than the given prefix. -// - There's no deny policy for any exact match that's within the given prefix. -func (p *policyAuthorizer) ServiceReadPrefix(prefix string, _ *AuthorizerContext) EnforcementDecision { - access := Default - - // 1. Walk the prefix tree from root to the given prefix. Find the longest prefix matching ours, - // and use that policy to determine our access as that is the most specific prefix, and it - // should take precedence. - p.serviceRules.WalkPath(prefix, func(path string, leaf interface{}) bool { - rule := leaf.(*policyAuthorizerRadixLeaf) - - if rule.prefix != nil { - switch rule.prefix.access { - case AccessRead, AccessWrite: - access = Allow - default: - access = Deny - } - } - - // Don't stop iteration because we want to visit all nodes down to our leaf to find the more specific match - // as it should take precedence. - return false - }) - - // 2. Check rules "below" the given prefix. Access is allowed if there's no deny policy - // for any prefix longer than ours or for any exact match that's within the prefix. - p.serviceRules.WalkPrefix(prefix, func(path string, leaf interface{}) bool { - rule := leaf.(*policyAuthorizerRadixLeaf) - - if rule.prefix != nil && (rule.prefix.access != AccessRead && rule.prefix.access != AccessWrite) { - // If any prefix longer than the provided prefix has "deny" policy, then access is denied. - access = Deny - - // We don't need to look at the rest of the tree in this case, so terminate early. - return true - } - - if rule.exact != nil && (rule.exact.access != AccessRead && rule.exact.access != AccessWrite) { - // If any exact match policy has an explicit deny, then access is denied. - access = Deny - - // We don't need to look at the rest of the tree in this case, so terminate early. - return true - } - - return false - }) - - return access -} - // ServiceWrite checks if writing (registering) a service is allowed func (p *policyAuthorizer) ServiceWrite(name string, _ *AuthorizerContext) EnforcementDecision { if rule, ok := getPolicy(name, p.serviceRules); ok { diff --git a/acl/policy_authorizer_ce.go b/acl/policy_authorizer_ce.go index 34f8f1bf947dd..89708a5be9c31 100644 --- a/acl/policy_authorizer_ce.go +++ b/acl/policy_authorizer_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package acl diff --git a/acl/policy_authorizer_test.go b/acl/policy_authorizer_test.go index 96272d8b12f4b..1c6959527899d 100644 --- a/acl/policy_authorizer_test.go +++ b/acl/policy_authorizer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -41,9 +41,6 @@ func TestPolicyAuthorizer(t *testing.T) { {name: "DefaultAgentWrite", prefix: "foo", check: checkDefaultAgentWrite}, {name: "DefaultEventRead", prefix: "foo", check: checkDefaultEventRead}, {name: "DefaultEventWrite", prefix: "foo", check: checkDefaultEventWrite}, - {name: "DefaultIdentityRead", prefix: "foo", check: checkDefaultIdentityRead}, - {name: "DefaultIdentityWrite", prefix: "foo", check: checkDefaultIdentityWrite}, - {name: "DefaultIdentityWriteAny", prefix: "", check: checkDefaultIdentityWriteAny}, {name: "DefaultIntentionDefaultAllow", prefix: "foo", check: checkDefaultIntentionDefaultAllow}, {name: "DefaultIntentionRead", prefix: "foo", check: checkDefaultIntentionRead}, {name: "DefaultIntentionWrite", prefix: "foo", check: checkDefaultIntentionWrite}, @@ -64,8 +61,6 @@ func TestPolicyAuthorizer(t *testing.T) { {name: "DefaultPreparedQueryRead", prefix: "foo", check: checkDefaultPreparedQueryRead}, {name: "DefaultPreparedQueryWrite", prefix: "foo", check: checkDefaultPreparedQueryWrite}, {name: "DefaultServiceRead", prefix: "foo", check: checkDefaultServiceRead}, - {name: "DefaultServiceReadAll", prefix: "foo", check: checkDefaultServiceReadAll}, - {name: "DefaultServiceReadPrefix", prefix: "foo", check: checkDefaultServiceReadPrefix}, {name: "DefaultServiceWrite", prefix: "foo", check: checkDefaultServiceWrite}, {name: "DefaultServiceWriteAny", prefix: "", check: checkDefaultServiceWriteAny}, {name: "DefaultSessionRead", prefix: "foo", check: checkDefaultSessionRead}, @@ -190,29 +185,6 @@ func TestPolicyAuthorizer(t *testing.T) { Policy: PolicyRead, }, }, - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: PolicyWrite, - Intentions: PolicyWrite, - }, - { - Name: "football", - Policy: PolicyDeny, - }, - }, - IdentityPrefixes: []*IdentityRule{ - { - Name: "foot", - Policy: PolicyRead, - Intentions: PolicyRead, - }, - { - Name: "fo", - Policy: PolicyRead, - Intentions: PolicyRead, - }, - }, Keys: []*KeyRule{ { Prefix: "foo", @@ -398,23 +370,21 @@ func TestPolicyAuthorizer(t *testing.T) { {name: "ServiceReadDenied", prefix: "football", check: checkDenyServiceRead}, {name: "ServiceWriteDenied", prefix: "football", check: checkDenyServiceWrite}, {name: "ServiceWriteAnyAllowed", prefix: "", check: checkAllowServiceWriteAny}, - {name: "ServiceReadWithinPrefixDenied", prefix: "foot", check: checkDenyServiceReadPrefix}, - {name: "IdentityReadPrefixAllowed", prefix: "fo", check: checkAllowIdentityRead}, - {name: "IdentityWritePrefixDenied", prefix: "fo", check: checkDenyIdentityWrite}, - {name: "IdentityReadPrefixAllowed", prefix: "for", check: checkAllowIdentityRead}, - {name: "IdentityWritePrefixDenied", prefix: "for", check: checkDenyIdentityWrite}, - {name: "IdentityReadAllowed", prefix: "foo", check: checkAllowIdentityRead}, - {name: "IdentityWriteAllowed", prefix: "foo", check: checkAllowIdentityWrite}, - {name: "IdentityReadPrefixAllowed", prefix: "foot", check: checkAllowIdentityRead}, - {name: "IdentityWritePrefixDenied", prefix: "foot", check: checkDenyIdentityWrite}, - {name: "IdentityReadPrefixAllowed", prefix: "foot2", check: checkAllowIdentityRead}, - {name: "IdentityWritePrefixDenied", prefix: "foot2", check: checkDenyIdentityWrite}, - {name: "IdentityReadPrefixAllowed", prefix: "food", check: checkAllowIdentityRead}, - {name: "IdentityWritePrefixDenied", prefix: "food", check: checkDenyIdentityWrite}, - {name: "IdentityReadDenied", prefix: "football", check: checkDenyIdentityRead}, - {name: "IdentityWriteDenied", prefix: "football", check: checkDenyIdentityWrite}, - {name: "IdentityWriteAnyAllowed", prefix: "", check: checkAllowIdentityWriteAny}, + {name: "NodeReadPrefixAllowed", prefix: "fo", check: checkAllowNodeRead}, + {name: "NodeWritePrefixDenied", prefix: "fo", check: checkDenyNodeWrite}, + {name: "NodeReadPrefixAllowed", prefix: "for", check: checkAllowNodeRead}, + {name: "NodeWritePrefixDenied", prefix: "for", check: checkDenyNodeWrite}, + {name: "NodeReadAllowed", prefix: "foo", check: checkAllowNodeRead}, + {name: "NodeWriteAllowed", prefix: "foo", check: checkAllowNodeWrite}, + {name: "NodeReadPrefixAllowed", prefix: "foot", check: checkAllowNodeRead}, + {name: "NodeWritePrefixDenied", prefix: "foot", check: checkDenyNodeWrite}, + {name: "NodeReadPrefixAllowed", prefix: "foot2", check: checkAllowNodeRead}, + {name: "NodeWritePrefixDenied", prefix: "foot2", check: checkDenyNodeWrite}, + {name: "NodeReadPrefixAllowed", prefix: "food", check: checkAllowNodeRead}, + {name: "NodeWritePrefixDenied", prefix: "food", check: checkDenyNodeWrite}, + {name: "NodeReadDenied", prefix: "football", check: checkDenyNodeRead}, + {name: "NodeWriteDenied", prefix: "football", check: checkDenyNodeWrite}, {name: "IntentionReadPrefixAllowed", prefix: "fo", check: checkAllowIntentionRead}, {name: "IntentionWritePrefixDenied", prefix: "fo", check: checkDenyIntentionWrite}, @@ -573,214 +543,6 @@ func TestPolicyAuthorizer(t *testing.T) { {name: "AllDenied", prefix: "*", check: checkDenyIntentionWrite}, }, }, - "Service Read Prefix - read allowed with write policy and exact prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo", - Policy: PolicyWrite, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixAllowed", prefix: "foo", check: checkAllowServiceReadPrefix}, - }, - }, - "Service Read Prefix - read allowed with read policy and exact prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo", - Policy: PolicyRead, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixAllowed", prefix: "foo", check: checkAllowServiceReadPrefix}, - }, - }, - "Service Read Prefix - read denied with deny policy and exact prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo", - Policy: PolicyDeny, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, - }, - }, - "Service Read Prefix - read allowed with write policy and shorter prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo", - Policy: PolicyWrite, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixAllowed", prefix: "foo1", check: checkAllowServiceReadPrefix}, - }, - }, - "Service Read Prefix - read allowed with read policy and shorter prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo", - Policy: PolicyRead, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixAllowed", prefix: "foo1", check: checkAllowServiceReadPrefix}, - }, - }, - "Service Read Prefix - read denied with deny policy and shorter prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo", - Policy: PolicyDeny, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixDenied", prefix: "foo1", check: checkDenyServiceReadPrefix}, - }, - }, - "Service Read Prefix - default with write policy and longer prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo1", - Policy: PolicyWrite, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixDefault", prefix: "foo", check: checkDefaultServiceReadPrefix}, - }, - }, - "Service Read Prefix - default with read policy and longer prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo1", - Policy: PolicyRead, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixDefault", prefix: "foo", check: checkDefaultServiceReadPrefix}, - }, - }, - "Service Read Prefix - deny with deny policy and longer prefix": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "foo1", - Policy: PolicyDeny, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, - }, - }, - "Service Read Prefix - allow with two shorter prefixes - more specific one allowing read and less specific denying": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "fo", - Policy: PolicyDeny, - }, - { - Name: "foo", - Policy: PolicyRead, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixAllowed", prefix: "foo", check: checkAllowServiceReadPrefix}, - }, - }, - "Service Read Prefix - deny with two shorter prefixes - more specific one denying and less specific allowing read": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "fo", - Policy: PolicyRead, - }, - { - Name: "foo", - Policy: PolicyDeny, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, - }, - }, - "Service Read Prefix - deny with exact match denying": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "fo", - Policy: PolicyRead, - }, - }, - Services: []*ServiceRule{ - { - Name: "foo-123", - Policy: PolicyDeny, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, - }, - }, - "Service Read Prefix - allow with exact match allowing read": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "fo", - Policy: PolicyRead, - }, - }, - Services: []*ServiceRule{ - { - Name: "foo-123", - Policy: PolicyRead, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixAllowed", prefix: "foo", check: checkAllowServiceReadPrefix}, - }, - }, - "Service Read Prefix - deny with exact match allowing read but prefix match denying": { - policy: &Policy{PolicyRules: PolicyRules{ - ServicePrefixes: []*ServiceRule{ - { - Name: "fo", - Policy: PolicyDeny, - }, - }, - Services: []*ServiceRule{ - { - Name: "foo-123", - Policy: PolicyRead, - }, - }, - }}, - checks: []aclCheck{ - {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, - }, - }, } for name, tcase := range cases { diff --git a/acl/policy_ce.go b/acl/policy_ce.go index fe139ef7ab757..b33c3243364ba 100644 --- a/acl/policy_ce.go +++ b/acl/policy_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package acl diff --git a/acl/policy_merger.go b/acl/policy_merger.go index 83166e167dd05..df065a9cb1b95 100644 --- a/acl/policy_merger.go +++ b/acl/policy_merger.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -9,8 +9,6 @@ type policyRulesMergeContext struct { agentPrefixRules map[string]*AgentRule eventRules map[string]*EventRule eventPrefixRules map[string]*EventRule - identityRules map[string]*IdentityRule - identityPrefixRules map[string]*IdentityRule keyringRule string keyRules map[string]*KeyRule keyPrefixRules map[string]*KeyRule @@ -35,8 +33,6 @@ func (p *policyRulesMergeContext) init() { p.agentPrefixRules = make(map[string]*AgentRule) p.eventRules = make(map[string]*EventRule) p.eventPrefixRules = make(map[string]*EventRule) - p.identityRules = make(map[string]*IdentityRule) - p.identityPrefixRules = make(map[string]*IdentityRule) p.keyringRule = "" p.keyRules = make(map[string]*KeyRule) p.keyPrefixRules = make(map[string]*KeyRule) @@ -102,42 +98,6 @@ func (p *policyRulesMergeContext) merge(policy *PolicyRules) { } } - for _, id := range policy.Identities { - existing, found := p.identityRules[id.Name] - - if !found { - p.identityRules[id.Name] = id - continue - } - - if takesPrecedenceOver(id.Policy, existing.Policy) { - existing.Policy = id.Policy - existing.EnterpriseRule = id.EnterpriseRule - } - - if takesPrecedenceOver(id.Intentions, existing.Intentions) { - existing.Intentions = id.Intentions - } - } - - for _, id := range policy.IdentityPrefixes { - existing, found := p.identityPrefixRules[id.Name] - - if !found { - p.identityPrefixRules[id.Name] = id - continue - } - - if takesPrecedenceOver(id.Policy, existing.Policy) { - existing.Policy = id.Policy - existing.EnterpriseRule = id.EnterpriseRule - } - - if takesPrecedenceOver(id.Intentions, existing.Intentions) { - existing.Intentions = id.Intentions - } - } - if takesPrecedenceOver(policy.Keyring, p.keyringRule) { p.keyringRule = policy.Keyring } @@ -309,16 +269,6 @@ func (p *policyRulesMergeContext) fill(merged *PolicyRules) { merged.EventPrefixes = append(merged.EventPrefixes, policy) } - merged.Identities = []*IdentityRule{} - for _, policy := range p.identityRules { - merged.Identities = append(merged.Identities, policy) - } - - merged.IdentityPrefixes = []*IdentityRule{} - for _, policy := range p.identityPrefixRules { - merged.IdentityPrefixes = append(merged.IdentityPrefixes, policy) - } - merged.Keys = []*KeyRule{} for _, policy := range p.keyRules { merged.Keys = append(merged.Keys, policy) diff --git a/acl/policy_merger_ce.go b/acl/policy_merger_ce.go index 4738314a6c1dd..b221f25875399 100644 --- a/acl/policy_merger_ce.go +++ b/acl/policy_merger_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package acl diff --git a/acl/policy_test.go b/acl/policy_test.go index 599c8c977e1b9..ac23e3c0df3b0 100644 --- a/acl/policy_test.go +++ b/acl/policy_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -42,12 +42,6 @@ func TestPolicySourceParse(t *testing.T) { event "bar" { policy = "deny" } - identity_prefix "" { - policy = "write" - } - identity "foo" { - policy = "read" - } key_prefix "" { policy = "read" } @@ -123,16 +117,6 @@ func TestPolicySourceParse(t *testing.T) { "policy": "deny" } }, - "identity_prefix": { - "": { - "policy": "write" - } - }, - "identity": { - "foo": { - "policy": "read" - } - }, "key_prefix": { "": { "policy": "read" @@ -233,18 +217,6 @@ func TestPolicySourceParse(t *testing.T) { Policy: PolicyDeny, }, }, - IdentityPrefixes: []*IdentityRule{ - { - Name: "", - Policy: PolicyWrite, - }, - }, - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: PolicyRead, - }, - }, Keyring: PolicyDeny, KeyPrefixes: []*KeyRule{ { @@ -331,39 +303,6 @@ func TestPolicySourceParse(t *testing.T) { }, }}, }, - { - Name: "Identity No Intentions", - Rules: `identity "foo" { policy = "write" }`, - RulesJSON: `{ "identity": { "foo": { "policy": "write" }}}`, - Expected: &Policy{PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: "write", - }, - }, - }}, - }, - { - Name: "Identity Intentions", - Rules: `identity "foo" { policy = "write" intentions = "read" }`, - RulesJSON: `{ "identity": { "foo": { "policy": "write", "intentions": "read" }}}`, - Expected: &Policy{PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: "write", - Intentions: "read", - }, - }, - }}, - }, - { - Name: "Identity Intention: invalid value", - Rules: `identity "foo" { policy = "write" intentions = "foo" }`, - RulesJSON: `{ "identity": { "foo": { "policy": "write", "intentions": "foo" }}}`, - Err: "Invalid identity intentions policy", - }, { Name: "Service No Intentions", Rules: `service "foo" { policy = "write" }`, @@ -415,18 +354,6 @@ func TestPolicySourceParse(t *testing.T) { RulesJSON: `{ "agent_prefix": { "foo": { "policy": "nope" }}}`, Err: "Invalid agent_prefix policy", }, - { - Name: "Bad Policy - Identity", - Rules: `identity "foo" { policy = "nope" }`, - RulesJSON: `{ "identity": { "foo": { "policy": "nope" }}}`, - Err: "Invalid identity policy", - }, - { - Name: "Bad Policy - Identity Prefix", - Rules: `identity_prefix "foo" { policy = "nope" }`, - RulesJSON: `{ "identity_prefix": { "foo": { "policy": "nope" }}}`, - Err: "Invalid identity_prefix policy", - }, { Name: "Bad Policy - Key", Rules: `key "foo" { policy = "nope" }`, @@ -758,109 +685,6 @@ func TestMergePolicies(t *testing.T) { }, }}, }, - { - name: "Identities", - input: []*Policy{ - {PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: PolicyWrite, - Intentions: PolicyWrite, - }, - { - Name: "bar", - Policy: PolicyRead, - Intentions: PolicyRead, - }, - { - Name: "baz", - Policy: PolicyWrite, - Intentions: PolicyWrite, - }, - }, - IdentityPrefixes: []*IdentityRule{ - { - Name: "000", - Policy: PolicyWrite, - Intentions: PolicyWrite, - }, - { - Name: "111", - Policy: PolicyRead, - Intentions: PolicyRead, - }, - { - Name: "222", - Policy: PolicyWrite, - Intentions: PolicyWrite, - }, - }, - }}, - {PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: PolicyRead, - Intentions: PolicyRead, - }, - { - Name: "baz", - Policy: PolicyDeny, - Intentions: PolicyDeny, - }, - }, - IdentityPrefixes: []*IdentityRule{ - { - Name: "000", - Policy: PolicyRead, - Intentions: PolicyRead, - }, - { - Name: "222", - Policy: PolicyDeny, - Intentions: PolicyDeny, - }, - }, - }}, - }, - expected: &Policy{PolicyRules: PolicyRules{ - Identities: []*IdentityRule{ - { - Name: "foo", - Policy: PolicyWrite, - Intentions: PolicyWrite, - }, - { - Name: "bar", - Policy: PolicyRead, - Intentions: PolicyRead, - }, - { - Name: "baz", - Policy: PolicyDeny, - Intentions: PolicyDeny, - }, - }, - IdentityPrefixes: []*IdentityRule{ - { - Name: "000", - Policy: PolicyWrite, - Intentions: PolicyWrite, - }, - { - Name: "111", - Policy: PolicyRead, - Intentions: PolicyRead, - }, - { - Name: "222", - Policy: PolicyDeny, - Intentions: PolicyDeny, - }, - }, - }}, - }, { name: "Node", input: []*Policy{ diff --git a/acl/resolver/danger.go b/acl/resolver/danger.go index 29b4f35ac1d0f..a72efa9278449 100644 --- a/acl/resolver/danger.go +++ b/acl/resolver/danger.go @@ -1,19 +1,15 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resolver -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/structs" -) +import "github.com/hashicorp/consul/acl" // DANGER_NO_AUTH implements an ACL resolver short-circuit authorization in // cases where it is handled somewhere else or expressly not required. type DANGER_NO_AUTH struct{} // ResolveTokenAndDefaultMeta returns an authorizer with unfettered permissions. -func (DANGER_NO_AUTH) ResolveTokenAndDefaultMeta(_ string, entMeta *acl.EnterpriseMeta, _ *acl.AuthorizerContext) (Result, error) { - entMeta.Merge(structs.DefaultEnterpriseMetaInDefaultPartition()) +func (DANGER_NO_AUTH) ResolveTokenAndDefaultMeta(string, *acl.EnterpriseMeta, *acl.AuthorizerContext) (Result, error) { return Result{Authorizer: acl.ManageAll()}, nil } diff --git a/acl/resolver/result.go b/acl/resolver/result.go index 1e52b1c573168..190d15eca5b8a 100644 --- a/acl/resolver/result.go +++ b/acl/resolver/result.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resolver diff --git a/acl/static_authorizer.go b/acl/static_authorizer.go index 759b378669ad8..a6678925695c9 100644 --- a/acl/static_authorizer.go +++ b/acl/static_authorizer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -75,34 +75,6 @@ func (s *staticAuthorizer) EventWrite(string, *AuthorizerContext) EnforcementDec return Deny } -func (s *staticAuthorizer) IdentityRead(string, *AuthorizerContext) EnforcementDecision { - if s.defaultAllow { - return Allow - } - return Deny -} - -func (s *staticAuthorizer) IdentityReadAll(*AuthorizerContext) EnforcementDecision { - if s.defaultAllow { - return Allow - } - return Deny -} - -func (s *staticAuthorizer) IdentityWrite(string, *AuthorizerContext) EnforcementDecision { - if s.defaultAllow { - return Allow - } - return Deny -} - -func (s *staticAuthorizer) IdentityWriteAny(*AuthorizerContext) EnforcementDecision { - if s.defaultAllow { - return Allow - } - return Deny -} - func (s *staticAuthorizer) IntentionDefaultAllow(*AuthorizerContext) EnforcementDecision { if s.defaultAllow { return Allow @@ -257,13 +229,6 @@ func (s *staticAuthorizer) ServiceReadAll(*AuthorizerContext) EnforcementDecisio return Deny } -func (s *staticAuthorizer) ServiceReadPrefix(string, *AuthorizerContext) EnforcementDecision { - if s.defaultAllow { - return Allow - } - return Deny -} - func (s *staticAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision { if s.defaultAllow { return Allow @@ -299,20 +264,6 @@ func (s *staticAuthorizer) Snapshot(_ *AuthorizerContext) EnforcementDecision { return Deny } -func (s *staticAuthorizer) TrafficPermissionsRead(string, *AuthorizerContext) EnforcementDecision { - if s.defaultAllow { - return Allow - } - return Deny -} - -func (s *staticAuthorizer) TrafficPermissionsWrite(string, *AuthorizerContext) EnforcementDecision { - if s.defaultAllow { - return Allow - } - return Deny -} - func (s *staticAuthorizer) ToAllowAuthorizer() AllowAuthorizer { return AllowAuthorizer{Authorizer: s} } diff --git a/acl/static_authorizer_test.go b/acl/static_authorizer_test.go index cdaf91ef71020..e94ac44e500f0 100644 --- a/acl/static_authorizer_test.go +++ b/acl/static_authorizer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/acl/testing.go b/acl/testing.go index ef4d0343c6b9e..1c67458b174f8 100644 --- a/acl/testing.go +++ b/acl/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/acl/validation.go b/acl/validation.go index c0017effa15d7..96119dcc0fbaa 100644 --- a/acl/validation.go +++ b/acl/validation.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/acl/validation_test.go b/acl/validation_test.go index 3bf14719b12ae..d5d01e0e9054e 100644 --- a/acl/validation_test.go +++ b/acl/validation_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/agent/acl.go b/agent/acl.go index 0f64ee62c79e9..381f2c028e4fc 100644 --- a/agent/acl.go +++ b/agent/acl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/acl_ce.go b/agent/acl_ce.go index 4ce9bb00642ab..aa505da1ef49b 100644 --- a/agent/acl_ce.go +++ b/agent/acl_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/acl_endpoint.go b/agent/acl_endpoint.go index fb94862800eba..3a52b0cf54413 100644 --- a/agent/acl_endpoint.go +++ b/agent/acl_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -1133,144 +1133,3 @@ func (s *HTTPHandlers) ACLAuthorize(resp http.ResponseWriter, req *http.Request) return responses, nil } - -func (s *HTTPHandlers) ACLTemplatedPoliciesList(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - if s.checkACLDisabled() { - return nil, aclDisabled - } - - var token string - s.parseToken(req, &token) - - var entMeta acl.EnterpriseMeta - if err := s.parseEntMetaNoWildcard(req, &entMeta); err != nil { - return nil, err - } - - s.defaultMetaPartitionToAgent(&entMeta) - var authzContext acl.AuthorizerContext - authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, &authzContext) - if err != nil { - return nil, err - } - - // Only ACLRead privileges are required to list templated policies - if err := authz.ToAllowAuthorizer().ACLReadAllowed(&authzContext); err != nil { - return nil, err - } - - templatedPolicies := make(map[string]api.ACLTemplatedPolicyResponse) - - for tp, tmpBase := range structs.GetACLTemplatedPolicyList() { - templatedPolicies[tp] = api.ACLTemplatedPolicyResponse{ - TemplateName: tmpBase.TemplateName, - Schema: tmpBase.Schema, - Template: tmpBase.Template, - } - } - - return templatedPolicies, nil -} - -func (s *HTTPHandlers) ACLTemplatedPolicyRead(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - if s.checkACLDisabled() { - return nil, aclDisabled - } - - templateName := strings.TrimPrefix(req.URL.Path, "/v1/acl/templated-policy/name/") - if templateName == "" { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing templated policy Name"} - } - - var token string - s.parseToken(req, &token) - - var entMeta acl.EnterpriseMeta - if err := s.parseEntMetaNoWildcard(req, &entMeta); err != nil { - return nil, err - } - - s.defaultMetaPartitionToAgent(&entMeta) - var authzContext acl.AuthorizerContext - authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, &authzContext) - if err != nil { - return nil, err - } - - // Only ACLRead privileges are required to read templated policies - if err := authz.ToAllowAuthorizer().ACLReadAllowed(&authzContext); err != nil { - return nil, err - } - - baseTemplate, ok := structs.GetACLTemplatedPolicyBase(templateName) - if !ok { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Invalid templated policy Name: %s", templateName)} - } - - return api.ACLTemplatedPolicyResponse{ - TemplateName: baseTemplate.TemplateName, - Schema: baseTemplate.Schema, - Template: baseTemplate.Template, - }, nil -} - -func (s *HTTPHandlers) ACLTemplatedPolicyPreview(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - if s.checkACLDisabled() { - return nil, aclDisabled - } - - templateName := strings.TrimPrefix(req.URL.Path, "/v1/acl/templated-policy/preview/") - if templateName == "" { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Missing templated policy Name"} - } - - var token string - s.parseToken(req, &token) - - var entMeta acl.EnterpriseMeta - if err := s.parseEntMetaNoWildcard(req, &entMeta); err != nil { - return nil, err - } - - s.defaultMetaPartitionToAgent(&entMeta) - var authzContext acl.AuthorizerContext - authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &entMeta, &authzContext) - if err != nil { - return nil, err - } - - // Only ACLRead privileges are required to read/preview templated policies - if err := authz.ToAllowAuthorizer().ACLReadAllowed(&authzContext); err != nil { - return nil, err - } - - baseTemplate, ok := structs.GetACLTemplatedPolicyBase(templateName) - if !ok { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("templated policy %q does not exist", templateName)} - } - - var tpRequest structs.ACLTemplatedPolicyVariables - - if err := decodeBody(req.Body, &tpRequest); err != nil { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Failed to decode request body: %s", err.Error())} - } - - templatedPolicy := structs.ACLTemplatedPolicy{ - TemplateID: baseTemplate.TemplateID, - TemplateName: baseTemplate.TemplateName, - TemplateVariables: &tpRequest, - } - - err = templatedPolicy.ValidateTemplatedPolicy(baseTemplate.Schema) - if err != nil { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("validation error for templated policy: %q: %s", templatedPolicy.TemplateName, err.Error())} - } - - renderedPolicy, err := templatedPolicy.SyntheticPolicy(&entMeta) - - if err != nil { - return nil, HTTPError{StatusCode: http.StatusInternalServerError, Reason: fmt.Sprintf("Failed to generate synthetic policy: %q: %s", templatedPolicy.TemplateName, err.Error())} - } - - return renderedPolicy, nil -} diff --git a/agent/acl_endpoint_test.go b/agent/acl_endpoint_test.go index 7ce090204d828..68d1888ff6668 100644 --- a/agent/acl_endpoint_test.go +++ b/agent/acl_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -21,7 +21,6 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/consul/authmethod/testauth" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/internal/go-sso/oidcauth/oidcauthtest" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/testrpc" @@ -1362,88 +1361,6 @@ func TestACL_HTTP(t *testing.T) { require.Equal(t, "sn1", token.ServiceIdentities[0].ServiceName) }) }) - - t.Run("ACLTemplatedPolicy", func(t *testing.T) { - t.Run("List", func(t *testing.T) { - req, _ := http.NewRequest("GET", "/v1/acl/templated-policies", nil) - req.Header.Add("X-Consul-Token", "root") - resp := httptest.NewRecorder() - a.srv.h.ServeHTTP(resp, req) - - require.Equal(t, http.StatusOK, resp.Code) - - var list map[string]api.ACLTemplatedPolicyResponse - require.NoError(t, json.NewDecoder(resp.Body).Decode(&list)) - require.Len(t, list, 5) - - require.Equal(t, api.ACLTemplatedPolicyResponse{ - TemplateName: api.ACLTemplatedPolicyServiceName, - Schema: structs.ACLTemplatedPolicyServiceSchema, - Template: structs.ACLTemplatedPolicyService, - }, list[api.ACLTemplatedPolicyServiceName]) - }) - t.Run("Read", func(t *testing.T) { - t.Run("With non existing templated policy", func(t *testing.T) { - req, _ := http.NewRequest("GET", "/v1/acl/templated-policy/name/fake", nil) - req.Header.Add("X-Consul-Token", "root") - resp := httptest.NewRecorder() - a.srv.h.ServeHTTP(resp, req) - require.Equal(t, http.StatusBadRequest, resp.Code) - }) - - t.Run("With existing templated policy", func(t *testing.T) { - req, _ := http.NewRequest("GET", "/v1/acl/templated-policy/name/"+api.ACLTemplatedPolicyDNSName, nil) - req.Header.Add("X-Consul-Token", "root") - resp := httptest.NewRecorder() - - a.srv.h.ServeHTTP(resp, req) - require.Equal(t, http.StatusOK, resp.Code) - - var templatedPolicy api.ACLTemplatedPolicyResponse - require.NoError(t, json.NewDecoder(resp.Body).Decode(&templatedPolicy)) - require.Equal(t, structs.ACLTemplatedPolicyNoRequiredVariablesSchema, templatedPolicy.Schema) - require.Equal(t, api.ACLTemplatedPolicyDNSName, templatedPolicy.TemplateName) - require.Equal(t, structs.ACLTemplatedPolicyDNS, templatedPolicy.Template) - }) - }) - t.Run("preview", func(t *testing.T) { - t.Run("When missing required variables", func(t *testing.T) { - previewInput := &structs.ACLTemplatedPolicyVariables{} - req, _ := http.NewRequest( - "POST", - fmt.Sprintf("/v1/acl/templated-policy/preview/%s", api.ACLTemplatedPolicyServiceName), - jsonBody(previewInput), - ) - req.Header.Add("X-Consul-Token", "root") - resp := httptest.NewRecorder() - - a.srv.h.ServeHTTP(resp, req) - require.Equal(t, http.StatusBadRequest, resp.Code) - }) - - t.Run("Correct input", func(t *testing.T) { - previewInput := &structs.ACLTemplatedPolicyVariables{Name: "web"} - req, _ := http.NewRequest( - "POST", - fmt.Sprintf("/v1/acl/templated-policy/preview/%s", api.ACLTemplatedPolicyServiceName), - jsonBody(previewInput), - ) - req.Header.Add("X-Consul-Token", "root") - resp := httptest.NewRecorder() - - a.srv.h.ServeHTTP(resp, req) - require.Equal(t, http.StatusOK, resp.Code) - - var syntheticPolicy *structs.ACLPolicy - require.NoError(t, json.NewDecoder(resp.Body).Decode(&syntheticPolicy)) - - require.NotEmpty(t, syntheticPolicy.ID) - require.NotEmpty(t, syntheticPolicy.Hash) - require.Equal(t, "synthetic policy generated from templated policy: builtin/service", syntheticPolicy.Description) - require.Contains(t, syntheticPolicy.Name, "synthetic-policy-") - }) - }) - }) } func TestACL_LoginProcedure_HTTP(t *testing.T) { @@ -2190,7 +2107,7 @@ func TestACL_Authorize(t *testing.T) { policyReq := structs.ACLPolicySetRequest{ Policy: structs.ACLPolicy{ Name: "test", - Rules: `acl = "read" operator = "write" identity_prefix "" { policy = "read"} service_prefix "" { policy = "read"} node_prefix "" { policy= "write" } key_prefix "/foo" { policy = "write" } `, + Rules: `acl = "read" operator = "write" service_prefix "" { policy = "read"} node_prefix "" { policy= "write" } key_prefix "/foo" { policy = "write" } `, }, Datacenter: "dc1", WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken}, @@ -2276,16 +2193,6 @@ func TestACL_Authorize(t *testing.T) { Segment: "foo", Access: "write", }, - { - Resource: "identity", - Segment: "foo", - Access: "read", - }, - { - Resource: "identity", - Segment: "foo", - Access: "write", - }, { Resource: "intention", Segment: "foo", @@ -2436,16 +2343,6 @@ func TestACL_Authorize(t *testing.T) { Segment: "foo", Access: "write", }, - { - Resource: "identity", - Segment: "foo", - Access: "read", - }, - { - Resource: "identity", - Segment: "foo", - Access: "write", - }, { Resource: "intention", Segment: "foo", @@ -2552,8 +2449,6 @@ func TestACL_Authorize(t *testing.T) { false, // agent:write false, // event:read false, // event:write - true, // identity:read - false, // identity:write true, // intentions:read false, // intention:write false, // key:read diff --git a/agent/acl_test.go b/agent/acl_test.go index 0958db8db6fb0..40662231ac367 100644 --- a/agent/acl_test.go +++ b/agent/acl_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -22,7 +22,6 @@ import ( "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib" - "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/types" @@ -164,9 +163,6 @@ func (a *TestACLAgent) Stats() map[string]map[string]string { func (a *TestACLAgent) ReloadConfig(_ consul.ReloadableConfig) error { return fmt.Errorf("Unimplemented") } -func (a *TestACLAgent) ResourceServiceClient() pbresource.ResourceServiceClient { - return nil -} func TestACL_Version8EnabledByDefault(t *testing.T) { t.Parallel() diff --git a/agent/ae/ae.go b/agent/ae/ae.go index f8b9a331d100c..8c4d8c9972966 100644 --- a/agent/ae/ae.go +++ b/agent/ae/ae.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package ae provides tools to synchronize state between local and remote consul servers. package ae @@ -81,9 +81,8 @@ type StateSyncer struct { SyncChanges *Trigger // paused stores whether sync runs are temporarily disabled. - pauseLock sync.Mutex - paused int - hardDisabled bool + pauseLock sync.Mutex + paused int // serverUpInterval is the max time after which a full sync is // performed when a server has been added to the cluster. @@ -152,20 +151,9 @@ const ( retryFullSyncState fsmState = "retryFullSync" ) -// HardDisableSync is like PauseSync but is one-way. It causes other -// Pause/Resume/Start operations to be completely ignored. -func (s *StateSyncer) HardDisableSync() { - s.pauseLock.Lock() - s.hardDisabled = true - s.pauseLock.Unlock() -} - // Run is the long running method to perform state synchronization // between local and remote servers. func (s *StateSyncer) Run() { - if s.Disabled() { - return - } if s.ClusterSize == nil { panic("ClusterSize not set") } @@ -341,14 +329,7 @@ func (s *StateSyncer) Pause() { func (s *StateSyncer) Paused() bool { s.pauseLock.Lock() defer s.pauseLock.Unlock() - return s.paused != 0 || s.hardDisabled -} - -// Disabled returns whether sync runs are permanently disabled. -func (s *StateSyncer) Disabled() bool { - s.pauseLock.Lock() - defer s.pauseLock.Unlock() - return s.hardDisabled + return s.paused != 0 } // Resume re-enables sync runs. It returns true if it was the last pause/resume @@ -359,7 +340,7 @@ func (s *StateSyncer) Resume() bool { if s.paused < 0 { panic("unbalanced pause/resume") } - trigger := s.paused == 0 && !s.hardDisabled + trigger := s.paused == 0 s.pauseLock.Unlock() if trigger { s.SyncChanges.Trigger() diff --git a/agent/ae/ae_test.go b/agent/ae/ae_test.go index 9e9593f4f92d2..873cd4128db34 100644 --- a/agent/ae/ae_test.go +++ b/agent/ae/ae_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ae diff --git a/agent/ae/trigger.go b/agent/ae/trigger.go index 29bdd988907eb..a320bda526d1f 100644 --- a/agent/ae/trigger.go +++ b/agent/ae/trigger.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ae diff --git a/agent/agent.go b/agent/agent.go index dab7d542c0dce..017b8fbd6dd26 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -66,14 +66,12 @@ import ( "github.com/hashicorp/consul/agent/xds" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api/watch" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" "github.com/hashicorp/consul/ipaddr" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/file" "github.com/hashicorp/consul/lib/mutex" "github.com/hashicorp/consul/lib/routine" "github.com/hashicorp/consul/logging" - "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/pboperator" "github.com/hashicorp/consul/proto/private/pbpeering" "github.com/hashicorp/consul/tlsutil" @@ -201,9 +199,6 @@ type delegate interface { RPC(ctx context.Context, method string, args interface{}, reply interface{}) error - // ResourceServiceClient is a client for the gRPC Resource Service. - ResourceServiceClient() pbresource.ResourceServiceClient - SnapshotRPC(args *structs.SnapshotRequest, in io.Reader, out io.Writer, replyFn structs.SnapshotReplyFn) error Shutdown() error Stats() map[string]map[string]string @@ -622,9 +617,6 @@ func (a *Agent) Start(ctx context.Context) error { // create the state synchronization manager which performs // regular and on-demand state synchronizations (anti-entropy). a.sync = ae.NewStateSyncer(a.State, c.AEInterval, a.shutdownCh, a.logger) - if a.baseDeps.UseV2Resources() { - a.sync.HardDisableSync() - } err = validateFIPSConfig(a.config) if err != nil { @@ -656,12 +648,7 @@ func (a *Agent) Start(ctx context.Context) error { return fmt.Errorf("failed to start Consul enterprise component: %v", err) } - // proxyTracker will be used in the creation of the XDS server and also - // in the registration of the v2 xds controller - var proxyTracker *proxytracker.ProxyTracker - // Setup either the client or the server. - var consulServer *consul.Server if c.ServerMode { serverLogger := a.baseDeps.Logger.NamedIntercept(logging.ConsulServer) @@ -698,18 +685,12 @@ func (a *Agent) Start(ctx context.Context) error { }, ) - if a.baseDeps.UseV2Resources() { - proxyTracker = proxytracker.NewProxyTracker(proxytracker.ProxyTrackerConfig{ - Logger: a.logger.Named("proxy-tracker"), - SessionLimiter: a.baseDeps.XDSStreamLimiter, - }) - } - consulServer, err = consul.NewServer(consulCfg, a.baseDeps.Deps, a.externalGRPCServer, incomingRPCLimiter, serverLogger, proxyTracker) + server, err := consul.NewServer(consulCfg, a.baseDeps.Deps, a.externalGRPCServer, incomingRPCLimiter, serverLogger) if err != nil { return fmt.Errorf("Failed to start Consul server: %v", err) } - incomingRPCLimiter.Register(consulServer) - a.delegate = consulServer + incomingRPCLimiter.Register(server) + a.delegate = server if a.config.PeeringEnabled && a.config.ConnectEnabled { d := servercert.Deps{ @@ -719,7 +700,7 @@ func (a *Agent) Start(ctx context.Context) error { ACLsEnabled: a.config.ACLsEnabled, }, LeafCertManager: a.leafCertManager, - GetStore: func() servercert.Store { return consulServer.FSM().State() }, + GetStore: func() servercert.Store { return server.FSM().State() }, TLSConfigurator: a.tlsConfigurator, } a.certManager = servercert.NewCertManager(d) @@ -775,8 +756,13 @@ func (a *Agent) Start(ctx context.Context) error { return err } - intentionDefaultAllow, err := a.config.ACLResolverSettings.IsDefaultAllow() - if err != nil { + var intentionDefaultAllow bool + switch a.config.ACLResolverSettings.ACLDefaultPolicy { + case "allow": + intentionDefaultAllow = true + case "deny": + intentionDefaultAllow = false + default: return fmt.Errorf("unexpected ACL default policy value of %q", a.config.ACLResolverSettings.ACLDefaultPolicy) } @@ -784,7 +770,7 @@ func (a *Agent) Start(ctx context.Context) error { // Start the proxy config manager. a.proxyConfig, err = proxycfg.NewManager(proxycfg.ManagerConfig{ - DataSources: a.proxyDataSources(consulServer), + DataSources: a.proxyDataSources(), Logger: a.logger.Named(logging.ProxyConfig), Source: &structs.QuerySource{ Datacenter: a.config.Datacenter, @@ -856,7 +842,7 @@ func (a *Agent) Start(ctx context.Context) error { } // Start grpc and grpc_tls servers. - if err := a.listenAndServeGRPC(proxyTracker, consulServer); err != nil { + if err := a.listenAndServeGRPC(); err != nil { return err } @@ -921,60 +907,39 @@ func (a *Agent) Failed() <-chan struct{} { return a.apiServers.failed } -// configureXDSServer configures an XDS server with the proper implementation of -// the PRoxyWatcher interface and registers the XDS server with Consul's -// external facing GRPC server. -func (a *Agent) configureXDSServer(proxyWatcher xds.ProxyWatcher, server *consul.Server) { +func (a *Agent) listenAndServeGRPC() error { + if len(a.config.GRPCAddrs) < 1 && len(a.config.GRPCTLSAddrs) < 1 { + return nil + } // TODO(agentless): rather than asserting the concrete type of delegate, we // should add a method to the Delegate interface to build a ConfigSource. - if server != nil { - switch proxyWatcher.(type) { - case *proxytracker.ProxyTracker: - go func() { - <-a.shutdownCh - proxyWatcher.(*proxytracker.ProxyTracker).Shutdown() - }() - default: - catalogCfg := catalogproxycfg.NewConfigSource(catalogproxycfg.Config{ - NodeName: a.config.NodeName, - LocalState: a.State, - LocalConfigSource: proxyWatcher, - Manager: a.proxyConfig, - GetStore: func() catalogproxycfg.Store { return server.FSM().State() }, - Logger: a.proxyConfig.Logger.Named("server-catalog"), - SessionLimiter: a.baseDeps.XDSStreamLimiter, - }) - go func() { - <-a.shutdownCh - catalogCfg.Shutdown() - }() - proxyWatcher = catalogCfg - } + var cfg xds.ProxyConfigSource = localproxycfg.NewConfigSource(a.proxyConfig) + if server, ok := a.delegate.(*consul.Server); ok { + catalogCfg := catalogproxycfg.NewConfigSource(catalogproxycfg.Config{ + NodeName: a.config.NodeName, + LocalState: a.State, + LocalConfigSource: cfg, + Manager: a.proxyConfig, + GetStore: func() catalogproxycfg.Store { return server.FSM().State() }, + Logger: a.proxyConfig.Logger.Named("server-catalog"), + SessionLimiter: a.baseDeps.XDSStreamLimiter, + }) + go func() { + <-a.shutdownCh + catalogCfg.Shutdown() + }() + cfg = catalogCfg } a.xdsServer = xds.NewServer( a.config.NodeName, a.logger.Named(logging.Envoy), - proxyWatcher, + cfg, func(id string) (acl.Authorizer, error) { return a.delegate.ResolveTokenAndDefaultMeta(id, nil, nil) }, a, ) a.xdsServer.Register(a.externalGRPCServer) -} - -func (a *Agent) listenAndServeGRPC(proxyTracker *proxytracker.ProxyTracker, server *consul.Server) error { - if len(a.config.GRPCAddrs) < 1 && len(a.config.GRPCTLSAddrs) < 1 { - return nil - } - var proxyWatcher xds.ProxyWatcher - if a.baseDeps.UseV2Resources() { - proxyWatcher = proxyTracker - } else { - proxyWatcher = localproxycfg.NewConfigSource(a.proxyConfig) - } - - a.configureXDSServer(proxyWatcher, server) // Attempt to spawn listeners var listeners []net.Listener @@ -4569,7 +4534,7 @@ func (a *Agent) listenerPortLocked(svcID structs.ServiceID, checkID structs.Chec return port, nil } -func (a *Agent) proxyDataSources(server *consul.Server) proxycfg.DataSources { +func (a *Agent) proxyDataSources() proxycfg.DataSources { sources := proxycfg.DataSources{ CARoots: proxycfgglue.CacheCARoots(a.cache), CompiledDiscoveryChain: proxycfgglue.CacheCompiledDiscoveryChain(a.cache), @@ -4596,7 +4561,7 @@ func (a *Agent) proxyDataSources(server *consul.Server) proxycfg.DataSources { ExportedPeeredServices: proxycfgglue.CacheExportedPeeredServices(a.cache), } - if server != nil { + if server, ok := a.delegate.(*consul.Server); ok { deps := proxycfgglue.ServerDataSourceDeps{ Datacenter: a.config.Datacenter, EventPublisher: a.baseDeps.EventPublisher, diff --git a/agent/agent_ce.go b/agent/agent_ce.go index a4a6cbf809d9e..e8cfea681b3cb 100644 --- a/agent/agent_ce.go +++ b/agent/agent_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/agent_ce_test.go b/agent/agent_ce_test.go index f9eed9018ba0a..ceb90beb0634c 100644 --- a/agent/agent_ce_test.go +++ b/agent/agent_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go index dd32bc6843500..23bfa49c88444 100644 --- a/agent/agent_endpoint.go +++ b/agent/agent_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -11,31 +11,32 @@ import ( "strings" "time" - "github.com/hashicorp/go-bexpr" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-memdb" + "github.com/mitchellh/hashstructure" + + "github.com/hashicorp/consul/envoyextensions/xdscommon" + "github.com/hashicorp/consul/version" + + "github.com/hashicorp/go-bexpr" "github.com/hashicorp/serf/coordinate" "github.com/hashicorp/serf/serf" - "github.com/mitchellh/hashstructure" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/hashicorp/consul/acl" cachetype "github.com/hashicorp/consul/agent/cache-types" - "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/debug" "github.com/hashicorp/consul/agent/leafcert" "github.com/hashicorp/consul/agent/structs" token_store "github.com/hashicorp/consul/agent/token" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/ipaddr" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/logging/monitor" "github.com/hashicorp/consul/types" - "github.com/hashicorp/consul/version" ) type Self struct { @@ -1532,9 +1533,6 @@ func (s *HTTPHandlers) AgentToken(resp http.ResponseWriter, req *http.Request) ( case "config_file_service_registration": s.agent.tokens.UpdateConfigFileRegistrationToken(args.Token, token_store.TokenSourceAPI) - case "dns_token", "dns": - s.agent.tokens.UpdateDNSToken(args.Token, token_store.TokenSourceAPI) - default: return HTTPError{StatusCode: http.StatusNotFound, Reason: fmt.Sprintf("Token %q is unknown", target)} } @@ -1657,108 +1655,14 @@ func (s *HTTPHandlers) AgentConnectAuthorize(resp http.ResponseWriter, req *http return nil, nil } - // We need to have a target to check intentions - if authReq.Target == "" { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "Target service must be specified"} - } - - // Parse the certificate URI from the client ID - uri, err := connect.ParseCertURIFromString(authReq.ClientCertURI) - if err != nil { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "ClientCertURI not a valid Connect identifier"} - } - - uriService, ok := uri.(*connect.SpiffeIDService) - if !ok { - return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: "ClientCertURI not a valid Service identifier"} - } - - // We need to verify service:write permissions for the given token. - // We do this manually here since the RPC request below only verifies - // service:read. - var authzContext acl.AuthorizerContext - authz, err := s.agent.delegate.ResolveTokenAndDefaultMeta(token, &authReq.EnterpriseMeta, &authzContext) + authz, reason, cacheMeta, err := s.agent.ConnectAuthorize(token, &authReq) if err != nil { - return nil, fmt.Errorf("Could not resolve token to authorizer: %w", err) - } - - if err := authz.ToAllowAuthorizer().ServiceWriteAllowed(authReq.Target, &authzContext); err != nil { return nil, err } - - if !uriService.MatchesPartition(authReq.TargetPartition()) { - return nil, HTTPError{ - StatusCode: http.StatusBadRequest, - Reason: fmt.Sprintf("Mismatched partitions: %q != %q", - uriService.PartitionOrDefault(), - acl.PartitionOrDefault(authReq.TargetPartition())), - } - } - - // Get the intentions for this target service. - args := &structs.IntentionQueryRequest{ - Datacenter: s.agent.config.Datacenter, - Match: &structs.IntentionQueryMatch{ - Type: structs.IntentionMatchDestination, - Entries: []structs.IntentionMatchEntry{ - { - Namespace: authReq.TargetNamespace(), - Partition: authReq.TargetPartition(), - Name: authReq.Target, - }, - }, - }, - QueryOptions: structs.QueryOptions{Token: token}, - } - - raw, meta, err := s.agent.cache.Get(req.Context(), cachetype.IntentionMatchName, args) - if err != nil { - return nil, fmt.Errorf("failed getting intention match: %w", err) - } - - reply, ok := raw.(*structs.IndexedIntentionMatches) - if !ok { - return nil, fmt.Errorf("internal error: response type not correct") - } - if len(reply.Matches) != 1 { - return nil, fmt.Errorf("Internal error loading matches") - } - - // Figure out which source matches this request. - var ixnMatch *structs.Intention - for _, ixn := range reply.Matches[0] { - // We match on the intention source because the uriService is the source of the connection to authorize. - if _, ok := connect.AuthorizeIntentionTarget( - uriService.Service, uriService.Namespace, uriService.Partition, "", ixn, structs.IntentionMatchSource); ok { - ixnMatch = ixn - break - } - } - - var ( - authorized bool - reason string - ) - - if ixnMatch != nil { - if len(ixnMatch.Permissions) == 0 { - // This is an L4 intention. - reason = fmt.Sprintf("Matched L4 intention: %s", ixnMatch.String()) - authorized = ixnMatch.Action == structs.IntentionActionAllow - } else { - reason = fmt.Sprintf("Matched L7 intention: %s", ixnMatch.String()) - // This is an L7 intention, so DENY. - authorized = false - } - } else { - reason = "Default behavior configured by ACLs" - authorized = authz.IntentionDefaultAllow(nil) == acl.Allow - } - - setCacheMeta(resp, &meta) + setCacheMeta(resp, cacheMeta) return &connectAuthorizeResp{ - Authorized: authorized, + Authorized: authz, Reason: reason, }, nil } diff --git a/agent/agent_endpoint_ce.go b/agent/agent_endpoint_ce.go index 657d5122fe247..48b9c439cac47 100644 --- a/agent/agent_endpoint_ce.go +++ b/agent/agent_endpoint_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/agent_endpoint_ce_test.go b/agent/agent_endpoint_ce_test.go index 1b1dc866837fd..763a5a006049c 100644 --- a/agent/agent_endpoint_ce_test.go +++ b/agent/agent_endpoint_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go index ab9a44ff98774..5814cf9a8a9cd 100644 --- a/agent/agent_endpoint_test.go +++ b/agent/agent_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -21,6 +21,10 @@ import ( "time" "github.com/armon/go-metrics" + + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/version" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-uuid" "github.com/hashicorp/serf/serf" @@ -40,14 +44,12 @@ import ( "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/token" tokenStore "github.com/hashicorp/consul/agent/token" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/types" - "github.com/hashicorp/consul/version" ) func createACLTokenWithAgentReadPolicy(t *testing.T, srv *HTTPHandlers) string { @@ -79,46 +81,6 @@ func createACLTokenWithAgentReadPolicy(t *testing.T, srv *HTTPHandlers) string { return svcToken.SecretID } -func TestAgentEndpointsFailInV2(t *testing.T) { - t.Parallel() - - a := NewTestAgent(t, `experiments = ["resource-apis"]`) - - checkRequest := func(method, url string) { - t.Run(method+" "+url, func(t *testing.T) { - assertV1CatalogEndpointDoesNotWorkWithV2(t, a, method, url, `{}`) - }) - } - - t.Run("agent-self-with-params", func(t *testing.T) { - req, err := http.NewRequest("GET", "/v1/agent/self?dc=dc1", nil) - require.NoError(t, err) - - resp := httptest.NewRecorder() - a.srv.h.ServeHTTP(resp, req) - require.Equal(t, http.StatusOK, resp.Code) - - _, err = io.ReadAll(resp.Body) - require.NoError(t, err) - }) - - checkRequest("PUT", "/v1/agent/maintenance") - checkRequest("GET", "/v1/agent/services") - checkRequest("GET", "/v1/agent/service/web") - checkRequest("GET", "/v1/agent/checks") - checkRequest("GET", "/v1/agent/health/service/id/web") - checkRequest("GET", "/v1/agent/health/service/name/web") - checkRequest("PUT", "/v1/agent/check/register") - checkRequest("PUT", "/v1/agent/check/deregister/web") - checkRequest("PUT", "/v1/agent/check/pass/web") - checkRequest("PUT", "/v1/agent/check/warn/web") - checkRequest("PUT", "/v1/agent/check/fail/web") - checkRequest("PUT", "/v1/agent/check/update/web") - checkRequest("PUT", "/v1/agent/service/register") - checkRequest("PUT", "/v1/agent/service/deregister/web") - checkRequest("PUT", "/v1/agent/service/maintenance/web") -} - func TestAgent_Services(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") @@ -1638,37 +1600,14 @@ func TestAgent_Metrics_ACLDeny(t *testing.T) { }) } -func newDefaultBaseDeps(t *testing.T) BaseDeps { - dataDir := testutil.TempDir(t, "acl-agent") - logBuffer := testutil.NewLogBuffer(t) - logger := hclog.NewInterceptLogger(nil) - loader := func(source config.Source) (config.LoadResult, error) { - dataDir := fmt.Sprintf(`data_dir = "%s"`, dataDir) - opts := config.LoadOpts{ - HCL: []string{TestConfigHCL(NodeID()), "", dataDir}, - DefaultConfig: source, - } - result, err := config.Load(opts) - if result.RuntimeConfig != nil { - result.RuntimeConfig.Telemetry.Disable = true - } - return result, err - } - bd, err := NewBaseDeps(loader, logBuffer, logger) - require.NoError(t, err) - return bd -} - func TestHTTPHandlers_AgentMetricsStream_ACLDeny(t *testing.T) { - bd := newDefaultBaseDeps(t) + bd := BaseDeps{} bd.Tokens = new(tokenStore.Store) sink := metrics.NewInmemSink(30*time.Millisecond, time.Second) bd.MetricsConfig = &lib.MetricsConfig{ Handler: sink, } - mockDelegate := delegateMock{} - mockDelegate.On("LicenseCheck").Return() - d := fakeResolveTokenDelegate{delegate: &mockDelegate, authorizer: acl.DenyAll()} + d := fakeResolveTokenDelegate{authorizer: acl.DenyAll()} agent := &Agent{ baseDeps: bd, delegate: d, @@ -1691,15 +1630,13 @@ func TestHTTPHandlers_AgentMetricsStream_ACLDeny(t *testing.T) { } func TestHTTPHandlers_AgentMetricsStream(t *testing.T) { - bd := newDefaultBaseDeps(t) + bd := BaseDeps{} bd.Tokens = new(tokenStore.Store) sink := metrics.NewInmemSink(20*time.Millisecond, time.Second) bd.MetricsConfig = &lib.MetricsConfig{ Handler: sink, } - mockDelegate := delegateMock{} - mockDelegate.On("LicenseCheck").Return() - d := fakeResolveTokenDelegate{delegate: &mockDelegate, authorizer: acl.ManageAll()} + d := fakeResolveTokenDelegate{authorizer: acl.ManageAll()} agent := &Agent{ baseDeps: bd, delegate: d, diff --git a/agent/agent_test.go b/agent/agent_test.go index 0b17190dd611e..e952d9dd87a19 100644 --- a/agent/agent_test.go +++ b/agent/agent_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -58,7 +58,6 @@ import ( "github.com/hashicorp/consul/agent/token" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/internal/go-sso/oidcauth/oidcauthtest" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/ipaddr" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/proto/private/pbautoconf" @@ -324,7 +323,6 @@ func TestAgent_HTTPMaxHeaderBytes(t *testing.T) { Tokens: new(token.Store), TLSConfigurator: tlsConf, GRPCConnPool: &fakeGRPCConnPool{}, - Registry: resource.NewRegistry(), }, RuntimeConfig: &config.RuntimeConfig{ HTTPAddrs: []net.Addr{ @@ -348,9 +346,6 @@ func TestAgent_HTTPMaxHeaderBytes(t *testing.T) { a, err := New(bd) require.NoError(t, err) - mockDelegate := delegateMock{} - mockDelegate.On("LicenseCheck").Return() - a.delegate = &mockDelegate a.startLicenseManager(testutil.TestContext(t)) @@ -385,8 +380,6 @@ func TestAgent_HTTPMaxHeaderBytes(t *testing.T) { resp, err := client.Do(req.WithContext(ctx)) require.NoError(t, err) require.Equal(t, tt.expectedHTTPResponse, resp.StatusCode, "expected a '%d' http response, got '%d'", tt.expectedHTTPResponse, resp.StatusCode) - resp.Body.Close() - s.Shutdown(ctx) } }) } @@ -5559,7 +5552,6 @@ func TestAgent_ListenHTTP_MultipleAddresses(t *testing.T) { Tokens: new(token.Store), TLSConfigurator: tlsConf, GRPCConnPool: &fakeGRPCConnPool{}, - Registry: resource.NewRegistry(), }, RuntimeConfig: &config.RuntimeConfig{ HTTPAddrs: []net.Addr{ @@ -5582,9 +5574,6 @@ func TestAgent_ListenHTTP_MultipleAddresses(t *testing.T) { require.NoError(t, err) agent, err := New(bd) - mockDelegate := delegateMock{} - mockDelegate.On("LicenseCheck").Return() - agent.delegate = &mockDelegate require.NoError(t, err) agent.startLicenseManager(testutil.TestContext(t)) @@ -6159,7 +6148,6 @@ func TestAgent_startListeners(t *testing.T) { Logger: hclog.NewInterceptLogger(nil), Tokens: new(token.Store), GRPCConnPool: &fakeGRPCConnPool{}, - Registry: resource.NewRegistry(), }, RuntimeConfig: &config.RuntimeConfig{ HTTPAddrs: []net.Addr{}, @@ -6178,9 +6166,6 @@ func TestAgent_startListeners(t *testing.T) { require.NoError(t, err) agent, err := New(bd) - mockDelegate := delegateMock{} - mockDelegate.On("LicenseCheck").Return() - agent.delegate = &mockDelegate require.NoError(t, err) // use up an address @@ -6303,7 +6288,6 @@ func TestAgent_startListeners_scada(t *testing.T) { HCP: hcp.Deps{ Provider: pvd, }, - Registry: resource.NewRegistry(), }, RuntimeConfig: &config.RuntimeConfig{}, Cache: cache.New(cache.Options{}), @@ -6321,9 +6305,6 @@ func TestAgent_startListeners_scada(t *testing.T) { require.NoError(t, err) agent, err := New(bd) - mockDelegate := delegateMock{} - mockDelegate.On("LicenseCheck").Return() - agent.delegate = &mockDelegate require.NoError(t, err) _, err = agent.startListeners([]net.Addr{c}) @@ -6367,7 +6348,6 @@ func TestAgent_checkServerLastSeen(t *testing.T) { Logger: hclog.NewInterceptLogger(nil), Tokens: new(token.Store), GRPCConnPool: &fakeGRPCConnPool{}, - Registry: resource.NewRegistry(), }, RuntimeConfig: &config.RuntimeConfig{}, Cache: cache.New(cache.Options{}), @@ -6379,9 +6359,6 @@ func TestAgent_checkServerLastSeen(t *testing.T) { Config: leafcert.Config{}, }) agent, err := New(bd) - mockDelegate := delegateMock{} - mockDelegate.On("LicenseCheck").Return() - agent.delegate = &mockDelegate require.NoError(t, err) // Test that an ErrNotExist OS error is treated as ok. diff --git a/agent/apiserver.go b/agent/apiserver.go index 1f386e3f6b171..a45e16a630b1a 100644 --- a/agent/apiserver.go +++ b/agent/apiserver.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/apiserver_test.go b/agent/apiserver_test.go index 848487a78154c..69188c4248176 100644 --- a/agent/apiserver_test.go +++ b/agent/apiserver_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/auto-config/auto_config.go b/agent/auto-config/auto_config.go index a1a5848f623f0..b73951df70d18 100644 --- a/agent/auto-config/auto_config.go +++ b/agent/auto-config/auto_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/auto_config_ce.go b/agent/auto-config/auto_config_ce.go index 9ac615847e69f..78c9ee66d97ba 100644 --- a/agent/auto-config/auto_config_ce.go +++ b/agent/auto-config/auto_config_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package autoconf diff --git a/agent/auto-config/auto_config_ce_test.go b/agent/auto-config/auto_config_ce_test.go index a38b0f155e391..b075ca7686b6e 100644 --- a/agent/auto-config/auto_config_ce_test.go +++ b/agent/auto-config/auto_config_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package autoconf diff --git a/agent/auto-config/auto_config_test.go b/agent/auto-config/auto_config_test.go index 7c5c629be2f73..a5ab97e0f45d7 100644 --- a/agent/auto-config/auto_config_test.go +++ b/agent/auto-config/auto_config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/auto_encrypt.go b/agent/auto-config/auto_encrypt.go index 1b77c089f6f60..59af662ee033f 100644 --- a/agent/auto-config/auto_encrypt.go +++ b/agent/auto-config/auto_encrypt.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/auto_encrypt_test.go b/agent/auto-config/auto_encrypt_test.go index 10a7c8da46888..2c94b6a5540a0 100644 --- a/agent/auto-config/auto_encrypt_test.go +++ b/agent/auto-config/auto_encrypt_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/config.go b/agent/auto-config/config.go index 69eee08bc061b..d0f1670ab73a7 100644 --- a/agent/auto-config/config.go +++ b/agent/auto-config/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/config_ce.go b/agent/auto-config/config_ce.go index 5d699f32a498d..4162bda4c4896 100644 --- a/agent/auto-config/config_ce.go +++ b/agent/auto-config/config_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package autoconf diff --git a/agent/auto-config/config_translate.go b/agent/auto-config/config_translate.go index b60b3388eb2a8..31aeb7cbdb22f 100644 --- a/agent/auto-config/config_translate.go +++ b/agent/auto-config/config_translate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/config_translate_test.go b/agent/auto-config/config_translate_test.go index 8e2cef8c46ea9..9b37c9870e318 100644 --- a/agent/auto-config/config_translate_test.go +++ b/agent/auto-config/config_translate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/mock_ce_test.go b/agent/auto-config/mock_ce_test.go index ea416a3de87cf..872aa5e5438f5 100644 --- a/agent/auto-config/mock_ce_test.go +++ b/agent/auto-config/mock_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package autoconf diff --git a/agent/auto-config/mock_test.go b/agent/auto-config/mock_test.go index 0ef5084af2640..263befae112cb 100644 --- a/agent/auto-config/mock_test.go +++ b/agent/auto-config/mock_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/persist.go b/agent/auto-config/persist.go index 66cda1c41438c..0abaa235451d9 100644 --- a/agent/auto-config/persist.go +++ b/agent/auto-config/persist.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/run.go b/agent/auto-config/run.go index ed3389c1880cb..74a78fde9f0d8 100644 --- a/agent/auto-config/run.go +++ b/agent/auto-config/run.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/server_addr.go b/agent/auto-config/server_addr.go index 6bca15d42fb8d..c70a6431fb33e 100644 --- a/agent/auto-config/server_addr.go +++ b/agent/auto-config/server_addr.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/tls.go b/agent/auto-config/tls.go index 8142a1eeb809b..e39022bc959b7 100644 --- a/agent/auto-config/tls.go +++ b/agent/auto-config/tls.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/auto-config/tls_test.go b/agent/auto-config/tls_test.go index 667c7dfa96e5c..b09ee295e60be 100644 --- a/agent/auto-config/tls_test.go +++ b/agent/auto-config/tls_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autoconf diff --git a/agent/blockingquery/blockingquery.go b/agent/blockingquery/blockingquery.go index 3e073a1ffab2b..cb46110222de0 100644 --- a/agent/blockingquery/blockingquery.go +++ b/agent/blockingquery/blockingquery.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package blockingquery import ( diff --git a/agent/blockingquery/blockingquery_test.go b/agent/blockingquery/blockingquery_test.go index 5861ed3991641..6cfc07c114aa7 100644 --- a/agent/blockingquery/blockingquery_test.go +++ b/agent/blockingquery/blockingquery_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package blockingquery // TODO: move tests from the consul package, rpc_test.go, TestServer_blockingQuery diff --git a/agent/cache-types/catalog_datacenters.go b/agent/cache-types/catalog_datacenters.go index 2a4e64c9e5c1c..12da6e9878e3d 100644 --- a/agent/cache-types/catalog_datacenters.go +++ b/agent/cache-types/catalog_datacenters.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/catalog_datacenters_test.go b/agent/cache-types/catalog_datacenters_test.go index f04bfb4c7b421..bef374d131cda 100644 --- a/agent/cache-types/catalog_datacenters_test.go +++ b/agent/cache-types/catalog_datacenters_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/catalog_list_services.go b/agent/cache-types/catalog_list_services.go index 0a14ed3ef120a..a605c7431388c 100644 --- a/agent/cache-types/catalog_list_services.go +++ b/agent/cache-types/catalog_list_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/catalog_list_services_test.go b/agent/cache-types/catalog_list_services_test.go index 623cda2cee3ce..b5da270f962d3 100644 --- a/agent/cache-types/catalog_list_services_test.go +++ b/agent/cache-types/catalog_list_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/catalog_service_list.go b/agent/cache-types/catalog_service_list.go index 37ac4ba0f8131..521ed1d3b1ada 100644 --- a/agent/cache-types/catalog_service_list.go +++ b/agent/cache-types/catalog_service_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/catalog_service_list_test.go b/agent/cache-types/catalog_service_list_test.go index eb686193cc3ca..995f7e8b6c8c0 100644 --- a/agent/cache-types/catalog_service_list_test.go +++ b/agent/cache-types/catalog_service_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/catalog_services.go b/agent/cache-types/catalog_services.go index 8e04997b9f62d..21b472ba3124f 100644 --- a/agent/cache-types/catalog_services.go +++ b/agent/cache-types/catalog_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/catalog_services_test.go b/agent/cache-types/catalog_services_test.go index c084de67ccaad..8723b9015d719 100644 --- a/agent/cache-types/catalog_services_test.go +++ b/agent/cache-types/catalog_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/config_entry.go b/agent/cache-types/config_entry.go index 98443363c1b87..9748c176d1033 100644 --- a/agent/cache-types/config_entry.go +++ b/agent/cache-types/config_entry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/config_entry_test.go b/agent/cache-types/config_entry_test.go index d892b069e4c7b..11b109d6634a5 100644 --- a/agent/cache-types/config_entry_test.go +++ b/agent/cache-types/config_entry_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/connect_ca_root.go b/agent/cache-types/connect_ca_root.go index 9ba1dab0b7dcd..0d6c8b700ca72 100644 --- a/agent/cache-types/connect_ca_root.go +++ b/agent/cache-types/connect_ca_root.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype @@ -8,12 +8,11 @@ import ( "fmt" "github.com/hashicorp/consul/agent/cache" - "github.com/hashicorp/consul/agent/cacheshim" "github.com/hashicorp/consul/agent/structs" ) // Recommended name for registration. -const ConnectCARootName = cacheshim.ConnectCARootName +const ConnectCARootName = "connect-ca-root" // ConnectCARoot supports fetching the Connect CA roots. This is a // straightforward cache type since it only has to block on the given diff --git a/agent/cache-types/connect_ca_root_test.go b/agent/cache-types/connect_ca_root_test.go index 74aa53c31a4c7..c1e906a8b810f 100644 --- a/agent/cache-types/connect_ca_root_test.go +++ b/agent/cache-types/connect_ca_root_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/discovery_chain.go b/agent/cache-types/discovery_chain.go index e27b621061e1d..8f0f177914887 100644 --- a/agent/cache-types/discovery_chain.go +++ b/agent/cache-types/discovery_chain.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/discovery_chain_test.go b/agent/cache-types/discovery_chain_test.go index a9c9783e882bb..b2b279faf7ddd 100644 --- a/agent/cache-types/discovery_chain_test.go +++ b/agent/cache-types/discovery_chain_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/exported_peered_services.go b/agent/cache-types/exported_peered_services.go index 69bd2d92ba71f..3e8f336281446 100644 --- a/agent/cache-types/exported_peered_services.go +++ b/agent/cache-types/exported_peered_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/exported_peered_services_test.go b/agent/cache-types/exported_peered_services_test.go index a2d618bb60c52..4848c2fce9dbe 100644 --- a/agent/cache-types/exported_peered_services_test.go +++ b/agent/cache-types/exported_peered_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/federation_state_list_gateways.go b/agent/cache-types/federation_state_list_gateways.go index 501a8bcead289..50658777b8d83 100644 --- a/agent/cache-types/federation_state_list_gateways.go +++ b/agent/cache-types/federation_state_list_gateways.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/federation_state_list_gateways_test.go b/agent/cache-types/federation_state_list_gateways_test.go index 04bd661e80fc6..7aaad80ed3b2e 100644 --- a/agent/cache-types/federation_state_list_gateways_test.go +++ b/agent/cache-types/federation_state_list_gateways_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/gateway_services.go b/agent/cache-types/gateway_services.go index 9c13800beeee0..030cec59ef88d 100644 --- a/agent/cache-types/gateway_services.go +++ b/agent/cache-types/gateway_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/gateway_services_test.go b/agent/cache-types/gateway_services_test.go index 49be4edf47808..babc30ead3c14 100644 --- a/agent/cache-types/gateway_services_test.go +++ b/agent/cache-types/gateway_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/health_services.go b/agent/cache-types/health_services.go index ae8369364743e..dc1a5e6648ad5 100644 --- a/agent/cache-types/health_services.go +++ b/agent/cache-types/health_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/health_services_test.go b/agent/cache-types/health_services_test.go index 6e83ec9a40181..e3680eb2d5adb 100644 --- a/agent/cache-types/health_services_test.go +++ b/agent/cache-types/health_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/intention_match.go b/agent/cache-types/intention_match.go index fd69eab65c75a..16671328fd2da 100644 --- a/agent/cache-types/intention_match.go +++ b/agent/cache-types/intention_match.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/intention_match_test.go b/agent/cache-types/intention_match_test.go index 26788b679befb..68a467a29d511 100644 --- a/agent/cache-types/intention_match_test.go +++ b/agent/cache-types/intention_match_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/intention_upstreams.go b/agent/cache-types/intention_upstreams.go index a0e1ea0c0fd35..b918a553526ca 100644 --- a/agent/cache-types/intention_upstreams.go +++ b/agent/cache-types/intention_upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/intention_upstreams_destination.go b/agent/cache-types/intention_upstreams_destination.go index 1b5200a163c2c..8adba2d7e7426 100644 --- a/agent/cache-types/intention_upstreams_destination.go +++ b/agent/cache-types/intention_upstreams_destination.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/intention_upstreams_destination_test.go b/agent/cache-types/intention_upstreams_destination_test.go index 32852891846f0..d4f8602c7d7e9 100644 --- a/agent/cache-types/intention_upstreams_destination_test.go +++ b/agent/cache-types/intention_upstreams_destination_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/intention_upstreams_test.go b/agent/cache-types/intention_upstreams_test.go index 3259969f03a8f..6f695576d0639 100644 --- a/agent/cache-types/intention_upstreams_test.go +++ b/agent/cache-types/intention_upstreams_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/node_services.go b/agent/cache-types/node_services.go index 44dd5624f5658..2b51de9f62f89 100644 --- a/agent/cache-types/node_services.go +++ b/agent/cache-types/node_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/node_services_test.go b/agent/cache-types/node_services_test.go index 6f16f93d5d61f..a1412bbe935be 100644 --- a/agent/cache-types/node_services_test.go +++ b/agent/cache-types/node_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/options.go b/agent/cache-types/options.go index cd46060f8bce4..cbfa2ff178ef8 100644 --- a/agent/cache-types/options.go +++ b/agent/cache-types/options.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/peered_upstreams.go b/agent/cache-types/peered_upstreams.go index 964b350eb1505..49997ecdf9675 100644 --- a/agent/cache-types/peered_upstreams.go +++ b/agent/cache-types/peered_upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/peered_upstreams_test.go b/agent/cache-types/peered_upstreams_test.go index 07be6e4188082..1e9dc29fdf4a5 100644 --- a/agent/cache-types/peered_upstreams_test.go +++ b/agent/cache-types/peered_upstreams_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/peerings.go b/agent/cache-types/peerings.go index 53138e5512d8e..e72b43d563129 100644 --- a/agent/cache-types/peerings.go +++ b/agent/cache-types/peerings.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/peerings_test.go b/agent/cache-types/peerings_test.go index 088a077c4f504..75fc21371eb7d 100644 --- a/agent/cache-types/peerings_test.go +++ b/agent/cache-types/peerings_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/prepared_query.go b/agent/cache-types/prepared_query.go index 8a9ec7720959c..995214a1b45b4 100644 --- a/agent/cache-types/prepared_query.go +++ b/agent/cache-types/prepared_query.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/prepared_query_test.go b/agent/cache-types/prepared_query_test.go index 50850c20fe9bc..26ea4d4c0b028 100644 --- a/agent/cache-types/prepared_query_test.go +++ b/agent/cache-types/prepared_query_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/resolved_service_config.go b/agent/cache-types/resolved_service_config.go index 76c333840f5d3..589afbcc6bd1b 100644 --- a/agent/cache-types/resolved_service_config.go +++ b/agent/cache-types/resolved_service_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/resolved_service_config_test.go b/agent/cache-types/resolved_service_config_test.go index a71cdb7834362..4c8376447ad5f 100644 --- a/agent/cache-types/resolved_service_config_test.go +++ b/agent/cache-types/resolved_service_config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/rpc.go b/agent/cache-types/rpc.go index 13bfdb3e5a5d7..905547d20fe82 100644 --- a/agent/cache-types/rpc.go +++ b/agent/cache-types/rpc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/service_checks.go b/agent/cache-types/service_checks.go index 55ea3896f33cb..88a065c94b865 100644 --- a/agent/cache-types/service_checks.go +++ b/agent/cache-types/service_checks.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/service_checks_test.go b/agent/cache-types/service_checks_test.go index 898ea4aa9c937..b936990d91a33 100644 --- a/agent/cache-types/service_checks_test.go +++ b/agent/cache-types/service_checks_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/service_dump.go b/agent/cache-types/service_dump.go index 60c2895aff1f5..3bab11239f04b 100644 --- a/agent/cache-types/service_dump.go +++ b/agent/cache-types/service_dump.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/service_dump_test.go b/agent/cache-types/service_dump_test.go index 3570fc9720a16..8fe39e63b268e 100644 --- a/agent/cache-types/service_dump_test.go +++ b/agent/cache-types/service_dump_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/service_gateways.go b/agent/cache-types/service_gateways.go index a080fc77451ce..d096d136fa2fb 100644 --- a/agent/cache-types/service_gateways.go +++ b/agent/cache-types/service_gateways.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/service_gateways_test.go b/agent/cache-types/service_gateways_test.go index 9f615162b6fb3..c8c62e7c9ad5f 100644 --- a/agent/cache-types/service_gateways_test.go +++ b/agent/cache-types/service_gateways_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/testing.go b/agent/cache-types/testing.go index 3789eff4e2a5e..459feaba9fa37 100644 --- a/agent/cache-types/testing.go +++ b/agent/cache-types/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/trust_bundle.go b/agent/cache-types/trust_bundle.go index 0bac27e2b8c23..301b18977d95c 100644 --- a/agent/cache-types/trust_bundle.go +++ b/agent/cache-types/trust_bundle.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/trust_bundle_test.go b/agent/cache-types/trust_bundle_test.go index f39a15bdc6622..dc39c3555bd51 100644 --- a/agent/cache-types/trust_bundle_test.go +++ b/agent/cache-types/trust_bundle_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/trust_bundles.go b/agent/cache-types/trust_bundles.go index 7098c01af47ad..a485ee53414c0 100644 --- a/agent/cache-types/trust_bundles.go +++ b/agent/cache-types/trust_bundles.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache-types/trust_bundles_test.go b/agent/cache-types/trust_bundles_test.go index f565bab18fdbf..373ba2a8d71f0 100644 --- a/agent/cache-types/trust_bundles_test.go +++ b/agent/cache-types/trust_bundles_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cachetype diff --git a/agent/cache/cache.go b/agent/cache/cache.go index c78a3baaf0901..ed1e4f911ada0 100644 --- a/agent/cache/cache.go +++ b/agent/cache/cache.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package cache provides caching features for data from a Consul server. // @@ -32,7 +32,6 @@ import ( "golang.org/x/time/rate" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/cacheshim" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/ttlcache" ) @@ -173,7 +172,32 @@ type typeEntry struct { // ResultMeta is returned from Get calls along with the value and can be used // to expose information about the cache status for debugging or testing. -type ResultMeta = cacheshim.ResultMeta +type ResultMeta struct { + // Hit indicates whether or not the request was a cache hit + Hit bool + + // Age identifies how "stale" the result is. It's semantics differ based on + // whether or not the cache type performs background refresh or not as defined + // in https://www.consul.io/api/index.html#agent-caching. + // + // For background refresh types, Age is 0 unless the background blocking query + // is currently in a failed state and so not keeping up with the server's + // values. If it is non-zero it represents the time since the first failure to + // connect during background refresh, and is reset after a background request + // does manage to reconnect and either return successfully, or block for at + // least the yamux keepalive timeout of 30 seconds (which indicates the + // connection is OK but blocked as expected). + // + // For simple cache types, Age is the time since the result being returned was + // fetched from the servers. + Age time.Duration + + // Index is the internal ModifyIndex for the cache entry. Not all types + // support blocking and all that do will likely have this in their result type + // already but this allows generic code to reason about whether cache values + // have changed. + Index uint64 +} // Options are options for the Cache. type Options struct { diff --git a/agent/cache/cache_test.go b/agent/cache/cache_test.go index 6a4216c85929a..4ab66a29d0bf0 100644 --- a/agent/cache/cache_test.go +++ b/agent/cache/cache_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cache diff --git a/agent/cache/entry.go b/agent/cache/entry.go index 9ee1fc0007fa9..fb8008d8c15ee 100644 --- a/agent/cache/entry.go +++ b/agent/cache/entry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cache diff --git a/agent/cache/request.go b/agent/cache/request.go index 92f5b6e1ffa68..7f66f4ce58819 100644 --- a/agent/cache/request.go +++ b/agent/cache/request.go @@ -1,10 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cache import ( - "github.com/hashicorp/consul/agent/cacheshim" + "time" ) // Request is a cacheable request. @@ -13,7 +13,10 @@ import ( // the agent/structs package. // //go:generate mockery --name Request --inpackage -type Request = cacheshim.Request +type Request interface { + // CacheInfo returns information used for caching this request. + CacheInfo() RequestInfo +} // RequestInfo represents cache information for a request. The caching // framework uses this to control the behavior of caching and to determine @@ -21,4 +24,53 @@ type Request = cacheshim.Request // // TODO(peering): finish ensuring everything that sets a Datacenter sets or doesn't set PeerName. // TODO(peering): also make sure the peer name is present in the cache key likely in lieu of the datacenter somehow. -type RequestInfo = cacheshim.RequestInfo +type RequestInfo struct { + // Key is a unique cache key for this request. This key should + // be globally unique to identify this request, since any conflicting + // cache keys could result in invalid data being returned from the cache. + // The Key does not need to include ACL or DC information, since the + // cache already partitions by these values prior to using this key. + Key string + + // Token is the ACL token associated with this request. + // + // Datacenter is the datacenter that the request is targeting. + // + // PeerName is the peer that the request is targeting. + // + // All of these values are used to partition the cache. The cache framework + // today partitions data on these values to simplify behavior: by + // partitioning ACL tokens, the cache doesn't need to be smart about + // filtering results. By filtering datacenter/peer results, the cache can + // service the multi-DC/multi-peer nature of Consul. This comes at the expense of + // working set size, but in general the effect is minimal. + Token string + Datacenter string + PeerName string + + // MinIndex is the minimum index being queried. This is used to + // determine if we already have data satisfying the query or if we need + // to block until new data is available. If no index is available, the + // default value (zero) is acceptable. + MinIndex uint64 + + // Timeout is the timeout for waiting on a blocking query. When the + // timeout is reached, the last known value is returned (or maybe nil + // if there was no prior value). This "last known value" behavior matches + // normal Consul blocking queries. + Timeout time.Duration + + // MaxAge if set limits how stale a cache entry can be. If it is non-zero and + // there is an entry in cache that is older than specified, it is treated as a + // cache miss and re-fetched. It is ignored for cachetypes with Refresh = + // true. + MaxAge time.Duration + + // MustRevalidate forces a new lookup of the cache even if there is an + // existing one that has not expired. It is implied by HTTP requests with + // `Cache-Control: max-age=0` but we can't distinguish that case from the + // unset case for MaxAge. Later we may support revalidating the index without + // a full re-fetch but for now the only option is to refetch. It is ignored + // for cachetypes with Refresh = true. + MustRevalidate bool +} diff --git a/agent/cache/testing.go b/agent/cache/testing.go index b754dae3e76a2..7f0df113bc839 100644 --- a/agent/cache/testing.go +++ b/agent/cache/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cache diff --git a/agent/cache/type.go b/agent/cache/type.go index ccab3216ca837..d58362fd470d7 100644 --- a/agent/cache/type.go +++ b/agent/cache/type.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cache diff --git a/agent/cache/watch.go b/agent/cache/watch.go index 111ac85acb3ef..d8693ad032f99 100644 --- a/agent/cache/watch.go +++ b/agent/cache/watch.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cache @@ -9,17 +9,26 @@ import ( "reflect" "time" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/agent/cacheshim" "github.com/hashicorp/consul/lib" + "google.golang.org/protobuf/proto" ) // UpdateEvent is a struct summarizing an update to a cache entry -type UpdateEvent = cacheshim.UpdateEvent +type UpdateEvent struct { + // CorrelationID is used by the Notify API to allow correlation of updates + // with specific requests. We could return the full request object and + // cachetype for consumers to match against the calls they made but in + // practice it's cleaner for them to choose the minimal necessary unique + // identifier given the set of things they are watching. They might even + // choose to assign random IDs for example. + CorrelationID string + Result interface{} + Meta ResultMeta + Err error +} // Callback is the function type accepted by NotifyCallback. -type Callback = cacheshim.Callback +type Callback func(ctx context.Context, event UpdateEvent) // Notify registers a desire to be updated about changes to a cache result. // @@ -117,7 +126,7 @@ func (c *Cache) notifyBlockingQuery(ctx context.Context, r getOptions, correlati // Check the index of the value returned in the cache entry to be sure it // changed if index == 0 || index < meta.Index { - cb(ctx, UpdateEvent{CorrelationID: correlationID, Result: res, Meta: meta, Err: err}) + cb(ctx, UpdateEvent{correlationID, res, meta, err}) // Update index for next request index = meta.Index @@ -177,7 +186,7 @@ func (c *Cache) notifyPollingQuery(ctx context.Context, r getOptions, correlatio // Check for a change in the value or an index change if index < meta.Index || !isEqual(lastValue, res) { - cb(ctx, UpdateEvent{CorrelationID: correlationID, Result: res, Meta: meta, Err: err}) + cb(ctx, UpdateEvent{correlationID, res, meta, err}) // Update index and lastValue lastValue = res diff --git a/agent/cache/watch_test.go b/agent/cache/watch_test.go index 41c30f4dbb5cf..e6a5848f4ccdd 100644 --- a/agent/cache/watch_test.go +++ b/agent/cache/watch_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cache diff --git a/agent/cacheshim/cache.go b/agent/cacheshim/cache.go deleted file mode 100644 index 64754da644865..0000000000000 --- a/agent/cacheshim/cache.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package cacheshim - -import ( - "context" - "time" -) - -// cacheshim defines any shared cache types for any packages that don't want to have a dependency on the agent cache. -// This was created as part of a refactor to remove agent/leafcert package's dependency on agent/cache. - -type ResultMeta struct { - // Hit indicates whether or not the request was a cache hit - Hit bool - - // Age identifies how "stale" the result is. It's semantics differ based on - // whether or not the cache type performs background refresh or not as defined - // in https://www.consul.io/api/index.html#agent-caching. - // - // For background refresh types, Age is 0 unless the background blocking query - // is currently in a failed state and so not keeping up with the server's - // values. If it is non-zero it represents the time since the first failure to - // connect during background refresh, and is reset after a background request - // does manage to reconnect and either return successfully, or block for at - // least the yamux keepalive timeout of 30 seconds (which indicates the - // connection is OK but blocked as expected). - // - // For simple cache types, Age is the time since the result being returned was - // fetched from the servers. - Age time.Duration - - // Index is the internal ModifyIndex for the cache entry. Not all types - // support blocking and all that do will likely have this in their result type - // already but this allows generic code to reason about whether cache values - // have changed. - Index uint64 -} - -type Request interface { - // CacheInfo returns information used for caching this request. - CacheInfo() RequestInfo -} - -type RequestInfo struct { - // Key is a unique cache key for this request. This key should - // be globally unique to identify this request, since any conflicting - // cache keys could result in invalid data being returned from the cache. - // The Key does not need to include ACL or DC information, since the - // cache already partitions by these values prior to using this key. - Key string - - // Token is the ACL token associated with this request. - // - // Datacenter is the datacenter that the request is targeting. - // - // PeerName is the peer that the request is targeting. - // - // All of these values are used to partition the cache. The cache framework - // today partitions data on these values to simplify behavior: by - // partitioning ACL tokens, the cache doesn't need to be smart about - // filtering results. By filtering datacenter/peer results, the cache can - // service the multi-DC/multi-peer nature of Consul. This comes at the expense of - // working set size, but in general the effect is minimal. - Token string - Datacenter string - PeerName string - - // MinIndex is the minimum index being queried. This is used to - // determine if we already have data satisfying the query or if we need - // to block until new data is available. If no index is available, the - // default value (zero) is acceptable. - MinIndex uint64 - - // Timeout is the timeout for waiting on a blocking query. When the - // timeout is reached, the last known value is returned (or maybe nil - // if there was no prior value). This "last known value" behavior matches - // normal Consul blocking queries. - Timeout time.Duration - - // MaxAge if set limits how stale a cache entry can be. If it is non-zero and - // there is an entry in cache that is older than specified, it is treated as a - // cache miss and re-fetched. It is ignored for cachetypes with Refresh = - // true. - MaxAge time.Duration - - // MustRevalidate forces a new lookup of the cache even if there is an - // existing one that has not expired. It is implied by HTTP requests with - // `Cache-Control: max-age=0` but we can't distinguish that case from the - // unset case for MaxAge. Later we may support revalidating the index without - // a full re-fetch but for now the only option is to refetch. It is ignored - // for cachetypes with Refresh = true. - MustRevalidate bool -} - -type UpdateEvent struct { - // CorrelationID is used by the Notify API to allow correlation of updates - // with specific requests. We could return the full request object and - // cachetype for consumers to match against the calls they made but in - // practice it's cleaner for them to choose the minimal necessary unique - // identifier given the set of things they are watching. They might even - // choose to assign random IDs for example. - CorrelationID string - Result interface{} - Meta ResultMeta - Err error -} - -type Callback func(ctx context.Context, event UpdateEvent) - -type Cache interface { - Get(ctx context.Context, t string, r Request) (interface{}, ResultMeta, error) - NotifyCallback(ctx context.Context, t string, r Request, correlationID string, cb Callback) error - Notify(ctx context.Context, t string, r Request, correlationID string, ch chan<- UpdateEvent) error -} - -const ConnectCARootName = "connect-ca-root" diff --git a/agent/catalog_endpoint.go b/agent/catalog_endpoint.go index 1dac61befa475..ad72c4b47f353 100644 --- a/agent/catalog_endpoint.go +++ b/agent/catalog_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/catalog_endpoint_ce.go b/agent/catalog_endpoint_ce.go index 68433e2196d7c..fcd8311356d87 100644 --- a/agent/catalog_endpoint_ce.go +++ b/agent/catalog_endpoint_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/catalog_endpoint_test.go b/agent/catalog_endpoint_test.go index 19d520220427c..da65097dbb581 100644 --- a/agent/catalog_endpoint_test.go +++ b/agent/catalog_endpoint_test.go @@ -1,73 +1,29 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent import ( "context" "fmt" - "io" "net/http" "net/http/httptest" "net/url" - "strings" "testing" "time" + "github.com/hashicorp/consul/acl" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/serf/coordinate" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/testrpc" ) -func TestCatalogEndpointsFailInV2(t *testing.T) { - t.Parallel() - - a := NewTestAgent(t, `experiments = ["resource-apis"]`) - - checkRequest := func(method, url string) { - t.Run(method+" "+url, func(t *testing.T) { - assertV1CatalogEndpointDoesNotWorkWithV2(t, a, method, url, "{}") - }) - } - - checkRequest("PUT", "/v1/catalog/register") - checkRequest("GET", "/v1/catalog/connect/") - checkRequest("PUT", "/v1/catalog/deregister") - checkRequest("GET", "/v1/catalog/datacenters") - checkRequest("GET", "/v1/catalog/nodes") - checkRequest("GET", "/v1/catalog/services") - checkRequest("GET", "/v1/catalog/service/") - checkRequest("GET", "/v1/catalog/node/") - checkRequest("GET", "/v1/catalog/node-services/") - checkRequest("GET", "/v1/catalog/gateway-services/") -} - -func assertV1CatalogEndpointDoesNotWorkWithV2(t *testing.T, a *TestAgent, method, url string, requestBody string) { - var body io.Reader - switch method { - case http.MethodPost, http.MethodPut: - body = strings.NewReader(requestBody + "\n") - } - - req, err := http.NewRequest(method, url, body) - require.NoError(t, err) - - resp := httptest.NewRecorder() - a.srv.h.ServeHTTP(resp, req) - require.Equal(t, http.StatusBadRequest, resp.Code) - - got, err := io.ReadAll(resp.Body) - require.NoError(t, err) - - require.Contains(t, string(got), structs.ErrUsingV2CatalogExperiment.Error()) -} - func TestCatalogRegister_PeeringRegistration(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") diff --git a/agent/check.go b/agent/check.go index 078361be66010..79c030d932424 100644 --- a/agent/check.go +++ b/agent/check.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/checks/alias.go b/agent/checks/alias.go index f75c05b9580bb..5e394105cf1c9 100644 --- a/agent/checks/alias.go +++ b/agent/checks/alias.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/alias_test.go b/agent/checks/alias_test.go index 1f5662019929a..70a301d1180ff 100644 --- a/agent/checks/alias_test.go +++ b/agent/checks/alias_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/check.go b/agent/checks/check.go index cabecddcf5a21..c6472f1fb97e5 100644 --- a/agent/checks/check.go +++ b/agent/checks/check.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/check_test.go b/agent/checks/check_test.go index ae53b477f5554..389b4cb14100a 100644 --- a/agent/checks/check_test.go +++ b/agent/checks/check_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/check_windows_test.go b/agent/checks/check_windows_test.go index 2f6d40f243648..b7c14dd18e853 100644 --- a/agent/checks/check_windows_test.go +++ b/agent/checks/check_windows_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build windows +// +build windows package checks diff --git a/agent/checks/docker.go b/agent/checks/docker.go index e3483e073b037..11bcac7e01c84 100644 --- a/agent/checks/docker.go +++ b/agent/checks/docker.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/docker_unix.go b/agent/checks/docker_unix.go index 6d169f2bbc3cd..33c8a2b817223 100644 --- a/agent/checks/docker_unix.go +++ b/agent/checks/docker_unix.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !windows +// +build !windows package checks diff --git a/agent/checks/docker_windows.go b/agent/checks/docker_windows.go index 6008b695ba1b0..edcb4f380a988 100644 --- a/agent/checks/docker_windows.go +++ b/agent/checks/docker_windows.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/grpc.go b/agent/checks/grpc.go index b3bcba20b5a61..87378521c9dfa 100644 --- a/agent/checks/grpc.go +++ b/agent/checks/grpc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/grpc_test.go b/agent/checks/grpc_test.go index e67b453bda62a..4500bcd67f3b5 100644 --- a/agent/checks/grpc_test.go +++ b/agent/checks/grpc_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/os_service.go b/agent/checks/os_service.go index 3350c73a2c3b4..af4e9b03ee873 100644 --- a/agent/checks/os_service.go +++ b/agent/checks/os_service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package checks diff --git a/agent/checks/os_service_unix.go b/agent/checks/os_service_unix.go index 4c61ac0babc7e..ab004e29fd9c3 100644 --- a/agent/checks/os_service_unix.go +++ b/agent/checks/os_service_unix.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !windows +// +build !windows package checks diff --git a/agent/checks/os_service_windows.go b/agent/checks/os_service_windows.go index f142ea698ec5c..8b73ce4ad2091 100644 --- a/agent/checks/os_service_windows.go +++ b/agent/checks/os_service_windows.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build windows +// +build windows package checks diff --git a/agent/config/agent_limits.go b/agent/config/agent_limits.go index 7abbb075d3166..fff5e267f203c 100644 --- a/agent/config/agent_limits.go +++ b/agent/config/agent_limits.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/builder.go b/agent/config/builder.go index 9d55696d8d88c..089da4bedd47b 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config @@ -882,7 +882,6 @@ func (b *builder) build() (rt RuntimeConfig, err error) { ACLAgentRecoveryToken: stringVal(c.ACL.Tokens.AgentRecovery), ACLReplicationToken: stringVal(c.ACL.Tokens.Replication), ACLConfigFileRegistrationToken: stringVal(c.ACL.Tokens.ConfigFileRegistration), - ACLDNSToken: stringVal(c.ACL.Tokens.DNS), }, // Autopilot @@ -1137,15 +1136,6 @@ func (b *builder) build() (rt RuntimeConfig, err error) { return RuntimeConfig{}, fmt.Errorf("cache.entry_fetch_rate must be strictly positive, was: %v", rt.Cache.EntryFetchRate) } - // TODO(CC-6389): Remove once resource-apis is no longer considered experimental and is supported by HCP - if stringslice.Contains(rt.Experiments, consul.CatalogResourceExperimentName) && rt.IsCloudEnabled() { - // Allow override of this check for development/testing purposes. Should not be used in production - override, err := strconv.ParseBool(os.Getenv("CONSUL_OVERRIDE_HCP_RESOURCE_APIS_CHECK")) - if err != nil || !override { - return RuntimeConfig{}, fmt.Errorf("`experiments` cannot include 'resource-apis' when HCP `cloud` configuration is set") - } - } - if rt.UIConfig.MetricsProvider == "prometheus" { // Handle defaulting for the built-in version of prometheus. if len(rt.UIConfig.MetricsProxy.PathAllowlist) == 0 { @@ -1302,10 +1292,6 @@ func (b *builder) validate(rt RuntimeConfig) error { "1 and 63 bytes.", rt.NodeName) } - if err := rt.StructLocality().Validate(); err != nil { - return fmt.Errorf("locality is invalid: %s", err) - } - if ipaddr.IsAny(rt.AdvertiseAddrLAN.IP) { return fmt.Errorf("Advertise address cannot be 0.0.0.0, :: or [::]") } @@ -1416,7 +1402,7 @@ func (b *builder) validate(rt RuntimeConfig) error { // Raft LogStore validation if rt.RaftLogStoreConfig.Backend != consul.LogStoreBackendBoltDB && - rt.RaftLogStoreConfig.Backend != consul.LogStoreBackendWAL && rt.RaftLogStoreConfig.Backend != consul.LogStoreBackendDefault { + rt.RaftLogStoreConfig.Backend != consul.LogStoreBackendWAL { return fmt.Errorf("raft_logstore.backend must be one of '%s' or '%s'", consul.LogStoreBackendBoltDB, consul.LogStoreBackendWAL) } @@ -1485,7 +1471,7 @@ func (b *builder) validate(rt RuntimeConfig) error { return err } case structs.VaultCAProvider: - if _, err := ca.ParseVaultCAConfig(rt.ConnectCAConfig, rt.PrimaryDatacenter == rt.Datacenter); err != nil { + if _, err := ca.ParseVaultCAConfig(rt.ConnectCAConfig); err != nil { return err } case structs.AWSCAProvider: @@ -2562,7 +2548,7 @@ func (b *builder) cloudConfigVal(v Config) hcpconfig.CloudConfig { val := hcpconfig.CloudConfig{ ResourceID: os.Getenv("HCP_RESOURCE_ID"), } - // Node id might get overridden in setup.go:142 + // Node id might get overriden in setup.go:142 nodeID := stringVal(v.NodeID) val.NodeID = types.NodeID(nodeID) val.NodeName = b.nodeName(v.NodeName) @@ -2666,10 +2652,10 @@ func (b *builder) buildTLSConfig(rt RuntimeConfig, t TLS) (tlsutil.Config, error return c, errors.New("verify_outgoing is not valid in the tls.grpc stanza") } - // Similarly, only the internal RPC and defaults configuration honor VerifyServerHostname + // Similarly, only the internal RPC configuration honors VerifyServerHostname // so we call it out here too. - if t.GRPC.VerifyServerHostname != nil || t.HTTPS.VerifyServerHostname != nil { - return c, errors.New("verify_server_hostname is only valid in the tls.defaults and tls.internal_rpc stanzas") + if t.Defaults.VerifyServerHostname != nil || t.GRPC.VerifyServerHostname != nil || t.HTTPS.VerifyServerHostname != nil { + return c, errors.New("verify_server_hostname is only valid in the tls.internal_rpc stanza") } // And UseAutoCert right now only applies to external gRPC interface. @@ -2719,11 +2705,8 @@ func (b *builder) buildTLSConfig(rt RuntimeConfig, t TLS) (tlsutil.Config, error } mapCommon("internal_rpc", t.InternalRPC, &c.InternalRPC) + c.InternalRPC.VerifyServerHostname = boolVal(t.InternalRPC.VerifyServerHostname) - c.InternalRPC.VerifyServerHostname = boolVal(t.Defaults.VerifyServerHostname) - if t.InternalRPC.VerifyServerHostname != nil { - c.InternalRPC.VerifyServerHostname = boolVal(t.InternalRPC.VerifyServerHostname) - } // Setting only verify_server_hostname is documented to imply verify_outgoing. // If it doesn't then we risk sending communication over plain TCP when we // documented it as forcing TLS for RPCs. Enforce this here rather than in @@ -2784,7 +2767,7 @@ func (b *builder) parsePrefixFilter(telemetry *Telemetry) ([]string, []string) { func (b *builder) raftLogStoreConfigVal(raw *RaftLogStoreRaw) consul.RaftLogStoreConfig { var cfg consul.RaftLogStoreConfig if raw != nil { - cfg.Backend = stringValWithDefault(raw.Backend, consul.LogStoreBackendDefault) + cfg.Backend = stringValWithDefault(raw.Backend, consul.LogStoreBackendBoltDB) cfg.DisableLogCache = boolVal(raw.DisableLogCache) cfg.Verification.Enabled = boolVal(raw.Verification.Enabled) diff --git a/agent/config/builder_ce.go b/agent/config/builder_ce.go index 068e02f0ce8b1..dae1e275c96a6 100644 --- a/agent/config/builder_ce.go +++ b/agent/config/builder_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package config diff --git a/agent/config/builder_ce_test.go b/agent/config/builder_ce_test.go index 9c3114ddc18ea..100f905859da6 100644 --- a/agent/config/builder_ce_test.go +++ b/agent/config/builder_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package config diff --git a/agent/config/builder_test.go b/agent/config/builder_test.go index 6f8fdc9598a0f..3eb81fdee4de6 100644 --- a/agent/config/builder_test.go +++ b/agent/config/builder_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config @@ -575,72 +575,3 @@ func TestBuidler_hostMetricsWithCloud(t *testing.T) { require.NotNil(t, cfg) require.True(t, cfg.Telemetry.EnableHostMetrics) } - -func TestBuilder_WarnCloudConfigWithResourceApis(t *testing.T) { - tests := []struct { - name string - hcl string - expectErr bool - override bool - }{ - { - name: "base_case", - hcl: ``, - }, - { - name: "resource-apis_no_cloud", - hcl: `experiments = ["resource-apis"]`, - }, - { - name: "cloud-config_no_experiments", - hcl: `cloud{ resource_id = "abc" client_id = "abc" client_secret = "abc"}`, - }, - { - name: "cloud-config_resource-apis_experiment", - hcl: ` - experiments = ["resource-apis"] - cloud{ resource_id = "abc" client_id = "abc" client_secret = "abc"}`, - expectErr: true, - }, - { - name: "cloud-config_other_experiment", - hcl: ` - experiments = ["test"] - cloud{ resource_id = "abc" client_id = "abc" client_secret = "abc"}`, - }, - { - name: "cloud-config_resource-apis_experiment_override", - hcl: ` - experiments = ["resource-apis"] - cloud{ resource_id = "abc" client_id = "abc" client_secret = "abc"}`, - override: true, - }, - } - for _, tc := range tests { - // using dev mode skips the need for a data dir - devMode := true - builderOpts := LoadOpts{ - DevMode: &devMode, - Overrides: []Source{ - FileSource{ - Name: "overrides", - Format: "hcl", - Data: tc.hcl, - }, - }, - } - if tc.override { - os.Setenv("CONSUL_OVERRIDE_HCP_RESOURCE_APIS_CHECK", "1") - } - _, err := Load(builderOpts) - if tc.override { - os.Unsetenv("CONSUL_OVERRIDE_HCP_RESOURCE_APIS_CHECK") - } - if tc.expectErr { - require.Error(t, err) - require.Contains(t, err.Error(), "cannot include 'resource-apis' when HCP") - } else { - require.NoError(t, err) - } - } -} diff --git a/agent/config/config.deepcopy.go b/agent/config/config.deepcopy.go index 2a5ebfce276c7..9e6b3e06ffd77 100644 --- a/agent/config/config.deepcopy.go +++ b/agent/config/config.deepcopy.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - // generated by deep-copy -pointer-receiver -o ./config.deepcopy.go -type RuntimeConfig ./; DO NOT EDIT. package config diff --git a/agent/config/config.go b/agent/config/config.go index eb82397d718c2..dbd5c2e4fd24f 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config @@ -780,7 +780,6 @@ type Tokens struct { Default *string `mapstructure:"default"` Agent *string `mapstructure:"agent"` ConfigFileRegistration *string `mapstructure:"config_file_service_registration"` - DNS *string `mapstructure:"dns"` // Enterprise Only ManagedServiceProvider []ServiceProviderToken `mapstructure:"managed_service_provider"` diff --git a/agent/config/config_ce.go b/agent/config/config_ce.go index a60a49be25db5..2fc8da58e6da8 100644 --- a/agent/config/config_ce.go +++ b/agent/config/config_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package config diff --git a/agent/config/deep-copy.sh b/agent/config/deep-copy.sh index 159dcf9535d6b..f69b95da931dc 100644 --- a/agent/config/deep-copy.sh +++ b/agent/config/deep-copy.sh @@ -1,6 +1,4 @@ #!/usr/bin/env bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 readonly PACKAGE_DIR="$(dirname "${BASH_SOURCE[0]}")" cd $PACKAGE_DIR diff --git a/agent/config/default.go b/agent/config/default.go index f07a8bdf46dcf..f4f1141638cef 100644 --- a/agent/config/default.go +++ b/agent/config/default.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config @@ -147,6 +147,7 @@ func DefaultSource() Source { raft_snapshot_interval = "` + cfg.RaftConfig.SnapshotInterval.String() + `" raft_trailing_logs = ` + strconv.Itoa(int(cfg.RaftConfig.TrailingLogs)) + ` raft_logstore { + backend = "boltdb" wal { segment_size_mb = 64 } @@ -210,7 +211,9 @@ func DevSource() Source { ports = { grpc = 8502 } - experiments = [] + experiments = [ + "resource-apis" + ] `, } } diff --git a/agent/config/default_ce.go b/agent/config/default_ce.go index 34caf4b52b71a..f91bb9c7d3600 100644 --- a/agent/config/default_ce.go +++ b/agent/config/default_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package config diff --git a/agent/config/deprecated.go b/agent/config/deprecated.go index 921e3329ffa6b..597095f8e2642 100644 --- a/agent/config/deprecated.go +++ b/agent/config/deprecated.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/deprecated_test.go b/agent/config/deprecated_test.go index 8d03e431f7afb..785c9555084f2 100644 --- a/agent/config/deprecated_test.go +++ b/agent/config/deprecated_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/doc.go b/agent/config/doc.go index 5bfc77d902528..4cbc2c41cfdcb 100644 --- a/agent/config/doc.go +++ b/agent/config/doc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package config contains the command line and config file code for the // consul agent. diff --git a/agent/config/file_watcher.go b/agent/config/file_watcher.go index 2afe19b1a659a..c91bb1dd50cc7 100644 --- a/agent/config/file_watcher.go +++ b/agent/config/file_watcher.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/file_watcher_test.go b/agent/config/file_watcher_test.go index f937d1401195a..02b1cd14117be 100644 --- a/agent/config/file_watcher_test.go +++ b/agent/config/file_watcher_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/flags.go b/agent/config/flags.go index b56a162287c0c..21e1ac612a530 100644 --- a/agent/config/flags.go +++ b/agent/config/flags.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/flags_test.go b/agent/config/flags_test.go index a6c9ee23bd4aa..10df0d6d7f005 100644 --- a/agent/config/flags_test.go +++ b/agent/config/flags_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/flagset.go b/agent/config/flagset.go index af1b06d70ce9a..3b2abe6fdf9a2 100644 --- a/agent/config/flagset.go +++ b/agent/config/flagset.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/golden_test.go b/agent/config/golden_test.go index a9ce20d7bd1af..fb4401efbf4d7 100644 --- a/agent/config/golden_test.go +++ b/agent/config/golden_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/limits.go b/agent/config/limits.go index baad156e63c5d..6b5d466ab639a 100644 --- a/agent/config/limits.go +++ b/agent/config/limits.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !windows +// +build !windows package config diff --git a/agent/config/limits_windows.go b/agent/config/limits_windows.go index f0efc27eaf9a0..d9d3499397b56 100644 --- a/agent/config/limits_windows.go +++ b/agent/config/limits_windows.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build windows +// +build windows package config diff --git a/agent/config/merge.go b/agent/config/merge.go index 64c7c1e974964..f40efdaa87793 100644 --- a/agent/config/merge.go +++ b/agent/config/merge.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/merge_test.go b/agent/config/merge_test.go index 9c2e2a1a07363..13e3cbb186ece 100644 --- a/agent/config/merge_test.go +++ b/agent/config/merge_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/ratelimited_file_watcher.go b/agent/config/ratelimited_file_watcher.go index 41f894837035f..33de08cf2b62e 100644 --- a/agent/config/ratelimited_file_watcher.go +++ b/agent/config/ratelimited_file_watcher.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/ratelimited_file_watcher_test.go b/agent/config/ratelimited_file_watcher_test.go index 8e4415aaa8712..d6a43b6be82be 100644 --- a/agent/config/ratelimited_file_watcher_test.go +++ b/agent/config/ratelimited_file_watcher_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/runtime.go b/agent/config/runtime.go index 954aa7198e253..9c8588e1848dd 100644 --- a/agent/config/runtime.go +++ b/agent/config/runtime.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/config/runtime_ce.go b/agent/config/runtime_ce.go index 4fb54ae079c20..94a6b7fa6a62c 100644 --- a/agent/config/runtime_ce.go +++ b/agent/config/runtime_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package config diff --git a/agent/config/runtime_ce_test.go b/agent/config/runtime_ce_test.go index af6bb1f8babe2..99a2f6789e134 100644 --- a/agent/config/runtime_ce_test.go +++ b/agent/config/runtime_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package config diff --git a/agent/config/runtime_test.go b/agent/config/runtime_test.go index 13497b04fc4a7..553bc5b06bb3f 100644 --- a/agent/config/runtime_test.go +++ b/agent/config/runtime_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config @@ -324,7 +324,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) { rt.DevMode = true rt.DisableAnonymousSignature = true rt.DisableKeyringFile = true - rt.Experiments = nil + rt.Experiments = []string{"resource-apis"} rt.EnableDebug = true rt.UIConfig.Enabled = true rt.LeaveOnTerm = false @@ -1038,13 +1038,6 @@ func TestLoad_IntegrationWithFlags(t *testing.T) { }, }, }) - run(t, testCase{ - desc: "locality invalid", - args: []string{`-data-dir=` + dataDir}, - json: []string{`{"locality": {"zone": "us-west-1a"}}`}, - hcl: []string{`locality { zone = "us-west-1a" }`}, - expectedErr: "locality is invalid: zone cannot be set without region", - }) run(t, testCase{ desc: "client addr and ports == 0", args: []string{`-data-dir=` + dataDir}, @@ -2790,44 +2783,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) { } } `}, - expected: func(rt *RuntimeConfig) { - rt.DataDir = dataDir - rt.TLS.InternalRPC.VerifyServerHostname = true - rt.TLS.InternalRPC.VerifyOutgoing = true - }, - }) - run(t, testCase{ - desc: "verify_server_hostname in the defaults stanza and internal_rpc", - args: []string{ - `-data-dir=` + dataDir, - }, - hcl: []string{` - tls { - defaults { - verify_server_hostname = false - }, - internal_rpc { - verify_server_hostname = true - } - } - `}, - json: []string{` - { - "tls": { - "defaults": { - "verify_server_hostname": false - }, - "internal_rpc": { - "verify_server_hostname": true - } - } - } - `}, - expected: func(rt *RuntimeConfig) { - rt.DataDir = dataDir - rt.TLS.InternalRPC.VerifyServerHostname = true - rt.TLS.InternalRPC.VerifyOutgoing = true - }, + expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza", }) run(t, testCase{ desc: "verify_server_hostname in the grpc stanza", @@ -2850,7 +2806,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) { } } `}, - expectedErr: "verify_server_hostname is only valid in the tls.defaults and tls.internal_rpc stanza", + expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza", }) run(t, testCase{ desc: "verify_server_hostname in the https stanza", @@ -2873,7 +2829,7 @@ func TestLoad_IntegrationWithFlags(t *testing.T) { } } `}, - expectedErr: "verify_server_hostname is only valid in the tls.defaults and tls.internal_rpc stanza", + expectedErr: "verify_server_hostname is only valid in the tls.internal_rpc stanza", }) run(t, testCase{ desc: "translated keys", @@ -5814,74 +5770,6 @@ func TestLoad_IntegrationWithFlags(t *testing.T) { rt.TLS.InternalRPC.VerifyOutgoing = true }, }) - run(t, testCase{ - desc: "tls.defaults.verify_server_hostname implies tls.internal_rpc.verify_outgoing", - args: []string{ - `-data-dir=` + dataDir, - }, - json: []string{` - { - "tls": { - "defaults": { - "verify_server_hostname": true - } - } - } - `}, - hcl: []string{` - tls { - defaults { - verify_server_hostname = true - } - } - `}, - expected: func(rt *RuntimeConfig) { - rt.DataDir = dataDir - - rt.TLS.Domain = "consul." - rt.TLS.NodeName = "thehostname" - - rt.TLS.InternalRPC.VerifyServerHostname = true - rt.TLS.InternalRPC.VerifyOutgoing = true - }, - }) - run(t, testCase{ - desc: "tls.internal_rpc.verify_server_hostname overwrites tls.defaults.verify_server_hostname", - args: []string{ - `-data-dir=` + dataDir, - }, - json: []string{` - { - "tls": { - "defaults": { - "verify_server_hostname": false - }, - "internal_rpc": { - "verify_server_hostname": true - } - } - } - `}, - hcl: []string{` - tls { - defaults { - verify_server_hostname = false - }, - internal_rpc { - verify_server_hostname = true - } - } - `}, - expected: func(rt *RuntimeConfig) { - rt.DataDir = dataDir - - rt.TLS.Domain = "consul." - rt.TLS.NodeName = "thehostname" - - rt.TLS.InternalRPC.VerifyServerHostname = true - rt.TLS.InternalRPC.VerifyOutgoing = true - }, - }) run(t, testCase{ desc: "tls.grpc.use_auto_cert defaults to false", args: []string{ @@ -6010,26 +5898,8 @@ func TestLoad_IntegrationWithFlags(t *testing.T) { hcl: []string{``}, expected: func(rt *RuntimeConfig) { rt.DataDir = dataDir - rt.RaftLogStoreConfig.Backend = consul.LogStoreBackendDefault - rt.RaftLogStoreConfig.WAL.SegmentSize = 64 * 1024 * 1024 - }, - }) - run(t, testCase{ - desc: "logstore defaults", - args: []string{ - `-data-dir=` + dataDir, - }, - json: []string{` - { - "experiments": ["resource-apis"] - } - `}, - hcl: []string{`experiments=["resource-apis"]`}, - expected: func(rt *RuntimeConfig) { - rt.DataDir = dataDir - rt.RaftLogStoreConfig.Backend = consul.LogStoreBackendDefault + rt.RaftLogStoreConfig.Backend = consul.LogStoreBackendBoltDB rt.RaftLogStoreConfig.WAL.SegmentSize = 64 * 1024 * 1024 - rt.Experiments = []string{"resource-apis"} }, }) run(t, testCase{ diff --git a/agent/config/segment_ce.go b/agent/config/segment_ce.go index 78ba9b87c7fdc..5f8e8cff7d8fc 100644 --- a/agent/config/segment_ce.go +++ b/agent/config/segment_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package config diff --git a/agent/config/segment_ce_test.go b/agent/config/segment_ce_test.go index f58781338184a..1fbaf3c2ae0bb 100644 --- a/agent/config/segment_ce_test.go +++ b/agent/config/segment_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package config diff --git a/agent/config/testdata/TestRuntimeConfig_Sanitize.golden b/agent/config/testdata/TestRuntimeConfig_Sanitize.golden index 56397ad94d0f0..ace159197051c 100644 --- a/agent/config/testdata/TestRuntimeConfig_Sanitize.golden +++ b/agent/config/testdata/TestRuntimeConfig_Sanitize.golden @@ -17,7 +17,6 @@ "ACLAgentRecoveryToken": "hidden", "ACLAgentToken": "hidden", "ACLConfigFileRegistrationToken": "hidden", - "ACLDNSToken": "hidden", "ACLDefaultToken": "hidden", "ACLReplicationToken": "hidden", "DataDir": "", diff --git a/agent/config/testdata/full-config.hcl b/agent/config/testdata/full-config.hcl index b008ad3db63f0..14df10487611e 100644 --- a/agent/config/testdata/full-config.hcl +++ b/agent/config/testdata/full-config.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 acl_agent_master_token = "furuQD0b" acl_agent_token = "cOshLOQ2" diff --git a/agent/config_endpoint.go b/agent/config_endpoint.go index e1b3f0eeef415..396215d78d990 100644 --- a/agent/config_endpoint.go +++ b/agent/config_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/config_endpoint_test.go b/agent/config_endpoint_test.go index 43a8ec206e9fe..f8c0c01e329a1 100644 --- a/agent/config_endpoint_test.go +++ b/agent/config_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -19,23 +19,6 @@ import ( "github.com/hashicorp/consul/testrpc" ) -func TestConfigEndpointsFailInV2(t *testing.T) { - t.Parallel() - - a := NewTestAgent(t, `experiments = ["resource-apis"]`) - - checkRequest := func(method, url string) { - t.Run(method+" "+url, func(t *testing.T) { - assertV1CatalogEndpointDoesNotWorkWithV2(t, a, method, url, `{"kind":"service-defaults", "name":"web"}`) - }) - } - - checkRequest("GET", "/v1/config/service-defaults") - checkRequest("GET", "/v1/config/service-defaults/web") - checkRequest("DELETE", "/v1/config/service-defaults/web") - checkRequest("PUT", "/v1/config") -} - func TestConfig_Get(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") diff --git a/agent/configentry/compare.go b/agent/configentry/compare.go index 3bf761dba828d..f28d5c9b03d94 100644 --- a/agent/configentry/compare.go +++ b/agent/configentry/compare.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package configentry import ( diff --git a/agent/configentry/compare_test.go b/agent/configentry/compare_test.go index eeeec32f853b4..fcb63d0fa86e7 100644 --- a/agent/configentry/compare_test.go +++ b/agent/configentry/compare_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package configentry import ( diff --git a/agent/configentry/config_entry.go b/agent/configentry/config_entry.go index b10989aa95d79..a4ebb254e0407 100644 --- a/agent/configentry/config_entry.go +++ b/agent/configentry/config_entry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry diff --git a/agent/configentry/discoverychain.go b/agent/configentry/discoverychain.go index 58bdb81fc20ca..d66b6590e0a42 100644 --- a/agent/configentry/discoverychain.go +++ b/agent/configentry/discoverychain.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry diff --git a/agent/configentry/doc.go b/agent/configentry/doc.go index 7dff4a06621b5..18fd1405ab18c 100644 --- a/agent/configentry/doc.go +++ b/agent/configentry/doc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package configentry contains structs and logic related to the Configuration // Entry subsystem. Currently this is restricted to structs used during diff --git a/agent/configentry/merge_service_config.go b/agent/configentry/merge_service_config.go index d36c152105af3..cc692e789b372 100644 --- a/agent/configentry/merge_service_config.go +++ b/agent/configentry/merge_service_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry @@ -7,7 +7,7 @@ import ( "fmt" "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-memdb" + memdb "github.com/hashicorp/go-memdb" "github.com/imdario/mergo" "github.com/mitchellh/copystructure" @@ -26,22 +26,32 @@ type StateStore interface { func MergeNodeServiceWithCentralConfig( ws memdb.WatchSet, state StateStore, - unmergedNS *structs.NodeService, + ns *structs.NodeService, logger hclog.Logger) (uint64, *structs.NodeService, error) { - ns := unmergedNS.WithNormalizedUpstreams() serviceName := ns.Service + var upstreams []structs.PeeredServiceName if ns.IsSidecarProxy() { // This is a sidecar proxy, ignore the proxy service's config since we are // managed by the target service config. serviceName = ns.Proxy.DestinationServiceName - } - var upstreams []structs.PeeredServiceName - for _, us := range ns.Proxy.Upstreams { - if us.DestinationType == "" || us.DestinationType == structs.UpstreamDestTypeService { - upstreams = append(upstreams, us.DestinationID()) + + // Also if we have any upstreams defined, add them to the defaults lookup request + // so we can learn about their configs. + for _, us := range ns.Proxy.Upstreams { + if us.DestinationType == "" || us.DestinationType == structs.UpstreamDestTypeService { + psn := us.DestinationID() + if psn.Peer == "" { + psn.ServiceName.EnterpriseMeta.Merge(&ns.EnterpriseMeta) + } else { + // Peer services should not have their namespace overwritten. + psn.ServiceName.EnterpriseMeta.OverridePartition(ns.EnterpriseMeta.PartitionOrDefault()) + } + upstreams = append(upstreams, psn) + } } } + configReq := &structs.ServiceConfigRequest{ Name: serviceName, MeshGateway: ns.Proxy.MeshGateway, @@ -131,10 +141,6 @@ func MergeServiceConfig(defaults *structs.ServiceConfigResponse, service *struct ns.Proxy.EnvoyExtensions = nsExtensions } - if ratelimit := defaults.RateLimits.ToEnvoyExtension(); ratelimit != nil { - ns.Proxy.EnvoyExtensions = append(ns.Proxy.EnvoyExtensions, *ratelimit) - } - if ns.Proxy.MeshGateway.Mode == structs.MeshGatewayModeDefault { ns.Proxy.MeshGateway.Mode = defaults.MeshGateway.Mode } diff --git a/agent/configentry/merge_service_config_test.go b/agent/configentry/merge_service_config_test.go index e9f051d0026af..4f6dbb55488a2 100644 --- a/agent/configentry/merge_service_config_test.go +++ b/agent/configentry/merge_service_config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry @@ -972,111 +972,3 @@ func Test_MergeServiceConfig_UpstreamOverrides(t *testing.T) { }) } } - -// Tests that RateLimit config is a no-op in non-enterprise. -// In practice, the ratelimit config would have been validated -// on write. -func Test_MergeServiceConfig_RateLimit(t *testing.T) { - rl := structs.RateLimits{ - InstanceLevel: structs.InstanceLevelRateLimits{ - RequestsPerSecond: 1234, - RequestsMaxBurst: 2345, - Routes: []structs.InstanceLevelRouteRateLimits{ - { - PathExact: "/admin", - RequestsPerSecond: 3333, - RequestsMaxBurst: 4444, - }, - }, - }, - } - tests := []struct { - name string - defaults *structs.ServiceConfigResponse - service *structs.NodeService - want *structs.NodeService - }{ - { - name: "injects ratelimit extension", - defaults: &structs.ServiceConfigResponse{ - RateLimits: rl, - }, - service: &structs.NodeService{ - ID: "foo-proxy", - Service: "foo-proxy", - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "foo", - DestinationServiceID: "foo", - }, - }, - want: &structs.NodeService{ - ID: "foo-proxy", - Service: "foo-proxy", - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "foo", - DestinationServiceID: "foo", - EnvoyExtensions: func() []structs.EnvoyExtension { - if ext := rl.ToEnvoyExtension(); ext != nil { - return []structs.EnvoyExtension{*ext} - } - return nil - }(), - }, - }, - }, - { - name: "injects ratelimit extension at the end", - defaults: &structs.ServiceConfigResponse{ - RateLimits: rl, - EnvoyExtensions: []structs.EnvoyExtension{ - { - Name: "existing-ext", - Required: true, - Arguments: map[string]interface{}{ - "arg1": "val1", - }, - }, - }, - }, - service: &structs.NodeService{ - ID: "foo-proxy", - Service: "foo-proxy", - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "foo", - DestinationServiceID: "foo", - }, - }, - - want: &structs.NodeService{ - ID: "foo-proxy", - Service: "foo-proxy", - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "foo", - DestinationServiceID: "foo", - EnvoyExtensions: func() []structs.EnvoyExtension { - existing := []structs.EnvoyExtension{ - { - Name: "existing-ext", - Required: true, - Arguments: map[string]interface{}{ - "arg1": "val1", - }, - }, - } - if ext := rl.ToEnvoyExtension(); ext != nil { - existing = append(existing, *ext) - } - return existing - }(), - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := MergeServiceConfig(tt.defaults, tt.service) - require.NoError(t, err) - assert.Equal(t, tt.want, got) - }) - } -} diff --git a/agent/configentry/resolve.go b/agent/configentry/resolve.go index 82efc3b8bd759..882f1d16b5489 100644 --- a/agent/configentry/resolve.go +++ b/agent/configentry/resolve.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry @@ -117,9 +117,6 @@ func ComputeResolvedServiceConfig( if serviceConf.Destination != nil { thisReply.Destination = *serviceConf.Destination } - if serviceConf.RateLimits != nil { - thisReply.RateLimits = *serviceConf.RateLimits - } // Populate values for the proxy config map proxyConf := thisReply.ProxyConfig diff --git a/agent/configentry/resolve_test.go b/agent/configentry/resolve_test.go index f93649df8ae7b..f0457730eaa06 100644 --- a/agent/configentry/resolve_test.go +++ b/agent/configentry/resolve_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry diff --git a/agent/configentry/service_config.go b/agent/configentry/service_config.go index 83e24e27c390b..4b7e5e2a27c1d 100644 --- a/agent/configentry/service_config.go +++ b/agent/configentry/service_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry diff --git a/agent/connect/authz.go b/agent/connect/authz.go index cc14dd0cb61d1..74b306354faf1 100644 --- a/agent/connect/authz.go +++ b/agent/connect/authz.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/authz_test.go b/agent/connect/authz_test.go index 1cbf17517d819..6428acfc4722e 100644 --- a/agent/connect/authz_test.go +++ b/agent/connect/authz_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/ca/common.go b/agent/connect/ca/common.go index f52b030ed977e..b83a196a8a235 100644 --- a/agent/connect/ca/common.go +++ b/agent/connect/ca/common.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider.go b/agent/connect/ca/provider.go index 898da46af7290..2ef34228bc483 100644 --- a/agent/connect/ca/provider.go +++ b/agent/connect/ca/provider.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca @@ -152,7 +152,7 @@ type PrimaryProvider interface { SignIntermediate(*x509.CertificateRequest) (string, error) // CrossSignCA must accept a CA certificate from another CA provider and cross - // sign it exactly as it is such that it forms a chain back the + // sign it exactly as it is such that it forms a chain back the the // CAProvider's current root. Specifically, the Distinguished Name, Subject // Alternative Name, SubjectKeyID and other relevant extensions must be kept. // The resulting certificate must have a distinct Serial Number and the diff --git a/agent/connect/ca/provider_aws.go b/agent/connect/ca/provider_aws.go index 1ce5a5eba57d8..d45f3295a8e74 100644 --- a/agent/connect/ca/provider_aws.go +++ b/agent/connect/ca/provider_aws.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_aws_test.go b/agent/connect/ca/provider_aws_test.go index d46221af1fce9..cba2897fa26a4 100644 --- a/agent/connect/ca/provider_aws_test.go +++ b/agent/connect/ca/provider_aws_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_consul.go b/agent/connect/ca/provider_consul.go index a4aba91942bf4..01c4987e07d81 100644 --- a/agent/connect/ca/provider_consul.go +++ b/agent/connect/ca/provider_consul.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_consul_config.go b/agent/connect/ca/provider_consul_config.go index c7e8b0346cdb9..b0998a0aa11b6 100644 --- a/agent/connect/ca/provider_consul_config.go +++ b/agent/connect/ca/provider_consul_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_consul_test.go b/agent/connect/ca/provider_consul_test.go index 658a97d39bd97..0c6959c7f5d41 100644 --- a/agent/connect/ca/provider_consul_test.go +++ b/agent/connect/ca/provider_consul_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_test.go b/agent/connect/ca/provider_test.go index 85deedbf4cb57..b7ed9e29b412d 100644 --- a/agent/connect/ca/provider_test.go +++ b/agent/connect/ca/provider_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca @@ -113,7 +113,7 @@ func TestStructs_CAConfiguration_MsgpackEncodeDecode(t *testing.T) { TLSSkipVerify: true, }, parseFunc: func(t *testing.T, raw map[string]interface{}) interface{} { - config, err := ParseVaultCAConfig(raw, true) + config, err := ParseVaultCAConfig(raw) require.NoError(t, err) return config }, diff --git a/agent/connect/ca/provider_vault.go b/agent/connect/ca/provider_vault.go index 692b9a568c236..542b2c55d0839 100644 --- a/agent/connect/ca/provider_vault.go +++ b/agent/connect/ca/provider_vault.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca @@ -99,7 +99,7 @@ func vaultTLSConfig(config *structs.VaultCAProviderConfig) *vaultapi.TLSConfig { // Configure sets up the provider using the given configuration. // Configure supports being called multiple times to re-configure the provider. func (v *VaultProvider) Configure(cfg ProviderConfig) error { - config, err := ParseVaultCAConfig(cfg.RawConfig, v.isPrimary) + config, err := ParseVaultCAConfig(cfg.RawConfig) if err != nil { return err } @@ -196,11 +196,11 @@ func (v *VaultProvider) Configure(cfg ProviderConfig) error { } func (v *VaultProvider) ValidateConfigUpdate(prevRaw, nextRaw map[string]interface{}) error { - prev, err := ParseVaultCAConfig(prevRaw, v.isPrimary) + prev, err := ParseVaultCAConfig(prevRaw) if err != nil { return fmt.Errorf("failed to parse existing CA config: %w", err) } - next, err := ParseVaultCAConfig(nextRaw, v.isPrimary) + next, err := ParseVaultCAConfig(nextRaw) if err != nil { return fmt.Errorf("failed to parse new CA config: %w", err) } @@ -848,7 +848,7 @@ func (v *VaultProvider) Cleanup(providerTypeChange bool, otherConfig map[string] v.Stop() if !providerTypeChange { - newConfig, err := ParseVaultCAConfig(otherConfig, v.isPrimary) + newConfig, err := ParseVaultCAConfig(otherConfig) if err != nil { return err } @@ -941,7 +941,7 @@ func (v *VaultProvider) autotidyIssuers(path string) (bool, string) { return tidySet, errStr } -func ParseVaultCAConfig(raw map[string]interface{}, isPrimary bool) (*structs.VaultCAProviderConfig, error) { +func ParseVaultCAConfig(raw map[string]interface{}) (*structs.VaultCAProviderConfig, error) { config := structs.VaultCAProviderConfig{ CommonCAProviderConfig: defaultCommonConfig(), } @@ -972,10 +972,10 @@ func ParseVaultCAConfig(raw map[string]interface{}, isPrimary bool) (*structs.Va return nil, fmt.Errorf("only one of Vault token or Vault auth method can be provided, but not both") } - if isPrimary && config.RootPKIPath == "" { + if config.RootPKIPath == "" { return nil, fmt.Errorf("must provide a valid path to a root PKI backend") } - if config.RootPKIPath != "" && !strings.HasSuffix(config.RootPKIPath, "/") { + if !strings.HasSuffix(config.RootPKIPath, "/") { config.RootPKIPath += "/" } diff --git a/agent/connect/ca/provider_vault_auth.go b/agent/connect/ca/provider_vault_auth.go index 70176cc3c328a..ddfbde34070c7 100644 --- a/agent/connect/ca/provider_vault_auth.go +++ b/agent/connect/ca/provider_vault_auth.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_auth_alicloud.go b/agent/connect/ca/provider_vault_auth_alicloud.go index d6ae5b185ed38..1c30583179254 100644 --- a/agent/connect/ca/provider_vault_auth_alicloud.go +++ b/agent/connect/ca/provider_vault_auth_alicloud.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_auth_approle.go b/agent/connect/ca/provider_vault_auth_approle.go index c3d7d8f9c8ac8..150c463aea9aa 100644 --- a/agent/connect/ca/provider_vault_auth_approle.go +++ b/agent/connect/ca/provider_vault_auth_approle.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_auth_aws.go b/agent/connect/ca/provider_vault_auth_aws.go index 61762b36fd618..02abf39824cb5 100644 --- a/agent/connect/ca/provider_vault_auth_aws.go +++ b/agent/connect/ca/provider_vault_auth_aws.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_auth_azure.go b/agent/connect/ca/provider_vault_auth_azure.go index ac8d326b32790..8025977007f4d 100644 --- a/agent/connect/ca/provider_vault_auth_azure.go +++ b/agent/connect/ca/provider_vault_auth_azure.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_auth_gcp.go b/agent/connect/ca/provider_vault_auth_gcp.go index 10dfbf4b294a7..5eefc7143663f 100644 --- a/agent/connect/ca/provider_vault_auth_gcp.go +++ b/agent/connect/ca/provider_vault_auth_gcp.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_auth_jwt.go b/agent/connect/ca/provider_vault_auth_jwt.go index e80751cd59c3d..2560f856d82af 100644 --- a/agent/connect/ca/provider_vault_auth_jwt.go +++ b/agent/connect/ca/provider_vault_auth_jwt.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_auth_k8s.go b/agent/connect/ca/provider_vault_auth_k8s.go index acd6f68bc5ddc..c3a69c6ccd44b 100644 --- a/agent/connect/ca/provider_vault_auth_k8s.go +++ b/agent/connect/ca/provider_vault_auth_k8s.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_auth_test.go b/agent/connect/ca/provider_vault_auth_test.go index 361d89400e22c..74507acb39e7b 100644 --- a/agent/connect/ca/provider_vault_auth_test.go +++ b/agent/connect/ca/provider_vault_auth_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/ca/provider_vault_test.go b/agent/connect/ca/provider_vault_test.go index edd094f5502a7..9316f65602fe1 100644 --- a/agent/connect/ca/provider_vault_test.go +++ b/agent/connect/ca/provider_vault_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca @@ -62,7 +62,6 @@ func TestVaultCAProvider_ParseVaultCAConfig(t *testing.T) { cases := map[string]struct { rawConfig map[string]interface{} expConfig *structs.VaultCAProviderConfig - isPrimary bool expError string }{ "no token and no auth method provided": { @@ -73,26 +72,15 @@ func TestVaultCAProvider_ParseVaultCAConfig(t *testing.T) { rawConfig: map[string]interface{}{"Token": "test", "AuthMethod": map[string]interface{}{"Type": "test"}}, expError: "only one of Vault token or Vault auth method can be provided, but not both", }, - "primary no root PKI path": { - rawConfig: map[string]interface{}{"Token": "test", "IntermediatePKIPath": "test"}, - isPrimary: true, + "no root PKI path": { + rawConfig: map[string]interface{}{"Token": "test"}, expError: "must provide a valid path to a root PKI backend", }, - "secondary no root PKI path": { - rawConfig: map[string]interface{}{"Token": "test", "IntermediatePKIPath": "test"}, - isPrimary: false, - expConfig: &structs.VaultCAProviderConfig{ - CommonCAProviderConfig: defaultCommonConfig(), - Token: "test", - IntermediatePKIPath: "test/", - }, - }, "no root intermediate path": { rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test"}, expError: "must provide a valid path for the intermediate PKI backend", }, "adds a slash to RootPKIPath and IntermediatePKIPath": { - isPrimary: true, rawConfig: map[string]interface{}{"Token": "test", "RootPKIPath": "test", "IntermediatePKIPath": "test"}, expConfig: &structs.VaultCAProviderConfig{ CommonCAProviderConfig: defaultCommonConfig(), @@ -105,7 +93,7 @@ func TestVaultCAProvider_ParseVaultCAConfig(t *testing.T) { for name, c := range cases { t.Run(name, func(t *testing.T) { - config, err := ParseVaultCAConfig(c.rawConfig, c.isPrimary) + config, err := ParseVaultCAConfig(c.rawConfig) if c.expError != "" { require.EqualError(t, err, c.expError) } else { @@ -637,6 +625,12 @@ func TestVaultCAProvider_CrossSignCA(t *testing.T) { run := func(t *testing.T, tc CASigningKeyTypes, withSudo, expectFailure bool) { t.Parallel() + if tc.SigningKeyType != tc.CSRKeyType { + // TODO: uncomment since the bug is closed + // See https://github.com/hashicorp/vault/issues/7709 + t.Skip("Vault doesn't support cross-signing different key types yet.") + } + testVault1 := NewTestVaultServer(t) attr1 := &VaultTokenAttributes{ @@ -1270,6 +1264,11 @@ func TestVaultCAProvider_DeletePreviousIssuerAndKey(t *testing.T) { }) res, err := testVault.Client().Logical().List("pki-intermediate/issuers") require.NoError(t, err) + + if res == nil { + t.Skip("Vault version < 1.11 does not have multi issuers functionality") + } + // Why 2 issuers? There is always an initial issuer that // gets created before we manage the lifecycle of issuers. // Since we're asserting that the number doesn't grow diff --git a/agent/connect/ca/testing.go b/agent/connect/ca/testing.go index 7386deea94944..f588106287660 100644 --- a/agent/connect/ca/testing.go +++ b/agent/connect/ca/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/agent/connect/common_names.go b/agent/connect/common_names.go index c52df9f10fb49..3c4c30633d533 100644 --- a/agent/connect/common_names.go +++ b/agent/connect/common_names.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/csr.go b/agent/connect/csr.go index 0a491b0b65522..9cf0d884dea7b 100644 --- a/agent/connect/csr.go +++ b/agent/connect/csr.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/csr_test.go b/agent/connect/csr_test.go index 1833b78a77985..6aef985f006fe 100644 --- a/agent/connect/csr_test.go +++ b/agent/connect/csr_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/generate.go b/agent/connect/generate.go index 84c91a246846b..819428d147a9c 100644 --- a/agent/connect/generate.go +++ b/agent/connect/generate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/generate_test.go b/agent/connect/generate_test.go index ca956b702f165..67be6081fe08c 100644 --- a/agent/connect/generate_test.go +++ b/agent/connect/generate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/parsing.go b/agent/connect/parsing.go index f1e89fe0255bc..a89544532fbb1 100644 --- a/agent/connect/parsing.go +++ b/agent/connect/parsing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect @@ -148,7 +148,7 @@ func ParseSigner(pemValue string) (crypto.Signer, error) { } // ParseCSR parses a CSR from a PEM-encoded value. The certificate request -// must be the first block in the PEM value. +// must be the the first block in the PEM value. func ParseCSR(pemValue string) (*x509.CertificateRequest, error) { // The _ result below is not an error but the remaining PEM bytes. block, _ := pem.Decode([]byte(pemValue)) diff --git a/agent/connect/sni.go b/agent/connect/sni.go index f7d14800a922f..339116b64c038 100644 --- a/agent/connect/sni.go +++ b/agent/connect/sni.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/sni_test.go b/agent/connect/sni_test.go index ed0bd07280417..acbfd49ce028e 100644 --- a/agent/connect/sni_test.go +++ b/agent/connect/sni_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/testing_ca.go b/agent/connect/testing_ca.go index a852d9130c87b..7b30d85176478 100644 --- a/agent/connect/testing_ca.go +++ b/agent/connect/testing_ca.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/testing_ca_test.go b/agent/connect/testing_ca_test.go index 9b62a2baee54b..492ca9e32d93b 100644 --- a/agent/connect/testing_ca_test.go +++ b/agent/connect/testing_ca_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/testing_spiffe.go b/agent/connect/testing_spiffe.go index fdbff5eda67d7..f48222c443f9c 100644 --- a/agent/connect/testing_spiffe.go +++ b/agent/connect/testing_spiffe.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/uri.go b/agent/connect/uri.go index bc898f78654f4..ce44967432f61 100644 --- a/agent/connect/uri.go +++ b/agent/connect/uri.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect @@ -23,8 +23,6 @@ type CertURI interface { } var ( - spiffeIDWorkloadIdentityRegexp = regexp.MustCompile( - `^(?:/ap/([^/]+))/ns/([^/]+)/identity/([^/]+)$`) spiffeIDServiceRegexp = regexp.MustCompile( `^(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/]+)$`) spiffeIDAgentRegexp = regexp.MustCompile( @@ -96,32 +94,6 @@ func ParseCertURI(input *url.URL) (CertURI, error) { Datacenter: dc, Service: service, }, nil - } else if v := spiffeIDWorkloadIdentityRegexp.FindStringSubmatch(path); v != nil { - // Determine the values. We assume they're reasonable to save cycles, - // but if the raw path is not empty that means that something is - // URL encoded so we go to the slow path. - ap := v[1] - ns := v[2] - workloadIdentity := v[3] - if input.RawPath != "" { - var err error - if ap, err = url.PathUnescape(v[1]); err != nil { - return nil, fmt.Errorf("Invalid admin partition: %s", err) - } - if ns, err = url.PathUnescape(v[2]); err != nil { - return nil, fmt.Errorf("Invalid namespace: %s", err) - } - if workloadIdentity, err = url.PathUnescape(v[3]); err != nil { - return nil, fmt.Errorf("Invalid workload identity: %s", err) - } - } - - return &SpiffeIDWorkloadIdentity{ - TrustDomain: input.Host, - Partition: ap, - Namespace: ns, - WorkloadIdentity: workloadIdentity, - }, nil } else if v := spiffeIDAgentRegexp.FindStringSubmatch(path); v != nil { // Determine the values. We assume they're reasonable to save cycles, // but if the raw path is not empty that means that something is diff --git a/agent/connect/uri_agent.go b/agent/connect/uri_agent.go index 1babf99873809..c3d3a86bf115c 100644 --- a/agent/connect/uri_agent.go +++ b/agent/connect/uri_agent.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/uri_agent_ce.go b/agent/connect/uri_agent_ce.go index 70e775f6e4975..2a87d108432fb 100644 --- a/agent/connect/uri_agent_ce.go +++ b/agent/connect/uri_agent_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package connect diff --git a/agent/connect/uri_agent_ce_test.go b/agent/connect/uri_agent_ce_test.go index 026d4bc173031..57f1286fd1e1a 100644 --- a/agent/connect/uri_agent_ce_test.go +++ b/agent/connect/uri_agent_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package connect diff --git a/agent/connect/uri_mesh_gateway.go b/agent/connect/uri_mesh_gateway.go index d5cf155bf8d7c..ec474efa40851 100644 --- a/agent/connect/uri_mesh_gateway.go +++ b/agent/connect/uri_mesh_gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/uri_mesh_gateway_ce.go b/agent/connect/uri_mesh_gateway_ce.go index 48c43326f1450..876e05101b6b6 100644 --- a/agent/connect/uri_mesh_gateway_ce.go +++ b/agent/connect/uri_mesh_gateway_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package connect diff --git a/agent/connect/uri_mesh_gateway_ce_test.go b/agent/connect/uri_mesh_gateway_ce_test.go index bb4579cdc641c..593de8ef31053 100644 --- a/agent/connect/uri_mesh_gateway_ce_test.go +++ b/agent/connect/uri_mesh_gateway_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package connect diff --git a/agent/connect/uri_server.go b/agent/connect/uri_server.go index 5a2b9c2429283..894ad63784bfe 100644 --- a/agent/connect/uri_server.go +++ b/agent/connect/uri_server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/uri_service.go b/agent/connect/uri_service.go index b35d1e0df437d..31bd3e5df62ba 100644 --- a/agent/connect/uri_service.go +++ b/agent/connect/uri_service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect @@ -8,7 +8,6 @@ import ( "net/url" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/proto-public/pbresource" ) // SpiffeIDService is the structure to represent the SPIFFE ID for a service. @@ -53,14 +52,3 @@ func (id SpiffeIDService) uriPath() string { } return path } - -// SpiffeIDFromIdentityRef creates the SPIFFE ID from a workload identity. -// TODO (ishustava): make sure ref type is workload identity. -func SpiffeIDFromIdentityRef(trustDomain string, ref *pbresource.Reference) string { - return SpiffeIDWorkloadIdentity{ - TrustDomain: trustDomain, - Partition: ref.Tenancy.Partition, - Namespace: ref.Tenancy.Namespace, - WorkloadIdentity: ref.Name, - }.URI().String() -} diff --git a/agent/connect/uri_service_ce.go b/agent/connect/uri_service_ce.go index 6aafde36a60e9..4106fc811b38c 100644 --- a/agent/connect/uri_service_ce.go +++ b/agent/connect/uri_service_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package connect diff --git a/agent/connect/uri_service_ce_test.go b/agent/connect/uri_service_ce_test.go index 8368454db5237..7d73151edc032 100644 --- a/agent/connect/uri_service_ce_test.go +++ b/agent/connect/uri_service_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package connect diff --git a/agent/connect/uri_signing.go b/agent/connect/uri_signing.go index 1913ae6bdfdfe..24330a3d70b12 100644 --- a/agent/connect/uri_signing.go +++ b/agent/connect/uri_signing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect @@ -51,20 +51,14 @@ func (id SpiffeIDSigning) CanSign(cu CertURI) bool { // worry about Unicode domains if we start allowing customisation beyond the // built-in cluster ids. return strings.ToLower(other.Host) == id.Host() - case *SpiffeIDWorkloadIdentity: - // The trust domain component of the workload identity SPIFFE ID must be an exact match for now under - // ascii case folding (since hostnames are case-insensitive). Later we might - // worry about Unicode domains if we start allowing customisation beyond the - // built-in cluster ids. - return strings.ToLower(other.TrustDomain) == id.Host() case *SpiffeIDMeshGateway: - // The host component of the mesh gateway SPIFFE ID must be an exact match for now under + // The host component of the service must be an exact match for now under // ascii case folding (since hostnames are case-insensitive). Later we might // worry about Unicode domains if we start allowing customisation beyond the // built-in cluster ids. return strings.ToLower(other.Host) == id.Host() case *SpiffeIDServer: - // The host component of the server SPIFFE ID must be an exact match for now under + // The host component of the service must be an exact match for now under // ascii case folding (since hostnames are case-insensitive). Later we might // worry about Unicode domains if we start allowing customisation beyond the // built-in cluster ids. diff --git a/agent/connect/uri_signing_test.go b/agent/connect/uri_signing_test.go index 737ca460542b7..ba426173160ea 100644 --- a/agent/connect/uri_signing_test.go +++ b/agent/connect/uri_signing_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect @@ -98,30 +98,6 @@ func TestSpiffeIDSigning_CanSign(t *testing.T) { input: &SpiffeIDService{Host: TestClusterID + ".fake", Namespace: "default", Datacenter: "dc1", Service: "web"}, want: false, }, - { - name: "workload - good", - id: testSigning, - input: &SpiffeIDWorkloadIdentity{TrustDomain: TestClusterID + ".consul", Namespace: "default", WorkloadIdentity: "web"}, - want: true, - }, - { - name: "workload - good mixed case", - id: testSigning, - input: &SpiffeIDWorkloadIdentity{TrustDomain: strings.ToUpper(TestClusterID) + ".CONsuL", Namespace: "defAUlt", WorkloadIdentity: "WEB"}, - want: true, - }, - { - name: "workload - different cluster", - id: testSigning, - input: &SpiffeIDWorkloadIdentity{TrustDomain: "55555555-4444-3333-2222-111111111111.consul", Namespace: "default", WorkloadIdentity: "web"}, - want: false, - }, - { - name: "workload - different TLD", - id: testSigning, - input: &SpiffeIDWorkloadIdentity{TrustDomain: TestClusterID + ".fake", Namespace: "default", WorkloadIdentity: "web"}, - want: false, - }, { name: "mesh gateway - good", id: testSigning, diff --git a/agent/connect/uri_test.go b/agent/connect/uri_test.go index 52116845975bb..2ea439f53668c 100644 --- a/agent/connect/uri_test.go +++ b/agent/connect/uri_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect @@ -51,61 +51,6 @@ func TestParseCertURIFromString(t *testing.T) { }, ParseError: "", }, - { - Name: "basic workload ID", - URI: "spiffe://1234.consul/ap/default/ns/default/identity/web", - Struct: &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - Partition: defaultEntMeta.PartitionOrDefault(), - Namespace: "default", - WorkloadIdentity: "web", - }, - ParseError: "", - }, - { - Name: "basic workload ID with nondefault partition", - URI: "spiffe://1234.consul/ap/bizdev/ns/default/identity/web", - Struct: &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - Partition: "bizdev", - Namespace: "default", - WorkloadIdentity: "web", - }, - ParseError: "", - }, - { - Name: "workload ID error - missing identity", - URI: "spiffe://1234.consul/ns/default", - Struct: &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - Partition: defaultEntMeta.PartitionOrDefault(), - Namespace: "default", - WorkloadIdentity: "web", - }, - ParseError: "SPIFFE ID is not in the expected format", - }, - { - Name: "workload ID error - missing partition", - URI: "spiffe://1234.consul/ns/default/identity/web", - Struct: &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - Partition: defaultEntMeta.PartitionOrDefault(), - Namespace: "default", - WorkloadIdentity: "web", - }, - ParseError: "SPIFFE ID is not in the expected format", - }, - { - Name: "workload ID error - missing namespace", - URI: "spiffe://1234.consul/ap/default/identity/web", - Struct: &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - Partition: defaultEntMeta.PartitionOrDefault(), - Namespace: "default", - WorkloadIdentity: "web", - }, - ParseError: "SPIFFE ID is not in the expected format", - }, { Name: "basic agent ID", URI: "spiffe://1234.consul/agent/client/dc/dc1/id/uuid", diff --git a/agent/connect/uri_workload_identity.go b/agent/connect/uri_workload_identity.go deleted file mode 100644 index 48afd1f534b27..0000000000000 --- a/agent/connect/uri_workload_identity.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package connect - -import ( - "fmt" - "net/url" - - "github.com/hashicorp/consul/acl" -) - -// SpiffeIDWorkloadIdentity is the structure to represent the SPIFFE ID for a workload. -type SpiffeIDWorkloadIdentity struct { - TrustDomain string - Partition string - Namespace string - WorkloadIdentity string -} - -func (id SpiffeIDWorkloadIdentity) NamespaceOrDefault() string { - return acl.NamespaceOrDefault(id.Namespace) -} - -// URI returns the *url.URL for this SPIFFE ID. -func (id SpiffeIDWorkloadIdentity) URI() *url.URL { - var result url.URL - result.Scheme = "spiffe" - result.Host = id.TrustDomain - result.Path = id.uriPath() - return &result -} - -func (id SpiffeIDWorkloadIdentity) uriPath() string { - // Although CE has no support for partitions, it still needs to be able to - // handle exportedPartition from peered Consul Enterprise clusters in order - // to generate the correct SpiffeID. - // We intentionally avoid using pbpartition.DefaultName here to be CE friendly. - path := fmt.Sprintf("/ap/%s/ns/%s/identity/%s", - id.PartitionOrDefault(), - id.NamespaceOrDefault(), - id.WorkloadIdentity, - ) - - return path -} diff --git a/agent/connect/uri_workload_identity_ce.go b/agent/connect/uri_workload_identity_ce.go deleted file mode 100644 index 99544b014efac..0000000000000 --- a/agent/connect/uri_workload_identity_ce.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package connect - -import ( - "strings" - - "github.com/hashicorp/consul/acl" -) - -// GetEnterpriseMeta will synthesize an EnterpriseMeta struct from the SpiffeIDWorkloadIdentity. -// in CE this just returns an empty (but never nil) struct pointer -func (id SpiffeIDWorkloadIdentity) GetEnterpriseMeta() *acl.EnterpriseMeta { - return &acl.EnterpriseMeta{} -} - -// PartitionOrDefault breaks from CE's pattern of returning empty strings. -// Although CE has no support for partitions, it still needs to be able to -// handle exportedPartition from peered Consul Enterprise clusters in order -// to generate the correct SpiffeID. -func (id SpiffeIDWorkloadIdentity) PartitionOrDefault() string { - if id.Partition == "" { - return "default" - } - - return strings.ToLower(id.Partition) -} diff --git a/agent/connect/uri_workload_identity_ce_test.go b/agent/connect/uri_workload_identity_ce_test.go deleted file mode 100644 index 17a2cc3d4a0e2..0000000000000 --- a/agent/connect/uri_workload_identity_ce_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package connect - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestSpiffeIDWorkloadURI(t *testing.T) { - t.Run("default partition; default namespace", func(t *testing.T) { - wl := &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - WorkloadIdentity: "web", - } - require.Equal(t, "spiffe://1234.consul/ap/default/ns/default/identity/web", wl.URI().String()) - }) - - t.Run("namespaces are ignored", func(t *testing.T) { - wl := &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - WorkloadIdentity: "web", - Namespace: "other", - } - require.Equal(t, "spiffe://1234.consul/ap/default/ns/default/identity/web", wl.URI().String()) - }) - - t.Run("partitions are not ignored", func(t *testing.T) { - wl := &SpiffeIDWorkloadIdentity{ - TrustDomain: "1234.consul", - WorkloadIdentity: "web", - Partition: "other", - } - require.Equal(t, "spiffe://1234.consul/ap/other/ns/default/identity/web", wl.URI().String()) - }) -} diff --git a/agent/connect/x509_patch.go b/agent/connect/x509_patch.go index 54a33ce07834f..f448154f8d9f0 100644 --- a/agent/connect/x509_patch.go +++ b/agent/connect/x509_patch.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect/x509_patch_test.go b/agent/connect/x509_patch_test.go index bdcb99045b578..1447802a5b879 100644 --- a/agent/connect/x509_patch_test.go +++ b/agent/connect/x509_patch_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/agent/connect_auth.go b/agent/connect_auth.go new file mode 100644 index 0000000000000..7060d10b599f5 --- /dev/null +++ b/agent/connect_auth.go @@ -0,0 +1,143 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package agent + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/consul/acl" + "github.com/hashicorp/consul/agent/cache" + cachetype "github.com/hashicorp/consul/agent/cache-types" + "github.com/hashicorp/consul/agent/connect" + "github.com/hashicorp/consul/agent/structs" +) + +// TODO(rb/intentions): this should move back into the agent endpoint since +// there is no ext_authz implementation anymore. +// +// ConnectAuthorize implements the core authorization logic for Connect. It's in +// a separate agent method here because we need to re-use this both in our own +// HTTP API authz endpoint and in the gRPX xDS/ext_authz API for envoy. +// +// NOTE: This treats any L7 intentions as DENY. +// +// The ACL token and the auth request are provided and the auth decision (true +// means authorized) and reason string are returned. +// +// If the request input is invalid the error returned will be a BadRequest HTTPError, +// if the token doesn't grant necessary access then an acl.ErrPermissionDenied +// error is returned, otherwise error indicates an unexpected server failure. If +// access is denied, no error is returned but the first return value is false. +func (a *Agent) ConnectAuthorize(token string, + req *structs.ConnectAuthorizeRequest) (allowed bool, reason string, m *cache.ResultMeta, err error) { + + // Helper to make the error cases read better without resorting to named + // returns which get messy and prone to mistakes in a method this long. + returnErr := func(err error) (bool, string, *cache.ResultMeta, error) { + return false, "", nil, err + } + + if req == nil { + return returnErr(HTTPError{StatusCode: http.StatusBadRequest, Reason: "Invalid request"}) + } + + // We need to have a target to check intentions + if req.Target == "" { + return returnErr(HTTPError{StatusCode: http.StatusBadRequest, Reason: "Target service must be specified"}) + } + + // Parse the certificate URI from the client ID + uri, err := connect.ParseCertURIFromString(req.ClientCertURI) + if err != nil { + return returnErr(HTTPError{StatusCode: http.StatusBadRequest, Reason: "ClientCertURI not a valid Connect identifier"}) + } + + uriService, ok := uri.(*connect.SpiffeIDService) + if !ok { + return returnErr(HTTPError{StatusCode: http.StatusBadRequest, Reason: "ClientCertURI not a valid Service identifier"}) + } + + // We need to verify service:write permissions for the given token. + // We do this manually here since the RPC request below only verifies + // service:read. + var authzContext acl.AuthorizerContext + authz, err := a.delegate.ResolveTokenAndDefaultMeta(token, &req.EnterpriseMeta, &authzContext) + if err != nil { + return returnErr(err) + } + + if err := authz.ToAllowAuthorizer().ServiceWriteAllowed(req.Target, &authzContext); err != nil { + return returnErr(err) + } + + if !uriService.MatchesPartition(req.TargetPartition()) { + reason = fmt.Sprintf("Mismatched partitions: %q != %q", + uriService.PartitionOrDefault(), + acl.PartitionOrDefault(req.TargetPartition())) + return false, reason, nil, nil + } + + // Note that we DON'T explicitly validate the trust-domain matches ours. See + // the PR for this change for details. + + // TODO(banks): Implement revocation list checking here. + + // Get the intentions for this target service. + args := &structs.IntentionQueryRequest{ + Datacenter: a.config.Datacenter, + Match: &structs.IntentionQueryMatch{ + Type: structs.IntentionMatchDestination, + Entries: []structs.IntentionMatchEntry{ + { + Namespace: req.TargetNamespace(), + Partition: req.TargetPartition(), + Name: req.Target, + }, + }, + }, + QueryOptions: structs.QueryOptions{Token: token}, + } + + raw, meta, err := a.cache.Get(context.TODO(), cachetype.IntentionMatchName, args) + if err != nil { + return returnErr(err) + } + + reply, ok := raw.(*structs.IndexedIntentionMatches) + if !ok { + return returnErr(fmt.Errorf("internal error: response type not correct")) + } + if len(reply.Matches) != 1 { + return returnErr(fmt.Errorf("Internal error loading matches")) + } + + // Figure out which source matches this request. + var ixnMatch *structs.Intention + for _, ixn := range reply.Matches[0] { + // We match on the intention source because the uriService is the source of the connection to authorize. + if _, ok := connect.AuthorizeIntentionTarget( + uriService.Service, uriService.Namespace, uriService.Partition, "", ixn, structs.IntentionMatchSource); ok { + ixnMatch = ixn + break + } + } + + if ixnMatch != nil { + if len(ixnMatch.Permissions) == 0 { + // This is an L4 intention. + reason = fmt.Sprintf("Matched L4 intention: %s", ixnMatch.String()) + auth := ixnMatch.Action == structs.IntentionActionAllow + return auth, reason, &meta, nil + } + + // This is an L7 intention, so DENY. + reason = fmt.Sprintf("Matched L7 intention: %s", ixnMatch.String()) + return false, reason, &meta, nil + } + + reason = "Default behavior configured by ACLs" + return authz.IntentionDefaultAllow(nil) == acl.Allow, reason, &meta, nil +} diff --git a/agent/connect_ca_endpoint.go b/agent/connect_ca_endpoint.go index 0a60f37662473..913836f8c8757 100644 --- a/agent/connect_ca_endpoint.go +++ b/agent/connect_ca_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/connect_ca_endpoint_test.go b/agent/connect_ca_endpoint_test.go index f83d7328863c9..575250de4cadc 100644 --- a/agent/connect_ca_endpoint_test.go +++ b/agent/connect_ca_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/consul/acl.go b/agent/consul/acl.go index ddba359d949f0..c0107a6aa5a2c 100644 --- a/agent/consul/acl.go +++ b/agent/consul/acl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -102,10 +102,6 @@ func (id *missingIdentity) NodeIdentityList() []*structs.ACLNodeIdentity { return nil } -func (id *missingIdentity) TemplatedPolicyList() []*structs.ACLTemplatedPolicy { - return nil -} - func (id *missingIdentity) IsExpired(asOf time.Time) bool { return false } @@ -221,17 +217,6 @@ type ACLResolverSettings struct { ACLDefaultPolicy string } -func (s ACLResolverSettings) IsDefaultAllow() (bool, error) { - switch s.ACLDefaultPolicy { - case "allow": - return true, nil - case "deny": - return false, nil - default: - return false, fmt.Errorf("unexpected ACL default policy value of %q", s.ACLDefaultPolicy) - } -} - // ACLResolver is the type to handle all your token and policy resolution needs. // // Supports: @@ -611,11 +596,9 @@ func (r *ACLResolver) resolvePoliciesForIdentity(identity structs.ACLIdentity) ( roleIDs = identity.RoleIDs() serviceIdentities = structs.ACLServiceIdentities(identity.ServiceIdentityList()) nodeIdentities = structs.ACLNodeIdentities(identity.NodeIdentityList()) - templatedPolicies = structs.ACLTemplatedPolicies(identity.TemplatedPolicyList()) ) - if len(policyIDs) == 0 && len(serviceIdentities) == 0 && - len(roleIDs) == 0 && len(nodeIdentities) == 0 && len(templatedPolicies) == 0 { + if len(policyIDs) == 0 && len(serviceIdentities) == 0 && len(roleIDs) == 0 && len(nodeIdentities) == 0 { // In this case the default policy will be all that is in effect. return nil, nil } @@ -633,19 +616,16 @@ func (r *ACLResolver) resolvePoliciesForIdentity(identity structs.ACLIdentity) ( } serviceIdentities = append(serviceIdentities, role.ServiceIdentities...) nodeIdentities = append(nodeIdentities, role.NodeIdentityList()...) - templatedPolicies = append(templatedPolicies, role.TemplatedPolicyList()...) } // Now deduplicate any policies or service identities that occur more than once. policyIDs = dedupeStringSlice(policyIDs) serviceIdentities = serviceIdentities.Deduplicate() nodeIdentities = nodeIdentities.Deduplicate() - templatedPolicies = templatedPolicies.Deduplicate() // Generate synthetic policies for all service identities in effect. syntheticPolicies := r.synthesizePoliciesForServiceIdentities(serviceIdentities, identity.EnterpriseMetadata()) syntheticPolicies = append(syntheticPolicies, r.synthesizePoliciesForNodeIdentities(nodeIdentities, identity.EnterpriseMetadata())...) - syntheticPolicies = append(syntheticPolicies, r.synthesizePoliciesForTemplatedPolicies(templatedPolicies, identity.EnterpriseMetadata())...) // For the new ACLs policy replication is mandatory for correct operation on servers. Therefore // we only attempt to resolve policies locally @@ -689,24 +669,6 @@ func (r *ACLResolver) synthesizePoliciesForNodeIdentities(nodeIdentities []*stru return syntheticPolicies } -func (r *ACLResolver) synthesizePoliciesForTemplatedPolicies(templatedPolicies []*structs.ACLTemplatedPolicy, entMeta *acl.EnterpriseMeta) []*structs.ACLPolicy { - if len(templatedPolicies) == 0 { - return nil - } - - syntheticPolicies := make([]*structs.ACLPolicy, 0, len(templatedPolicies)) - for _, tp := range templatedPolicies { - policy, err := tp.SyntheticPolicy(entMeta) - if err != nil { - r.logger.Warn(fmt.Sprintf("could not generate synthetic policy for templated policy: %q", tp.TemplateName), "error", err) - continue - } - syntheticPolicies = append(syntheticPolicies, policy) - } - - return syntheticPolicies -} - func mergeStringSlice(a, b []string) []string { out := make([]string, 0, len(a)+len(b)) out = append(out, a...) diff --git a/agent/consul/acl_authmethod.go b/agent/consul/acl_authmethod.go index 217007f2b5ee4..42f5b6e2404df 100644 --- a/agent/consul/acl_authmethod.go +++ b/agent/consul/acl_authmethod.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/acl_authmethod_ce.go b/agent/consul/acl_authmethod_ce.go index 28802e77e633b..94bf78bd25693 100644 --- a/agent/consul/acl_authmethod_ce.go +++ b/agent/consul/acl_authmethod_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/acl_ce.go b/agent/consul/acl_ce.go index a21514f3bbb7f..aafe26a13ef91 100644 --- a/agent/consul/acl_ce.go +++ b/agent/consul/acl_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/acl_ce_test.go b/agent/consul/acl_ce_test.go index 5078ab41af743..69660f9da8044 100644 --- a/agent/consul/acl_ce_test.go +++ b/agent/consul/acl_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/acl_client.go b/agent/consul/acl_client.go index e6ff70720cfc8..d133807604bf3 100644 --- a/agent/consul/acl_client.go +++ b/agent/consul/acl_client.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/acl_endpoint.go b/agent/consul/acl_endpoint.go index 2b8eb88952ef0..0dac4fdd9436a 100644 --- a/agent/consul/acl_endpoint.go +++ b/agent/consul/acl_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -350,10 +350,9 @@ func (a *ACL) lookupExpandedTokenInfo(ws memdb.WatchSet, state *state.Store, tok policyIDs := make(map[string]struct{}) roleIDs := make(map[string]struct{}) identityPolicies := make(map[string]*structs.ACLPolicy) - templatedPolicies := make(map[string]*structs.ACLPolicy) tokenInfo := structs.ExpandedTokenInfo{} - // Add the token's policies, templated policies and node/service identity policies + // Add the token's policies and node/service identity policies for _, policy := range token.Policies { policyIDs[policy.ID] = struct{}{} } @@ -369,14 +368,6 @@ func (a *ACL) lookupExpandedTokenInfo(ws memdb.WatchSet, state *state.Store, tok policy := identity.SyntheticPolicy(&token.EnterpriseMeta) identityPolicies[policy.ID] = policy } - for _, templatedPolicy := range token.TemplatedPolicies { - policy, err := templatedPolicy.SyntheticPolicy(&token.EnterpriseMeta) - if err != nil { - a.logger.Warn(fmt.Sprintf("could not generate synthetic policy for templated policy: %q", templatedPolicy.TemplateName), "error", err) - continue - } - templatedPolicies[policy.ID] = policy - } // Get any namespace default roles/policies to look up nsPolicies, nsRoles, err := getTokenNamespaceDefaults(ws, state, &token.EnterpriseMeta) @@ -414,14 +405,6 @@ func (a *ACL) lookupExpandedTokenInfo(ws memdb.WatchSet, state *state.Store, tok policy := identity.SyntheticPolicy(&role.EnterpriseMeta) identityPolicies[policy.ID] = policy } - for _, templatedPolicy := range role.TemplatedPolicies { - policy, err := templatedPolicy.SyntheticPolicy(&role.EnterpriseMeta) - if err != nil { - a.logger.Warn(fmt.Sprintf("could not generate synthetic policy for templated policy: %q", templatedPolicy.TemplateName), "error", err) - continue - } - templatedPolicies[policy.ID] = policy - } tokenInfo.ExpandedRoles = append(tokenInfo.ExpandedRoles, role) } @@ -440,9 +423,6 @@ func (a *ACL) lookupExpandedTokenInfo(ws memdb.WatchSet, state *state.Store, tok for _, policy := range identityPolicies { policies = append(policies, policy) } - for _, policy := range templatedPolicies { - policies = append(policies, policy) - } tokenInfo.ExpandedPolicies = policies tokenInfo.AgentACLDefaultPolicy = a.srv.config.ACLResolverSettings.ACLDefaultPolicy @@ -506,7 +486,6 @@ func (a *ACL) TokenClone(args *structs.ACLTokenSetRequest, reply *structs.ACLTok Roles: token.Roles, ServiceIdentities: token.ServiceIdentities, NodeIdentities: token.NodeIdentities, - TemplatedPolicies: token.TemplatedPolicies, Local: token.Local, Description: token.Description, ExpirationTime: token.ExpirationTime, @@ -1385,27 +1364,6 @@ func (a *ACL) RoleSet(args *structs.ACLRoleSetRequest, reply *structs.ACLRole) e } role.NodeIdentities = role.NodeIdentities.Deduplicate() - for _, templatedPolicy := range role.TemplatedPolicies { - if templatedPolicy.TemplateName == "" { - return fmt.Errorf("templated policy is missing the template name field on this role") - } - - baseTemplate, ok := structs.GetACLTemplatedPolicyBase(templatedPolicy.TemplateName) - if !ok { - return fmt.Errorf("templated policy with an invalid templated name: %s for this role", templatedPolicy.TemplateName) - } - - if templatedPolicy.TemplateID == "" { - templatedPolicy.TemplateID = baseTemplate.TemplateID - } - - err := templatedPolicy.ValidateTemplatedPolicy(baseTemplate.Schema) - if err != nil { - return fmt.Errorf("encountered role with invalid templated policy: %w", err) - } - } - role.TemplatedPolicies = role.TemplatedPolicies.Deduplicate() - // calculate the hash for this role role.SetHash(true) @@ -1719,12 +1677,18 @@ func (a *ACL) BindingRuleSet(args *structs.ACLBindingRuleSetRequest, reply *stru return fmt.Errorf("Invalid Binding Rule: no BindName is set") } - if rule.BindType != structs.BindingRuleBindTypeTemplatedPolicy && rule.BindVars != nil { - return fmt.Errorf("invalid Binding Rule: BindVars cannot be set when bind type is not templated-policy.") + switch rule.BindType { + case structs.BindingRuleBindTypeService: + case structs.BindingRuleBindTypeNode: + case structs.BindingRuleBindTypeRole: + default: + return fmt.Errorf("Invalid Binding Rule: unknown BindType %q", rule.BindType) } - if err := auth.IsValidBindingRule(rule.BindType, rule.BindName, rule.BindVars, blankID.ProjectedVarNames()); err != nil { - return fmt.Errorf("Invalid Binding Rule: invalid BindName or BindVars: %w", err) + if valid, err := auth.IsValidBindName(rule.BindType, rule.BindName, blankID.ProjectedVarNames()); err != nil { + return fmt.Errorf("Invalid Binding Rule: invalid BindName: %v", err) + } else if !valid { + return fmt.Errorf("Invalid Binding Rule: invalid BindName") } req := &structs.ACLBindingRuleBatchSetRequest{ diff --git a/agent/consul/acl_endpoint_ce.go b/agent/consul/acl_endpoint_ce.go index 13d00a1694752..9d45f0fd7d890 100644 --- a/agent/consul/acl_endpoint_ce.go +++ b/agent/consul/acl_endpoint_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/acl_endpoint_test.go b/agent/consul/acl_endpoint_test.go index 39840942d1851..20deb56aa4b00 100644 --- a/agent/consul/acl_endpoint_test.go +++ b/agent/consul/acl_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -23,7 +23,6 @@ import ( "github.com/hashicorp/consul/agent/consul/authmethod/testauth" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs/aclfilter" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/internal/go-sso/oidcauth/oidcauthtest" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" @@ -377,7 +376,7 @@ func TestACLEndpoint_TokenRead(t *testing.T) { require.ElementsMatch(t, []*structs.ACLRole{r1, r2}, resp.ExpandedRoles) }) - t.Run("expanded output with node/service identities and templated policies", func(t *testing.T) { + t.Run("expanded output with node/service identities", func(t *testing.T) { setReq := structs.ACLTokenSetRequest{ Datacenter: "dc1", ACLToken: structs.ACLToken{ @@ -402,22 +401,6 @@ func TestACLEndpoint_TokenRead(t *testing.T) { Datacenter: "dc1", }, }, - TemplatedPolicies: []*structs.ACLTemplatedPolicy{ - { - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &structs.ACLTemplatedPolicyVariables{ - Name: "web", - }, - Datacenters: []string{"dc1"}, - }, - { - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &structs.ACLTemplatedPolicyVariables{ - Name: "foo", - }, - Datacenters: []string{"dc1"}, - }, - }, Local: false, }, WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken}, @@ -431,11 +414,6 @@ func TestACLEndpoint_TokenRead(t *testing.T) { for _, serviceIdentity := range setReq.ACLToken.NodeIdentities { expectedPolicies = append(expectedPolicies, serviceIdentity.SyntheticPolicy(entMeta)) } - for _, templatedPolicy := range setReq.ACLToken.TemplatedPolicies { - pol, tmplError := templatedPolicy.SyntheticPolicy(entMeta) - require.NoError(t, tmplError) - expectedPolicies = append(expectedPolicies, pol) - } setResp := structs.ACLToken{} err := msgpackrpc.CallWithCodec(codec, "ACL.TokenSet", &setReq, &setResp) @@ -490,10 +468,6 @@ func TestACLEndpoint_TokenClone(t *testing.T) { t.NodeIdentities = []*structs.ACLNodeIdentity{ {NodeName: "foo", Datacenter: "bar"}, } - t.TemplatedPolicies = []*structs.ACLTemplatedPolicy{ - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "foo"}, Datacenters: []string{"bar"}}, - {TemplateName: api.ACLTemplatedPolicyNodeName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "node"}}, - } }) require.NoError(t, err) @@ -516,7 +490,6 @@ func TestACLEndpoint_TokenClone(t *testing.T) { require.Equal(t, t1.Roles, t2.Roles) require.Equal(t, t1.ServiceIdentities, t2.ServiceIdentities) require.Equal(t, t1.NodeIdentities, t2.NodeIdentities) - require.Equal(t, t1.TemplatedPolicies, t2.TemplatedPolicies) require.Equal(t, t1.Local, t2.Local) require.NotEqual(t, t1.AccessorID, t2.AccessorID) require.NotEqual(t, t1.SecretID, t2.SecretID) @@ -575,10 +548,6 @@ func TestACLEndpoint_TokenSet(t *testing.T) { Datacenter: "dc1", }, }, - TemplatedPolicies: []*structs.ACLTemplatedPolicy{ - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "foo"}, Datacenters: []string{"bar"}}, - {TemplateName: api.ACLTemplatedPolicyNodeName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "node"}}, - }, }, WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken}, } @@ -601,19 +570,6 @@ func TestACLEndpoint_TokenSet(t *testing.T) { require.Equal(t, "foo", token.NodeIdentities[0].NodeName) require.Equal(t, "dc1", token.NodeIdentities[0].Datacenter) - require.Len(t, token.TemplatedPolicies, 2) - require.Contains(t, token.TemplatedPolicies, &structs.ACLTemplatedPolicy{ - TemplateID: structs.ACLTemplatedPolicyServiceID, - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "foo"}, - Datacenters: []string{"bar"}, - }) - require.Contains(t, token.TemplatedPolicies, &structs.ACLTemplatedPolicy{ - TemplateID: structs.ACLTemplatedPolicyNodeID, - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "node"}, - }) - accessorID = token.AccessorID }) @@ -2227,39 +2183,6 @@ func TestACLEndpoint_PolicySet_CustomID(t *testing.T) { require.Error(t, err) } -func TestACLEndpoint_TemplatedPolicySet_UnknownTemplateName(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - _, srv, _ := testACLServerWithConfig(t, nil, false) - waitForLeaderEstablishment(t, srv) - - aclEp := ACL{srv: srv} - - t.Run("unknown template name", func(t *testing.T) { - req := structs.ACLTokenSetRequest{ - Datacenter: "dc1", - ACLToken: structs.ACLToken{ - Description: "foobar", - Policies: nil, - Local: false, - TemplatedPolicies: []*structs.ACLTemplatedPolicy{{TemplateName: "fake-builtin"}}, - }, - Create: true, - WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken}, - } - - resp := structs.ACLToken{} - - err := aclEp.TokenSet(&req, &resp) - require.Error(t, err) - require.ErrorContains(t, err, "no such ACL templated policy with Name \"fake-builtin\"") - }) -} - func TestACLEndpoint_PolicySet_builtins(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") @@ -3573,7 +3496,7 @@ func TestACLEndpoint_BindingRuleSet(t *testing.T) { } } - requireSetErrors := func(t *testing.T, reqRule structs.ACLBindingRule, msg ...string) { + requireSetErrors := func(t *testing.T, reqRule structs.ACLBindingRule) { req := structs.ACLBindingRuleSetRequest{ Datacenter: "dc1", BindingRule: reqRule, @@ -3583,10 +3506,6 @@ func TestACLEndpoint_BindingRuleSet(t *testing.T) { err := aclEp.BindingRuleSet(&req, &resp) require.Error(t, err) - - for _, s := range msg { - require.Contains(t, err.Error(), s) - } } requireOK := func(t *testing.T, reqRule structs.ACLBindingRule) *structs.ACLBindingRule { @@ -3663,40 +3582,6 @@ func TestACLEndpoint_BindingRuleSet(t *testing.T) { require.Equal(t, "test-node", rule.BindName) }) - t.Run("templated policy", func(t *testing.T) { - req := structs.ACLBindingRuleSetRequest{ - Datacenter: "dc1", - BindingRule: structs.ACLBindingRule{ - Description: "templated policy binding rule", - AuthMethod: testAuthMethod.Name, - Selector: "serviceaccount.name==abc", - BindType: structs.BindingRuleBindTypeTemplatedPolicy, - BindName: api.ACLTemplatedPolicyNodeName, - BindVars: &structs.ACLTemplatedPolicyVariables{ - Name: "test-node", - }, - }, - WriteRequest: structs.WriteRequest{Token: TestDefaultInitialManagementToken}, - } - var resp structs.ACLBindingRule - - err := aclEp.BindingRuleSet(&req, &resp) - require.NoError(t, err) - require.NotNil(t, resp.ID) - - // Get the rule directly to validate that it exists - ruleResp, err := retrieveTestBindingRule(codec, TestDefaultInitialManagementToken, "dc1", resp.ID) - require.NoError(t, err) - rule := ruleResp.BindingRule - - require.NotEmpty(t, rule.ID) - require.Equal(t, rule.Description, "templated policy binding rule") - require.Equal(t, rule.AuthMethod, testAuthMethod.Name) - require.Equal(t, "serviceaccount.name==abc", rule.Selector) - require.Equal(t, structs.BindingRuleBindTypeTemplatedPolicy, rule.BindType) - require.Equal(t, api.ACLTemplatedPolicyNodeName, rule.BindName) - }) - t.Run("Update fails; cannot change method name", func(t *testing.T) { reqRule := newRule() reqRule.ID = ruleID @@ -3813,35 +3698,10 @@ func TestACLEndpoint_BindingRuleSet(t *testing.T) { requireSetErrors(t, reqRule) }) - t.Run("Create fails; when bind vars is set for non templated policy", func(t *testing.T) { - reqRule := newRule() - reqRule.BindVars = &structs.ACLTemplatedPolicyVariables{ - Name: "test", - } - requireSetErrors(t, reqRule, "invalid Binding Rule: BindVars cannot be set when bind type is not templated-policy.") - }) - - t.Run("Create fails; when missing required bindvars", func(t *testing.T) { - reqRule := newRule() - reqRule.BindName = api.ACLTemplatedPolicyServiceName - reqRule.BindType = structs.BindingRuleBindTypeTemplatedPolicy - requireSetErrors(t, reqRule, "Invalid Binding Rule: invalid BindName or BindVars") - }) - - t.Run("Create fails; when bindvars contains unknown vars", func(t *testing.T) { - reqRule := newRule() - reqRule.BindName = api.ACLTemplatedPolicyServiceName - reqRule.BindType = structs.BindingRuleBindTypeTemplatedPolicy - reqRule.BindVars = &structs.ACLTemplatedPolicyVariables{ - Name: "method-${serviceaccount.bizarroname}", - } - requireSetErrors(t, reqRule, "Invalid Binding Rule: invalid BindName or BindVars") - }) - t.Run("Create fails; invalid bind type", func(t *testing.T) { reqRule := newRule() reqRule.BindType = "invalid" - requireSetErrors(t, reqRule, "Invalid Binding Rule: unknown BindType") + requireSetErrors(t, reqRule) }) t.Run("Create fails; bind name with unknown vars", func(t *testing.T) { diff --git a/agent/consul/acl_replication.go b/agent/consul/acl_replication.go index 79e4e5d7a7d89..849e81adf697a 100644 --- a/agent/consul/acl_replication.go +++ b/agent/consul/acl_replication.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/acl_replication_test.go b/agent/consul/acl_replication_test.go index 70ed42672916b..2b50f142bf303 100644 --- a/agent/consul/acl_replication_test.go +++ b/agent/consul/acl_replication_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/acl_replication_types.go b/agent/consul/acl_replication_types.go index 8a672cb90d566..6d6b68690682b 100644 --- a/agent/consul/acl_replication_types.go +++ b/agent/consul/acl_replication_types.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/acl_server.go b/agent/consul/acl_server.go index 8fe1f45fd0984..f91cb77620238 100644 --- a/agent/consul/acl_server.go +++ b/agent/consul/acl_server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/acl_server_ce.go b/agent/consul/acl_server_ce.go index 5adb8be5725d5..f2de1486a28af 100644 --- a/agent/consul/acl_server_ce.go +++ b/agent/consul/acl_server_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/acl_test.go b/agent/consul/acl_test.go index a6d6a77405f5a..386c60e38e39f 100644 --- a/agent/consul/acl_test.go +++ b/agent/consul/acl_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -21,7 +21,6 @@ import ( "github.com/hashicorp/consul/acl/resolver" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/token" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" ) @@ -615,6 +614,10 @@ func (d *ACLResolverTestDelegate) ACLDatacenter() string { return d.datacenter } +func (d *ACLResolverTestDelegate) UseLegacyACLs() bool { + return d.legacy +} + func (d *ACLResolverTestDelegate) ResolveIdentityFromToken(token string) (bool, structs.ACLIdentity, error) { if !d.localTokens { return false, nil, nil @@ -727,6 +730,7 @@ func TestACLResolver_Disabled(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: false, datacenter: "dc1", + legacy: false, } r := newTestACLResolver(t, delegate, nil) @@ -741,6 +745,7 @@ func TestACLResolver_ResolveRootACL(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, } r := newTestACLResolver(t, delegate, nil) @@ -791,6 +796,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: true, localRoles: true, @@ -818,6 +824,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: true, localRoles: true, @@ -845,6 +852,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: true, localPolicies: false, localRoles: false, @@ -880,6 +888,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: true, localPolicies: false, localRoles: false, @@ -910,6 +919,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: true, localRoles: true, @@ -960,6 +970,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: true, localRoles: true, @@ -990,6 +1001,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: true, localPolicies: false, localRoles: false, @@ -1025,6 +1037,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: true, localPolicies: false, localRoles: false, @@ -1056,6 +1069,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: true, localPolicies: false, localRoles: false, @@ -1102,6 +1116,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: true, localPolicies: false, localRoles: false, @@ -1143,6 +1158,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: false, localRoles: false, @@ -1177,6 +1193,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: false, localRoles: false, @@ -1212,6 +1229,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: true, localRoles: true, @@ -1257,6 +1275,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: false, tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error { @@ -1320,6 +1339,7 @@ func TestACLResolver_DownPolicy(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: false, tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error { @@ -1377,6 +1397,7 @@ func TestACLResolver_DatacenterScoping(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: true, localPolicies: true, localRoles: true, @@ -1396,6 +1417,7 @@ func TestACLResolver_DatacenterScoping(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc2", + legacy: false, localTokens: true, localPolicies: true, localRoles: true, @@ -1431,6 +1453,7 @@ func TestACLResolver_Client(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: false, tokenReadFn: func(_ *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error { @@ -1521,6 +1544,7 @@ func TestACLResolver_Client(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: false, tokenReadFn: func(args *structs.ACLTokenGetRequest, reply *structs.ACLTokenResponse) error { @@ -1583,6 +1607,7 @@ func TestACLResolver_Client_TokensPoliciesAndRoles(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: false, localRoles: false, @@ -1599,6 +1624,7 @@ func TestACLResolver_LocalTokensPoliciesAndRoles(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: true, localPolicies: true, localRoles: true, @@ -1614,6 +1640,7 @@ func TestACLResolver_LocalPoliciesAndRoles(t *testing.T) { delegate := &ACLResolverTestDelegate{ enabled: true, datacenter: "dc1", + legacy: false, localTokens: false, localPolicies: true, localRoles: true, @@ -1951,48 +1978,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega }, }, }, - &structs.ACLToken{ - AccessorID: "359b9927-25fd-46b9-84c2-3470f848ec65", - SecretID: "found-synthetic-policy-5", - TemplatedPolicies: []*structs.ACLTemplatedPolicy{ - { - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &structs.ACLTemplatedPolicyVariables{ - Name: "templated-test-node1", - }, - Datacenters: []string{"dc1"}, - }, - { - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &structs.ACLTemplatedPolicyVariables{ - Name: "templated-test-node2", - }, - // as the resolver is in dc1 this identity should be ignored - Datacenters: []string{"dc2"}, - }, - }, - }, - &structs.ACLToken{ - AccessorID: "359b9927-25fd-46b9-84c2-3470f848ec65", - SecretID: "found-synthetic-policy-6", - TemplatedPolicies: []*structs.ACLTemplatedPolicy{ - { - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &structs.ACLTemplatedPolicyVariables{ - Name: "templated-test-node3", - }, - Datacenters: []string{"dc1"}, - }, - { - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &structs.ACLTemplatedPolicyVariables{ - Name: "templated-test-node4", - }, - // as the resolver is in dc1 this identity should be ignored - Datacenters: []string{"dc2"}, - }, - }, - }, }) // We resolve these tokens in the same cache session @@ -2058,22 +2043,6 @@ func testACLResolver_variousTokens(t *testing.T, delegate *ACLResolverTestDelega // ensure node identity for other DC is ignored require.Equal(t, acl.Deny, authz.NodeWrite("test-node-dc2", nil)) }) - t.Run("synthetic-policy-6", func(t *testing.T) { // templated policy - authz, err := r.ResolveToken("found-synthetic-policy-6") - require.NoError(t, err) - require.NotNil(t, authz) - - // spot check some random perms - require.Equal(t, acl.Deny, authz.ACLRead(nil)) - require.Equal(t, acl.Deny, authz.NodeWrite("foo", nil)) - // ensure we didn't bleed over to the other synthetic policy - require.Equal(t, acl.Deny, authz.NodeWrite("templated-test-node1", nil)) - // check our own synthetic policy - require.Equal(t, acl.Allow, authz.ServiceRead("literally-anything", nil)) - require.Equal(t, acl.Allow, authz.NodeWrite("templated-test-node3", nil)) - // ensure template identity for other DC is ignored - require.Equal(t, acl.Deny, authz.NodeWrite("templated-test-node4", nil)) - }) }) runTwiceAndReset("Anonymous", func(t *testing.T) { diff --git a/agent/consul/acl_token_exp.go b/agent/consul/acl_token_exp.go index 06559ce71d566..7f5de395c7a9d 100644 --- a/agent/consul/acl_token_exp.go +++ b/agent/consul/acl_token_exp.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/acl_token_exp_test.go b/agent/consul/acl_token_exp_test.go index 031c150dabb0c..949d54510ba54 100644 --- a/agent/consul/acl_token_exp_test.go +++ b/agent/consul/acl_token_exp_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/auth/binder.go b/agent/consul/auth/binder.go index 1964cc5a877ea..354fedc8f1854 100644 --- a/agent/consul/auth/binder.go +++ b/agent/consul/auth/binder.go @@ -1,10 +1,9 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package auth import ( - "errors" "fmt" "github.com/hashicorp/go-bexpr" @@ -38,13 +37,12 @@ type BinderStateStore interface { ACLRoleGetByName(ws memdb.WatchSet, roleName string, entMeta *acl.EnterpriseMeta) (uint64, *structs.ACLRole, error) } -// Bindings contains the ACL roles, service identities, node identities, -// templated policies, and enterprise meta to be assigned to the created token. +// Bindings contains the ACL roles, service identities, node identities and +// enterprise meta to be assigned to the created token. type Bindings struct { Roles []structs.ACLTokenRoleLink ServiceIdentities []*structs.ACLServiceIdentity NodeIdentities []*structs.ACLNodeIdentity - TemplatedPolicies structs.ACLTemplatedPolicies EnterpriseMeta acl.EnterpriseMeta } @@ -57,7 +55,6 @@ func (b *Bindings) None() bool { return len(b.ServiceIdentities) == 0 && len(b.NodeIdentities) == 0 && - len(b.TemplatedPolicies) == 0 && len(b.Roles) == 0 } @@ -89,42 +86,30 @@ func (b *Binder) Bind(authMethod *structs.ACLAuthMethod, verifiedIdentity *authm return &bindings, nil } - // Compute role, service identity, node identity or templated policy names by interpolating + // Compute role, service identity, or node identity names by interpolating // the identity's projected variables into the rule BindName templates. for _, rule := range matchingRules { + bindName, valid, err := computeBindName(rule.BindType, rule.BindName, verifiedIdentity.ProjectedVars) + switch { + case err != nil: + return nil, fmt.Errorf("cannot compute %q bind name for bind target: %w", rule.BindType, err) + case !valid: + return nil, fmt.Errorf("computed %q bind name for bind target is invalid: %q", rule.BindType, bindName) + } + switch rule.BindType { case structs.BindingRuleBindTypeService: - bindName, err := computeBindName(rule.BindName, verifiedIdentity.ProjectedVars, acl.IsValidServiceIdentityName) - if err != nil { - return nil, err - } bindings.ServiceIdentities = append(bindings.ServiceIdentities, &structs.ACLServiceIdentity{ ServiceName: bindName, }) case structs.BindingRuleBindTypeNode: - bindName, err := computeBindName(rule.BindName, verifiedIdentity.ProjectedVars, acl.IsValidNodeIdentityName) - if err != nil { - return nil, err - } bindings.NodeIdentities = append(bindings.NodeIdentities, &structs.ACLNodeIdentity{ NodeName: bindName, Datacenter: b.datacenter, }) - case structs.BindingRuleBindTypeTemplatedPolicy: - templatedPolicy, err := generateTemplatedPolicies(rule.BindName, rule.BindVars, verifiedIdentity.ProjectedVars) - if err != nil { - return nil, err - } - bindings.TemplatedPolicies = append(bindings.TemplatedPolicies, templatedPolicy) - case structs.BindingRuleBindTypeRole: - bindName, err := computeBindName(rule.BindName, verifiedIdentity.ProjectedVars, acl.IsValidRoleName) - if err != nil { - return nil, err - } - _, role, err := b.store.ACLRoleGetByName(nil, bindName, &bindings.EnterpriseMeta) if err != nil { return nil, err @@ -141,11 +126,11 @@ func (b *Binder) Bind(authMethod *structs.ACLAuthMethod, verifiedIdentity *authm return &bindings, nil } -// IsValidBindingRule returns whether the given BindName and/or BindVars template produces valid +// IsValidBindName returns whether the given BindName template produces valid // results when interpolating the auth method's available variables. -func IsValidBindingRule(bindType, bindName string, bindVars *structs.ACLTemplatedPolicyVariables, availableVariables []string) error { +func IsValidBindName(bindType, bindName string, availableVariables []string) (bool, error) { if bindType == "" || bindName == "" { - return errors.New("bindType and bindName must not be empty") + return false, nil } fakeVarMap := make(map[string]string) @@ -153,96 +138,38 @@ func IsValidBindingRule(bindType, bindName string, bindVars *structs.ACLTemplate fakeVarMap[v] = "fake" } - switch bindType { - case structs.BindingRuleBindTypeService: - if _, err := computeBindName(bindName, fakeVarMap, acl.IsValidServiceIdentityName); err != nil { - return fmt.Errorf("failed to validate bindType %q: %w", bindType, err) - } - - case structs.BindingRuleBindTypeNode: - if _, err := computeBindName(bindName, fakeVarMap, acl.IsValidNodeIdentityName); err != nil { - return fmt.Errorf("failed to validate bindType %q: %w", bindType, err) - } - - case structs.BindingRuleBindTypeTemplatedPolicy: - // If user-defined templated policies are supported in the future, - // we will need to lookup state to ensure a template exists for given - // bindName. A possible solution is to rip out the check for templated - // policy into its own step which has access to the state store. - if _, err := generateTemplatedPolicies(bindName, bindVars, fakeVarMap); err != nil { - return fmt.Errorf("failed to validate bindType %q: %w", bindType, err) - } - - case structs.BindingRuleBindTypeRole: - if _, err := computeBindName(bindName, fakeVarMap, acl.IsValidRoleName); err != nil { - return fmt.Errorf("failed to validate bindType %q: %w", bindType, err) - } - default: - return fmt.Errorf("Invalid Binding Rule: unknown BindType %q", bindType) - } - - return nil -} - -// computeBindName interprets given HIL bindName with any given variables in projectedVars. -// validate (if not nil) will be called on the interpreted string. -func computeBindName(bindName string, projectedVars map[string]string, validate func(string) bool) (string, error) { - computed, err := template.InterpolateHIL(bindName, projectedVars, true) + _, valid, err := computeBindName(bindType, bindName, fakeVarMap) if err != nil { - return "", fmt.Errorf("error interpreting template: %w", err) + return false, err } - if validate != nil && !validate(computed) { - return "", fmt.Errorf("invalid bind name: %q", computed) - } - return computed, nil + return valid, nil } -// generateTemplatedPolicies fetches a templated policy by bindName then attempts to interpret -// bindVars with any given variables in projectedVars. The resulting template is validated -// by the template's schema. -func generateTemplatedPolicies( - bindName string, - bindVars *structs.ACLTemplatedPolicyVariables, - projectedVars map[string]string, -) (*structs.ACLTemplatedPolicy, error) { - baseTemplate, ok := structs.GetACLTemplatedPolicyBase(bindName) - if !ok { - return nil, fmt.Errorf("Bind name for templated-policy bind type does not match existing template name: %s", bindName) - } - - computedBindVars, err := computeBindVars(bindVars, projectedVars) +// computeBindName processes the HIL for the provided bind type+name using the +// projected variables. +// +// - If the HIL is invalid ("", false, AN_ERROR) is returned. +// - If the computed name is not valid for the type ("INVALID_NAME", false, nil) is returned. +// - If the computed name is valid for the type ("VALID_NAME", true, nil) is returned. +func computeBindName(bindType, bindName string, projectedVars map[string]string) (string, bool, error) { + bindName, err := template.InterpolateHIL(bindName, projectedVars, true) if err != nil { - return nil, fmt.Errorf("failed to interpret templated policy variables: %w", err) - } - - out := &structs.ACLTemplatedPolicy{ - TemplateName: bindName, - TemplateVariables: computedBindVars, - TemplateID: baseTemplate.TemplateID, + return "", false, err } - if err := out.ValidateTemplatedPolicy(baseTemplate.Schema); err != nil { - return nil, fmt.Errorf("templated policy failed validation: %w", err) - } - - return out, nil -} - -func computeBindVars(bindVars *structs.ACLTemplatedPolicyVariables, projectedVars map[string]string) (*structs.ACLTemplatedPolicyVariables, error) { - if bindVars == nil { - return nil, nil - } - - out := &structs.ACLTemplatedPolicyVariables{} - if bindVars.Name != "" { - nameValue, err := template.InterpolateHIL(bindVars.Name, projectedVars, true) - if err != nil { - return nil, err - } - out.Name = nameValue + var valid bool + switch bindType { + case structs.BindingRuleBindTypeService: + valid = acl.IsValidServiceIdentityName(bindName) + case structs.BindingRuleBindTypeNode: + valid = acl.IsValidNodeIdentityName(bindName) + case structs.BindingRuleBindTypeRole: + valid = acl.IsValidRoleName(bindName) + default: + return "", false, fmt.Errorf("unknown binding rule bind type: %s", bindType) } - return out, nil + return bindName, valid, nil } // doesSelectorMatch checks that a single selector matches the provided vars. diff --git a/agent/consul/auth/binder_ce.go b/agent/consul/auth/binder_ce.go index 2b1a474a407cb..f6fa5e5e841c1 100644 --- a/agent/consul/auth/binder_ce.go +++ b/agent/consul/auth/binder_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package auth diff --git a/agent/consul/auth/binder_test.go b/agent/consul/auth/binder_test.go index 41e0d14ddc35f..b86d4526dd006 100644 --- a/agent/consul/auth/binder_test.go +++ b/agent/consul/auth/binder_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package auth @@ -119,7 +119,7 @@ func TestBinder_Roles_NameValidation(t *testing.T) { _, err := binder.Bind(&structs.ACLAuthMethod{}, &authmethod.Identity{}) require.Error(t, err) - require.Contains(t, err.Error(), "invalid bind name") + require.Contains(t, err.Error(), "bind name for bind target is invalid") } func TestBinder_ServiceIdentities_Success(t *testing.T) { @@ -187,7 +187,7 @@ func TestBinder_ServiceIdentities_NameValidation(t *testing.T) { _, err := binder.Bind(&structs.ACLAuthMethod{}, &authmethod.Identity{}) require.Error(t, err) - require.Contains(t, err.Error(), "invalid bind name") + require.Contains(t, err.Error(), "bind name for bind target is invalid") } func TestBinder_NodeIdentities_Success(t *testing.T) { @@ -255,87 +255,74 @@ func TestBinder_NodeIdentities_NameValidation(t *testing.T) { _, err := binder.Bind(&structs.ACLAuthMethod{}, &authmethod.Identity{}) require.Error(t, err) - require.Contains(t, err.Error(), "invalid bind name") + require.Contains(t, err.Error(), "bind name for bind target is invalid") } -func Test_IsValidBindingRule(t *testing.T) { +func Test_IsValidBindName(t *testing.T) { type testcase struct { name string bindType string bindName string - bindVars *structs.ACLTemplatedPolicyVariables fields string - err bool + valid bool // valid HIL, invalid contents + err bool // invalid HIL } for _, test := range []testcase{ {"no bind type", - "", "", nil, "", true}, + "", "", "", false, false}, {"bad bind type", - "invalid", "blah", nil, "", true}, + "invalid", "blah", "", false, true}, // valid HIL, invalid name {"empty", - "both", "", nil, "", true}, + "both", "", "", false, false}, {"just end", - "both", "}", nil, "", true}, + "both", "}", "", false, false}, {"var without start", - "both", " item }", nil, "item", true}, + "both", " item }", "item", false, false}, {"two vars missing second start", - "both", "before-${ item }after--more }", nil, "item,more", true}, + "both", "before-${ item }after--more }", "item,more", false, false}, // names for the two types are validated differently {"@ is disallowed", - "both", "bad@name", nil, "", true}, + "both", "bad@name", "", false, false}, {"leading dash", - "role", "-name", nil, "", false}, + "role", "-name", "", true, false}, {"leading dash", - "service", "-name", nil, "", true}, + "service", "-name", "", false, false}, {"trailing dash", - "role", "name-", nil, "", false}, + "role", "name-", "", true, false}, {"trailing dash", - "service", "name-", nil, "", true}, + "service", "name-", "", false, false}, {"inner dash", - "both", "name-end", nil, "", false}, + "both", "name-end", "", true, false}, {"upper case", - "role", "NAME", nil, "", false}, + "role", "NAME", "", true, false}, {"upper case", - "service", "NAME", nil, "", true}, + "service", "NAME", "", false, false}, // valid HIL, valid name {"no vars", - "both", "nothing", nil, "", false}, + "both", "nothing", "", true, false}, {"just var", - "both", "${item}", nil, "item", false}, + "both", "${item}", "item", true, false}, {"var in middle", - "both", "before-${item}after", nil, "item", false}, + "both", "before-${item}after", "item", true, false}, {"two vars", - "both", "before-${item}after-${more}", nil, "item,more", false}, + "both", "before-${item}after-${more}", "item,more", true, false}, // bad {"no bind name", - "both", "", nil, "", true}, + "both", "", "", false, false}, {"just start", - "both", "${", nil, "", true}, + "both", "${", "", false, true}, {"backwards", - "both", "}${", nil, "", true}, + "both", "}${", "", false, true}, {"no varname", - "both", "${}", nil, "", true}, + "both", "${}", "", false, true}, {"missing map key", - "both", "${item}", nil, "", true}, + "both", "${item}", "", false, true}, {"var without end", - "both", "${ item ", nil, "item", true}, + "both", "${ item ", "item", false, true}, {"two vars missing first end", - "both", "before-${ item after-${ more }", nil, "item,more", true}, - - // bind type: templated policy - bad input - {"templated-policy missing bindvars", "templated-policy", "builtin/service", nil, "", true}, - {"templated-policy with unknown templated policy name", - "templated-policy", "builtin/service", &structs.ACLTemplatedPolicyVariables{Name: "before-${item}after-${more}"}, "", true}, - {"templated-policy with correct bindvars and unknown vars", - "templated-policy", "builtin/fake", &structs.ACLTemplatedPolicyVariables{Name: "test"}, "", true}, - {"templated-policy with correct bindvars but incorrect HIL", - "templated-policy", "builtin/service", &structs.ACLTemplatedPolicyVariables{Name: "before-${ item }after--more }"}, "", true}, - - // bind type: templated policy - good input - {"templated-policy with appropriate bindvars", - "templated-policy", "builtin/service", &structs.ACLTemplatedPolicyVariables{Name: "before-${item}after-${more}"}, "item,more", false}, + "both", "before-${ item after-${ more }", "item,more", false, true}, } { var cases []testcase if test.bindType == "both" { @@ -352,13 +339,18 @@ func Test_IsValidBindingRule(t *testing.T) { test := test t.Run(test.bindType+"--"+test.name, func(t *testing.T) { t.Parallel() - err := IsValidBindingRule( + valid, err := IsValidBindName( test.bindType, test.bindName, - test.bindVars, strings.Split(test.fields, ","), ) - require.Equal(t, test.err, err != nil) + if test.err { + require.NotNil(t, err) + require.False(t, valid) + } else { + require.NoError(t, err) + require.Equal(t, test.valid, valid) + } }) } } diff --git a/agent/consul/auth/login.go b/agent/consul/auth/login.go index a084f33bf19bf..9592e5a841d6f 100644 --- a/agent/consul/auth/login.go +++ b/agent/consul/auth/login.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package auth @@ -46,7 +46,6 @@ func (l *Login) TokenForVerifiedIdentity(identity *authmethod.Identity, authMeth ExpirationTTL: authMethod.MaxTokenTTL, ServiceIdentities: bindings.ServiceIdentities, NodeIdentities: bindings.NodeIdentities, - TemplatedPolicies: bindings.TemplatedPolicies, Roles: bindings.Roles, EnterpriseMeta: bindings.EnterpriseMeta, } diff --git a/agent/consul/auth/token_writer.go b/agent/consul/auth/token_writer.go index 0112d0387c56d..857a2e3d13213 100644 --- a/agent/consul/auth/token_writer.go +++ b/agent/consul/auth/token_writer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package auth @@ -309,12 +309,6 @@ func (w *TokenWriter) write(token, existing *structs.ACLToken, fromLogin bool) ( } token.NodeIdentities = nodeIdentities - templatedPolicies, err := w.normalizeTemplatedPolicies(token.TemplatedPolicies) - if err != nil { - return nil, err - } - token.TemplatedPolicies = templatedPolicies - if err := w.enterpriseValidation(token, existing); err != nil { return nil, err } @@ -448,32 +442,3 @@ func (w *TokenWriter) normalizeNodeIdentities(nodeIDs structs.ACLNodeIdentities) } return nodeIDs.Deduplicate(), nil } - -func (w *TokenWriter) normalizeTemplatedPolicies(templatedPolicies structs.ACLTemplatedPolicies) (structs.ACLTemplatedPolicies, error) { - if len(templatedPolicies) == 0 { - return templatedPolicies, nil - } - - finalPolicies := make(structs.ACLTemplatedPolicies, 0, len(templatedPolicies)) - for _, templatedPolicy := range templatedPolicies { - if templatedPolicy.TemplateName == "" { - return nil, errors.New("templated policy is missing the template name field on this token") - } - - tmp, ok := structs.GetACLTemplatedPolicyBase(templatedPolicy.TemplateName) - if !ok { - return nil, fmt.Errorf("no such ACL templated policy with Name %q", templatedPolicy.TemplateName) - } - - out := templatedPolicy.Clone() - out.TemplateID = tmp.TemplateID - - err := templatedPolicy.ValidateTemplatedPolicy(tmp.Schema) - if err != nil { - return nil, fmt.Errorf("validation error for templated policy %q: %w", templatedPolicy.TemplateName, err) - } - finalPolicies = append(finalPolicies, out) - } - - return finalPolicies.Deduplicate(), nil -} diff --git a/agent/consul/auth/token_writer_ce.go b/agent/consul/auth/token_writer_ce.go index fe8840138a823..b0ad9e833bb0e 100644 --- a/agent/consul/auth/token_writer_ce.go +++ b/agent/consul/auth/token_writer_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package auth diff --git a/agent/consul/auth/token_writer_test.go b/agent/consul/auth/token_writer_test.go index 3206476a504d9..51a2b3cc45a83 100644 --- a/agent/consul/auth/token_writer_test.go +++ b/agent/consul/auth/token_writer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package auth @@ -15,7 +15,6 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/consul/state" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/api" ) func TestTokenWriter_Create_Validation(t *testing.T) { @@ -358,59 +357,6 @@ func TestTokenWriter_NodeIdentities(t *testing.T) { } } -func TestTokenWriter_TemplatedPolicies(t *testing.T) { - aclCache := &MockACLCache{} - aclCache.On("RemoveIdentityWithSecretToken", mock.Anything) - - store := testStateStore(t) - - writer := buildTokenWriter(store, aclCache) - - testCases := map[string]struct { - input []*structs.ACLTemplatedPolicy - output []*structs.ACLTemplatedPolicy - errorContains string - }{ - "missing templated policy name": { - input: []*structs.ACLTemplatedPolicy{{TemplateName: ""}}, - errorContains: "templated policy is missing the template name field on this token", - }, - "invalid templated policy name": { - input: []*structs.ACLTemplatedPolicy{{TemplateName: "faketemplate"}}, - errorContains: "no such ACL templated policy with Name \"faketemplate\"", - }, - "missing required template variable: name": { - input: []*structs.ACLTemplatedPolicy{{TemplateName: api.ACLTemplatedPolicyServiceName, Datacenters: []string{"dc1"}}}, - errorContains: "validation error for templated policy \"builtin/service\"", - }, - "duplicate templated policies are removed and ids are set": { - input: []*structs.ACLTemplatedPolicy{ - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "web"}}, - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "web"}}, - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "api"}}, - {TemplateName: api.ACLTemplatedPolicyNodeName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "nodename"}}, - }, - output: []*structs.ACLTemplatedPolicy{ - {TemplateID: structs.ACLTemplatedPolicyServiceID, TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "web"}}, - {TemplateID: structs.ACLTemplatedPolicyServiceID, TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "api"}}, - {TemplateID: structs.ACLTemplatedPolicyNodeID, TemplateName: api.ACLTemplatedPolicyNodeName, TemplateVariables: &structs.ACLTemplatedPolicyVariables{Name: "nodename"}}, - }, - }, - } - for desc, tc := range testCases { - t.Run(desc, func(t *testing.T) { - updated, err := writer.Create(&structs.ACLToken{TemplatedPolicies: tc.input}, false) - if tc.errorContains == "" { - require.NoError(t, err) - require.ElementsMatch(t, tc.output, updated.TemplatedPolicies) - } else { - require.Error(t, err) - require.Contains(t, err.Error(), tc.errorContains) - } - }) - } -} - func TestTokenWriter_Create_Expiration(t *testing.T) { aclCache := &MockACLCache{} aclCache.On("RemoveIdentityWithSecretToken", mock.Anything) diff --git a/agent/consul/authmethod/authmethods.go b/agent/consul/authmethod/authmethods.go index d03e2b410cb4f..946fce927e697 100644 --- a/agent/consul/authmethod/authmethods.go +++ b/agent/consul/authmethod/authmethods.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethod diff --git a/agent/consul/authmethod/authmethods_ce.go b/agent/consul/authmethod/authmethods_ce.go index 38b27b70115bc..0839b4aba5a74 100644 --- a/agent/consul/authmethod/authmethods_ce.go +++ b/agent/consul/authmethod/authmethods_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package authmethod diff --git a/agent/consul/authmethod/awsauth/aws.go b/agent/consul/authmethod/awsauth/aws.go index 3381a893fa5da..d2cd73482cde5 100644 --- a/agent/consul/authmethod/awsauth/aws.go +++ b/agent/consul/authmethod/awsauth/aws.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package awsauth diff --git a/agent/consul/authmethod/awsauth/aws_test.go b/agent/consul/authmethod/awsauth/aws_test.go index 279e4b3e46d48..7a894cc217878 100644 --- a/agent/consul/authmethod/awsauth/aws_test.go +++ b/agent/consul/authmethod/awsauth/aws_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package awsauth diff --git a/agent/consul/authmethod/kubeauth/k8s.go b/agent/consul/authmethod/kubeauth/k8s.go index 274dd2ec9d03a..f71157cbeccb7 100644 --- a/agent/consul/authmethod/kubeauth/k8s.go +++ b/agent/consul/authmethod/kubeauth/k8s.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package kubeauth diff --git a/agent/consul/authmethod/kubeauth/k8s_ce.go b/agent/consul/authmethod/kubeauth/k8s_ce.go index b180836948cf3..b2b7e8a2d8715 100644 --- a/agent/consul/authmethod/kubeauth/k8s_ce.go +++ b/agent/consul/authmethod/kubeauth/k8s_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package kubeauth diff --git a/agent/consul/authmethod/kubeauth/k8s_test.go b/agent/consul/authmethod/kubeauth/k8s_test.go index 48ef6e61c4839..95decce11597c 100644 --- a/agent/consul/authmethod/kubeauth/k8s_test.go +++ b/agent/consul/authmethod/kubeauth/k8s_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package kubeauth diff --git a/agent/consul/authmethod/kubeauth/testing.go b/agent/consul/authmethod/kubeauth/testing.go index 38b7d9c330a3f..e5538bb90998f 100644 --- a/agent/consul/authmethod/kubeauth/testing.go +++ b/agent/consul/authmethod/kubeauth/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package kubeauth diff --git a/agent/consul/authmethod/ssoauth/sso.go b/agent/consul/authmethod/ssoauth/sso.go index 398f5689799b3..6215c0eafe719 100644 --- a/agent/consul/authmethod/ssoauth/sso.go +++ b/agent/consul/authmethod/ssoauth/sso.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ssoauth diff --git a/agent/consul/authmethod/ssoauth/sso_ce.go b/agent/consul/authmethod/ssoauth/sso_ce.go index 504329d20089c..74e3be3082ccb 100644 --- a/agent/consul/authmethod/ssoauth/sso_ce.go +++ b/agent/consul/authmethod/ssoauth/sso_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package ssoauth diff --git a/agent/consul/authmethod/ssoauth/sso_test.go b/agent/consul/authmethod/ssoauth/sso_test.go index 357612fad6894..840e37b86fd46 100644 --- a/agent/consul/authmethod/ssoauth/sso_test.go +++ b/agent/consul/authmethod/ssoauth/sso_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ssoauth diff --git a/agent/consul/authmethod/testauth/testing.go b/agent/consul/authmethod/testauth/testing.go index ead9ae081a7ea..9f6c85ae23d5e 100644 --- a/agent/consul/authmethod/testauth/testing.go +++ b/agent/consul/authmethod/testauth/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package testauth diff --git a/agent/consul/authmethod/testauth/testing_ce.go b/agent/consul/authmethod/testauth/testing_ce.go index 460f30fe4f798..f4b909b4b8127 100644 --- a/agent/consul/authmethod/testauth/testing_ce.go +++ b/agent/consul/authmethod/testauth/testing_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package testauth diff --git a/agent/consul/authmethod/testing.go b/agent/consul/authmethod/testing.go index 0f43e5e5201fc..933082a5b4295 100644 --- a/agent/consul/authmethod/testing.go +++ b/agent/consul/authmethod/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethod diff --git a/agent/consul/auto_config_backend.go b/agent/consul/auto_config_backend.go index 0aaccfa35d99b..78413fe0121c1 100644 --- a/agent/consul/auto_config_backend.go +++ b/agent/consul/auto_config_backend.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -34,7 +34,7 @@ func (b autoConfigBackend) GetCARoots() (*structs.IndexedCARoots, error) { } // DatacenterJoinAddresses will return all the strings suitable for usage in -// retry join operations to connect to the LAN or LAN segment gossip pool. +// retry join operations to connect to the the LAN or LAN segment gossip pool. func (b autoConfigBackend) DatacenterJoinAddresses(partition, segment string) ([]string, error) { members, err := b.Server.LANMembers(LANMemberFilter{ Segment: segment, diff --git a/agent/consul/auto_config_backend_test.go b/agent/consul/auto_config_backend_test.go index 00c0dc10d80d7..6a4a202fceb8e 100644 --- a/agent/consul/auto_config_backend_test.go +++ b/agent/consul/auto_config_backend_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/auto_config_endpoint.go b/agent/consul/auto_config_endpoint.go index f491bcbad832a..808aa63304dcd 100644 --- a/agent/consul/auto_config_endpoint.go +++ b/agent/consul/auto_config_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/auto_config_endpoint_test.go b/agent/consul/auto_config_endpoint_test.go index 39c4f3a7a5efa..a3f485ee60c2a 100644 --- a/agent/consul/auto_config_endpoint_test.go +++ b/agent/consul/auto_config_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/auto_encrypt_endpoint.go b/agent/consul/auto_encrypt_endpoint.go index dbd39355cfbf3..b893e783215ad 100644 --- a/agent/consul/auto_encrypt_endpoint.go +++ b/agent/consul/auto_encrypt_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/auto_encrypt_endpoint_test.go b/agent/consul/auto_encrypt_endpoint_test.go index f3b2320116340..d8124f9fb3623 100644 --- a/agent/consul/auto_encrypt_endpoint_test.go +++ b/agent/consul/auto_encrypt_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/autopilot.go b/agent/consul/autopilot.go index 70391f6b99107..f682ffed6f164 100644 --- a/agent/consul/autopilot.go +++ b/agent/consul/autopilot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/autopilot_ce.go b/agent/consul/autopilot_ce.go index 4a95e69e23fed..92f9b4ccae41d 100644 --- a/agent/consul/autopilot_ce.go +++ b/agent/consul/autopilot_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/autopilot_test.go b/agent/consul/autopilot_test.go index 8d1d214b17104..4429340eda5a8 100644 --- a/agent/consul/autopilot_test.go +++ b/agent/consul/autopilot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/autopilotevents/ready_servers_events.go b/agent/consul/autopilotevents/ready_servers_events.go index 16e064aa7905d..404276f3ec2d5 100644 --- a/agent/consul/autopilotevents/ready_servers_events.go +++ b/agent/consul/autopilotevents/ready_servers_events.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autopilotevents diff --git a/agent/consul/autopilotevents/ready_servers_events_test.go b/agent/consul/autopilotevents/ready_servers_events_test.go index 16d78b52e3b5f..994020c290c0d 100644 --- a/agent/consul/autopilotevents/ready_servers_events_test.go +++ b/agent/consul/autopilotevents/ready_servers_events_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autopilotevents diff --git a/agent/consul/catalog_endpoint.go b/agent/consul/catalog_endpoint.go index 36426afe253a2..c53c413567391 100644 --- a/agent/consul/catalog_endpoint.go +++ b/agent/consul/catalog_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/catalog_endpoint_test.go b/agent/consul/catalog_endpoint_test.go index 628ad83ae4db0..192a3d6d7d275 100644 --- a/agent/consul/catalog_endpoint_test.go +++ b/agent/consul/catalog_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/client.go b/agent/consul/client.go index fa5f1239e134e..23e96be002875 100644 --- a/agent/consul/client.go +++ b/agent/consul/client.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -25,7 +25,6 @@ import ( "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/logging" - "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/tlsutil" "github.com/hashicorp/consul/types" ) @@ -94,9 +93,6 @@ type Client struct { EnterpriseClient tlsConfigurator *tlsutil.Configurator - - // resourceServiceClient is a client for the gRPC Resource Service. - resourceServiceClient pbresource.ResourceServiceClient } // NewClient creates and returns a Client @@ -155,13 +151,6 @@ func NewClient(config *Config, deps Deps) (*Client, error) { } c.router = deps.Router - conn, err := deps.GRPCConnPool.ClientConn(deps.ConnPool.Datacenter) - if err != nil { - c.Shutdown() - return nil, fmt.Errorf("Failed to get gRPC client connection: %w", err) - } - c.resourceServiceClient = pbresource.NewResourceServiceClient(conn) - // Start LAN event handlers after the router is complete since the event // handlers depend on the router and the router depends on Serf. go c.lanEventHandler() @@ -462,7 +451,3 @@ func (c *Client) AgentEnterpriseMeta() *acl.EnterpriseMeta { func (c *Client) agentSegmentName() string { return c.config.Segment } - -func (c *Client) ResourceServiceClient() pbresource.ResourceServiceClient { - return c.resourceServiceClient -} diff --git a/agent/consul/client_serf.go b/agent/consul/client_serf.go index c92fdd1726c30..7d68b50395e49 100644 --- a/agent/consul/client_serf.go +++ b/agent/consul/client_serf.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/client_test.go b/agent/consul/client_test.go index 1d6fa28b526c0..4b8f5c433d8e7 100644 --- a/agent/consul/client_test.go +++ b/agent/consul/client_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -7,9 +7,6 @@ import ( "bytes" "context" "fmt" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/mesh" - "github.com/hashicorp/consul/internal/resource/demo" "net" "os" "strings" @@ -17,8 +14,6 @@ import ( "testing" "time" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/go-hclog" "github.com/hashicorp/serf/serf" "github.com/stretchr/testify/require" @@ -562,10 +557,6 @@ func newDefaultDeps(t *testing.T, c *Config) Deps { RPCHoldTimeout: c.RPCHoldTimeout, } connPool.SetRPCClientTimeout(c.RPCClientTimeout) - registry := resource.NewRegistry() - demo.RegisterTypes(registry) - mesh.RegisterTypes(registry) - catalog.RegisterTypes(registry) return Deps{ EventPublisher: stream.NewEventPublisher(10 * time.Second), Logger: logger, @@ -585,7 +576,6 @@ func newDefaultDeps(t *testing.T, c *Config) Deps { GetNetRPCInterceptorFunc: middleware.GetNetRPCInterceptor, EnterpriseDeps: newDefaultDepsEnterprise(t, logger, c), XDSStreamLimiter: limiter.NewSessionLimiter(), - Registry: registry, } } diff --git a/agent/consul/cluster_test.go b/agent/consul/cluster_test.go index 7cc266908198c..925d32a610692 100644 --- a/agent/consul/cluster_test.go +++ b/agent/consul/cluster_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/config.go b/agent/consul/config.go index 8e3bb92e4eb1d..eef4bc4376f4e 100644 --- a/agent/consul/config.go +++ b/agent/consul/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -40,9 +40,8 @@ const ( // LogStoreBackend* are well-known string values used to configure different // log store backends. - LogStoreBackendDefault = "default" - LogStoreBackendBoltDB = "boltdb" - LogStoreBackendWAL = "wal" + LogStoreBackendBoltDB = "boltdb" + LogStoreBackendWAL = "wal" ) var ( diff --git a/agent/consul/config_ce.go b/agent/consul/config_ce.go index b65a518615086..e91d0981e86ee 100644 --- a/agent/consul/config_ce.go +++ b/agent/consul/config_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/config_cloud.go b/agent/consul/config_cloud.go index 5b62574c811b4..b0780052f668a 100644 --- a/agent/consul/config_cloud.go +++ b/agent/consul/config_cloud.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package consul type CloudConfig struct { diff --git a/agent/consul/config_endpoint.go b/agent/consul/config_endpoint.go index a78859c35058e..4108eb20b95c6 100644 --- a/agent/consul/config_endpoint.go +++ b/agent/consul/config_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/config_endpoint_test.go b/agent/consul/config_endpoint_test.go index 49a10dce21797..7dc7632fade71 100644 --- a/agent/consul/config_endpoint_test.go +++ b/agent/consul/config_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/config_replication.go b/agent/consul/config_replication.go index d9573ad58bf99..1b9ac0284939a 100644 --- a/agent/consul/config_replication.go +++ b/agent/consul/config_replication.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/config_replication_test.go b/agent/consul/config_replication_test.go index 41ccf53362d5d..a0eb8cf52a6e1 100644 --- a/agent/consul/config_replication_test.go +++ b/agent/consul/config_replication_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/config_test.go b/agent/consul/config_test.go index 8e61b8fe96806..e2706e00b4065 100644 --- a/agent/consul/config_test.go +++ b/agent/consul/config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/connect_ca_endpoint.go b/agent/consul/connect_ca_endpoint.go index c61ee6ded900e..771eae2464b95 100644 --- a/agent/consul/connect_ca_endpoint.go +++ b/agent/consul/connect_ca_endpoint.go @@ -1,9 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul import ( + "errors" "fmt" "time" @@ -25,11 +26,10 @@ var ( // variable points to. Clients need to compare using `err.Error() == // consul.ErrRateLimited.Error()` which is very sad. Short of replacing our // RPC mechanism it's hard to know how to make that much better though. - - ErrConnectNotEnabled = structs.ErrConnectNotEnabled - ErrRateLimited = structs.ErrRateLimited - ErrNotPrimaryDatacenter = structs.ErrNotPrimaryDatacenter - ErrStateReadOnly = structs.ErrStateReadOnly + ErrConnectNotEnabled = errors.New("Connect must be enabled in order to use this endpoint") + ErrRateLimited = errors.New("Rate limit reached, try again later") // Note: we depend on this error message in the gRPC ConnectCA.Sign endpoint (see: isRateLimitError). + ErrNotPrimaryDatacenter = errors.New("not the primary datacenter") + ErrStateReadOnly = errors.New("CA Provider State is read-only") ) const ( diff --git a/agent/consul/connect_ca_endpoint_test.go b/agent/consul/connect_ca_endpoint_test.go index 587ed42b5a10e..3911db1923109 100644 --- a/agent/consul/connect_ca_endpoint_test.go +++ b/agent/consul/connect_ca_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/context.go b/agent/consul/context.go index d85124f74881a..7de4157d8f401 100644 --- a/agent/consul/context.go +++ b/agent/consul/context.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/context_test.go b/agent/consul/context_test.go index 42e6feb744868..264dcdd988611 100644 --- a/agent/consul/context_test.go +++ b/agent/consul/context_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/controller/controller.go b/agent/consul/controller/controller.go index 1eccb7e7aba04..f8d6a50c7f827 100644 --- a/agent/consul/controller/controller.go +++ b/agent/consul/controller/controller.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controller diff --git a/agent/consul/controller/controller_test.go b/agent/consul/controller/controller_test.go index 1d1002e8abede..97d110222b3e3 100644 --- a/agent/consul/controller/controller_test.go +++ b/agent/consul/controller/controller_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controller diff --git a/agent/consul/controller/doc.go b/agent/consul/controller/doc.go index ba30d95a546fd..638eb5c5d9a2e 100644 --- a/agent/consul/controller/doc.go +++ b/agent/consul/controller/doc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package controller contains a re-implementation of the Kubernetes // [controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) diff --git a/agent/consul/controller/queue/defer.go b/agent/consul/controller/queue/defer.go index e9b8a9c3ad751..01666219c2919 100644 --- a/agent/consul/controller/queue/defer.go +++ b/agent/consul/controller/queue/defer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package queue diff --git a/agent/consul/controller/queue/queue.go b/agent/consul/controller/queue/queue.go index 92c624cc2a734..6d9f0a657125d 100644 --- a/agent/consul/controller/queue/queue.go +++ b/agent/consul/controller/queue/queue.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package queue diff --git a/agent/consul/controller/queue/rate.go b/agent/consul/controller/queue/rate.go index 615047fdeb39b..471601f85a270 100644 --- a/agent/consul/controller/queue/rate.go +++ b/agent/consul/controller/queue/rate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package queue diff --git a/agent/consul/controller/queue/rate_test.go b/agent/consul/controller/queue/rate_test.go index 166111d5c7508..40dc540138e2a 100644 --- a/agent/consul/controller/queue/rate_test.go +++ b/agent/consul/controller/queue/rate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package queue diff --git a/agent/consul/controller/queue_test.go b/agent/consul/controller/queue_test.go index cb6f609829100..11e1bc82b7626 100644 --- a/agent/consul/controller/queue_test.go +++ b/agent/consul/controller/queue_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controller diff --git a/agent/consul/controller/reconciler.go b/agent/consul/controller/reconciler.go index fa948f81f6e62..dc4222508b57b 100644 --- a/agent/consul/controller/reconciler.go +++ b/agent/consul/controller/reconciler.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controller diff --git a/agent/consul/controller/reconciler_test.go b/agent/consul/controller/reconciler_test.go index c3b8a450b18bb..56ae022ea263b 100644 --- a/agent/consul/controller/reconciler_test.go +++ b/agent/consul/controller/reconciler_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controller diff --git a/agent/consul/coordinate_endpoint.go b/agent/consul/coordinate_endpoint.go index f0e69332ee686..28bf63b0bfd80 100644 --- a/agent/consul/coordinate_endpoint.go +++ b/agent/consul/coordinate_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/coordinate_endpoint_test.go b/agent/consul/coordinate_endpoint_test.go index 1c693ba83bbfe..fbb3e13aa76d6 100644 --- a/agent/consul/coordinate_endpoint_test.go +++ b/agent/consul/coordinate_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/discovery_chain_endpoint.go b/agent/consul/discovery_chain_endpoint.go index c70cebb094e68..4d1f9959c96e8 100644 --- a/agent/consul/discovery_chain_endpoint.go +++ b/agent/consul/discovery_chain_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/discovery_chain_endpoint_test.go b/agent/consul/discovery_chain_endpoint_test.go index 62d90e9020af6..b0197f00d493d 100644 --- a/agent/consul/discovery_chain_endpoint_test.go +++ b/agent/consul/discovery_chain_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/discoverychain/compile.go b/agent/consul/discoverychain/compile.go index 32a6408be5445..20227db3ef195 100644 --- a/agent/consul/discoverychain/compile.go +++ b/agent/consul/discoverychain/compile.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain diff --git a/agent/consul/discoverychain/compile_ce.go b/agent/consul/discoverychain/compile_ce.go index d407e4cc1c891..d980c71f38f05 100644 --- a/agent/consul/discoverychain/compile_ce.go +++ b/agent/consul/discoverychain/compile_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package discoverychain diff --git a/agent/consul/discoverychain/compile_test.go b/agent/consul/discoverychain/compile_test.go index dda28780431d1..ca39aa236fc95 100644 --- a/agent/consul/discoverychain/compile_test.go +++ b/agent/consul/discoverychain/compile_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain diff --git a/agent/consul/discoverychain/gateway.go b/agent/consul/discoverychain/gateway.go index c60c77b028fbf..d4447db73b595 100644 --- a/agent/consul/discoverychain/gateway.go +++ b/agent/consul/discoverychain/gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain @@ -27,10 +27,9 @@ type GatewayChainSynthesizer struct { } type hostnameMatch struct { - match structs.HTTPMatch - filters structs.HTTPFilters - responseFilters structs.HTTPResponseFilters - services []structs.HTTPService + match structs.HTTPMatch + filters structs.HTTPFilters + services []structs.HTTPService } // NewGatewayChainSynthesizer creates a new GatewayChainSynthesizer for the @@ -88,10 +87,9 @@ func initHostMatches(hostname string, route *structs.HTTPRouteConfigEntry, curre // Add all matches for this rule to the list for this hostname for _, match := range rule.Matches { matches = append(matches, hostnameMatch{ - match: match, - filters: rule.Filters, - responseFilters: rule.ResponseFilters, - services: rule.Services, + match: match, + filters: rule.Filters, + services: rule.Services, }) } } @@ -233,10 +231,9 @@ func consolidateHTTPRoutes(matchesByHostname map[string][]hostnameMatch, listene // Add all rules for this hostname for _, rule := range rules { route.Rules = append(route.Rules, structs.HTTPRouteRule{ - Matches: []structs.HTTPMatch{rule.match}, - Filters: rule.filters, - ResponseFilters: rule.responseFilters, - Services: rule.services, + Matches: []structs.HTTPMatch{rule.match}, + Filters: rule.filters, + Services: rule.services, }) } diff --git a/agent/consul/discoverychain/gateway_httproute.go b/agent/consul/discoverychain/gateway_httproute.go index c4816e0274497..fcd2dc440259f 100644 --- a/agent/consul/discoverychain/gateway_httproute.go +++ b/agent/consul/discoverychain/gateway_httproute.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain @@ -79,8 +79,7 @@ func httpRouteToDiscoveryChain(route structs.HTTPRouteConfigEntry) (*structs.Ser var defaults []*structs.ServiceConfigEntry for idx, rule := range route.Rules { - requestModifier := httpRouteFiltersToServiceRouteHeaderModifier(rule.Filters.Headers) - responseModifier := httpRouteFiltersToServiceRouteHeaderModifier(rule.ResponseFilters.Headers) + modifier := httpRouteFiltersToServiceRouteHeaderModifier(rule.Filters.Headers) prefixRewrite := httpRouteFiltersToDestinationPrefixRewrite(rule.Filters.URLRewrite) var destination structs.ServiceRouteDestination @@ -91,29 +90,16 @@ func httpRouteToDiscoveryChain(route structs.HTTPRouteConfigEntry) (*structs.Ser if service.Filters.URLRewrite == nil { servicePrefixRewrite = prefixRewrite } - - // Merge service request header modifier(s) onto route rule modifiers - // Note: Removals for the same header may exist on the rule + the service and - // will result in idempotent duplicate values in the modifier w/ service coming last - serviceRequestModifier := httpRouteFiltersToServiceRouteHeaderModifier(service.Filters.Headers) - requestModifier.Add = mergeMaps(requestModifier.Add, serviceRequestModifier.Add) - requestModifier.Set = mergeMaps(requestModifier.Set, serviceRequestModifier.Set) - requestModifier.Remove = append(requestModifier.Remove, serviceRequestModifier.Remove...) - - // Merge service response header modifier(s) onto route rule modifiers - // Note: Removals for the same header may exist on the rule + the service and - // will result in idempotent duplicate values in the modifier w/ service coming last - serviceResponseModifier := httpRouteFiltersToServiceRouteHeaderModifier(service.ResponseFilters.Headers) - responseModifier.Add = mergeMaps(responseModifier.Add, serviceResponseModifier.Add) - responseModifier.Set = mergeMaps(responseModifier.Set, serviceResponseModifier.Set) - responseModifier.Remove = append(responseModifier.Remove, serviceResponseModifier.Remove...) + serviceModifier := httpRouteFiltersToServiceRouteHeaderModifier(service.Filters.Headers) + modifier.Add = mergeMaps(modifier.Add, serviceModifier.Add) + modifier.Set = mergeMaps(modifier.Set, serviceModifier.Set) + modifier.Remove = append(modifier.Remove, serviceModifier.Remove...) destination.Service = service.Name destination.Namespace = service.NamespaceOrDefault() destination.Partition = service.PartitionOrDefault() destination.PrefixRewrite = servicePrefixRewrite - destination.RequestHeaders = requestModifier - destination.ResponseHeaders = responseModifier + destination.RequestHeaders = modifier // since we have already validated the protocol elsewhere, we // create a new service defaults here to make sure we pass validation @@ -129,8 +115,7 @@ func httpRouteToDiscoveryChain(route structs.HTTPRouteConfigEntry) (*structs.Ser destination.Namespace = route.NamespaceOrDefault() destination.Partition = route.PartitionOrDefault() destination.PrefixRewrite = prefixRewrite - destination.RequestHeaders = requestModifier - destination.ResponseHeaders = responseModifier + destination.RequestHeaders = modifier splitter := &structs.ServiceSplitterConfigEntry{ Kind: structs.ServiceSplitter, @@ -176,25 +161,6 @@ func httpRouteToDiscoveryChain(route structs.HTTPRouteConfigEntry) (*structs.Ser } } - if rule.Filters.RetryFilter != nil { - - destination.NumRetries = rule.Filters.RetryFilter.NumRetries - destination.RetryOnConnectFailure = rule.Filters.RetryFilter.RetryOnConnectFailure - - if len(rule.Filters.RetryFilter.RetryOn) > 0 { - destination.RetryOn = rule.Filters.RetryFilter.RetryOn - } - - if len(rule.Filters.RetryFilter.RetryOnStatusCodes) > 0 { - destination.RetryOnStatusCodes = rule.Filters.RetryFilter.RetryOnStatusCodes - } - } - - if rule.Filters.TimeoutFilter != nil { - destination.IdleTimeout = rule.Filters.TimeoutFilter.IdleTimeout - destination.RequestTimeout = rule.Filters.TimeoutFilter.RequestTimeout - } - // for each match rule a ServiceRoute is created for the service-router // if there are no rules a single route with the destination is set if len(rule.Matches) == 0 { @@ -207,7 +173,6 @@ func httpRouteToDiscoveryChain(route structs.HTTPRouteConfigEntry) (*structs.Ser Destination: &destination, }) } - } return router, splitters, defaults diff --git a/agent/consul/discoverychain/gateway_tcproute.go b/agent/consul/discoverychain/gateway_tcproute.go index 910fd517551c0..21afef3ec1846 100644 --- a/agent/consul/discoverychain/gateway_tcproute.go +++ b/agent/consul/discoverychain/gateway_tcproute.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain diff --git a/agent/consul/discoverychain/gateway_test.go b/agent/consul/discoverychain/gateway_test.go index 00c37e8aa407a..42bbed65ebfb6 100644 --- a/agent/consul/discoverychain/gateway_test.go +++ b/agent/consul/discoverychain/gateway_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain @@ -518,70 +518,8 @@ func TestGatewayChainSynthesizer_Synthesize(t *testing.T) { Kind: structs.HTTPRoute, Name: "http-route", Rules: []structs.HTTPRouteRule{{ - Filters: structs.HTTPFilters{ - Headers: []structs.HTTPHeaderFilter{ - { - Add: map[string]string{"add me to the rule request": "present"}, - Set: map[string]string{"set me on the rule request": "present"}, - Remove: []string{"remove me from the rule request"}, - }, - { - Add: map[string]string{"add me to the rule and service request": "rule"}, - Set: map[string]string{"set me on the rule and service request": "rule"}, - }, - { - Remove: []string{"remove me from the rule and service request"}, - }, - }, - }, - ResponseFilters: structs.HTTPResponseFilters{ - Headers: []structs.HTTPHeaderFilter{{ - Add: map[string]string{ - "add me to the rule response": "present", - "add me to the rule and service response": "rule", - }, - Set: map[string]string{ - "set me on the rule response": "present", - "set me on the rule and service response": "rule", - }, - Remove: []string{ - "remove me from the rule response", - "remove me from the rule and service response", - }, - }}, - }, Services: []structs.HTTPService{{ Name: "foo", - Filters: structs.HTTPFilters{ - Headers: []structs.HTTPHeaderFilter{ - { - Add: map[string]string{"add me to the service request": "present"}, - }, - { - Set: map[string]string{"set me on the service request": "present"}, - Remove: []string{"remove me from the service request"}, - }, - { - Add: map[string]string{"add me to the rule and service request": "service"}, - Set: map[string]string{"set me on the rule and service request": "service"}, - Remove: []string{"remove me from the rule and service request"}, - }, - }, - }, - ResponseFilters: structs.HTTPResponseFilters{ - Headers: []structs.HTTPHeaderFilter{ - { - Add: map[string]string{"add me to the service response": "present"}, - Set: map[string]string{"set me on the service response": "present"}, - Remove: []string{"remove me from the service response"}, - }, - { - Add: map[string]string{"add me to the rule and service response": "service"}, - Set: map[string]string{"set me on the rule and service response": "service"}, - Remove: []string{"remove me from the rule and service response"}, - }, - }, - }, }}, }}, }, @@ -619,40 +557,8 @@ func TestGatewayChainSynthesizer_Synthesize(t *testing.T) { Partition: "default", Namespace: "default", RequestHeaders: &structs.HTTPHeaderModifiers{ - Add: map[string]string{ - "add me to the rule request": "present", - "add me to the service request": "present", - "add me to the rule and service request": "service", - }, - Set: map[string]string{ - "set me on the rule request": "present", - "set me on the service request": "present", - "set me on the rule and service request": "service", - }, - Remove: []string{ - "remove me from the rule request", - "remove me from the rule and service request", - "remove me from the service request", - "remove me from the rule and service request", - }, - }, - ResponseHeaders: &structs.HTTPHeaderModifiers{ - Add: map[string]string{ - "add me to the rule response": "present", - "add me to the service response": "present", - "add me to the rule and service response": "service", - }, - Set: map[string]string{ - "set me on the rule response": "present", - "set me on the service response": "present", - "set me on the rule and service response": "service", - }, - Remove: []string{ - "remove me from the rule response", - "remove me from the rule and service response", - "remove me from the service response", - "remove me from the rule and service response", - }, + Add: make(map[string]string), + Set: make(map[string]string), }, }, }, @@ -757,10 +663,6 @@ func TestGatewayChainSynthesizer_Synthesize(t *testing.T) { Add: make(map[string]string), Set: make(map[string]string), }, - ResponseHeaders: &structs.HTTPHeaderModifiers{ - Add: make(map[string]string), - Set: make(map[string]string), - }, }, }, NextNode: "resolver:foo-2.default.default.dc2", @@ -948,10 +850,6 @@ func TestGatewayChainSynthesizer_ComplexChain(t *testing.T) { Add: make(map[string]string), Set: make(map[string]string), }, - ResponseHeaders: &structs.HTTPHeaderModifiers{ - Add: make(map[string]string), - Set: make(map[string]string), - }, }, }, NextNode: "splitter:splitter-one.default.default", diff --git a/agent/consul/discoverychain/string_stack.go b/agent/consul/discoverychain/string_stack.go index d5f842f3dc615..e47743a3f3861 100644 --- a/agent/consul/discoverychain/string_stack.go +++ b/agent/consul/discoverychain/string_stack.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain diff --git a/agent/consul/discoverychain/string_stack_test.go b/agent/consul/discoverychain/string_stack_test.go index 9867b91795206..84f58203d43b2 100644 --- a/agent/consul/discoverychain/string_stack_test.go +++ b/agent/consul/discoverychain/string_stack_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain diff --git a/agent/consul/discoverychain/testing.go b/agent/consul/discoverychain/testing.go index 8992870f9c457..37a3bb4ec1162 100644 --- a/agent/consul/discoverychain/testing.go +++ b/agent/consul/discoverychain/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discoverychain diff --git a/agent/consul/enterprise_client_ce.go b/agent/consul/enterprise_client_ce.go index 585c84d91d3ac..3d432213bd848 100644 --- a/agent/consul/enterprise_client_ce.go +++ b/agent/consul/enterprise_client_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/enterprise_config_ce.go b/agent/consul/enterprise_config_ce.go index cb26252e59358..15af4ea1603e7 100644 --- a/agent/consul/enterprise_config_ce.go +++ b/agent/consul/enterprise_config_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/enterprise_server_ce.go b/agent/consul/enterprise_server_ce.go index 61eb03cd1162e..8e56a8108cb35 100644 --- a/agent/consul/enterprise_server_ce.go +++ b/agent/consul/enterprise_server_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/enterprise_server_ce_test.go b/agent/consul/enterprise_server_ce_test.go index 1a3622d5d743c..9bd3eb8c0c9b0 100644 --- a/agent/consul/enterprise_server_ce_test.go +++ b/agent/consul/enterprise_server_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/federation_state_endpoint.go b/agent/consul/federation_state_endpoint.go index 4afa481a397b6..db842e666d65d 100644 --- a/agent/consul/federation_state_endpoint.go +++ b/agent/consul/federation_state_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/federation_state_endpoint_test.go b/agent/consul/federation_state_endpoint_test.go index 2ada2fc17a469..977de1c9c193c 100644 --- a/agent/consul/federation_state_endpoint_test.go +++ b/agent/consul/federation_state_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/federation_state_replication.go b/agent/consul/federation_state_replication.go index 2f5a6dd150f31..f56c3c6089c73 100644 --- a/agent/consul/federation_state_replication.go +++ b/agent/consul/federation_state_replication.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/federation_state_replication_test.go b/agent/consul/federation_state_replication_test.go index 97a34b8dc8c16..5100e45926a13 100644 --- a/agent/consul/federation_state_replication_test.go +++ b/agent/consul/federation_state_replication_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/filter.go b/agent/consul/filter.go index 920b8e843676f..18643463690ee 100644 --- a/agent/consul/filter.go +++ b/agent/consul/filter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/filter_test.go b/agent/consul/filter_test.go index 1ca34b0ed0726..d8f6ba54c3232 100644 --- a/agent/consul/filter_test.go +++ b/agent/consul/filter_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/flood.go b/agent/consul/flood.go index e01b5ed97eb83..ee7dfbc1dd5ec 100644 --- a/agent/consul/flood.go +++ b/agent/consul/flood.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/fsm/commands_ce.go b/agent/consul/fsm/commands_ce.go index 77bc94de1a9ae..e9f9f66e3361e 100644 --- a/agent/consul/fsm/commands_ce.go +++ b/agent/consul/fsm/commands_ce.go @@ -1,10 +1,9 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package fsm import ( - "errors" "fmt" "time" @@ -153,11 +152,7 @@ func init() { func (c *FSM) applyRegister(buf []byte, index uint64) interface{} { defer metrics.MeasureSince([]string{"fsm", "register"}, time.Now()) var req structs.RegisterRequest - if err := decodeRegistrationReq(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted register request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } @@ -172,11 +167,7 @@ func (c *FSM) applyRegister(buf []byte, index uint64) interface{} { func (c *FSM) applyDeregister(buf []byte, index uint64) interface{} { defer metrics.MeasureSince([]string{"fsm", "deregister"}, time.Now()) var req structs.DeregisterRequest - if err := decodeDeregistrationReq(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted deregister request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } @@ -204,11 +195,7 @@ func (c *FSM) applyDeregister(buf []byte, index uint64) interface{} { func (c *FSM) applyKVSOperation(buf []byte, index uint64) interface{} { var req structs.KVSRequest - if err := decodeKVSRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted KV request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "kvs"}, time.Now(), @@ -253,11 +240,7 @@ func (c *FSM) applyKVSOperation(buf []byte, index uint64) interface{} { func (c *FSM) applySessionOperation(buf []byte, index uint64) interface{} { var req structs.SessionRequest - if err := decodeSessionRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted session request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "session"}, time.Now(), @@ -316,11 +299,7 @@ func (c *FSM) applyCoordinateBatchUpdate(buf []byte, index uint64) interface{} { // state store. func (c *FSM) applyPreparedQueryOperation(buf []byte, index uint64) interface{} { var req structs.PreparedQueryRequest - if err := decodePreparedQueryRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted prepared query request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } @@ -339,7 +318,7 @@ func (c *FSM) applyPreparedQueryOperation(buf []byte, index uint64) interface{} func (c *FSM) applyTxn(buf []byte, index uint64) interface{} { var req structs.TxnRequest - if err := decodeTxnRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSince([]string{"fsm", "txn"}, time.Now()) @@ -506,7 +485,7 @@ func (c *FSM) applyConnectCALeafOperation(buf []byte, index uint64) interface{} func (c *FSM) applyACLTokenSetOperation(buf []byte, index uint64) interface{} { var req structs.ACLTokenBatchSetRequest - if err := decodeACLTokenBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "token"}, time.Now(), @@ -544,7 +523,7 @@ func (c *FSM) applyACLTokenBootstrap(buf []byte, index uint64) interface{} { func (c *FSM) applyACLPolicySetOperation(buf []byte, index uint64) interface{} { var req structs.ACLPolicyBatchSetRequest - if err := decodeACLPolicyBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "policy"}, time.Now(), @@ -565,12 +544,10 @@ func (c *FSM) applyACLPolicyDeleteOperation(buf []byte, index uint64) interface{ } func (c *FSM) applyConfigEntryOperation(buf []byte, index uint64) interface{} { - req := structs.ConfigEntryRequest{} - if err := decodeConfigEntryOperationRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted config entry request") - return nil - } + req := structs.ConfigEntryRequest{ + Entry: &structs.ProxyConfigEntry{}, + } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } @@ -617,7 +594,7 @@ func (c *FSM) applyConfigEntryOperation(buf []byte, index uint64) interface{} { func (c *FSM) applyACLRoleSetOperation(buf []byte, index uint64) interface{} { var req structs.ACLRoleBatchSetRequest - if err := decodeACLRoleBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "role"}, time.Now(), @@ -639,7 +616,7 @@ func (c *FSM) applyACLRoleDeleteOperation(buf []byte, index uint64) interface{} func (c *FSM) applyACLBindingRuleSetOperation(buf []byte, index uint64) interface{} { var req structs.ACLBindingRuleBatchSetRequest - if err := decodeACLBindingRuleBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "bindingrule"}, time.Now(), @@ -661,7 +638,7 @@ func (c *FSM) applyACLBindingRuleDeleteOperation(buf []byte, index uint64) inter func (c *FSM) applyACLAuthMethodSetOperation(buf []byte, index uint64) interface{} { var req structs.ACLAuthMethodBatchSetRequest - if err := decodeACLAuthMethodBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "authmethod"}, time.Now(), @@ -672,11 +649,7 @@ func (c *FSM) applyACLAuthMethodSetOperation(buf []byte, index uint64) interface func (c *FSM) applyACLAuthMethodDeleteOperation(buf []byte, index uint64) interface{} { var req structs.ACLAuthMethodBatchDeleteRequest - if err := decodeACLAuthMethodBatchDeleteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted acl auth method delete request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "authmethod"}, time.Now(), @@ -733,11 +706,7 @@ func (c *FSM) applySystemMetadataOperation(buf []byte, index uint64) interface{} func (c *FSM) applyPeeringWrite(buf []byte, index uint64) interface{} { var req pbpeering.PeeringWriteRequest - if err := decodePeeringWriteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted peering write request") - return nil - } + if err := structs.DecodeProto(buf, &req); err != nil { panic(fmt.Errorf("failed to decode peering write request: %v", err)) } @@ -749,11 +718,7 @@ func (c *FSM) applyPeeringWrite(buf []byte, index uint64) interface{} { func (c *FSM) applyPeeringDelete(buf []byte, index uint64) interface{} { var req pbpeering.PeeringDeleteRequest - if err := decodePeeringDeleteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted peering delete request") - return nil - } + if err := structs.DecodeProto(buf, &req); err != nil { panic(fmt.Errorf("failed to decode peering delete request: %v", err)) } @@ -793,11 +758,7 @@ func (c *FSM) applyPeeringTerminate(buf []byte, index uint64) interface{} { func (c *FSM) applyPeeringTrustBundleWrite(buf []byte, index uint64) interface{} { var req pbpeering.PeeringTrustBundleWriteRequest - if err := decodePeeringTrustBundleWriteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted peering trust bundle write request") - return nil - } + if err := structs.DecodeProto(buf, &req); err != nil { panic(fmt.Errorf("failed to decode peering trust bundle write request: %v", err)) } @@ -809,11 +770,7 @@ func (c *FSM) applyPeeringTrustBundleWrite(buf []byte, index uint64) interface{} func (c *FSM) applyPeeringTrustBundleDelete(buf []byte, index uint64) interface{} { var req pbpeering.PeeringTrustBundleDeleteRequest - if err := decodePeeringTrustBundleDeleteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted peering trust bundle delete request") - return nil - } + if err := structs.DecodeProto(buf, &req); err != nil { panic(fmt.Errorf("failed to decode peering trust bundle delete request: %v", err)) } @@ -833,11 +790,7 @@ func (f *FSM) applyResourceOperation(buf []byte, idx uint64) any { func (c *FSM) applyManualVirtualIPs(buf []byte, index uint64) interface{} { var req state.ServiceVirtualIP - if err := decodeServiceVirtualIPRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted virtual ip request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } diff --git a/agent/consul/fsm/commands_ce_test.go b/agent/consul/fsm/commands_ce_test.go index 445f4c0190760..cea6f05f54f3f 100644 --- a/agent/consul/fsm/commands_ce_test.go +++ b/agent/consul/fsm/commands_ce_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package fsm diff --git a/agent/consul/fsm/decode_ce.go b/agent/consul/fsm/decode_ce.go deleted file mode 100644 index 2f4d3da3a26cb..0000000000000 --- a/agent/consul/fsm/decode_ce.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent -// +build !consulent - -package fsm - -import ( - "github.com/hashicorp/consul/agent/consul/state" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/proto/private/pbpeering" -) - -func decodeRegistrationReq(buf []byte, req *structs.RegisterRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeRegistration(buf, req) -} - -func decodeDeregistrationReq(buf []byte, req *structs.DeregisterRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeDeregistration(buf, req) -} - -func decodeKVSRequest(buf []byte, req *structs.KVSRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeKVS(buf, req) -} - -func decodeSessionRequest(buf []byte, req *structs.SessionRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - - return decodeSession(buf, req) -} - -func decodePreparedQueryRequest(buf []byte, req *structs.PreparedQueryRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodePreparedQuery(buf, req) -} - -func decodeTxnRequest(buf []byte, req *structs.TxnRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeTxn(buf, req) -} - -func decodeACLTokenBatchSetRequest(buf []byte, req *structs.ACLTokenBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLTokenBatchSet(buf, req) - -} - -func decodeACLPolicyBatchSetRequest(buf []byte, req *structs.ACLPolicyBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLPolicyBatchSet(buf, req) - -} - -func decodeACLRoleBatchSetRequest(buf []byte, req *structs.ACLRoleBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLRoleBatchSet(buf, req) -} - -func decodeACLBindingRuleBatchSetRequest(buf []byte, req *structs.ACLBindingRuleBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLBindingRuleBatchSet(buf, req) -} - -func decodeACLAuthMethodBatchSetRequest(buf []byte, req *structs.ACLAuthMethodBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLAuthMethodBatchSet(buf, req) -} - -func decodeACLAuthMethodBatchDeleteRequest(buf []byte, req *structs.ACLAuthMethodBatchDeleteRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - - return decodeACLAuthMethodBatchDelete(buf, req) -} - -func decodeServiceVirtualIPRequest(buf []byte, req *state.ServiceVirtualIP) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeServiceVirtualIP(buf, req) -} - -func decodePeeringWriteRequest(buf []byte, req *pbpeering.PeeringWriteRequest) error { - if !structs.CEDowngrade { - return structs.DecodeProto(buf, req) - } - return decodePeeringWrite(buf, req) -} - -func decodePeeringDeleteRequest(buf []byte, req *pbpeering.PeeringDeleteRequest) error { - if !structs.CEDowngrade { - return structs.DecodeProto(buf, req) - } - - return decodePeeringDelete(buf, req) -} - -func decodePeeringTrustBundleWriteRequest(buf []byte, req *pbpeering.PeeringTrustBundleWriteRequest) error { - if !structs.CEDowngrade { - return structs.DecodeProto(buf, req) - } - return decodePeeringTrustBundleWrite(buf, req) -} - -func decodePeeringTrustBundleDeleteRequest(buf []byte, req *pbpeering.PeeringTrustBundleDeleteRequest) error { - if !structs.CEDowngrade { - return structs.DecodeProto(buf, req) - } - return decodePeeringTrustBundleDelete(buf, req) -} - -func decodeConfigEntryOperationRequest(buf []byte, req *structs.ConfigEntryRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - - return decodeConfigEntryOperation(buf, req) -} diff --git a/agent/consul/fsm/decode_downgrade.go b/agent/consul/fsm/decode_downgrade.go deleted file mode 100644 index 7b8e2fce719f2..0000000000000 --- a/agent/consul/fsm/decode_downgrade.go +++ /dev/null @@ -1,1011 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package fsm - -import ( - "errors" - "fmt" - - "github.com/hashicorp/consul-net-rpc/go-msgpack/codec" - "github.com/hashicorp/consul/agent/consul/state" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" - "github.com/hashicorp/consul/proto/private/pbpeering" -) - -func IsEnterpriseData(namespace, partition string) bool { - if (namespace != "" && namespace != "default") || (partition != "" && partition != "default") { - return true - } - return false -} - -var errIncompatibleTenantedData = errors.New("incompatible tenanted data") -var ErrDroppingTenantedReq = errors.New("dropping tenanted request") - -func decodeRegistration(buf []byte, req *structs.RegisterRequest) error { - type serviceRequest struct { - Namespace string - Partition string - *structs.NodeService - } - type checkRequest struct { - Namespace string - Partition string - *structs.HealthCheck - } - type NewRegReq struct { - - // shadows the Service field from the register request so that we can detect - // tenanted service registrations for untenanted nodes - Service *serviceRequest - - // shadows the Check field from the register request so that we can detect - // tenanted check registrations for untenanted nodes. - Check *checkRequest - - // shadows the Checks field for the same reasons as the singular version. - Checks []*checkRequest - - // Allows parsing the namespace of the whole request/node - Namespace string - - // Allows parsing the partition of the whole request/node - Partition string - *structs.RegisterRequest - } - var newReq NewRegReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - // checks if the node is tenanted - if IsEnterpriseData(newReq.Namespace, newReq.Partition) { - // the whole request can be dropped because the node itself is tenanted - return ErrDroppingTenantedReq - } - - // check if the service is tenanted - if newReq.Service != nil && !IsEnterpriseData(newReq.Service.Namespace, newReq.Service.Partition) { - // copy the shadow service pointer into the real RegisterRequest - newReq.RegisterRequest.Service = newReq.Service.NodeService - } - - // check if the singular check is tenanted - if newReq.Check != nil && !IsEnterpriseData(newReq.Check.Namespace, newReq.Check.Partition) { - newReq.RegisterRequest.Check = newReq.Check.HealthCheck - } - - // check for tenanted checks in the slice - for _, chk := range newReq.Checks { - if !IsEnterpriseData(chk.Namespace, chk.Partition) { - newReq.RegisterRequest.Checks = append(newReq.RegisterRequest.Checks, chk.HealthCheck) - } - } - // copy the data to the output request value - *req = *newReq.RegisterRequest - return nil -} - -func decodeDeregistration(buf []byte, req *structs.DeregisterRequest) error { - type NewDeRegReq struct { - Namespace string - - // Allows parsing the partition of the whole request/node - Partition string - - *structs.DeregisterRequest - - // Allows parsing the namespace of the whole request/node - - } - var newReq NewDeRegReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - // checks if the node is tenanted - if IsEnterpriseData(newReq.Namespace, newReq.Partition) { - // the whole request can be dropped because the node itself is tenanted - return ErrDroppingTenantedReq - } - - // copy the data to the output request value - *req = *newReq.DeregisterRequest - return nil -} - -func decodeKVS(buf []byte, req *structs.KVSRequest) error { - type dirEntryReq struct { - Namespace string - Partition string - *structs.DirEntry - } - type NewDirEntReq struct { - // shadows the DirEnt field from KVSRequest so that we can detect - // tenanted service registrations for untenanted nodes - DirEnt *dirEntryReq - *structs.KVSRequest - } - var newReq NewDirEntReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if newReq.DirEnt != nil && IsEnterpriseData(newReq.DirEnt.Namespace, newReq.DirEnt.Partition) { - return ErrDroppingTenantedReq - } - - newReq.KVSRequest.DirEnt = *newReq.DirEnt.DirEntry - *req = *newReq.KVSRequest - return nil -} - -func decodeSession(buf []byte, req *structs.SessionRequest) error { - type sessionReq struct { - Namespace string - Partition string - *structs.Session - } - type NewSessionReq struct { - // shadows the Session field from SessionRequest so that we can detect - // tenanted service registrations for untenanted nodes - Session *sessionReq - *structs.SessionRequest - } - var newReq NewSessionReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if newReq.Session != nil && IsEnterpriseData(newReq.Session.Namespace, newReq.Session.Partition) { - return ErrDroppingTenantedReq - - } - serviceChecks := newReq.Session.ServiceChecks - newReq.Session.ServiceChecks = nil - for _, sessionServiceCheck := range serviceChecks { - if !IsEnterpriseData(sessionServiceCheck.Namespace, "") { - newReq.Session.ServiceChecks = append(newReq.Session.ServiceChecks, sessionServiceCheck) - } - } - - newReq.SessionRequest.Session = *newReq.Session.Session - *req = *newReq.SessionRequest - return nil -} - -func decodePreparedQuery(buf []byte, req *structs.PreparedQueryRequest) error { - type serviceQuery struct { - Namespace string - Partition string - *structs.ServiceQuery - } - type prepQuery struct { - Service *serviceQuery - *structs.PreparedQuery - } - type NewPreparedQueryReq struct { - Query *prepQuery - *structs.PreparedQueryRequest - } - var newReq NewPreparedQueryReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if newReq.Query != nil && newReq.Query.Service != nil && IsEnterpriseData(newReq.Query.Service.Namespace, newReq.Query.Service.Partition) { - return ErrDroppingTenantedReq - } - - newReq.Query.PreparedQuery.Service = *newReq.Query.Service.ServiceQuery - newReq.PreparedQueryRequest.Query = newReq.Query.PreparedQuery - *req = *newReq.PreparedQueryRequest - return nil -} - -func decodeTxn(buf []byte, req *structs.TxnRequest) error { - type dirEntryReq struct { - Namespace string - Partition string - *structs.DirEntry - } - type txnKVOp struct { - DirEnt *dirEntryReq - *structs.TxnKVOp - } - type nodeService struct { - Namespace string - Partition string - *structs.NodeService - } - type txnServiceOp struct { - Service *nodeService - *structs.TxnServiceOp - } - type healthCheck struct { - Namespace string - Partition string - *structs.HealthCheck - } - type txnCheckOp struct { - Check *healthCheck - *structs.TxnCheckOp - } - type session struct { - Namespace string - Partition string - *structs.Session - } - type txnSessionOp struct { - Session *session - *structs.TxnSessionOp - } - // Only one of the types should be filled out per entry. - type txnOp struct { - KV *txnKVOp - Service *txnServiceOp - Check *txnCheckOp - Session *txnSessionOp - *structs.TxnOp - } - type NewTxnRequest struct { - Ops []*txnOp - *structs.TxnRequest - } - var newReq NewTxnRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - for _, op := range newReq.Ops { - if op.KV != nil && op.KV.DirEnt != nil && !IsEnterpriseData(op.KV.DirEnt.Namespace, op.KV.DirEnt.Partition) { - txnOp := &structs.TxnOp{ - KV: &structs.TxnKVOp{ - Verb: op.KV.Verb, - DirEnt: *op.KV.DirEnt.DirEntry, - }, - } - newReq.TxnRequest.Ops = append(newReq.TxnRequest.Ops, txnOp) - continue - } - - if op.Service != nil && op.Service.Service != nil && !IsEnterpriseData(op.Service.Service.Namespace, op.Service.Service.Partition) { - txnOp := &structs.TxnOp{ - Service: &structs.TxnServiceOp{ - Verb: op.Service.Verb, - Node: op.Service.Node, - Service: *op.Service.Service.NodeService, - }, - } - newReq.TxnRequest.Ops = append(newReq.TxnRequest.Ops, txnOp) - continue - } - - if op.Check != nil && op.Check.Check != nil && !IsEnterpriseData(op.Check.Check.Namespace, op.Check.Check.Partition) { - txnOp := &structs.TxnOp{ - Check: &structs.TxnCheckOp{ - Verb: op.Check.Verb, - Check: *op.Check.Check.HealthCheck, - }, - } - newReq.TxnRequest.Ops = append(newReq.TxnRequest.Ops, txnOp) - continue - } - - if op.Session != nil && op.Session.Session != nil && !IsEnterpriseData(op.Session.Session.Namespace, op.Session.Session.Partition) { - txnOp := &structs.TxnOp{ - Session: &structs.TxnSessionOp{ - Verb: op.Session.Verb, - Session: *op.Session.Session.Session, - }, - } - txnOp.Session.Session.ServiceChecks = nil - for _, sessionServiceCheck := range op.Session.Session.ServiceChecks { - if !IsEnterpriseData(sessionServiceCheck.Namespace, "") { - txnOp.Session.Session.ServiceChecks = append(txnOp.Session.Session.ServiceChecks, sessionServiceCheck) - } - } - newReq.TxnRequest.Ops = append(newReq.TxnRequest.Ops, txnOp) - } - } - - *req = *newReq.TxnRequest - return nil -} - -func decodeACLTokenBatchSet(buf []byte, req *structs.ACLTokenBatchSetRequest) error { - type aclToken struct { - Namespace string - Partition string - *structs.ACLToken - } - type NewACLTokenBatchSetRequest struct { - Tokens []*aclToken - *structs.ACLTokenBatchSetRequest - } - var newReq NewACLTokenBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - for _, token := range newReq.Tokens { - if !IsEnterpriseData(token.Namespace, token.Partition) { - newReq.ACLTokenBatchSetRequest.Tokens = append(newReq.ACLTokenBatchSetRequest.Tokens, token.ACLToken) - } - } - - *req = *newReq.ACLTokenBatchSetRequest - return nil - -} - -func decodeACLPolicyBatchSet(buf []byte, req *structs.ACLPolicyBatchSetRequest) error { - type aclPolicy struct { - Namespace string - Partition string - *structs.ACLPolicy - } - type NewACLPolicyBatchSetRequest struct { - Policies []*aclPolicy - *structs.ACLPolicyBatchSetRequest - } - var newReq NewACLPolicyBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - if newReq.ACLPolicyBatchSetRequest == nil { - newReq.ACLPolicyBatchSetRequest = &structs.ACLPolicyBatchSetRequest{} - } - for _, policy := range newReq.Policies { - if !IsEnterpriseData(policy.Namespace, policy.Partition) { - newReq.ACLPolicyBatchSetRequest.Policies = append(newReq.ACLPolicyBatchSetRequest.Policies, policy.ACLPolicy) - } - } - - *req = *newReq.ACLPolicyBatchSetRequest - return nil - -} - -func decodeACLRoleBatchSet(buf []byte, req *structs.ACLRoleBatchSetRequest) error { - type aclRole struct { - Namespace string - Partition string - *structs.ACLRole - } - type NewACLRoleBatchSetRequest struct { - Roles []*aclRole - *structs.ACLRoleBatchSetRequest - } - var newReq NewACLRoleBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - for _, role := range newReq.Roles { - if !IsEnterpriseData(role.Namespace, role.Partition) { - newReq.ACLRoleBatchSetRequest.Roles = append(newReq.ACLRoleBatchSetRequest.Roles, role.ACLRole) - } - } - - *req = *newReq.ACLRoleBatchSetRequest - return nil -} - -func decodeACLBindingRuleBatchSet(buf []byte, req *structs.ACLBindingRuleBatchSetRequest) error { - type aCLBindingRule struct { - Namespace string - Partition string - *structs.ACLBindingRule - } - type NewACLBindingRuleBatchSetRequest struct { - BindingRules []*aCLBindingRule - *structs.ACLBindingRuleBatchSetRequest - } - var newReq NewACLBindingRuleBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - if newReq.ACLBindingRuleBatchSetRequest == nil { - newReq.ACLBindingRuleBatchSetRequest = &structs.ACLBindingRuleBatchSetRequest{} - } - for _, rule := range newReq.BindingRules { - if !IsEnterpriseData(rule.Namespace, rule.Partition) { - newReq.ACLBindingRuleBatchSetRequest.BindingRules = append(newReq.ACLBindingRuleBatchSetRequest.BindingRules, rule.ACLBindingRule) - } - } - - *req = *newReq.ACLBindingRuleBatchSetRequest - return nil -} - -func decodeACLAuthMethodBatchSet(buf []byte, req *structs.ACLAuthMethodBatchSetRequest) error { - type aCLAuthMethod struct { - Namespace string - Partition string - *structs.ACLAuthMethod - } - type NewACLAuthMethodBatchSetRequest struct { - AuthMethods []*aCLAuthMethod - *structs.ACLAuthMethodBatchSetRequest - } - var newReq NewACLAuthMethodBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - if newReq.ACLAuthMethodBatchSetRequest == nil { - newReq.ACLAuthMethodBatchSetRequest = &structs.ACLAuthMethodBatchSetRequest{} - } - for _, authMethod := range newReq.AuthMethods { - if !IsEnterpriseData(authMethod.Namespace, authMethod.Partition) { - newReq.ACLAuthMethodBatchSetRequest.AuthMethods = append(newReq.ACLAuthMethodBatchSetRequest.AuthMethods, authMethod.ACLAuthMethod) - } - } - - *req = *newReq.ACLAuthMethodBatchSetRequest - return nil -} - -func decodeACLAuthMethodBatchDelete(buf []byte, req *structs.ACLAuthMethodBatchDeleteRequest) error { - type NewACLAuthMethodBatchDeleteRequest struct { - Namespace string - Partition string - *structs.ACLAuthMethodBatchDeleteRequest - } - - var newReq NewACLAuthMethodBatchDeleteRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if IsEnterpriseData(newReq.Namespace, newReq.Partition) { - return ErrDroppingTenantedReq - } - - *req = *newReq.ACLAuthMethodBatchDeleteRequest - return nil -} - -func decodeServiceVirtualIP(buf []byte, req *state.ServiceVirtualIP) error { - type serviceName struct { - Namespace string - Partition string - *structs.ServiceName - } - type peeredServiceName struct { - ServiceName *serviceName - *structs.PeeredServiceName - } - type NewServiceVirtualIP struct { - Service *peeredServiceName - *state.ServiceVirtualIP - } - var newReq NewServiceVirtualIP - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if newReq.Service != nil && newReq.Service.ServiceName != nil && IsEnterpriseData(newReq.Service.ServiceName.Namespace, newReq.Service.ServiceName.Partition) { - return ErrDroppingTenantedReq - } - newReq.ServiceVirtualIP.Service.ServiceName = *newReq.Service.ServiceName.ServiceName - *req = *newReq.ServiceVirtualIP - return nil -} - -func decodePeeringWrite(buf []byte, req *pbpeering.PeeringWriteRequest) error { - if err := structs.DecodeProto(buf, req); err != nil { - return err - } - - if req.Peering != nil && IsEnterpriseData("", req.Peering.Partition) { - return ErrDroppingTenantedReq - } - - return nil -} - -func decodePeeringDelete(buf []byte, req *pbpeering.PeeringDeleteRequest) error { - if err := structs.DecodeProto(buf, req); err != nil { - return err - } - - if IsEnterpriseData("", req.Partition) { - return ErrDroppingTenantedReq - } - - return nil -} - -func decodePeeringTrustBundleWrite(buf []byte, req *pbpeering.PeeringTrustBundleWriteRequest) error { - if err := structs.DecodeProto(buf, req); err != nil { - return err - } - - if IsEnterpriseData("", req.PeeringTrustBundle.Partition) { - return ErrDroppingTenantedReq - } - - return nil -} - -func decodePeeringTrustBundleDelete(buf []byte, req *pbpeering.PeeringTrustBundleDeleteRequest) error { - if err := structs.DecodeProto(buf, req); err != nil { - return err - } - - if IsEnterpriseData("", req.Partition) { - return ErrDroppingTenantedReq - } - - return nil -} - -func decodeConfigEntryOperation(buf []byte, req *structs.ConfigEntryRequest) error { - - newReq := &ShadowConfigEntryRequest{ - ConfigEntryRequest: req, - } - if err := structs.Decode(buf, newReq); err != nil { - return err - } - shadowConfigEntry := newReq.ConfigEntryRequest.Entry.(ShadowConfigentry) - if err := shadowConfigEntry.CheckEnt(); err != nil { - return err - } - req.Entry = shadowConfigEntry.GetRealConfigEntry() - return nil -} - -type ShadowConfigEntryRequest struct { - *structs.ConfigEntryRequest -} - -func (c *ShadowConfigEntryRequest) UnmarshalBinary(data []byte) error { - // First decode the kind prefix - var kind string - dec := codec.NewDecoderBytes(data, structs.MsgpackHandle) - if err := dec.Decode(&kind); err != nil { - return err - } - - // Then decode the real thing with appropriate kind of ConfigEntry - entry, err := MakeShadowConfigEntry(kind, "") - if err != nil { - return err - } - c.Entry = entry - // Alias juggling to prevent infinite recursive calls back to this decode - // method. - type Alias structs.ConfigEntryRequest - as := struct { - *Alias - }{ - Alias: (*Alias)(c.ConfigEntryRequest), - } - if err := dec.Decode(&as); err != nil { - return err - } - return nil -} -func MakeShadowConfigEntry(kind, name string) (structs.ConfigEntry, error) { - switch kind { - case structs.RateLimitIPConfig: - return nil, ErrDroppingTenantedReq - case structs.ServiceDefaults: - return &ShadowServiceConfigEntry{ServiceConfigEntry: &structs.ServiceConfigEntry{Name: name}}, nil - case structs.ProxyDefaults: - return &ShadowProxyConfigEntry{ProxyConfigEntry: &structs.ProxyConfigEntry{Name: name}}, nil - case structs.ServiceRouter: - return &ShadowServiceRouterConfigEntry{ServiceRouterConfigEntry: &structs.ServiceRouterConfigEntry{Name: name}}, nil - case structs.ServiceSplitter: - return &ShadowServiceSplitterConfigEntry{ServiceSplitterConfigEntry: &structs.ServiceSplitterConfigEntry{Name: name}}, nil - case structs.ServiceResolver: - return &ShadowServiceResolverConfigEntry{ServiceResolverConfigEntry: &structs.ServiceResolverConfigEntry{Name: name}}, nil - case structs.IngressGateway: - return &ShadowIngressGatewayConfigEntry{IngressGatewayConfigEntry: &structs.IngressGatewayConfigEntry{Name: name}}, nil - case structs.TerminatingGateway: - return &ShadowTerminatingGatewayConfigEntry{TerminatingGatewayConfigEntry: &structs.TerminatingGatewayConfigEntry{Name: name}}, nil - case structs.ServiceIntentions: - return &ShadowServiceIntentionsConfigEntry{ServiceIntentionsConfigEntry: &structs.ServiceIntentionsConfigEntry{Name: name}}, nil - case structs.MeshConfig: - return &ShadowMeshConfigEntry{MeshConfigEntry: &structs.MeshConfigEntry{}}, nil - case structs.ExportedServices: - return &ShadowExportedServicesConfigEntry{ExportedServicesConfigEntry: &structs.ExportedServicesConfigEntry{Name: name}}, nil - case structs.SamenessGroup: - return &ShadowSamenessGroupConfigEntry{SamenessGroupConfigEntry: &structs.SamenessGroupConfigEntry{Name: name}}, nil - case structs.APIGateway: - return &ShadowAPIGatewayConfigEntry{APIGatewayConfigEntry: &structs.APIGatewayConfigEntry{Name: name}}, nil - case structs.BoundAPIGateway: - return &ShadowBoundAPIGatewayConfigEntry{BoundAPIGatewayConfigEntry: &structs.BoundAPIGatewayConfigEntry{Name: name}}, nil - case structs.InlineCertificate: - return &ShadowInlineCertificateConfigEntry{InlineCertificateConfigEntry: &structs.InlineCertificateConfigEntry{Name: name}}, nil - case structs.HTTPRoute: - return &ShadowHTTPRouteConfigEntry{HTTPRouteConfigEntry: &structs.HTTPRouteConfigEntry{Name: name}}, nil - case structs.TCPRoute: - return &ShadowTCPRouteConfigEntry{TCPRouteConfigEntry: &structs.TCPRouteConfigEntry{Name: name}}, nil - case structs.JWTProvider: - return &ShadowJWTProviderConfigEntry{JWTProviderConfigEntry: &structs.JWTProviderConfigEntry{Name: name}}, nil - default: - return nil, fmt.Errorf("invalid config entry kind: %s", kind) - } -} - -type ShadowBase struct { - Namespace string - Partition string -} - -func (s ShadowBase) CheckEnt() error { - if IsEnterpriseData(s.Namespace, s.Partition) { - return ErrDroppingTenantedReq - } - return nil -} - -type ShadowConfigentry interface { - CheckEnt() error - GetRealConfigEntry() structs.ConfigEntry -} - -type ShadowProxyConfigEntry struct { - ShadowBase - *structs.ProxyConfigEntry -} - -func (s ShadowProxyConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.ProxyConfigEntry -} - -type ShadowServiceResolverConfigEntry struct { - ShadowBase - *structs.ServiceResolverConfigEntry -} - -func (s ShadowServiceResolverConfigEntry) CheckEnt() error { - if err := s.ShadowBase.CheckEnt(); err != nil { - return err - } - if s.ServiceResolverConfigEntry.Redirect != nil && (IsEnterpriseData(s.ServiceResolverConfigEntry.Redirect.Namespace, s.ServiceResolverConfigEntry.Redirect.Partition) || s.ServiceResolverConfigEntry.Redirect.SamenessGroup != "") { - return errIncompatibleTenantedData - } - for _, failover := range s.ServiceResolverConfigEntry.Failover { - if IsEnterpriseData(failover.Namespace, "") || failover.SamenessGroup != "" { - return errIncompatibleTenantedData - } - for _, target := range failover.Targets { - if IsEnterpriseData(target.Namespace, target.Partition) { - return errIncompatibleTenantedData - } - } - } - return nil -} - -func (s ShadowServiceResolverConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.ServiceResolverConfigEntry -} - -func (e *ShadowProxyConfigEntry) UnmarshalBinary(data []byte) error { - // The goal here is to add a post-decoding operation to - // decoding of a ProxyConfigEntry. The cleanest way I could - // find to do so was to implement the BinaryMarshaller interface - // and use a type alias to do the original round of decoding, - // followed by a MapWalk of the Config to coerce everything - // into JSON compatible types. - type Alias structs.ProxyConfigEntry - as := struct { - *ShadowBase - *Alias - }{ - ShadowBase: &e.ShadowBase, - Alias: (*Alias)(e.ProxyConfigEntry), - } - dec := codec.NewDecoderBytes(data, structs.MsgpackHandle) - if err := dec.Decode(&as); err != nil { - return err - } - config, err := lib.MapWalk(e.Config) - if err != nil { - return err - } - e.Config = config - return nil -} - -type ShadowUpstreamConfig struct { - ShadowBase - *structs.UpstreamConfig -} -type ShadowUpstreamConfiguration struct { - Overrides []*ShadowUpstreamConfig - *structs.UpstreamConfiguration -} -type ShadowServiceConfigEntry struct { - ShadowBase - UpstreamConfig *ShadowUpstreamConfiguration - *structs.ServiceConfigEntry -} - -func (s ShadowServiceConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - if s.UpstreamConfig != nil { - for _, override := range s.UpstreamConfig.Overrides { - if !IsEnterpriseData(override.Namespace, override.Partition) { - if s.ServiceConfigEntry.UpstreamConfig == nil { - s.ServiceConfigEntry.UpstreamConfig = &structs.UpstreamConfiguration{} - } - s.ServiceConfigEntry.UpstreamConfig.Overrides = append(s.ServiceConfigEntry.UpstreamConfig.Overrides, override.UpstreamConfig) - } - } - } - return s.ServiceConfigEntry -} - -type ShadowServiceRouterConfigEntry struct { - ShadowBase - *structs.ServiceRouterConfigEntry -} - -func (s ShadowServiceRouterConfigEntry) CheckEnt() error { - if err := s.ShadowBase.CheckEnt(); err != nil { - return err - } - for _, route := range s.ServiceRouterConfigEntry.Routes { - if IsEnterpriseData(route.Destination.Namespace, route.Destination.Partition) { - return errIncompatibleTenantedData - } - } - return nil -} - -func (s ShadowServiceRouterConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.ServiceRouterConfigEntry -} - -type ShadowServiceSplitterConfigEntry struct { - ShadowBase - *structs.ServiceSplitterConfigEntry -} - -func (s ShadowServiceSplitterConfigEntry) CheckEnt() error { - if err := s.ShadowBase.CheckEnt(); err != nil { - return err - } - for _, split := range s.ServiceSplitterConfigEntry.Splits { - if IsEnterpriseData(split.Namespace, split.Partition) { - return errIncompatibleTenantedData - } - } - return nil -} -func (s ShadowServiceSplitterConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.ServiceSplitterConfigEntry -} - -type ShadowIngressService struct { - ShadowBase - *structs.IngressService -} -type ShadowIngressListener struct { - Services []ShadowIngressService - *structs.IngressListener -} -type ShadowIngressGatewayConfigEntry struct { - ShadowBase - Listeners []ShadowIngressListener - *structs.IngressGatewayConfigEntry -} - -func (s ShadowIngressGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, listner := range s.Listeners { - for _, svc := range listner.Services { - if !IsEnterpriseData(svc.Namespace, svc.Partition) { - listner.IngressListener.Services = append(listner.IngressListener.Services, *svc.IngressService) - } - } - if len(listner.IngressListener.Services) == 0 { - continue - } - s.IngressGatewayConfigEntry.Listeners = append(s.IngressGatewayConfigEntry.Listeners, *listner.IngressListener) - } - return s.IngressGatewayConfigEntry -} - -type ShadowLinkedService struct { - ShadowBase - *structs.LinkedService -} - -type ShadowTerminatingGatewayConfigEntry struct { - ShadowBase - Services []ShadowLinkedService - *structs.TerminatingGatewayConfigEntry -} - -func (s ShadowTerminatingGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, svc := range s.Services { - if !IsEnterpriseData(svc.Namespace, svc.Partition) { - s.TerminatingGatewayConfigEntry.Services = append(s.TerminatingGatewayConfigEntry.Services, *svc.LinkedService) - } - } - return s.TerminatingGatewayConfigEntry -} - -type ShadowSourceIntention struct { - ShadowBase - *structs.SourceIntention -} -type ShadowServiceIntentionsConfigEntry struct { - ShadowBase - Sources []*ShadowSourceIntention - *structs.ServiceIntentionsConfigEntry -} - -func (s ShadowServiceIntentionsConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, source := range s.Sources { - if !IsEnterpriseData(source.Namespace, source.Partition) && source.SamenessGroup == "" { - s.ServiceIntentionsConfigEntry.Sources = append(s.ServiceIntentionsConfigEntry.Sources, source.SourceIntention) - } - } - return s.ServiceIntentionsConfigEntry -} - -type ShadowMeshConfigEntry struct { - ShadowBase - *structs.MeshConfigEntry -} - -func (s ShadowMeshConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.MeshConfigEntry -} - -type ShadowExportedServicesConfigEntry struct { - ShadowBase - *structs.ExportedServicesConfigEntry -} - -func (s ShadowExportedServicesConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - services := []structs.ExportedService{} - for _, svc := range s.ExportedServicesConfigEntry.Services { - if !IsEnterpriseData(svc.Namespace, "") { - consumers := []structs.ServiceConsumer{} - for _, consumer := range svc.Consumers { - if !IsEnterpriseData("", consumer.Partition) && consumer.SamenessGroup == "" { - consumers = append(consumers, consumer) - } - } - if len(consumers) == 0 { - continue - } - services = append(services, svc) - } - } - s.ExportedServicesConfigEntry.Services = services - return s.ExportedServicesConfigEntry -} - -type ShadowSamenessGroupConfigEntry struct { - ShadowBase - *structs.SamenessGroupConfigEntry -} - -func (s ShadowSamenessGroupConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.SamenessGroupConfigEntry -} - -type ShadowAPIGatewayConfigEntry struct { - ShadowBase - *structs.APIGatewayConfigEntry -} - -func (s ShadowAPIGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.APIGatewayConfigEntry -} - -type ShadowBoundAPIGatewayListener struct { - Routes []ShadowResourceReference - Certificates []ShadowResourceReference - *structs.BoundAPIGatewayListener -} -type ShadowBoundAPIGatewayConfigEntry struct { - ShadowBase - Listeners []ShadowBoundAPIGatewayListener - *structs.BoundAPIGatewayConfigEntry -} - -func (s ShadowBoundAPIGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, listner := range s.Listeners { - for _, route := range listner.Routes { - if !IsEnterpriseData(route.Namespace, route.Partition) { - listner.BoundAPIGatewayListener.Routes = append(listner.BoundAPIGatewayListener.Routes, *route.ResourceReference) - } - } - for _, cf := range listner.Certificates { - if !IsEnterpriseData(cf.Namespace, cf.Partition) { - listner.BoundAPIGatewayListener.Certificates = append(listner.BoundAPIGatewayListener.Certificates, *cf.ResourceReference) - } - } - s.BoundAPIGatewayConfigEntry.Listeners = append(s.BoundAPIGatewayConfigEntry.Listeners, *listner.BoundAPIGatewayListener) - } - return s.BoundAPIGatewayConfigEntry -} - -type ShadowInlineCertificateConfigEntry struct { - ShadowBase - *structs.InlineCertificateConfigEntry -} - -func (s ShadowInlineCertificateConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.InlineCertificateConfigEntry -} - -type ShadowHTTPService struct { - ShadowBase - *structs.HTTPService -} -type ShadowHTTPRouteRule struct { - Services []ShadowHTTPService - *structs.HTTPRouteRule -} -type ShadowResourceReference struct { - ShadowBase - *structs.ResourceReference -} -type ShadowHTTPRouteConfigEntry struct { - ShadowBase - Parents []ShadowResourceReference - Rules []ShadowHTTPRouteRule - *structs.HTTPRouteConfigEntry -} - -func (s ShadowHTTPRouteConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, parent := range s.Parents { - if !IsEnterpriseData(parent.Namespace, parent.Partition) { - s.HTTPRouteConfigEntry.Parents = append(s.HTTPRouteConfigEntry.Parents, *parent.ResourceReference) - } - } - for _, rule := range s.Rules { - for _, svc := range rule.Services { - if !IsEnterpriseData(svc.Namespace, svc.Partition) { - rule.HTTPRouteRule.Services = append(rule.HTTPRouteRule.Services, *svc.HTTPService) - } - } - s.HTTPRouteConfigEntry.Rules = append(s.HTTPRouteConfigEntry.Rules, *rule.HTTPRouteRule) - } - return s.HTTPRouteConfigEntry -} - -type ShadowTCPService struct { - ShadowBase - *structs.TCPService -} -type ShadowTCPRouteConfigEntry struct { - ShadowBase - Parents []ShadowResourceReference - Services []ShadowTCPService - *structs.TCPRouteConfigEntry -} - -func (s ShadowTCPRouteConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, parent := range s.Parents { - if !IsEnterpriseData(parent.Namespace, parent.Partition) { - s.TCPRouteConfigEntry.Parents = append(s.TCPRouteConfigEntry.Parents, *parent.ResourceReference) - } - } - for _, svc := range s.Services { - if !IsEnterpriseData(svc.Namespace, svc.Partition) { - s.TCPRouteConfigEntry.Services = append(s.TCPRouteConfigEntry.Services, *svc.TCPService) - } - } - return s.TCPRouteConfigEntry -} - -type ShadowJWTProviderConfigEntry struct { - ShadowBase - *structs.JWTProviderConfigEntry -} - -func (s ShadowJWTProviderConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.JWTProviderConfigEntry -} diff --git a/agent/consul/fsm/fsm.go b/agent/consul/fsm/fsm.go index 5a350e4dae778..4357ad7c39e2b 100644 --- a/agent/consul/fsm/fsm.go +++ b/agent/consul/fsm/fsm.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package fsm @@ -195,10 +195,6 @@ func (c *FSM) Apply(log *raft.Log) interface{} { c.logger.Warn("ignoring unknown message type, upgrade to newer version", "type", msgType) return nil } - if structs.CEDowngrade && msgType >= 64 { - c.logger.Warn("ignoring enterprise message, for downgrading to oss", "type", msgType) - return nil - } panic(fmt.Errorf("failed to apply request: %#v", buf)) } @@ -267,10 +263,7 @@ func (c *FSM) Restore(old io.ReadCloser) error { return err } default: - if structs.CEDowngrade && msg >= 64 { - c.logger.Warn("ignoring enterprise message , for downgrading to oss", "type", msg) - return nil - } else if msg >= 64 { + if msg >= 64 { return fmt.Errorf("msg type <%d> is a Consul Enterprise log entry. Consul CE cannot restore it", msg) } else { return fmt.Errorf("Unrecognized msg type %d", msg) diff --git a/agent/consul/fsm/fsm_test.go b/agent/consul/fsm/fsm_test.go index 839401014b52e..aa31615a5aa7a 100644 --- a/agent/consul/fsm/fsm_test.go +++ b/agent/consul/fsm/fsm_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package fsm diff --git a/agent/consul/fsm/log_verification_chunking_shim.go b/agent/consul/fsm/log_verification_chunking_shim.go index 4f40c1820b74d..a74b92b5684d3 100644 --- a/agent/consul/fsm/log_verification_chunking_shim.go +++ b/agent/consul/fsm/log_verification_chunking_shim.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package fsm diff --git a/agent/consul/fsm/snapshot.go b/agent/consul/fsm/snapshot.go index 24c8450cad2c1..a73b17daa4148 100644 --- a/agent/consul/fsm/snapshot.go +++ b/agent/consul/fsm/snapshot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package fsm diff --git a/agent/consul/fsm/snapshot_ce.go b/agent/consul/fsm/snapshot_ce.go index 0fcd38703661f..0ac39426a82b9 100644 --- a/agent/consul/fsm/snapshot_ce.go +++ b/agent/consul/fsm/snapshot_ce.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package fsm diff --git a/agent/consul/fsm/snapshot_ce_test.go b/agent/consul/fsm/snapshot_ce_test.go index 70ab2000faa41..b08e75716f385 100644 --- a/agent/consul/fsm/snapshot_ce_test.go +++ b/agent/consul/fsm/snapshot_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package fsm diff --git a/agent/consul/fsm/snapshot_test.go b/agent/consul/fsm/snapshot_test.go index 22d6f5e956eea..c09398d7a1534 100644 --- a/agent/consul/fsm/snapshot_test.go +++ b/agent/consul/fsm/snapshot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package fsm diff --git a/agent/consul/gateway_locator.go b/agent/consul/gateway_locator.go index 6503ca0c979d5..8f8ca29fbb469 100644 --- a/agent/consul/gateway_locator.go +++ b/agent/consul/gateway_locator.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/gateway_locator_test.go b/agent/consul/gateway_locator_test.go index a3e9da3d69007..f9b1daf26d825 100644 --- a/agent/consul/gateway_locator_test.go +++ b/agent/consul/gateway_locator_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/gateways/controller_gateways.go b/agent/consul/gateways/controller_gateways.go index ae82bdddc4495..cf4f25aa5d46d 100644 --- a/agent/consul/gateways/controller_gateways.go +++ b/agent/consul/gateways/controller_gateways.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package gateways @@ -63,8 +63,6 @@ func (r *apiGatewayReconciler) Reconcile(ctx context.Context, req controller.Req return reconcileEntry(r.fsm.State(), r.logger, ctx, req, r.reconcileTCPRoute, r.cleanupRoute) case structs.InlineCertificate: return r.enqueueCertificateReferencedGateways(r.fsm.State(), ctx, req) - case structs.JWTProvider: - return r.enqueueJWTProviderReferencedGatewaysAndHTTPRoutes(r.fsm.State(), ctx, req) default: return nil } @@ -235,18 +233,7 @@ func (r *apiGatewayReconciler) reconcileGateway(_ context.Context, req controlle logger.Warn("error retrieving bound api gateway", "error", err) return err } - - _, jwtProvidersConfigEntries, err := store.ConfigEntriesByKind(nil, structs.JWTProvider, wildcardMeta()) - if err != nil { - return err - } - - jwtProviders := make(map[string]*structs.JWTProviderConfigEntry, len(jwtProvidersConfigEntries)) - for _, provider := range jwtProvidersConfigEntries { - jwtProviders[provider.GetName()] = provider.(*structs.JWTProviderConfigEntry) - } - - meta := newGatewayMeta(gateway, bound, jwtProviders) + meta := newGatewayMeta(gateway, bound) certificateErrors, err := meta.checkCertificates(store) if err != nil { @@ -254,22 +241,16 @@ func (r *apiGatewayReconciler) reconcileGateway(_ context.Context, req controlle return err } - jwtErrors, err := meta.checkJWTProviders() - if err != nil { - logger.Warn("error checking gateway JWT Providers", "error", err) - return err - } - - // set each listener as having resolved refs, then overwrite that status condition + // set each listener as having valid certs, then overwrite that status condition // if there are any certificate errors - meta.eachListener(func(_ *structs.APIGatewayListener, bound *structs.BoundAPIGatewayListener) error { + meta.eachListener(func(listener *structs.APIGatewayListener, bound *structs.BoundAPIGatewayListener) error { listenerRef := structs.ResourceReference{ Kind: structs.APIGateway, Name: meta.BoundGateway.Name, SectionName: bound.Name, EnterpriseMeta: meta.BoundGateway.EnterpriseMeta, } - updater.SetCondition(resolvedRefs(listenerRef)) + updater.SetCondition(validCertificate(listenerRef)) return nil }) @@ -277,19 +258,9 @@ func (r *apiGatewayReconciler) reconcileGateway(_ context.Context, req controlle updater.SetCondition(invalidCertificate(ref, err)) } - for ref, err := range jwtErrors { - updater.SetCondition(invalidJWTProvider(ref, err)) - } - if len(certificateErrors) > 0 { updater.SetCondition(invalidCertificates()) - } - - if len(jwtErrors) > 0 { - updater.SetCondition(invalidJWTProviders()) - } - - if len(certificateErrors) == 0 && len(jwtErrors) == 0 { + } else { updater.SetCondition(gatewayAccepted()) } @@ -565,11 +536,6 @@ func NewAPIGatewayController(fsm *fsm.FSM, publisher state.EventPublisher, updat &stream.SubscribeRequest{ Topic: state.EventTopicInlineCertificate, Subject: stream.SubjectWildcard, - }, - ).Subscribe( - &stream.SubscribeRequest{ - Topic: state.EventTopicJWTProvider, - Subject: stream.SubjectWildcard, }) } @@ -592,10 +558,6 @@ type gatewayMeta struct { // the map values are pointers so that we can update them directly // and have the changes propagate back to the container gateways. boundListeners map[string]*structs.BoundAPIGatewayListener - // jwtProviders holds the list of all the JWT Providers in a given partition - // we expect this list to be relatively small so we're okay with holding them all - // in memory - jwtProviders map[string]*structs.JWTProviderConfigEntry } // getAllGatewayMeta returns a pre-constructed list of all valid gateway and state @@ -611,16 +573,6 @@ func getAllGatewayMeta(store *state.Store) ([]*gatewayMeta, error) { return nil, err } - _, jwtProvidersConfigEntries, err := store.ConfigEntriesByKind(nil, structs.JWTProvider, wildcardMeta()) - if err != nil { - return nil, err - } - - jwtProviders := make(map[string]*structs.JWTProviderConfigEntry, len(jwtProvidersConfigEntries)) - for _, provider := range jwtProvidersConfigEntries { - jwtProviders[provider.GetName()] = provider.(*structs.JWTProviderConfigEntry) - } - meta := make([]*gatewayMeta, 0, len(boundGateways)) for _, b := range boundGateways { bound := b.(*structs.BoundAPIGatewayConfigEntry) @@ -630,7 +582,6 @@ func getAllGatewayMeta(store *state.Store) ([]*gatewayMeta, error) { meta = append(meta, (&gatewayMeta{ BoundGateway: bound, Gateway: gateway, - jwtProviders: jwtProviders, }).initialize()) break } @@ -685,17 +636,7 @@ func (g *gatewayMeta) updateRouteBinding(route structs.BoundRoute) (bool, []stru if err != nil { errors[ref] = err } - - isValidJWT := true - if httpRoute, ok := route.(*structs.HTTPRouteConfigEntry); ok { - var jwtErrors map[structs.ResourceReference]error - isValidJWT, jwtErrors = g.validateJWTForRoute(httpRoute) - for ref, err := range jwtErrors { - errors[ref] = err - } - } - - if didBind && isValidJWT { + if didBind { refDidBind = true listenerBound[listener.Name] = true } @@ -706,7 +647,6 @@ func (g *gatewayMeta) updateRouteBinding(route structs.BoundRoute) (bool, []stru if !refDidBind && errors[ref] == nil { errors[ref] = fmt.Errorf("failed to bind route %s to gateway %s with listener '%s'", route.GetName(), g.Gateway.Name, ref.SectionName) } - if refDidBind { boundRefs = append(boundRefs, ref) } @@ -879,7 +819,7 @@ func (g *gatewayMeta) initialize() *gatewayMeta { } // newGatewayMeta returns an object that wraps the given APIGateway and BoundAPIGateway -func newGatewayMeta(gateway *structs.APIGatewayConfigEntry, bound structs.ConfigEntry, jwtProviders map[string]*structs.JWTProviderConfigEntry) *gatewayMeta { +func newGatewayMeta(gateway *structs.APIGatewayConfigEntry, bound structs.ConfigEntry) *gatewayMeta { var b *structs.BoundAPIGatewayConfigEntry if bound == nil { b = &structs.BoundAPIGatewayConfigEntry{ @@ -905,7 +845,6 @@ func newGatewayMeta(gateway *structs.APIGatewayConfigEntry, bound structs.Config return (&gatewayMeta{ BoundGateway: b, Gateway: gateway, - jwtProviders: jwtProviders, }).initialize() } @@ -923,7 +862,7 @@ func gatewayAccepted() structs.Condition { // invalidCertificate returns a condition used when a gateway references a // certificate that does not exist. It takes a ref used to scope the condition // to a given APIGateway listener. -func resolvedRefs(ref structs.ResourceReference) structs.Condition { +func validCertificate(ref structs.ResourceReference) structs.Condition { return structs.NewGatewayCondition( api.GatewayConditionResolvedRefs, api.ConditionStatusTrue, @@ -958,31 +897,6 @@ func invalidCertificates() structs.Condition { ) } -// invalidJWTProvider returns a condition used when a gateway listener references -// a JWTProvider that does not exist. It takes a ref used to scope the condition -// to a given APIGateway listener. -func invalidJWTProvider(ref structs.ResourceReference, err error) structs.Condition { - return structs.NewGatewayCondition( - api.GatewayConditionResolvedRefs, - api.ConditionStatusFalse, - api.GatewayListenerReasonInvalidJWTProviderRef, - err.Error(), - ref, - ) -} - -// invalidJWTProviders is used to set the overall condition of the APIGateway -// to invalid due to missing JWT providers that it references. -func invalidJWTProviders() structs.Condition { - return structs.NewGatewayCondition( - api.GatewayConditionAccepted, - api.ConditionStatusFalse, - api.GatewayReasonInvalidJWTProviders, - "gateway references invalid JWT Providers", - structs.ResourceReference{}, - ) -} - // gatewayListenerNoConflicts marks an APIGateway listener as having no conflicts within its // bound routes func gatewayListenerNoConflicts(ref structs.ResourceReference) structs.Condition { diff --git a/agent/consul/gateways/controller_gateways_ce.go b/agent/consul/gateways/controller_gateways_ce.go deleted file mode 100644 index 4e2aa9a523c84..0000000000000 --- a/agent/consul/gateways/controller_gateways_ce.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package gateways - -import ( - "context" - - "github.com/hashicorp/consul/agent/consul/controller" - "github.com/hashicorp/consul/agent/consul/state" - "github.com/hashicorp/consul/agent/structs" -) - -func (r *apiGatewayReconciler) enqueueJWTProviderReferencedGatewaysAndHTTPRoutes(_ *state.Store, _ context.Context, _ controller.Request) error { - return nil -} - -func (m *gatewayMeta) checkJWTProviders() (map[structs.ResourceReference]error, error) { - return nil, nil -} - -func (m *gatewayMeta) validateJWTForRoute(_ *structs.HTTPRouteConfigEntry) (bool, map[structs.ResourceReference]error) { - return true, nil -} diff --git a/agent/consul/gateways/controller_gateways_test.go b/agent/consul/gateways/controller_gateways_test.go index 5acb06f0411b8..07d85357acdc7 100644 --- a/agent/consul/gateways/controller_gateways_test.go +++ b/agent/consul/gateways/controller_gateways_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package gateways @@ -2013,7 +2013,7 @@ func TestAPIGatewayController(t *testing.T) { EnterpriseMeta: *defaultMeta, SectionName: "listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", EnterpriseMeta: *defaultMeta, @@ -2111,7 +2111,7 @@ func TestAPIGatewayController(t *testing.T) { EnterpriseMeta: *defaultMeta, SectionName: "listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", EnterpriseMeta: *defaultMeta, @@ -2240,7 +2240,7 @@ func TestAPIGatewayController(t *testing.T) { EnterpriseMeta: *defaultMeta, SectionName: "listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", EnterpriseMeta: *defaultMeta, @@ -2389,7 +2389,7 @@ func TestAPIGatewayController(t *testing.T) { EnterpriseMeta: *defaultMeta, SectionName: "listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", EnterpriseMeta: *defaultMeta, @@ -2536,7 +2536,7 @@ func TestAPIGatewayController(t *testing.T) { EnterpriseMeta: *defaultMeta, SectionName: "listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", EnterpriseMeta: *defaultMeta, @@ -2700,12 +2700,12 @@ func TestAPIGatewayController(t *testing.T) { Name: "gateway", SectionName: "tcp-listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", SectionName: "http-listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", SectionName: "tcp-listener", @@ -3054,7 +3054,7 @@ func TestAPIGatewayController(t *testing.T) { Name: "gateway", SectionName: "http-listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", SectionName: "http-listener", @@ -3407,7 +3407,7 @@ func TestAPIGatewayController(t *testing.T) { Name: "gateway", SectionName: "http-listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", SectionName: "http-listener", @@ -3504,12 +3504,12 @@ func TestAPIGatewayController(t *testing.T) { }, Status: structs.Status{ Conditions: []structs.Condition{ - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", SectionName: "listener-1", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", SectionName: "listener-2", @@ -3728,7 +3728,7 @@ func TestAPIGatewayController(t *testing.T) { Name: "gateway", SectionName: "invalid-listener", }, errors.New("certificate \"missing certificate\" not found")), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", SectionName: "valid-listener", @@ -3834,7 +3834,7 @@ func TestAPIGatewayController(t *testing.T) { Name: "gateway", SectionName: "http-listener", }), - resolvedRefs(structs.ResourceReference{ + validCertificate(structs.ResourceReference{ Kind: structs.APIGateway, Name: "gateway", SectionName: "http-listener", diff --git a/agent/consul/grpc_integration_test.go b/agent/consul/grpc_integration_test.go index 6ae49e09fa3aa..678403a450409 100644 --- a/agent/consul/grpc_integration_test.go +++ b/agent/consul/grpc_integration_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/health_endpoint.go b/agent/consul/health_endpoint.go index d26bbcd3b6f2f..c1286cce172fd 100644 --- a/agent/consul/health_endpoint.go +++ b/agent/consul/health_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/health_endpoint_test.go b/agent/consul/health_endpoint_test.go index b47159c229424..21a83ea90db2e 100644 --- a/agent/consul/health_endpoint_test.go +++ b/agent/consul/health_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/helper_test.go b/agent/consul/helper_test.go index d21523b8fecff..0619004c546e6 100644 --- a/agent/consul/helper_test.go +++ b/agent/consul/helper_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/intention_endpoint.go b/agent/consul/intention_endpoint.go index a3e4ad678b1d3..b00ebfbb46f0d 100644 --- a/agent/consul/intention_endpoint.go +++ b/agent/consul/intention_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/intention_endpoint_test.go b/agent/consul/intention_endpoint_test.go index d7e469b80326f..fb7dcaebf5737 100644 --- a/agent/consul/intention_endpoint_test.go +++ b/agent/consul/intention_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/internal_endpoint.go b/agent/consul/internal_endpoint.go index 1a8a0fca3028e..16dab8c22f87b 100644 --- a/agent/consul/internal_endpoint.go +++ b/agent/consul/internal_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/internal_endpoint_test.go b/agent/consul/internal_endpoint_test.go index 3f853df7ceb22..d7da66244336b 100644 --- a/agent/consul/internal_endpoint_test.go +++ b/agent/consul/internal_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/issue_test.go b/agent/consul/issue_test.go index 17624400fe3f1..14928a9db99d1 100644 --- a/agent/consul/issue_test.go +++ b/agent/consul/issue_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/kvs_endpoint.go b/agent/consul/kvs_endpoint.go index 65dc2cd56d40f..183f95f7f8bf0 100644 --- a/agent/consul/kvs_endpoint.go +++ b/agent/consul/kvs_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/kvs_endpoint_test.go b/agent/consul/kvs_endpoint_test.go index dc4272c4bd55d..ca9960f4b6e4e 100644 --- a/agent/consul/kvs_endpoint_test.go +++ b/agent/consul/kvs_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader.go b/agent/consul/leader.go index fcbf794541f3d..17408d4ef4419 100644 --- a/agent/consul/leader.go +++ b/agent/consul/leader.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_ce_test.go b/agent/consul/leader_ce_test.go index 8988adb9f7782..7ff6f64ee193d 100644 --- a/agent/consul/leader_ce_test.go +++ b/agent/consul/leader_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/leader_connect.go b/agent/consul/leader_connect.go index 794820786f576..f872508bbcf90 100644 --- a/agent/consul/leader_connect.go +++ b/agent/consul/leader_connect.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_connect_ca.go b/agent/consul/leader_connect_ca.go index 92cdf40a6abd2..717c9ff0b2544 100644 --- a/agent/consul/leader_connect_ca.go +++ b/agent/consul/leader_connect_ca.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -1436,7 +1436,6 @@ func (c *CAManager) AuthorizeAndSignCertificate(csr *x509.CertificateRequest, au if err != nil { return nil, err } - c.logger.Trace("authorizing and signing cert", "spiffeID", spiffeID) // Perform authorization. var authzContext acl.AuthorizerContext @@ -1455,11 +1454,6 @@ func (c *CAManager) AuthorizeAndSignCertificate(csr *x509.CertificateRequest, au return nil, connect.InvalidCSRError("SPIFFE ID in CSR from a different datacenter: %s, "+ "we are %s", v.Datacenter, dc) } - case *connect.SpiffeIDWorkloadIdentity: - v.GetEnterpriseMeta().FillAuthzContext(&authzContext) - if err := allow.IdentityWriteAllowed(v.WorkloadIdentity, &authzContext); err != nil { - return nil, err - } case *connect.SpiffeIDAgent: v.GetEnterpriseMeta().FillAuthzContext(&authzContext) if err := allow.NodeWriteAllowed(v.Agent, &authzContext); err != nil { @@ -1493,7 +1487,6 @@ func (c *CAManager) AuthorizeAndSignCertificate(csr *x509.CertificateRequest, au "we are %s", v.Datacenter, dc) } default: - c.logger.Trace("spiffe ID type is not expected", "spiffeID", spiffeID, "spiffeIDType", v) return nil, connect.InvalidCSRError("SPIFFE ID in CSR must be a service, mesh-gateway, or agent ID") } @@ -1520,7 +1513,6 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne agentID, isAgent := spiffeID.(*connect.SpiffeIDAgent) serverID, isServer := spiffeID.(*connect.SpiffeIDServer) mgwID, isMeshGateway := spiffeID.(*connect.SpiffeIDMeshGateway) - wID, isWorkloadIdentity := spiffeID.(*connect.SpiffeIDWorkloadIdentity) var entMeta acl.EnterpriseMeta switch { @@ -1530,12 +1522,7 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne "we are %s", serviceID.Host, signingID.Host()) } entMeta.Merge(serviceID.GetEnterpriseMeta()) - case isWorkloadIdentity: - if !signingID.CanSign(spiffeID) { - return nil, connect.InvalidCSRError("SPIFFE ID in CSR from a different trust domain: %s, "+ - "we are %s", wID.TrustDomain, signingID.Host()) - } - entMeta.Merge(wID.GetEnterpriseMeta()) + case isMeshGateway: if !signingID.CanSign(spiffeID) { return nil, connect.InvalidCSRError("SPIFFE ID in CSR from a different trust domain: %s, "+ @@ -1658,9 +1645,6 @@ func (c *CAManager) SignCertificate(csr *x509.CertificateRequest, spiffeID conne case isService: reply.Service = serviceID.Service reply.ServiceURI = cert.URIs[0].String() - case isWorkloadIdentity: - reply.WorkloadIdentity = wID.WorkloadIdentity - reply.WorkloadIdentityURI = cert.URIs[0].String() case isMeshGateway: reply.Kind = structs.ServiceKindMeshGateway reply.KindURI = cert.URIs[0].String() diff --git a/agent/consul/leader_connect_ca_test.go b/agent/consul/leader_connect_ca_test.go index e372c010a7064..e1c2cf8506c29 100644 --- a/agent/consul/leader_connect_ca_test.go +++ b/agent/consul/leader_connect_ca_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -566,7 +566,7 @@ func TestCAManager_Initialize_Logging(t *testing.T) { deps := newDefaultDeps(t, conf1) deps.Logger = logger - s1, err := NewServer(conf1, deps, grpc.NewServer(), nil, logger, nil) + s1, err := NewServer(conf1, deps, grpc.NewServer(), nil, logger) require.NoError(t, err) defer s1.Shutdown() testrpc.WaitForLeader(t, s1.RPC, "dc1") @@ -1317,12 +1317,6 @@ func TestCAManager_AuthorizeAndSignCertificate(t *testing.T) { Host: "test-host", Partition: "test-partition", }.URI() - identityURL := connect.SpiffeIDWorkloadIdentity{ - TrustDomain: "test-trust-domain", - Partition: "test-partition", - Namespace: "test-namespace", - WorkloadIdentity: "test-workload-identity", - }.URI() tests := []struct { name string @@ -1418,15 +1412,6 @@ func TestCAManager_AuthorizeAndSignCertificate(t *testing.T) { } }, }, - { - name: "err_identity_write_not_allowed", - expectErr: "Permission denied", - getCSR: func() *x509.CertificateRequest { - return &x509.CertificateRequest{ - URIs: []*url.URL{identityURL}, - } - }, - }, } for _, tc := range tests { diff --git a/agent/consul/leader_connect_test.go b/agent/consul/leader_connect_test.go index dbee808de99eb..e57107a242f52 100644 --- a/agent/consul/leader_connect_test.go +++ b/agent/consul/leader_connect_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_federation_state_ae.go b/agent/consul/leader_federation_state_ae.go index 870dc5460e2b0..fa46bea770b3a 100644 --- a/agent/consul/leader_federation_state_ae.go +++ b/agent/consul/leader_federation_state_ae.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_federation_state_ae_test.go b/agent/consul/leader_federation_state_ae_test.go index ca5ac47b7a974..ef3333da31dac 100644 --- a/agent/consul/leader_federation_state_ae_test.go +++ b/agent/consul/leader_federation_state_ae_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_intentions.go b/agent/consul/leader_intentions.go index 52736838aec81..cf0844d3ff5cd 100644 --- a/agent/consul/leader_intentions.go +++ b/agent/consul/leader_intentions.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_intentions_ce.go b/agent/consul/leader_intentions_ce.go index 2d997b2329498..83880d31de371 100644 --- a/agent/consul/leader_intentions_ce.go +++ b/agent/consul/leader_intentions_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/leader_intentions_ce_test.go b/agent/consul/leader_intentions_ce_test.go index e97c45a320cf1..7d144fb2e98e7 100644 --- a/agent/consul/leader_intentions_ce_test.go +++ b/agent/consul/leader_intentions_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/leader_intentions_test.go b/agent/consul/leader_intentions_test.go index fc868bc747fc1..2de1b97dd7e10 100644 --- a/agent/consul/leader_intentions_test.go +++ b/agent/consul/leader_intentions_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_log_verification.go b/agent/consul/leader_log_verification.go index 32a23dd3f5c06..ef32ce17904ea 100644 --- a/agent/consul/leader_log_verification.go +++ b/agent/consul/leader_log_verification.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_metrics.go b/agent/consul/leader_metrics.go index e210b2ffd9333..188e409e3bbd1 100644 --- a/agent/consul/leader_metrics.go +++ b/agent/consul/leader_metrics.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_metrics_test.go b/agent/consul/leader_metrics_test.go index e3636e1bcf8c9..96e7a0d75d971 100644 --- a/agent/consul/leader_metrics_test.go +++ b/agent/consul/leader_metrics_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_peering.go b/agent/consul/leader_peering.go index 0f58ed08f491e..32f220164b64c 100644 --- a/agent/consul/leader_peering.go +++ b/agent/consul/leader_peering.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_peering_test.go b/agent/consul/leader_peering_test.go index 8db496273d281..0787115ca70ac 100644 --- a/agent/consul/leader_peering_test.go +++ b/agent/consul/leader_peering_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/leader_test.go b/agent/consul/leader_test.go index 7a4b63eb05ee9..8a5a158ce34a3 100644 --- a/agent/consul/leader_test.go +++ b/agent/consul/leader_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -1640,7 +1640,7 @@ func TestLeader_ConfigEntryBootstrap_Fail(t *testing.T) { deps := newDefaultDeps(t, config) deps.Logger = logger - srv, err := NewServer(config, deps, grpc.NewServer(), nil, logger, nil) + srv, err := NewServer(config, deps, grpc.NewServer(), nil, logger) require.NoError(t, err) defer srv.Shutdown() diff --git a/agent/consul/logging.go b/agent/consul/logging.go index cfafe62b0d31f..da07daa8febfa 100644 --- a/agent/consul/logging.go +++ b/agent/consul/logging.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/logging_test.go b/agent/consul/logging_test.go index 3b756c0bb6226..7f090992a7a26 100644 --- a/agent/consul/logging_test.go +++ b/agent/consul/logging_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/merge.go b/agent/consul/merge.go index f6771d110f0ce..21b59f1aa92d6 100644 --- a/agent/consul/merge.go +++ b/agent/consul/merge.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/merge_ce.go b/agent/consul/merge_ce.go index c5d8096e708a7..59704f6533203 100644 --- a/agent/consul/merge_ce.go +++ b/agent/consul/merge_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/merge_ce_test.go b/agent/consul/merge_ce_test.go index e12ea660f72fa..8b0a7514ab264 100644 --- a/agent/consul/merge_ce_test.go +++ b/agent/consul/merge_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/merge_test.go b/agent/consul/merge_test.go index bc9d1f2cb4da8..f5f5c6d88ff1c 100644 --- a/agent/consul/merge_test.go +++ b/agent/consul/merge_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/multilimiter/multilimiter.go b/agent/consul/multilimiter/multilimiter.go index a0b9a6044f0df..f40e6c501abe6 100644 --- a/agent/consul/multilimiter/multilimiter.go +++ b/agent/consul/multilimiter/multilimiter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package multilimiter diff --git a/agent/consul/multilimiter/multilimiter_test.go b/agent/consul/multilimiter/multilimiter_test.go index e7cdab4e14824..b649bdb6c9c95 100644 --- a/agent/consul/multilimiter/multilimiter_test.go +++ b/agent/consul/multilimiter/multilimiter_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package multilimiter diff --git a/agent/consul/operator_autopilot_endpoint.go b/agent/consul/operator_autopilot_endpoint.go index 39bd5b648ddb8..b6ef7d38e6565 100644 --- a/agent/consul/operator_autopilot_endpoint.go +++ b/agent/consul/operator_autopilot_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/operator_autopilot_endpoint_test.go b/agent/consul/operator_autopilot_endpoint_test.go index 4cef3f0960d42..c9258e9aa2705 100644 --- a/agent/consul/operator_autopilot_endpoint_test.go +++ b/agent/consul/operator_autopilot_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/operator_backend.go b/agent/consul/operator_backend.go index 136baa1a22ab1..a72128735ab3c 100644 --- a/agent/consul/operator_backend.go +++ b/agent/consul/operator_backend.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/operator_backend_test.go b/agent/consul/operator_backend_test.go index 0a4650359ec1e..2189fe00630c7 100644 --- a/agent/consul/operator_backend_test.go +++ b/agent/consul/operator_backend_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/operator_endpoint.go b/agent/consul/operator_endpoint.go index 67259c9408a95..33e73e6ee1df9 100644 --- a/agent/consul/operator_endpoint.go +++ b/agent/consul/operator_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/operator_raft_endpoint.go b/agent/consul/operator_raft_endpoint.go index b8a16fc2c3ec9..7b0bcbc5cc035 100644 --- a/agent/consul/operator_raft_endpoint.go +++ b/agent/consul/operator_raft_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/operator_raft_endpoint_test.go b/agent/consul/operator_raft_endpoint_test.go index bb2dc88fc89e3..7242c40e6c45a 100644 --- a/agent/consul/operator_raft_endpoint_test.go +++ b/agent/consul/operator_raft_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/operator_usage_endpoint.go b/agent/consul/operator_usage_endpoint.go index 68f3137d0a61f..d23815b147c7d 100644 --- a/agent/consul/operator_usage_endpoint.go +++ b/agent/consul/operator_usage_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/options.go b/agent/consul/options.go index 88c16bd1a99c5..26cb2471a89bc 100644 --- a/agent/consul/options.go +++ b/agent/consul/options.go @@ -1,10 +1,9 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul import ( - "github.com/hashicorp/consul/lib/stringslice" "google.golang.org/grpc" "github.com/hashicorp/consul-net-rpc/net/rpc" @@ -13,17 +12,14 @@ import ( "github.com/hashicorp/consul/agent/consul/stream" "github.com/hashicorp/consul/agent/grpc-external/limiter" "github.com/hashicorp/consul/agent/hcp" - "github.com/hashicorp/consul/agent/leafcert" "github.com/hashicorp/consul/agent/pool" "github.com/hashicorp/consul/agent/router" "github.com/hashicorp/consul/agent/rpc/middleware" "github.com/hashicorp/consul/agent/token" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/tlsutil" ) type Deps struct { - LeafCertManager *leafcert.Manager EventPublisher *stream.EventPublisher Logger hclog.InterceptLogger TLSConfigurator *tlsutil.Configurator @@ -33,7 +29,6 @@ type Deps struct { GRPCConnPool GRPCClientConner LeaderForwarder LeaderForwarder XDSStreamLimiter *limiter.SessionLimiter - Registry resource.Registry // GetNetRPCInterceptorFunc, if not nil, sets the net/rpc rpc.ServerServiceCallInterceptor on // the server side to record metrics around the RPC requests. If nil, no interceptor is added to // the rpc server. @@ -49,24 +44,6 @@ type Deps struct { EnterpriseDeps } -// UseV2Resources returns true if "resource-apis" is present in the Experiments -// array of the agent config. -func (d Deps) UseV2Resources() bool { - if stringslice.Contains(d.Experiments, CatalogResourceExperimentName) { - return true - } - return false -} - -// UseV2Tenancy returns true if "v2tenancy" is present in the Experiments -// array of the agent config. -func (d Deps) UseV2Tenancy() bool { - if stringslice.Contains(d.Experiments, V2TenancyExperimentName) { - return true - } - return false -} - type GRPCClientConner interface { ClientConn(datacenter string) (*grpc.ClientConn, error) ClientConnLeader() (*grpc.ClientConn, error) diff --git a/agent/consul/options_ce.go b/agent/consul/options_ce.go index dbc8dd15ca7ee..7604ddd87f925 100644 --- a/agent/consul/options_ce.go +++ b/agent/consul/options_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/peering_backend.go b/agent/consul/peering_backend.go index 5a27bc6442a1d..1771be10fbaac 100644 --- a/agent/consul/peering_backend.go +++ b/agent/consul/peering_backend.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/peering_backend_ce.go b/agent/consul/peering_backend_ce.go index 22b70886ab4ae..81a133b3425a0 100644 --- a/agent/consul/peering_backend_ce.go +++ b/agent/consul/peering_backend_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/peering_backend_ce_test.go b/agent/consul/peering_backend_ce_test.go index d8c476925969c..410bf5f234273 100644 --- a/agent/consul/peering_backend_ce_test.go +++ b/agent/consul/peering_backend_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/peering_backend_test.go b/agent/consul/peering_backend_test.go index adfe6fe228f95..648052b7a15fe 100644 --- a/agent/consul/peering_backend_test.go +++ b/agent/consul/peering_backend_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/prepared_query/template.go b/agent/consul/prepared_query/template.go index 03cf9d2f58505..ef2e2abd4cae4 100644 --- a/agent/consul/prepared_query/template.go +++ b/agent/consul/prepared_query/template.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package prepared_query diff --git a/agent/consul/prepared_query/template_test.go b/agent/consul/prepared_query/template_test.go index 7c9b2f1a3af29..d4f78402140de 100644 --- a/agent/consul/prepared_query/template_test.go +++ b/agent/consul/prepared_query/template_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package prepared_query diff --git a/agent/consul/prepared_query/walk.go b/agent/consul/prepared_query/walk.go index 72296c0c7fe64..da53ce105b5f3 100644 --- a/agent/consul/prepared_query/walk.go +++ b/agent/consul/prepared_query/walk.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package prepared_query diff --git a/agent/consul/prepared_query/walk_ce_test.go b/agent/consul/prepared_query/walk_ce_test.go index 00f3edb10de11..dec84b241b0a3 100644 --- a/agent/consul/prepared_query/walk_ce_test.go +++ b/agent/consul/prepared_query/walk_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package prepared_query diff --git a/agent/consul/prepared_query/walk_test.go b/agent/consul/prepared_query/walk_test.go index b788571e4af5f..9ff380248bd2b 100644 --- a/agent/consul/prepared_query/walk_test.go +++ b/agent/consul/prepared_query/walk_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package prepared_query diff --git a/agent/consul/prepared_query_endpoint.go b/agent/consul/prepared_query_endpoint.go index 139556bb1af8c..101839708ea2f 100644 --- a/agent/consul/prepared_query_endpoint.go +++ b/agent/consul/prepared_query_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/prepared_query_endpoint_ce.go b/agent/consul/prepared_query_endpoint_ce.go index 3498b7063d3e4..612b81b2e6880 100644 --- a/agent/consul/prepared_query_endpoint_ce.go +++ b/agent/consul/prepared_query_endpoint_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/prepared_query_endpoint_ce_test.go b/agent/consul/prepared_query_endpoint_ce_test.go index d090fa1d84046..876f91d42cd5d 100644 --- a/agent/consul/prepared_query_endpoint_ce_test.go +++ b/agent/consul/prepared_query_endpoint_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/prepared_query_endpoint_test.go b/agent/consul/prepared_query_endpoint_test.go index f0d63dc277c18..af1fd65a876d1 100644 --- a/agent/consul/prepared_query_endpoint_test.go +++ b/agent/consul/prepared_query_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -2808,7 +2808,7 @@ func TestPreparedQuery_Wrapper(t *testing.T) { t.Fatalf("bad: %v", ret) } // Since we have no idea when the joinWAN operation completes - // we keep on querying until the join operation completes. + // we keep on querying until the the join operation completes. retry.Run(t, func(r *retry.R) { r.Check(s1.forwardDC("Status.Ping", "dc2", &struct{}{}, &struct{}{})) }) diff --git a/agent/consul/raft_handle.go b/agent/consul/raft_handle.go index 2906fe7115f19..bf38f0ee9e767 100644 --- a/agent/consul/raft_handle.go +++ b/agent/consul/raft_handle.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/raft_rpc.go b/agent/consul/raft_rpc.go index 1a0d6caa64d4a..7928ad31e2b9a 100644 --- a/agent/consul/raft_rpc.go +++ b/agent/consul/raft_rpc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/rate/handler.go b/agent/consul/rate/handler.go index bb3aef63931dd..c18ec85eddc8d 100644 --- a/agent/consul/rate/handler.go +++ b/agent/consul/rate/handler.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package rate implements server-side RPC rate limiting. package rate diff --git a/agent/consul/rate/handler_ce.go b/agent/consul/rate/handler_ce.go index b0a7beb7c18a0..fc33a69487f88 100644 --- a/agent/consul/rate/handler_ce.go +++ b/agent/consul/rate/handler_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package rate diff --git a/agent/consul/rate/handler_test.go b/agent/consul/rate/handler_test.go index 268568ce9599c..54a8b86a4b989 100644 --- a/agent/consul/rate/handler_test.go +++ b/agent/consul/rate/handler_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rate diff --git a/agent/consul/rate/metrics.go b/agent/consul/rate/metrics.go index ac69c14661776..cbf796fa935c6 100644 --- a/agent/consul/rate/metrics.go +++ b/agent/consul/rate/metrics.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rate diff --git a/agent/consul/replication.go b/agent/consul/replication.go index 08b8811129bea..0d85d082653cb 100644 --- a/agent/consul/replication.go +++ b/agent/consul/replication.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/replication_test.go b/agent/consul/replication_test.go index 27000fc563b78..e37e19b1f2933 100644 --- a/agent/consul/replication_test.go +++ b/agent/consul/replication_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/reporting/reporting.go b/agent/consul/reporting/reporting.go index d6c480f6bace4..fec7050f695ba 100644 --- a/agent/consul/reporting/reporting.go +++ b/agent/consul/reporting/reporting.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package reporting diff --git a/agent/consul/reporting/reporting_ce.go b/agent/consul/reporting/reporting_ce.go index b9eb978b8c026..a1e95a177416c 100644 --- a/agent/consul/reporting/reporting_ce.go +++ b/agent/consul/reporting/reporting_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package reporting diff --git a/agent/consul/rpc.go b/agent/consul/rpc.go index dbb781951e348..f97a5ff886746 100644 --- a/agent/consul/rpc.go +++ b/agent/consul/rpc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/rpc_test.go b/agent/consul/rpc_test.go index 39351c98ca92a..f1b05fa528287 100644 --- a/agent/consul/rpc_test.go +++ b/agent/consul/rpc_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/rtt.go b/agent/consul/rtt.go index 1599301e158df..5db0a634b4352 100644 --- a/agent/consul/rtt.go +++ b/agent/consul/rtt.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/rtt_test.go b/agent/consul/rtt_test.go index aeed0b66f50d5..9420f36c83657 100644 --- a/agent/consul/rtt_test.go +++ b/agent/consul/rtt_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/segment_ce.go b/agent/consul/segment_ce.go index 25e941ced0056..a3c0162d2a1e2 100644 --- a/agent/consul/segment_ce.go +++ b/agent/consul/segment_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/serf_filter.go b/agent/consul/serf_filter.go index 7b09c2b9e8020..fd6911bf0ab8a 100644 --- a/agent/consul/serf_filter.go +++ b/agent/consul/serf_filter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/serf_test.go b/agent/consul/serf_test.go index 4d4bc4926a46d..62cc6d0a0ba3f 100644 --- a/agent/consul/serf_test.go +++ b/agent/consul/serf_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server.go b/agent/consul/server.go index 0dfe48b4bf781..6bb424c67535d 100644 --- a/agent/consul/server.go +++ b/agent/consul/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -34,9 +34,9 @@ import ( "golang.org/x/time/rate" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/reflection" "github.com/hashicorp/consul-net-rpc/net/rpc" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" "github.com/hashicorp/consul/agent/blockingquery" @@ -70,21 +70,17 @@ import ( "github.com/hashicorp/consul/agent/rpc/peering" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/token" - "github.com/hashicorp/consul/internal/auth" "github.com/hashicorp/consul/internal/catalog" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/mesh" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/internal/resource/reaper" raftstorage "github.com/hashicorp/consul/internal/storage/raft" - "github.com/hashicorp/consul/internal/tenancy" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/routine" "github.com/hashicorp/consul/lib/stringslice" "github.com/hashicorp/consul/logging" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/pbsubscribe" "github.com/hashicorp/consul/tlsutil" @@ -137,8 +133,7 @@ const ( LeaderTransferMinVersion = "1.6.0" - CatalogResourceExperimentName = "resource-apis" - V2TenancyExperimentName = "v2tenancy" + catalogResourceExperimentName = "resource-apis" ) const ( @@ -247,7 +242,7 @@ type Server struct { // serf cluster that spans datacenters eventChWAN chan serf.Event - // wanMembershipNotifyCh is used to receive notifications that the + // wanMembershipNotifyCh is used to receive notifications that the the // serfWAN wan pool may have changed. // // If this is nil, notification is skipped. @@ -444,33 +439,19 @@ type Server struct { // run by the Server routineManager *routine.Manager - // resourceServiceServer implements the Resource Service. - resourceServiceServer *resourcegrpc.Server - - // insecureResourceServiceClient is a client that can be used to communicate - // with the Resource Service in-process (i.e. not via the network) *without* - // auth. It should only be used for purely-internal workloads, such as - // controllers. - insecureResourceServiceClient pbresource.ResourceServiceClient + // typeRegistry contains Consul's registered resource types. + typeRegistry resource.Registry - // secureResourceServiceClient is a client that can be used to communicate - // with the Resource Service in-process (i.e. not via the network) *with* auth. - // It can be used to make requests to the Resource Service on behalf of the user - // (e.g. from the HTTP API). - secureResourceServiceClient pbresource.ResourceServiceClient + // internalResourceServiceClient is a client that can be used to communicate + // with the Resource Service in-process (i.e. not via the network) without auth. + // It should only be used for purely-internal workloads, such as controllers. + internalResourceServiceClient pbresource.ResourceServiceClient // controllerManager schedules the execution of controllers. controllerManager *controller.Manager // handles metrics reporting to HashiCorp reportingManager *reporting.ReportingManager - - registry resource.Registry - - useV2Resources bool - - // useV2Tenancy is tied to the "v2tenancy" feature flag. - useV2Tenancy bool } func (s *Server) DecrementBlockingQueries() uint64 { @@ -491,22 +472,9 @@ type connHandler interface { Shutdown() error } -// ProxyUpdater is an interface for ProxyTracker. -type ProxyUpdater interface { - // PushChange allows pushing a computed ProxyState to xds for xds resource generation to send to a proxy. - PushChange(id *pbresource.ID, snapshot proxysnapshot.ProxySnapshot) error - - // ProxyConnectedToServer returns whether this id is connected to this server. If it is connected, it also returns - // the token as the first argument. - ProxyConnectedToServer(id *pbresource.ID) (string, bool) - - EventChannel() chan controller.Event -} - // NewServer is used to construct a new Consul server from the configuration // and extra options, potentially returning an error. -func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, - incomingRPCLimiter rpcRate.RequestLimitsHandler, serverLogger hclog.InterceptLogger, proxyUpdater ProxyUpdater) (*Server, error) { +func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, incomingRPCLimiter rpcRate.RequestLimitsHandler, serverLogger hclog.InterceptLogger) (*Server, error) { logger := flat.Logger if err := config.CheckProtocolVersion(); err != nil { return nil, err @@ -558,9 +526,7 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, publisher: flat.EventPublisher, incomingRPCLimiter: incomingRPCLimiter, routineManager: routine.NewManager(logger.Named(logging.ConsulServer)), - registry: flat.Registry, - useV2Resources: flat.UseV2Resources(), - useV2Tenancy: flat.UseV2Tenancy(), + typeRegistry: resource.NewRegistry(), } incomingRPCLimiter.Register(s) @@ -596,17 +562,7 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, } rpcServerOpts := []func(*rpc.Server){ - rpc.WithPreBodyInterceptor( - middleware.ChainedRPCPreBodyInterceptor( - func(reqServiceMethod string, sourceAddr net.Addr) error { - if s.useV2Resources && isV1CatalogRequest(reqServiceMethod) { - return structs.ErrUsingV2CatalogExperiment - } - return nil - }, - middleware.GetNetRPCRateLimitingInterceptor(s.incomingRPCLimiter, middleware.NewPanicHandler(s.logger)), - ), - ), + rpc.WithPreBodyInterceptor(middleware.GetNetRPCRateLimitingInterceptor(s.incomingRPCLimiter, middleware.NewPanicHandler(s.logger))), } if flat.GetNetRPCInterceptorFunc != nil { @@ -708,7 +664,7 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, } // Initialize the Raft server. - if err := s.setupRaft(stringslice.Contains(flat.Experiments, CatalogResourceExperimentName)); err != nil { + if err := s.setupRaft(); err != nil { s.Shutdown() return nil, fmt.Errorf("Failed to start Raft: %v", err) } @@ -837,19 +793,8 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, s.reportingManager = reporting.NewReportingManager(s.logger, getEnterpriseReportingDeps(flat), s, s.fsm.State()) go s.reportingManager.Run(&lib.StopChannelContext{StopCh: s.shutdownCh}) - // Setup insecure resource service client. - if err := s.setupInsecureResourceServiceClient(flat.Registry, logger); err != nil { - return nil, err - } - // Initialize external gRPC server - s.setupExternalGRPC(config, flat, logger) - - // Setup secure resource service client. We need to do it after we setup the - // gRPC server because it needs the server to be instantiated. - if err := s.setupSecureResourceServiceClient(); err != nil { - return nil, err - } + s.setupExternalGRPC(config, logger) // Initialize internal gRPC server. // @@ -858,13 +803,14 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, s.grpcHandler = newGRPCHandlerFromConfig(flat, config, s) s.grpcLeaderForwarder = flat.LeaderForwarder + if err := s.setupInternalResourceService(logger); err != nil { + return nil, err + } s.controllerManager = controller.NewManager( - s.insecureResourceServiceClient, + s.internalResourceServiceClient, logger.Named(logging.ControllerRuntime), ) - if err := s.registerControllers(flat, proxyUpdater); err != nil { - return nil, err - } + s.registerResources(flat) go s.controllerManager.Run(&lib.StopChannelContext{StopCh: shutdownCh}) go s.trackLeaderChanges() @@ -915,78 +861,20 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, return s, nil } -func isV1CatalogRequest(rpcName string) bool { - switch { - case strings.HasPrefix(rpcName, "Catalog."), - strings.HasPrefix(rpcName, "Health."), - strings.HasPrefix(rpcName, "ConfigEntry."): - return true - } - - switch rpcName { - case "Internal.EventFire", "Internal.KeyringOperation", "Internal.OIDCAuthMethods": - return false - default: - if strings.HasPrefix(rpcName, "Internal.") { - return true - } - return false - } -} - -func (s *Server) registerControllers(deps Deps, proxyUpdater ProxyUpdater) error { - // When not enabled, the v1 tenancy bridge is used by default. - if s.useV2Tenancy { - tenancy.RegisterControllers(s.controllerManager) - } - - if s.useV2Resources { +func (s *Server) registerResources(deps Deps) { + if stringslice.Contains(deps.Experiments, catalogResourceExperimentName) { + catalog.RegisterTypes(s.typeRegistry) catalog.RegisterControllers(s.controllerManager, catalog.DefaultControllerDependencies()) - defaultAllow, err := s.config.ACLResolverSettings.IsDefaultAllow() - if err != nil { - return err - } - - mesh.RegisterControllers(s.controllerManager, mesh.ControllerDependencies{ - TrustBundleFetcher: func() (*pbproxystate.TrustBundle, error) { - var bundle pbproxystate.TrustBundle - roots, err := s.getCARoots(nil, s.GetState()) - if err != nil { - return nil, err - } - bundle.TrustDomain = roots.TrustDomain - for _, root := range roots.Roots { - bundle.Roots = append(bundle.Roots, root.RootCert) - } - return &bundle, nil - }, - // This function is adapted from server_connect.go:getCARoots. - TrustDomainFetcher: func() (string, error) { - _, caConfig, err := s.fsm.State().CAConfig(nil) - if err != nil { - return "", err - } - - return s.getTrustDomain(caConfig) - }, - - LeafCertManager: deps.LeafCertManager, - LocalDatacenter: s.config.Datacenter, - DefaultAllow: defaultAllow, - ProxyUpdater: proxyUpdater, - }) - - auth.RegisterControllers(s.controllerManager, auth.DefaultControllerDependencies()) + mesh.RegisterTypes(s.typeRegistry) } reaper.RegisterControllers(s.controllerManager) if s.config.DevMode { + demo.RegisterTypes(s.typeRegistry) demo.RegisterControllers(s.controllerManager) } - - return s.controllerManager.ValidateDependencies(s.registry.Types()) } func newGRPCHandlerFromConfig(deps Deps, config *Config, s *Server) connHandler { @@ -1041,7 +929,6 @@ func newGRPCHandlerFromConfig(deps Deps, config *Config, s *Server) connHandler s.peerStreamServer.Register(srv) s.externalACLServer.Register(srv) s.externalConnectCAServer.Register(srv) - s.resourceServiceServer.Register(srv) } return agentgrpc.NewHandler(deps.Logger, config.RPCAddr, register, nil, s.incomingRPCLimiter) @@ -1073,7 +960,7 @@ func (s *Server) connectCARootsMonitor(ctx context.Context) { } // setupRaft is used to setup and initialize Raft -func (s *Server) setupRaft(isCatalogResourceExperiment bool) error { +func (s *Server) setupRaft() error { // If we have an unclean exit then attempt to close the Raft store. defer func() { if s.raft == nil && s.raftStore != nil { @@ -1132,7 +1019,8 @@ func (s *Server) setupRaft(isCatalogResourceExperiment bool) error { return fmt.Errorf("failed trying to see if raft.db exists not sure how to continue: %w", err) } - initWAL := func() error { + // Only use WAL if there is no existing raft.db, even if it's enabled. + if s.config.LogStoreConfig.Backend == LogStoreBackendWAL && !boltFileExists { walDir := filepath.Join(path, "wal") if err := os.MkdirAll(walDir, 0755); err != nil { return err @@ -1151,29 +1039,13 @@ func (s *Server) setupRaft(isCatalogResourceExperiment bool) error { s.raftStore = wal log = wal stable = wal - return nil - } - // Only use WAL if there is no existing raft.db, even if it's enabled. - if s.config.LogStoreConfig.Backend == LogStoreBackendDefault && !boltFileExists && isCatalogResourceExperiment { - s.config.LogStoreConfig.Backend = LogStoreBackendWAL - if !s.config.LogStoreConfig.Verification.Enabled { - s.config.LogStoreConfig.Verification.Enabled = true - s.config.LogStoreConfig.Verification.Interval = 1 * time.Minute - } - if err = initWAL(); err != nil { - return err - } - } else if s.config.LogStoreConfig.Backend == LogStoreBackendWAL && !boltFileExists { - if err = initWAL(); err != nil { - return err - } } else { if s.config.LogStoreConfig.Backend == LogStoreBackendWAL { // User configured the new storage, but still has old raft.db. Warn // them! s.logger.Warn("BoltDB file raft.db found, IGNORING raft_logstore.backend which is set to 'wal'") } - s.config.LogStoreConfig.Backend = LogStoreBackendBoltDB + // Create the backend raft store for logs and stable storage. store, err := raftboltdb.New(raftboltdb.Options{ BoltOptions: &bbolt.Options{ @@ -1397,7 +1269,7 @@ func (s *Server) setupRPC() error { } // Initialize and register services on external gRPC server. -func (s *Server) setupExternalGRPC(config *Config, deps Deps, logger hclog.Logger) { +func (s *Server) setupExternalGRPC(config *Config, logger hclog.Logger) { s.externalACLServer = aclgrpc.NewServer(aclgrpc.Config{ ACLsEnabled: s.config.ACLsEnabled, ForwardRPC: func(info structs.RPCInfo, fn func(*grpc.ClientConn) error) (bool, error) { @@ -1430,12 +1302,10 @@ func (s *Server) setupExternalGRPC(config *Config, deps Deps, logger hclog.Logge s.externalConnectCAServer.Register(s.externalGRPCServer) dataplane.NewServer(dataplane.Config{ - GetStore: func() dataplane.StateStore { return s.FSM().State() }, - Logger: logger.Named("grpc-api.dataplane"), - ACLResolver: s.ACLResolver, - Datacenter: s.config.Datacenter, - EnableV2: stringslice.Contains(deps.Experiments, CatalogResourceExperimentName), - ResourceAPIClient: s.insecureResourceServiceClient, + GetStore: func() dataplane.StateStore { return s.FSM().State() }, + Logger: logger.Named("grpc-api.dataplane"), + ACLResolver: s.ACLResolver, + Datacenter: s.config.Datacenter, }).Register(s.externalGRPCServer) serverdiscovery.NewServer(serverdiscovery.Config{ @@ -1464,75 +1334,23 @@ func (s *Server) setupExternalGRPC(config *Config, deps Deps, logger hclog.Logge }) s.peerStreamServer.Register(s.externalGRPCServer) - tenancyBridge := NewV1TenancyBridge(s) - if s.useV2Tenancy { - tenancyBridgeV2 := tenancy.NewV2TenancyBridge() - tenancyBridge = tenancyBridgeV2.WithClient(s.insecureResourceServiceClient) - } - - s.resourceServiceServer = resourcegrpc.NewServer(resourcegrpc.Config{ - Registry: deps.Registry, - Backend: s.raftStorageBackend, - ACLResolver: s.ACLResolver, - Logger: logger.Named("grpc-api.resource"), - TenancyBridge: tenancyBridge, - UseV2Tenancy: s.useV2Tenancy, - }) - s.resourceServiceServer.Register(s.externalGRPCServer) - - reflection.Register(s.externalGRPCServer) -} - -func (s *Server) setupInsecureResourceServiceClient(typeRegistry resource.Registry, logger hclog.Logger) error { - if s.raftStorageBackend == nil { - return fmt.Errorf("raft storage backend cannot be nil") - } - - // Can't use interface type var here since v2 specific "WithClient(...)" is called futher down. - tenancyBridge := NewV1TenancyBridge(s) - tenancyBridgeV2 := tenancy.NewV2TenancyBridge() - if s.useV2Tenancy { - tenancyBridge = tenancyBridgeV2 - } - server := resourcegrpc.NewServer(resourcegrpc.Config{ - Registry: typeRegistry, - Backend: s.raftStorageBackend, - ACLResolver: resolver.DANGER_NO_AUTH{}, - Logger: logger.Named("grpc-api.resource"), - TenancyBridge: tenancyBridge, - UseV2Tenancy: s.useV2Tenancy, - }) - - conn, err := s.runInProcessGRPCServer(server.Register) - if err != nil { - return err - } - s.insecureResourceServiceClient = pbresource.NewResourceServiceClient(conn) - tenancyBridgeV2.WithClient(s.insecureResourceServiceClient) - return nil -} - -func (s *Server) setupSecureResourceServiceClient() error { - if s.resourceServiceServer == nil { - return fmt.Errorf("resource service server cannot be nil") - } - conn, err := s.runInProcessGRPCServer(s.resourceServiceServer.Register) - if err != nil { - return err - } - s.secureResourceServiceClient = pbresource.NewResourceServiceClient(conn) - - return nil + resourcegrpc.NewServer(resourcegrpc.Config{ + Registry: s.typeRegistry, + Backend: s.raftStorageBackend, + ACLResolver: s.ACLResolver, + Logger: logger.Named("grpc-api.resource"), + }).Register(s.externalGRPCServer) } -// runInProcessGRPCServer runs a gRPC server that can only be accessed in the -// same process, rather than over the network, using a pipe listener. -func (s *Server) runInProcessGRPCServer(registerFn ...func(*grpc.Server)) (*grpc.ClientConn, error) { +func (s *Server) setupInternalResourceService(logger hclog.Logger) error { server := grpc.NewServer() - for _, fn := range registerFn { - fn(server) - } + resourcegrpc.NewServer(resourcegrpc.Config{ + Registry: s.typeRegistry, + Backend: s.raftStorageBackend, + ACLResolver: resolver.DANGER_NO_AUTH{}, + Logger: logger.Named("grpc-api.resource"), + }).Register(server) pipe := agentgrpc.NewPipeListener() go server.Serve(pipe) @@ -1549,14 +1367,15 @@ func (s *Server) runInProcessGRPCServer(registerFn ...func(*grpc.Server)) (*grpc ) if err != nil { server.Stop() - return nil, err + return err } go func() { <-s.shutdownCh conn.Close() }() + s.internalResourceServiceClient = pbresource.NewResourceServiceClient(conn) - return conn, nil + return nil } // Shutdown is used to shutdown the server @@ -2276,10 +2095,6 @@ func (s *Server) hcpServerStatus(deps Deps) hcp.StatusCallback { } } -func (s *Server) ResourceServiceClient() pbresource.ResourceServiceClient { - return s.secureResourceServiceClient -} - func fileExists(name string) (bool, error) { _, err := os.Stat(name) if err == nil { diff --git a/agent/consul/server_ce.go b/agent/consul/server_ce.go index fb3e55e76519f..22660f490b7f2 100644 --- a/agent/consul/server_ce.go +++ b/agent/consul/server_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/server_ce_test.go b/agent/consul/server_ce_test.go index 0b75cda1a5b7d..c1760589a9e14 100644 --- a/agent/consul/server_ce_test.go +++ b/agent/consul/server_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package consul diff --git a/agent/consul/server_connect.go b/agent/consul/server_connect.go index 2274aff523bad..496d059cb4941 100644 --- a/agent/consul/server_connect.go +++ b/agent/consul/server_connect.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul @@ -19,15 +19,21 @@ func (s *Server) getCARoots(ws memdb.WatchSet, state *state.Store) (*structs.Ind if err != nil { return nil, err } - - trustDomain, err := s.getTrustDomain(config) - if err != nil { - return nil, err + if config == nil || config.ClusterID == "" { + return nil, fmt.Errorf("CA has not finished initializing") } indexedRoots := &structs.IndexedCARoots{} - indexedRoots.TrustDomain = trustDomain + // Build TrustDomain based on the ClusterID stored. + signingID := connect.SpiffeIDSigningForCluster(config.ClusterID) + if signingID == nil { + // If CA is bootstrapped at all then this should never happen but be + // defensive. + return nil, fmt.Errorf("no cluster trust domain setup") + } + + indexedRoots.TrustDomain = signingID.Host() indexedRoots.Index, indexedRoots.Roots = index, roots if indexedRoots.Roots == nil { @@ -71,19 +77,3 @@ func (s *Server) getCARoots(ws memdb.WatchSet, state *state.Store) (*structs.Ind return indexedRoots, nil } - -func (s *Server) getTrustDomain(config *structs.CAConfiguration) (string, error) { - if config == nil || config.ClusterID == "" { - return "", fmt.Errorf("CA has not finished initializing") - } - - // Build TrustDomain based on the ClusterID stored. - signingID := connect.SpiffeIDSigningForCluster(config.ClusterID) - if signingID == nil { - // If CA is bootstrapped at all then this should never happen but be - // defensive. - return "", fmt.Errorf("no cluster trust domain setup") - } - - return signingID.Host(), nil -} diff --git a/agent/consul/server_log_verification.go b/agent/consul/server_log_verification.go index 2bde7dbc81b40..5646e78760989 100644 --- a/agent/consul/server_log_verification.go +++ b/agent/consul/server_log_verification.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_lookup.go b/agent/consul/server_lookup.go index 60b9c076bf148..e1952d671d07d 100644 --- a/agent/consul/server_lookup.go +++ b/agent/consul/server_lookup.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_lookup_test.go b/agent/consul/server_lookup_test.go index 52e3605de719b..5d3d3d4e0e42f 100644 --- a/agent/consul/server_lookup_test.go +++ b/agent/consul/server_lookup_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_metadata.go b/agent/consul/server_metadata.go index 03e4751a290c2..742391e0b6a1f 100644 --- a/agent/consul/server_metadata.go +++ b/agent/consul/server_metadata.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_metadata_test.go b/agent/consul/server_metadata_test.go index bf993bc1be57c..d091bfdf3630e 100644 --- a/agent/consul/server_metadata_test.go +++ b/agent/consul/server_metadata_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_overview.go b/agent/consul/server_overview.go index a94749d53498a..62bdb34406121 100644 --- a/agent/consul/server_overview.go +++ b/agent/consul/server_overview.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_overview_test.go b/agent/consul/server_overview_test.go index 7780b5ce83967..ebb930a1e2bf2 100644 --- a/agent/consul/server_overview_test.go +++ b/agent/consul/server_overview_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_register.go b/agent/consul/server_register.go index 90d95f061956f..61f1daefc7dfa 100644 --- a/agent/consul/server_register.go +++ b/agent/consul/server_register.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_serf.go b/agent/consul/server_serf.go index aea50aa6dd199..1dc6c25b1cce5 100644 --- a/agent/consul/server_serf.go +++ b/agent/consul/server_serf.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/server_test.go b/agent/consul/server_test.go index 95fa102d4a464..37feca269e8e7 100644 --- a/agent/consul/server_test.go +++ b/agent/consul/server_test.go @@ -1,16 +1,14 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul import ( "context" "crypto/x509" - "flag" "fmt" "net" "os" - "path/filepath" "reflect" "strings" "sync" @@ -38,12 +36,10 @@ import ( external "github.com/hashicorp/consul/agent/grpc-external" grpcmiddleware "github.com/hashicorp/consul/agent/grpc-middleware" hcpclient "github.com/hashicorp/consul/agent/hcp/client" - "github.com/hashicorp/consul/agent/leafcert" "github.com/hashicorp/consul/agent/metadata" "github.com/hashicorp/consul/agent/rpc/middleware" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/token" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" "github.com/hashicorp/consul/ipaddr" "github.com/hashicorp/consul/sdk/freeport" "github.com/hashicorp/consul/sdk/testutil" @@ -341,8 +337,7 @@ func newServerWithDeps(t *testing.T, c *Config, deps Deps) (*Server, error) { } } grpcServer := external.NewServer(deps.Logger.Named("grpc.external"), nil, deps.TLSConfigurator, rpcRate.NullRequestLimitsHandler(), keepalive.ServerParameters{}) - proxyUpdater := proxytracker.NewProxyTracker(proxytracker.ProxyTrackerConfig{}) - srv, err := NewServer(c, deps, grpcServer, nil, deps.Logger, proxyUpdater) + srv, err := NewServer(c, deps, grpcServer, nil, deps.Logger) if err != nil { return nil, err } @@ -1249,7 +1244,7 @@ func TestServer_RPC_MetricsIntercept_Off(t *testing.T) { } } - s1, err := NewServer(conf, deps, grpc.NewServer(), nil, deps.Logger, nil) + s1, err := NewServer(conf, deps, grpc.NewServer(), nil, deps.Logger) if err != nil { t.Fatalf("err: %v", err) } @@ -1287,7 +1282,7 @@ func TestServer_RPC_MetricsIntercept_Off(t *testing.T) { return nil } - s2, err := NewServer(conf, deps, grpc.NewServer(), nil, deps.Logger, nil) + s2, err := NewServer(conf, deps, grpc.NewServer(), nil, deps.Logger) if err != nil { t.Fatalf("err: %v", err) } @@ -1321,7 +1316,7 @@ func TestServer_RPC_RequestRecorder(t *testing.T) { deps := newDefaultDeps(t, conf) deps.NewRequestRecorderFunc = nil - s1, err := NewServer(conf, deps, grpc.NewServer(), nil, deps.Logger, nil) + s1, err := NewServer(conf, deps, grpc.NewServer(), nil, deps.Logger) require.Error(t, err, "need err when provider func is nil") require.Equal(t, err.Error(), "cannot initialize server without an RPC request recorder provider") @@ -1340,7 +1335,7 @@ func TestServer_RPC_RequestRecorder(t *testing.T) { return nil } - s2, err := NewServer(conf, deps, grpc.NewServer(), nil, deps.Logger, nil) + s2, err := NewServer(conf, deps, grpc.NewServer(), nil, deps.Logger) require.Error(t, err, "need err when RequestRecorder is nil") require.Equal(t, err.Error(), "cannot initialize server with a nil RPC request recorder") @@ -2106,38 +2101,3 @@ func TestServer_hcpManager(t *testing.T) { hcp1.AssertExpectations(t) } - -// goldenMarkdown reads and optionally writes the expected data to the goldenMarkdown file, -// returning the contents as a string. -func goldenMarkdown(t *testing.T, name, got string) string { - t.Helper() - - golden := filepath.Join("testdata", name+".md") - update := flag.Lookup("update").Value.(flag.Getter).Get().(bool) - if update && got != "" { - err := os.WriteFile(golden, []byte(got), 0644) - require.NoError(t, err) - } - - expected, err := os.ReadFile(golden) - require.NoError(t, err) - - return string(expected) -} - -func TestServer_ControllerDependencies(t *testing.T) { - t.Parallel() - - _, conf := testServerConfig(t) - deps := newDefaultDeps(t, conf) - deps.Experiments = []string{"resource-apis"} - deps.LeafCertManager = &leafcert.Manager{} - - s1, err := newServerWithDeps(t, conf, deps) - require.NoError(t, err) - - waitForLeaderEstablishment(t, s1) - actual := fmt.Sprintf("```mermaid\n%s\n```", s1.controllerManager.CalculateDependencies(s1.registry.Types()).ToMermaid()) - expected := goldenMarkdown(t, "v2-resource-dependencies", actual) - require.Equal(t, expected, actual) -} diff --git a/agent/consul/servercert/manager.go b/agent/consul/servercert/manager.go index 664753439477d..75c2a4f276082 100644 --- a/agent/consul/servercert/manager.go +++ b/agent/consul/servercert/manager.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package servercert diff --git a/agent/consul/servercert/manager_test.go b/agent/consul/servercert/manager_test.go index e9cc0c81c58c1..dfadfe4b953fb 100644 --- a/agent/consul/servercert/manager_test.go +++ b/agent/consul/servercert/manager_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package servercert diff --git a/agent/consul/session_endpoint.go b/agent/consul/session_endpoint.go index f2f8ab7740234..6e41138f983c6 100644 --- a/agent/consul/session_endpoint.go +++ b/agent/consul/session_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/session_endpoint_test.go b/agent/consul/session_endpoint_test.go index 408cd7b058c59..ae04d2658f9a7 100644 --- a/agent/consul/session_endpoint_test.go +++ b/agent/consul/session_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/session_timers.go b/agent/consul/session_timers.go index f1c62b08a8196..b4c1b425cb267 100644 --- a/agent/consul/session_timers.go +++ b/agent/consul/session_timers.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/session_timers_test.go b/agent/consul/session_timers_test.go index f944cc76745d8..d44ed2b366fed 100644 --- a/agent/consul/session_timers_test.go +++ b/agent/consul/session_timers_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/session_ttl.go b/agent/consul/session_ttl.go index 8f5440e14dffa..7866ec8fed198 100644 --- a/agent/consul/session_ttl.go +++ b/agent/consul/session_ttl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/session_ttl_test.go b/agent/consul/session_ttl_test.go index e552f0ff6cdff..5cd720f3f8933 100644 --- a/agent/consul/session_ttl_test.go +++ b/agent/consul/session_ttl_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/snapshot_endpoint.go b/agent/consul/snapshot_endpoint.go index c9a6e9ace47c8..7e5f21113aebd 100644 --- a/agent/consul/snapshot_endpoint.go +++ b/agent/consul/snapshot_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // The snapshot endpoint is a special non-RPC endpoint that supports streaming // for taking and restoring snapshots for disaster recovery. This gets wired diff --git a/agent/consul/snapshot_endpoint_test.go b/agent/consul/snapshot_endpoint_test.go index 40bede9149743..f401bb72e38d0 100644 --- a/agent/consul/snapshot_endpoint_test.go +++ b/agent/consul/snapshot_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/state/acl.go b/agent/consul/state/acl.go index 34c26c621ab95..f57c3387352de 100644 --- a/agent/consul/state/acl.go +++ b/agent/consul/state/acl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state @@ -526,8 +526,7 @@ func aclTokenSetTxn(tx WriteTxn, idx uint64, token *structs.ACLToken, opts ACLTo } if opts.ProhibitUnprivileged { - if numValidRoles == 0 && numValidPolicies == 0 && len(token.ServiceIdentities) == 0 && - len(token.NodeIdentities) == 0 && len(token.TemplatedPolicies) == 0 { + if numValidRoles == 0 && numValidPolicies == 0 && len(token.ServiceIdentities) == 0 && len(token.NodeIdentities) == 0 { return ErrTokenHasNoPrivileges } } @@ -1178,26 +1177,6 @@ func aclRoleSetTxn(tx WriteTxn, idx uint64, role *structs.ACLRole, allowMissing } } - for _, templatedPolicy := range role.TemplatedPolicies { - if templatedPolicy.TemplateName == "" { - return fmt.Errorf("encountered a Role %s (%s) with an empty templated policy name in the state store", role.Name, role.ID) - } - - baseTemplate, ok := structs.GetACLTemplatedPolicyBase(templatedPolicy.TemplateName) - if !ok { - return fmt.Errorf("encountered a Role %s (%s) with an invalid templated policy name %q", role.Name, role.ID, templatedPolicy.TemplateName) - } - - if templatedPolicy.TemplateID == "" { - templatedPolicy.TemplateID = baseTemplate.TemplateID - } - - err := templatedPolicy.ValidateTemplatedPolicy(baseTemplate.Schema) - if err != nil { - return fmt.Errorf("encountered a Role %s (%s) with an invalid templated policy: %w", role.Name, role.ID, err) - } - } - if err := aclRoleUpsertValidateEnterprise(tx, role, existing); err != nil { return err } diff --git a/agent/consul/state/acl_ce.go b/agent/consul/state/acl_ce.go index 9e1dd7ebdbb11..33b3b5986fcaa 100644 --- a/agent/consul/state/acl_ce.go +++ b/agent/consul/state/acl_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/acl_ce_test.go b/agent/consul/state/acl_ce_test.go index 77b5bf3adb5a9..4d3bcdcfc00b7 100644 --- a/agent/consul/state/acl_ce_test.go +++ b/agent/consul/state/acl_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/acl_events.go b/agent/consul/state/acl_events.go index d00062c23bac9..3767d2d2d1542 100644 --- a/agent/consul/state/acl_events.go +++ b/agent/consul/state/acl_events.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/acl_events_test.go b/agent/consul/state/acl_events_test.go index 3c6e3fdfab174..303d54a25be1b 100644 --- a/agent/consul/state/acl_events_test.go +++ b/agent/consul/state/acl_events_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/acl_schema.go b/agent/consul/state/acl_schema.go index 17c772b37e01c..75ca0f3a26893 100644 --- a/agent/consul/state/acl_schema.go +++ b/agent/consul/state/acl_schema.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/acl_test.go b/agent/consul/state/acl_test.go index f72f961114684..eec05b5fa9d2b 100644 --- a/agent/consul/state/acl_test.go +++ b/agent/consul/state/acl_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/autopilot.go b/agent/consul/state/autopilot.go index 608f08f5215c2..472ce4bfc31c2 100644 --- a/agent/consul/state/autopilot.go +++ b/agent/consul/state/autopilot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/autopilot_test.go b/agent/consul/state/autopilot_test.go index a2877e2df5ffa..f26163bc4ec1b 100644 --- a/agent/consul/state/autopilot_test.go +++ b/agent/consul/state/autopilot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/catalog.go b/agent/consul/state/catalog.go index 02abd77132ac6..ceb63fab386c7 100644 --- a/agent/consul/state/catalog.go +++ b/agent/consul/state/catalog.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state @@ -1318,6 +1318,7 @@ func (s *Store) ServicesByNodeMeta(ws memdb.WatchSet, filters map[string]string, EnterpriseMeta: *entMeta, PeerName: peerName, }) + if err != nil { return 0, nil, fmt.Errorf("failed nodes lookup: %s", err) } @@ -1337,7 +1338,6 @@ func (s *Store) ServicesByNodeMeta(ws memdb.WatchSet, filters map[string]string, if len(filters) > 1 && !structs.SatisfiesMetaFilters(n.Meta, filters) { continue } - // List all the services on the node services, err := catalogServiceListByNode(tx, n.Node, entMeta, n.PeerName, false) if err != nil { @@ -3985,7 +3985,7 @@ func updateGatewayService(tx WriteTxn, idx uint64, mapping *structs.GatewayServi } // checkWildcardForGatewaysAndUpdate checks whether a service matches a -// wildcard definition in gateway config entries and if so adds it the +// wildcard definition in gateway config entries and if so adds it the the // gateway-services table. func checkGatewayWildcardsAndUpdate(tx WriteTxn, idx uint64, svc *structs.ServiceName, ns *structs.NodeService, kind structs.GatewayServiceKind) error { sn := structs.ServiceName{Name: structs.WildcardSpecifier, EnterpriseMeta: svc.EnterpriseMeta} @@ -4033,7 +4033,7 @@ func checkGatewayWildcardsAndUpdate(tx WriteTxn, idx uint64, svc *structs.Servic } // checkGatewayAndUpdate checks whether a service matches a -// wildcard definition in gateway config entries and if so adds it the +// wildcard definition in gateway config entries and if so adds it the the // gateway-services table. func checkGatewayAndUpdate(tx WriteTxn, idx uint64, svc *structs.ServiceName, kind structs.GatewayServiceKind) error { sn := structs.ServiceName{Name: svc.Name, EnterpriseMeta: svc.EnterpriseMeta} diff --git a/agent/consul/state/catalog_ce.go b/agent/consul/state/catalog_ce.go index 8068b7f0700fc..bec9a6a619771 100644 --- a/agent/consul/state/catalog_ce.go +++ b/agent/consul/state/catalog_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/catalog_ce_test.go b/agent/consul/state/catalog_ce_test.go index d1050ecfa04c1..e8c71812f860f 100644 --- a/agent/consul/state/catalog_ce_test.go +++ b/agent/consul/state/catalog_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/catalog_events.go b/agent/consul/state/catalog_events.go index 7b2057c6f43a0..0cd7258d5e806 100644 --- a/agent/consul/state/catalog_events.go +++ b/agent/consul/state/catalog_events.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state @@ -645,7 +645,7 @@ func getPayloadCheckServiceNode(payload stream.Payload) *structs.CheckServiceNod } // newServiceHealthEventsForNode returns health events for all services on the -// given node. This mirrors some of the logic in the oddly-named +// given node. This mirrors some of the the logic in the oddly-named // parseCheckServiceNodes but is more efficient since we know they are all on // the same node. func newServiceHealthEventsForNode(tx ReadTxn, idx uint64, node string, entMeta *acl.EnterpriseMeta, peerName string) ([]stream.Event, error) { diff --git a/agent/consul/state/catalog_events_ce.go b/agent/consul/state/catalog_events_ce.go index 5b1559b22f364..72e3993b5d56d 100644 --- a/agent/consul/state/catalog_events_ce.go +++ b/agent/consul/state/catalog_events_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/catalog_events_ce_test.go b/agent/consul/state/catalog_events_ce_test.go index 6945b5c47656e..0de8286c44c85 100644 --- a/agent/consul/state/catalog_events_ce_test.go +++ b/agent/consul/state/catalog_events_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/catalog_events_test.go b/agent/consul/state/catalog_events_test.go index 94406e34f9aee..46e0b269617fa 100644 --- a/agent/consul/state/catalog_events_test.go +++ b/agent/consul/state/catalog_events_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/catalog_schema.deepcopy.go b/agent/consul/state/catalog_schema.deepcopy.go index af4d430d2f971..406a7fdce796f 100644 --- a/agent/consul/state/catalog_schema.deepcopy.go +++ b/agent/consul/state/catalog_schema.deepcopy.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - // generated by deep-copy -pointer-receiver -o ./catalog_schema.deepcopy.go -type upstreamDownstream ./; DO NOT EDIT. package state diff --git a/agent/consul/state/catalog_schema.go b/agent/consul/state/catalog_schema.go index b8da7c0999361..8702cc2e0cf5f 100644 --- a/agent/consul/state/catalog_schema.go +++ b/agent/consul/state/catalog_schema.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/catalog_test.go b/agent/consul/state/catalog_test.go index f18b9beae8433..7ca578307e2f2 100644 --- a/agent/consul/state/catalog_test.go +++ b/agent/consul/state/catalog_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/config_entry.go b/agent/consul/state/config_entry.go index b298b6122080d..9abaafc390d3a 100644 --- a/agent/consul/state/config_entry.go +++ b/agent/consul/state/config_entry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/config_entry_ce.go b/agent/consul/state/config_entry_ce.go index 1f70baf19bb88..ec01e0c09aaea 100644 --- a/agent/consul/state/config_entry_ce.go +++ b/agent/consul/state/config_entry_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/config_entry_ce_test.go b/agent/consul/state/config_entry_ce_test.go index 4b9103a74ede8..02fb3be78a2c5 100644 --- a/agent/consul/state/config_entry_ce_test.go +++ b/agent/consul/state/config_entry_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/config_entry_events.go b/agent/consul/state/config_entry_events.go index c6c19fce3453e..5681362dbe16e 100644 --- a/agent/consul/state/config_entry_events.go +++ b/agent/consul/state/config_entry_events.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/config_entry_events_test.go b/agent/consul/state/config_entry_events_test.go index e8ceb10f65d85..1ee92770bc65b 100644 --- a/agent/consul/state/config_entry_events_test.go +++ b/agent/consul/state/config_entry_events_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/config_entry_exported_services.go b/agent/consul/state/config_entry_exported_services.go index 7534613ae137a..b758adc09eafb 100644 --- a/agent/consul/state/config_entry_exported_services.go +++ b/agent/consul/state/config_entry_exported_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/config_entry_exported_services_ce.go b/agent/consul/state/config_entry_exported_services_ce.go index aa495fb0d8f48..9dfc4751d2d61 100644 --- a/agent/consul/state/config_entry_exported_services_ce.go +++ b/agent/consul/state/config_entry_exported_services_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/config_entry_intention.go b/agent/consul/state/config_entry_intention.go index 459d8c4276e6f..301baf9c09093 100644 --- a/agent/consul/state/config_entry_intention.go +++ b/agent/consul/state/config_entry_intention.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/config_entry_intention_ce.go b/agent/consul/state/config_entry_intention_ce.go index 8cefdf2c3dffc..6d479f9ad6bfb 100644 --- a/agent/consul/state/config_entry_intention_ce.go +++ b/agent/consul/state/config_entry_intention_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/config_entry_sameness_group.go b/agent/consul/state/config_entry_sameness_group.go index d8308008dfbb4..7f02787b6553b 100644 --- a/agent/consul/state/config_entry_sameness_group.go +++ b/agent/consul/state/config_entry_sameness_group.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package state import ( diff --git a/agent/consul/state/config_entry_sameness_group_ce.go b/agent/consul/state/config_entry_sameness_group_ce.go index fcff27158ba2e..16437cd8fd187 100644 --- a/agent/consul/state/config_entry_sameness_group_ce.go +++ b/agent/consul/state/config_entry_sameness_group_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/config_entry_sameness_group_ce_test.go b/agent/consul/state/config_entry_sameness_group_ce_test.go index 3d307238f3329..ce4aeb8394f8b 100644 --- a/agent/consul/state/config_entry_sameness_group_ce_test.go +++ b/agent/consul/state/config_entry_sameness_group_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/config_entry_schema.go b/agent/consul/state/config_entry_schema.go index c662415252966..e420d657cae8a 100644 --- a/agent/consul/state/config_entry_schema.go +++ b/agent/consul/state/config_entry_schema.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/config_entry_test.go b/agent/consul/state/config_entry_test.go index af9dc0997156d..d72f12c876890 100644 --- a/agent/consul/state/config_entry_test.go +++ b/agent/consul/state/config_entry_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/connect_ca.go b/agent/consul/state/connect_ca.go index 4b1eeeab783d4..99e99637b6aa9 100644 --- a/agent/consul/state/connect_ca.go +++ b/agent/consul/state/connect_ca.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/connect_ca_events.go b/agent/consul/state/connect_ca_events.go index a285b9d07cb75..554a867dcd59c 100644 --- a/agent/consul/state/connect_ca_events.go +++ b/agent/consul/state/connect_ca_events.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/connect_ca_events_test.go b/agent/consul/state/connect_ca_events_test.go index 79df8df5be879..bf13eefcb9376 100644 --- a/agent/consul/state/connect_ca_events_test.go +++ b/agent/consul/state/connect_ca_events_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/connect_ca_test.go b/agent/consul/state/connect_ca_test.go index 2a49723d65cbc..124392cf1a432 100644 --- a/agent/consul/state/connect_ca_test.go +++ b/agent/consul/state/connect_ca_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/coordinate.go b/agent/consul/state/coordinate.go index bcd71e5a0f08d..f2eb7b30425e6 100644 --- a/agent/consul/state/coordinate.go +++ b/agent/consul/state/coordinate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/coordinate_ce.go b/agent/consul/state/coordinate_ce.go index 000c3714c794b..17956e964eee6 100644 --- a/agent/consul/state/coordinate_ce.go +++ b/agent/consul/state/coordinate_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/coordinate_ce_test.go b/agent/consul/state/coordinate_ce_test.go index b80a7b8ae832f..a4608245060ea 100644 --- a/agent/consul/state/coordinate_ce_test.go +++ b/agent/consul/state/coordinate_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/coordinate_test.go b/agent/consul/state/coordinate_test.go index dad0ce3e32ec6..0fe582eab5aa9 100644 --- a/agent/consul/state/coordinate_test.go +++ b/agent/consul/state/coordinate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/deep-copy.sh b/agent/consul/state/deep-copy.sh index 809e20432b624..d976d921f3c83 100755 --- a/agent/consul/state/deep-copy.sh +++ b/agent/consul/state/deep-copy.sh @@ -1,7 +1,4 @@ #!/usr/bin/env bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - readonly PACKAGE_DIR="$(dirname "${BASH_SOURCE[0]}")" cd $PACKAGE_DIR diff --git a/agent/consul/state/delay_ce.go b/agent/consul/state/delay_ce.go index d0d2013cb0c8b..a2471ae636241 100644 --- a/agent/consul/state/delay_ce.go +++ b/agent/consul/state/delay_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/delay_test.go b/agent/consul/state/delay_test.go index 6a2d0fa80c2d6..40f1842efd679 100644 --- a/agent/consul/state/delay_test.go +++ b/agent/consul/state/delay_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/events.go b/agent/consul/state/events.go index 0d4f4eb4fe403..666dc60035d1e 100644 --- a/agent/consul/state/events.go +++ b/agent/consul/state/events.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/events_test.go b/agent/consul/state/events_test.go index c2a4ad399d641..3da9a26549b2a 100644 --- a/agent/consul/state/events_test.go +++ b/agent/consul/state/events_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/federation_state.go b/agent/consul/state/federation_state.go index a02a38ed3b532..556caa4b48549 100644 --- a/agent/consul/state/federation_state.go +++ b/agent/consul/state/federation_state.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/graveyard.go b/agent/consul/state/graveyard.go index 45398584356cf..5b6a95dafbaa2 100644 --- a/agent/consul/state/graveyard.go +++ b/agent/consul/state/graveyard.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/graveyard_ce.go b/agent/consul/state/graveyard_ce.go index c39a8c335ec5c..963ed6632e5be 100644 --- a/agent/consul/state/graveyard_ce.go +++ b/agent/consul/state/graveyard_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/graveyard_test.go b/agent/consul/state/graveyard_test.go index 66aaaf92fb143..af50673e9e741 100644 --- a/agent/consul/state/graveyard_test.go +++ b/agent/consul/state/graveyard_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/index_connect_test.go b/agent/consul/state/index_connect_test.go index 7b5404b5b2a8e..a598fab68ac44 100644 --- a/agent/consul/state/index_connect_test.go +++ b/agent/consul/state/index_connect_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/indexer.go b/agent/consul/state/indexer.go index c752b3af55cfc..f360eb2befe97 100644 --- a/agent/consul/state/indexer.go +++ b/agent/consul/state/indexer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/intention.go b/agent/consul/state/intention.go index f360555228586..4341590e4ec20 100644 --- a/agent/consul/state/intention.go +++ b/agent/consul/state/intention.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/intention_ce.go b/agent/consul/state/intention_ce.go index 33e9bbe26184e..e82177eb1a563 100644 --- a/agent/consul/state/intention_ce.go +++ b/agent/consul/state/intention_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/intention_test.go b/agent/consul/state/intention_test.go index 72455565d5821..3545527b790c2 100644 --- a/agent/consul/state/intention_test.go +++ b/agent/consul/state/intention_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/kvs.go b/agent/consul/state/kvs.go index b0b4f6c1e52dc..0d0a419ae5c29 100644 --- a/agent/consul/state/kvs.go +++ b/agent/consul/state/kvs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/kvs_ce.go b/agent/consul/state/kvs_ce.go index 69d4c28ad2a4e..10528e3be6dbb 100644 --- a/agent/consul/state/kvs_ce.go +++ b/agent/consul/state/kvs_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/kvs_ce_test.go b/agent/consul/state/kvs_ce_test.go index 30e7b22e40d9c..adf41fe7dbe86 100644 --- a/agent/consul/state/kvs_ce_test.go +++ b/agent/consul/state/kvs_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/kvs_test.go b/agent/consul/state/kvs_test.go index b85a08f98d181..4ced02586f0c0 100644 --- a/agent/consul/state/kvs_test.go +++ b/agent/consul/state/kvs_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/memdb.go b/agent/consul/state/memdb.go index 93707d0e0751d..0a3b66c6a6275 100644 --- a/agent/consul/state/memdb.go +++ b/agent/consul/state/memdb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/memdb_test.go b/agent/consul/state/memdb_test.go index e603fc5bb1691..7e893619be5de 100644 --- a/agent/consul/state/memdb_test.go +++ b/agent/consul/state/memdb_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/operations_ce.go b/agent/consul/state/operations_ce.go index 00469d6b0c95d..08de08015b449 100644 --- a/agent/consul/state/operations_ce.go +++ b/agent/consul/state/operations_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/peering.go b/agent/consul/state/peering.go index 05dfa59a37af3..90db748458847 100644 --- a/agent/consul/state/peering.go +++ b/agent/consul/state/peering.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state @@ -202,9 +202,6 @@ func (s *Store) peeringSecretsWriteTxn(tx WriteTxn, req *pbpeering.SecretsWriteR return fmt.Errorf("failed to read peering by id: %w", err) } if peering == nil { - if structs.CEDowngrade { - return nil - } return fmt.Errorf("unknown peering %q for secret", req.PeerID) } diff --git a/agent/consul/state/peering_ce.go b/agent/consul/state/peering_ce.go index 72082689486e8..a54e2d37ddffb 100644 --- a/agent/consul/state/peering_ce.go +++ b/agent/consul/state/peering_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/peering_ce_test.go b/agent/consul/state/peering_ce_test.go index 88546c17855ed..41d1bce452db0 100644 --- a/agent/consul/state/peering_ce_test.go +++ b/agent/consul/state/peering_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/peering_test.go b/agent/consul/state/peering_test.go index 764286bb77b8e..8125b96860aac 100644 --- a/agent/consul/state/peering_test.go +++ b/agent/consul/state/peering_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/prepared_query.go b/agent/consul/state/prepared_query.go index 62cf39588d17a..7638d925170f0 100644 --- a/agent/consul/state/prepared_query.go +++ b/agent/consul/state/prepared_query.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/prepared_query_index.go b/agent/consul/state/prepared_query_index.go index 83bb5dc738251..ac76846366699 100644 --- a/agent/consul/state/prepared_query_index.go +++ b/agent/consul/state/prepared_query_index.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/prepared_query_index_test.go b/agent/consul/state/prepared_query_index_test.go index aaaa62692f1cf..a486047f57e33 100644 --- a/agent/consul/state/prepared_query_index_test.go +++ b/agent/consul/state/prepared_query_index_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/prepared_query_test.go b/agent/consul/state/prepared_query_test.go index dc902de4ad309..f0b0cd95f4469 100644 --- a/agent/consul/state/prepared_query_test.go +++ b/agent/consul/state/prepared_query_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/query.go b/agent/consul/state/query.go index 288e715e83314..2256aab995fb0 100644 --- a/agent/consul/state/query.go +++ b/agent/consul/state/query.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/query_ce.go b/agent/consul/state/query_ce.go index 809f35279987c..98108d6ff02b2 100644 --- a/agent/consul/state/query_ce.go +++ b/agent/consul/state/query_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/schema.go b/agent/consul/state/schema.go index 0934ca483e5eb..9e0e6db2fee42 100644 --- a/agent/consul/state/schema.go +++ b/agent/consul/state/schema.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/schema_ce.go b/agent/consul/state/schema_ce.go index 7dce71a038f99..eecde09aab619 100644 --- a/agent/consul/state/schema_ce.go +++ b/agent/consul/state/schema_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/schema_ce_test.go b/agent/consul/state/schema_ce_test.go index 9ed597acf6562..55fc3ee54c194 100644 --- a/agent/consul/state/schema_ce_test.go +++ b/agent/consul/state/schema_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/schema_test.go b/agent/consul/state/schema_test.go index a0af2223e27ce..f67b18e8c3beb 100644 --- a/agent/consul/state/schema_test.go +++ b/agent/consul/state/schema_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/session.go b/agent/consul/state/session.go index d57b05947d396..5e666f80fd894 100644 --- a/agent/consul/state/session.go +++ b/agent/consul/state/session.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/session_ce.go b/agent/consul/state/session_ce.go index 2fa24878541cb..1854fb3e1448b 100644 --- a/agent/consul/state/session_ce.go +++ b/agent/consul/state/session_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/session_test.go b/agent/consul/state/session_test.go index 08f7ad09d0c1f..eab4299581637 100644 --- a/agent/consul/state/session_test.go +++ b/agent/consul/state/session_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/state_store.go b/agent/consul/state/state_store.go index dff3441535bb5..fce3b3c96155f 100644 --- a/agent/consul/state/state_store.go +++ b/agent/consul/state/state_store.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/state_store_ce_test.go b/agent/consul/state/state_store_ce_test.go index ca57cf1aface8..5515b193f688c 100644 --- a/agent/consul/state/state_store_ce_test.go +++ b/agent/consul/state/state_store_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/state_store_test.go b/agent/consul/state/state_store_test.go index 751ecee779dee..587f15c03d948 100644 --- a/agent/consul/state/state_store_test.go +++ b/agent/consul/state/state_store_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/store_integration_test.go b/agent/consul/state/store_integration_test.go index 25a91c558646f..9395aa1cb1820 100644 --- a/agent/consul/state/store_integration_test.go +++ b/agent/consul/state/store_integration_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/system_metadata.go b/agent/consul/state/system_metadata.go index 06e2d3cc598b9..ed802efbd1cd8 100644 --- a/agent/consul/state/system_metadata.go +++ b/agent/consul/state/system_metadata.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/system_metadata_test.go b/agent/consul/state/system_metadata_test.go index c2ac97b390b8c..59f8bcd30c3eb 100644 --- a/agent/consul/state/system_metadata_test.go +++ b/agent/consul/state/system_metadata_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/tombstone_gc.go b/agent/consul/state/tombstone_gc.go index 6eab5b6b5ba91..3fc19c5cd9cc8 100644 --- a/agent/consul/state/tombstone_gc.go +++ b/agent/consul/state/tombstone_gc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/tombstone_gc_test.go b/agent/consul/state/tombstone_gc_test.go index def4c9af19720..d0fd11fa7c5a6 100644 --- a/agent/consul/state/tombstone_gc_test.go +++ b/agent/consul/state/tombstone_gc_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/txn.go b/agent/consul/state/txn.go index 30189fc1ed602..81d8acd039291 100644 --- a/agent/consul/state/txn.go +++ b/agent/consul/state/txn.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/txn_test.go b/agent/consul/state/txn_test.go index bda004a63a3b6..a128badf42e52 100644 --- a/agent/consul/state/txn_test.go +++ b/agent/consul/state/txn_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/usage.go b/agent/consul/state/usage.go index 20515e2e7b0cd..0893d25288b68 100644 --- a/agent/consul/state/usage.go +++ b/agent/consul/state/usage.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/state/usage_ce.go b/agent/consul/state/usage_ce.go index 679d114232d07..1824cf12399a5 100644 --- a/agent/consul/state/usage_ce.go +++ b/agent/consul/state/usage_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package state diff --git a/agent/consul/state/usage_test.go b/agent/consul/state/usage_test.go index 4195779b8c037..68844ebc1140d 100644 --- a/agent/consul/state/usage_test.go +++ b/agent/consul/state/usage_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/agent/consul/stats_fetcher.go b/agent/consul/stats_fetcher.go index 94e122f2b4389..d52930e85add3 100644 --- a/agent/consul/stats_fetcher.go +++ b/agent/consul/stats_fetcher.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/stats_fetcher_test.go b/agent/consul/stats_fetcher_test.go index 8dc9ce9eb2880..783424393a79e 100644 --- a/agent/consul/stats_fetcher_test.go +++ b/agent/consul/stats_fetcher_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/status_endpoint.go b/agent/consul/status_endpoint.go index bca454e25eb0f..efa2fa2cf4fa6 100644 --- a/agent/consul/status_endpoint.go +++ b/agent/consul/status_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/status_endpoint_test.go b/agent/consul/status_endpoint_test.go index d4cf5cb7798b9..6d95d7f6fd48d 100644 --- a/agent/consul/status_endpoint_test.go +++ b/agent/consul/status_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/stream/event.go b/agent/consul/stream/event.go index df8160d2dd366..db6f3a6312f38 100644 --- a/agent/consul/stream/event.go +++ b/agent/consul/stream/event.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 /* Package stream provides a publish/subscribe system for events produced by changes diff --git a/agent/consul/stream/event_buffer.go b/agent/consul/stream/event_buffer.go index 08060306e8d64..1c7f8c2b956a5 100644 --- a/agent/consul/stream/event_buffer.go +++ b/agent/consul/stream/event_buffer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/event_buffer_test.go b/agent/consul/stream/event_buffer_test.go index 892a14d733e1a..b6ec48e1775e1 100644 --- a/agent/consul/stream/event_buffer_test.go +++ b/agent/consul/stream/event_buffer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/event_publisher.go b/agent/consul/stream/event_publisher.go index bb6d87f8bacf2..f39ea22869a08 100644 --- a/agent/consul/stream/event_publisher.go +++ b/agent/consul/stream/event_publisher.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/event_publisher_test.go b/agent/consul/stream/event_publisher_test.go index 4ae53ebcbf8f3..13efd0fb564ab 100644 --- a/agent/consul/stream/event_publisher_test.go +++ b/agent/consul/stream/event_publisher_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/event_snapshot.go b/agent/consul/stream/event_snapshot.go index 40c9f3d007d50..6b4b693689b42 100644 --- a/agent/consul/stream/event_snapshot.go +++ b/agent/consul/stream/event_snapshot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/event_snapshot_test.go b/agent/consul/stream/event_snapshot_test.go index 8a6d4e27c6bf5..0888b90c39c9c 100644 --- a/agent/consul/stream/event_snapshot_test.go +++ b/agent/consul/stream/event_snapshot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/event_test.go b/agent/consul/stream/event_test.go index 22afe390de9c7..ff6f07c10ea83 100644 --- a/agent/consul/stream/event_test.go +++ b/agent/consul/stream/event_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/noop.go b/agent/consul/stream/noop.go index 65fcbb3fb7770..1cd35ea922eb8 100644 --- a/agent/consul/stream/noop.go +++ b/agent/consul/stream/noop.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/string_types.go b/agent/consul/stream/string_types.go index 2d0cb656777d3..6e6c4ef8e92fa 100644 --- a/agent/consul/stream/string_types.go +++ b/agent/consul/stream/string_types.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/subscription.go b/agent/consul/stream/subscription.go index 23911eff2e657..40286768abe02 100644 --- a/agent/consul/stream/subscription.go +++ b/agent/consul/stream/subscription.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/stream/subscription_test.go b/agent/consul/stream/subscription_test.go index fd4af464ee532..9bf0b95b5d564 100644 --- a/agent/consul/stream/subscription_test.go +++ b/agent/consul/stream/subscription_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stream diff --git a/agent/consul/subscribe_backend.go b/agent/consul/subscribe_backend.go index c73dea18136af..9afcd4fc567df 100644 --- a/agent/consul/subscribe_backend.go +++ b/agent/consul/subscribe_backend.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/subscribe_backend_test.go b/agent/consul/subscribe_backend_test.go index 8d0f7a501ca1e..833f049c9728a 100644 --- a/agent/consul/subscribe_backend_test.go +++ b/agent/consul/subscribe_backend_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/system_metadata.go b/agent/consul/system_metadata.go index f110255aa2e09..40185294b8d77 100644 --- a/agent/consul/system_metadata.go +++ b/agent/consul/system_metadata.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/system_metadata_test.go b/agent/consul/system_metadata_test.go index 75e69786b8dd5..7c4eb30e4732e 100644 --- a/agent/consul/system_metadata_test.go +++ b/agent/consul/system_metadata_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/tenancy_bridge.go b/agent/consul/tenancy_bridge.go deleted file mode 100644 index 4e8daa0bc8def..0000000000000 --- a/agent/consul/tenancy_bridge.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package consul - -import "github.com/hashicorp/consul/agent/grpc-external/services/resource" - -// V1TenancyBridge is used by the resource service to access V1 implementations of -// partitions and namespaces. This bridge will be removed when V2 implemenations -// of partitions and namespaces are available. -type V1TenancyBridge struct { - server *Server -} - -func NewV1TenancyBridge(server *Server) resource.TenancyBridge { - return &V1TenancyBridge{server: server} -} diff --git a/agent/consul/tenancy_bridge_ce.go b/agent/consul/tenancy_bridge_ce.go deleted file mode 100644 index f2938b156f026..0000000000000 --- a/agent/consul/tenancy_bridge_ce.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package consul - -func (b *V1TenancyBridge) PartitionExists(partition string) (bool, error) { - if partition == "default" { - return true, nil - } - return false, nil -} - -func (b *V1TenancyBridge) IsPartitionMarkedForDeletion(partition string) (bool, error) { - return false, nil -} - -func (b *V1TenancyBridge) NamespaceExists(partition, namespace string) (bool, error) { - if partition == "default" && namespace == "default" { - return true, nil - } - return false, nil -} - -func (b *V1TenancyBridge) IsNamespaceMarkedForDeletion(partition, namespace string) (bool, error) { - return false, nil -} diff --git a/agent/consul/testdata/v2-resource-dependencies.md b/agent/consul/testdata/v2-resource-dependencies.md deleted file mode 100644 index 1e34812446a41..0000000000000 --- a/agent/consul/testdata/v2-resource-dependencies.md +++ /dev/null @@ -1,45 +0,0 @@ -```mermaid -flowchart TD - auth/v2beta1/computedtrafficpermissions --> auth/v2beta1/trafficpermissions - auth/v2beta1/computedtrafficpermissions --> auth/v2beta1/workloadidentity - catalog/v2beta1/failoverpolicy --> catalog/v2beta1/service - catalog/v2beta1/healthstatus - catalog/v2beta1/node --> catalog/v2beta1/healthstatus - catalog/v2beta1/service - catalog/v2beta1/serviceendpoints --> catalog/v2beta1/service - catalog/v2beta1/serviceendpoints --> catalog/v2beta1/workload - catalog/v2beta1/workload --> catalog/v2beta1/healthstatus - catalog/v2beta1/workload --> catalog/v2beta1/node - demo/v1/album - demo/v1/artist - demo/v1/concept - demo/v1/executive - demo/v1/recordlabel - demo/v2/album - demo/v2/artist - internal/v1/tombstone - mesh/v2beta1/computedexplicitdestinations --> catalog/v2beta1/service - mesh/v2beta1/computedexplicitdestinations --> catalog/v2beta1/workload - mesh/v2beta1/computedexplicitdestinations --> mesh/v2beta1/computedroutes - mesh/v2beta1/computedexplicitdestinations --> mesh/v2beta1/destinations - mesh/v2beta1/computedproxyconfiguration --> catalog/v2beta1/workload - mesh/v2beta1/computedproxyconfiguration --> mesh/v2beta1/proxyconfiguration - mesh/v2beta1/computedroutes --> catalog/v2beta1/failoverpolicy - mesh/v2beta1/computedroutes --> catalog/v2beta1/service - mesh/v2beta1/computedroutes --> mesh/v2beta1/destinationpolicy - mesh/v2beta1/computedroutes --> mesh/v2beta1/grpcroute - mesh/v2beta1/computedroutes --> mesh/v2beta1/httproute - mesh/v2beta1/computedroutes --> mesh/v2beta1/tcproute - mesh/v2beta1/destinationpolicy - mesh/v2beta1/destinations - mesh/v2beta1/grpcroute - mesh/v2beta1/httproute - mesh/v2beta1/proxyconfiguration - mesh/v2beta1/proxystatetemplate --> auth/v2beta1/computedtrafficpermissions - mesh/v2beta1/proxystatetemplate --> catalog/v2beta1/service - mesh/v2beta1/proxystatetemplate --> catalog/v2beta1/workload - mesh/v2beta1/proxystatetemplate --> mesh/v2beta1/computedexplicitdestinations - mesh/v2beta1/proxystatetemplate --> mesh/v2beta1/computedproxyconfiguration - mesh/v2beta1/proxystatetemplate --> mesh/v2beta1/computedroutes - mesh/v2beta1/tcproute -``` \ No newline at end of file diff --git a/agent/consul/txn_endpoint.go b/agent/consul/txn_endpoint.go index f39cd502cb170..e7e5d870875e9 100644 --- a/agent/consul/txn_endpoint.go +++ b/agent/consul/txn_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/txn_endpoint_test.go b/agent/consul/txn_endpoint_test.go index ef2ecd13a3f85..f5654fdc001db 100644 --- a/agent/consul/txn_endpoint_test.go +++ b/agent/consul/txn_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/type_registry.go b/agent/consul/type_registry.go deleted file mode 100644 index 8bf093c41a112..0000000000000 --- a/agent/consul/type_registry.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package consul - -import ( - "github.com/hashicorp/consul/internal/auth" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/mesh" - "github.com/hashicorp/consul/internal/multicluster" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/demo" - "github.com/hashicorp/consul/internal/tenancy" -) - -// NewTypeRegistry returns a registry populated with all supported resource -// types. -// -// Note: the registry includes resource types that may not be suitable for -// production use (e.g. experimental or development resource types) because -// it is used in the CLI, where feature flags and other runtime configuration -// may not be available. -func NewTypeRegistry() resource.Registry { - registry := resource.NewRegistry() - - demo.RegisterTypes(registry) - mesh.RegisterTypes(registry) - catalog.RegisterTypes(registry) - auth.RegisterTypes(registry) - tenancy.RegisterTypes(registry) - multicluster.RegisterTypes(registry) - - return registry -} diff --git a/agent/consul/usagemetrics/usagemetrics.go b/agent/consul/usagemetrics/usagemetrics.go index 9539a743bbe69..eee4a8da06d48 100644 --- a/agent/consul/usagemetrics/usagemetrics.go +++ b/agent/consul/usagemetrics/usagemetrics.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package usagemetrics diff --git a/agent/consul/usagemetrics/usagemetrics_ce.go b/agent/consul/usagemetrics/usagemetrics_ce.go index 71457cbb48a1b..17853b4fcf6e3 100644 --- a/agent/consul/usagemetrics/usagemetrics_ce.go +++ b/agent/consul/usagemetrics/usagemetrics_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package usagemetrics diff --git a/agent/consul/usagemetrics/usagemetrics_ce_test.go b/agent/consul/usagemetrics/usagemetrics_ce_test.go index d0b7587d068c1..01a8b9eab5b8d 100644 --- a/agent/consul/usagemetrics/usagemetrics_ce_test.go +++ b/agent/consul/usagemetrics/usagemetrics_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package usagemetrics diff --git a/agent/consul/usagemetrics/usagemetrics_test.go b/agent/consul/usagemetrics/usagemetrics_test.go index 4e48beb0a3b2e..5aea3588f0558 100644 --- a/agent/consul/usagemetrics/usagemetrics_test.go +++ b/agent/consul/usagemetrics/usagemetrics_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package usagemetrics diff --git a/agent/consul/util.go b/agent/consul/util.go index 0fd88e14c8eb9..6fd6c77da33b1 100644 --- a/agent/consul/util.go +++ b/agent/consul/util.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/util_test.go b/agent/consul/util_test.go index d0a4fcb6842f1..c41b7748919fa 100644 --- a/agent/consul/util_test.go +++ b/agent/consul/util_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package consul diff --git a/agent/consul/wanfed/pool.go b/agent/consul/wanfed/pool.go index 3d083019346d4..9320087b3f713 100644 --- a/agent/consul/wanfed/pool.go +++ b/agent/consul/wanfed/pool.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package wanfed diff --git a/agent/consul/wanfed/wanfed.go b/agent/consul/wanfed/wanfed.go index 7732e05ad39a4..e82eddcfa88ef 100644 --- a/agent/consul/wanfed/wanfed.go +++ b/agent/consul/wanfed/wanfed.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package wanfed diff --git a/agent/consul/wanfed/wanfed_test.go b/agent/consul/wanfed/wanfed_test.go index 8254e9434b367..ef45c197c179a 100644 --- a/agent/consul/wanfed/wanfed_test.go +++ b/agent/consul/wanfed/wanfed_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package wanfed diff --git a/agent/consul/watch/server_local.go b/agent/consul/watch/server_local.go index 2bb98fe349df9..5937ba1c6a10e 100644 --- a/agent/consul/watch/server_local.go +++ b/agent/consul/watch/server_local.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package watch diff --git a/agent/consul/watch/server_local_test.go b/agent/consul/watch/server_local_test.go index 84ab8de5739a2..1f96b1ec00d03 100644 --- a/agent/consul/watch/server_local_test.go +++ b/agent/consul/watch/server_local_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package watch diff --git a/agent/consul/xdscapacity/capacity.go b/agent/consul/xdscapacity/capacity.go index bf3cf4ced02a1..6396841d63fe8 100644 --- a/agent/consul/xdscapacity/capacity.go +++ b/agent/consul/xdscapacity/capacity.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xdscapacity diff --git a/agent/consul/xdscapacity/capacity_test.go b/agent/consul/xdscapacity/capacity_test.go index b3a3935a8806f..d26453feae607 100644 --- a/agent/consul/xdscapacity/capacity_test.go +++ b/agent/consul/xdscapacity/capacity_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xdscapacity diff --git a/agent/coordinate_endpoint.go b/agent/coordinate_endpoint.go index 60b69244afd5d..744498c055336 100644 --- a/agent/coordinate_endpoint.go +++ b/agent/coordinate_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/coordinate_endpoint_test.go b/agent/coordinate_endpoint_test.go index 508f308d13c7c..fe6deeef9567e 100644 --- a/agent/coordinate_endpoint_test.go +++ b/agent/coordinate_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/debug/host.go b/agent/debug/host.go index f863117e547b0..5116bf7499f7e 100644 --- a/agent/debug/host.go +++ b/agent/debug/host.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package debug diff --git a/agent/debug/host_test.go b/agent/debug/host_test.go index dce469b542f2a..1289e21b4f066 100644 --- a/agent/debug/host_test.go +++ b/agent/debug/host_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package debug diff --git a/agent/delegate_mock_test.go b/agent/delegate_mock_test.go index a75cf2d1e2624..9f91a6a0d919b 100644 --- a/agent/delegate_mock_test.go +++ b/agent/delegate_mock_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -15,7 +15,6 @@ import ( "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/lib" - "github.com/hashicorp/consul/proto-public/pbresource" ) type delegateMock struct { @@ -77,7 +76,3 @@ func (m *delegateMock) Stats() map[string]map[string]string { func (m *delegateMock) ReloadConfig(config consul.ReloadableConfig) error { return m.Called(config).Error(0) } - -func (m *delegateMock) ResourceServiceClient() pbresource.ResourceServiceClient { - return nil -} diff --git a/agent/denylist.go b/agent/denylist.go index 5fdd8cc9f8721..b621465298146 100644 --- a/agent/denylist.go +++ b/agent/denylist.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/denylist_test.go b/agent/denylist_test.go index dd77e977d94d7..f9370723a7c30 100644 --- a/agent/denylist_test.go +++ b/agent/denylist_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/discovery_chain_endpoint.go b/agent/discovery_chain_endpoint.go index 69a5e668f46e1..a3aaa421f9387 100644 --- a/agent/discovery_chain_endpoint.go +++ b/agent/discovery_chain_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/discovery_chain_endpoint_test.go b/agent/discovery_chain_endpoint_test.go index 7e1e9a5524e4f..ed42ca0aede8a 100644 --- a/agent/discovery_chain_endpoint_test.go +++ b/agent/discovery_chain_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/dns.go b/agent/dns.go index b55338ea3e671..5804dc97dd8ef 100644 --- a/agent/dns.go +++ b/agent/dns.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -416,7 +416,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) { args := structs.DCSpecificRequest{ Datacenter: datacenter, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.agent.tokens.UserToken(), AllowStale: cfg.AllowStale, }, } @@ -452,7 +452,7 @@ func (d *DNSServer) handlePtr(resp dns.ResponseWriter, req *dns.Msg) { sargs := structs.ServiceSpecificRequest{ Datacenter: datacenter, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.agent.tokens.UserToken(), AllowStale: cfg.AllowStale, }, ServiceAddress: serviceAddress, @@ -513,7 +513,7 @@ func (d *DNSServer) handleQuery(resp dns.ResponseWriter, req *dns.Msg) { cfg := d.config.Load().(*dnsConfig) - // Set up the message response + // Setup the message response m := new(dns.Msg) m.SetReply(req) m.Compress = !cfg.DisableCompression @@ -875,7 +875,7 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi ServiceName: queryParts[len(queryParts)-1], EnterpriseMeta: locality.EnterpriseMeta, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.agent.tokens.UserToken(), }, } if args.PeerName == "" { @@ -1093,7 +1093,7 @@ func (d *DNSServer) nodeLookup(cfg *dnsConfig, lookup nodeLookup, req, resp *dns PeerName: lookup.PeerName, Node: lookup.Node, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.agent.tokens.UserToken(), AllowStale: cfg.AllowStale, }, EnterpriseMeta: lookup.EnterpriseMeta, @@ -1425,7 +1425,7 @@ func (d *DNSServer) lookupServiceNodes(cfg *dnsConfig, lookup serviceLookup) (st ServiceTags: serviceTags, TagFilter: lookup.Tag != "", QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.agent.tokens.UserToken(), AllowStale: cfg.AllowStale, MaxAge: cfg.CacheMaxAge, UseCache: cfg.UseCache, @@ -1503,7 +1503,7 @@ func (d *DNSServer) preparedQueryLookup(cfg *dnsConfig, datacenter, query string Datacenter: datacenter, QueryIDOrName: query, QueryOptions: structs.QueryOptions{ - Token: d.coalesceDNSToken(), + Token: d.agent.tokens.UserToken(), AllowStale: cfg.AllowStale, MaxAge: cfg.CacheMaxAge, }, @@ -2172,11 +2172,3 @@ func (d *DNSServer) resolveCNAME(cfg *dnsConfig, name string, maxRecursionLevel d.logger.Error("all resolvers failed for name", "name", name) return nil } - -func (d *DNSServer) coalesceDNSToken() string { - if d.agent.tokens.DNSToken() != "" { - return d.agent.tokens.DNSToken() - } else { - return d.agent.tokens.UserToken() - } -} diff --git a/agent/dns/dns.go b/agent/dns/dns.go index 1942a1fdd8d23..9f8e785a390b6 100644 --- a/agent/dns/dns.go +++ b/agent/dns/dns.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dns diff --git a/agent/dns/dns_test.go b/agent/dns/dns_test.go index 3acd2260e0a78..91dc3ea72a919 100644 --- a/agent/dns/dns_test.go +++ b/agent/dns/dns_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dns diff --git a/agent/dns/validation.go b/agent/dns/validation.go index a88aaff2dbcba..cd66acf6fa8fe 100644 --- a/agent/dns/validation.go +++ b/agent/dns/validation.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dns diff --git a/agent/dns/validation_test.go b/agent/dns/validation_test.go index 8855e375c5f9c..bcb65adf14a23 100644 --- a/agent/dns/validation_test.go +++ b/agent/dns/validation_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dns_test diff --git a/agent/dns_ce.go b/agent/dns_ce.go index bc6216e30a424..8c055776ed997 100644 --- a/agent/dns_ce.go +++ b/agent/dns_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/dns_ce_test.go b/agent/dns_ce_test.go index 976b7e7ebe549..920568cd3b9bd 100644 --- a/agent/dns_ce_test.go +++ b/agent/dns_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent @@ -9,12 +10,11 @@ import ( "context" "testing" - "github.com/miekg/dns" - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/testrpc" + "github.com/miekg/dns" + "github.com/stretchr/testify/require" ) func TestDNS_CE_PeeredServices(t *testing.T) { diff --git a/agent/dns_test.go b/agent/dns_test.go index 3c447db36ee2b..ef5364964dd35 100644 --- a/agent/dns_test.go +++ b/agent/dns_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -6310,22 +6310,6 @@ func TestDNS_ServiceLookup_SRV_RFC_TCP_Default(t *testing.T) { } -func initDNSToken(t *testing.T, rpc RPC) { - t.Helper() - - reqToken := structs.ACLTokenSetRequest{ - Datacenter: "dc1", - ACLToken: structs.ACLToken{ - SecretID: "279d4735-f8ca-4d48-b5cc-c00a9713bbf8", - Policies: nil, - TemplatedPolicies: []*structs.ACLTemplatedPolicy{{TemplateName: "builtin/dns"}}, - }, - WriteRequest: structs.WriteRequest{Token: "root"}, - } - err := rpc.RPC(context.Background(), "ACL.TokenSet", &reqToken, &structs.ACLToken{}) - require.NoError(t, err) -} - func TestDNS_ServiceLookup_FilterACL(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") @@ -6338,11 +6322,10 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) { }{ {"root", 1}, {"anonymous", 0}, - {"dns", 1}, } for _, tt := range tests { t.Run("ACLToken == "+tt.token, func(t *testing.T) { - hcl := ` + a := NewTestAgent(t, ` primary_datacenter = "dc1" acl { @@ -6352,34 +6335,13 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) { tokens { initial_management = "root" -` - if tt.token == "dns" { - // Create a UUID for dns token since it doesn't have an alias - dnsToken := "279d4735-f8ca-4d48-b5cc-c00a9713bbf8" - - hcl = hcl + ` - default = "anonymous" - dns = "` + dnsToken + `" -` - } else { - hcl = hcl + ` - default = "` + tt.token + `" -` - } - - hcl = hcl + ` + default = "`+tt.token+`" } } - ` - - a := NewTestAgent(t, hcl) + `) defer a.Shutdown() testrpc.WaitForLeader(t, a.RPC, "dc1") - if tt.token == "dns" { - initDNSToken(t, a) - } - // Register a service args := &structs.RegisterRequest{ Datacenter: "dc1", @@ -6411,7 +6373,6 @@ func TestDNS_ServiceLookup_FilterACL(t *testing.T) { }) } } - func TestDNS_ServiceLookup_MetaTXT(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") diff --git a/agent/enterprise_delegate_ce.go b/agent/enterprise_delegate_ce.go index 85128b8b3c074..39ae3db7c46d2 100644 --- a/agent/enterprise_delegate_ce.go +++ b/agent/enterprise_delegate_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/envoyextensions/builtin/aws-lambda/aws_lambda.go b/agent/envoyextensions/builtin/aws-lambda/aws_lambda.go index 978fc5cf5552b..fa36d6fa500d9 100644 --- a/agent/envoyextensions/builtin/aws-lambda/aws_lambda.go +++ b/agent/envoyextensions/builtin/aws-lambda/aws_lambda.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package awslambda diff --git a/agent/envoyextensions/builtin/aws-lambda/aws_lambda_test.go b/agent/envoyextensions/builtin/aws-lambda/aws_lambda_test.go index 3dda09e317a47..26f49eef4bd16 100644 --- a/agent/envoyextensions/builtin/aws-lambda/aws_lambda_test.go +++ b/agent/envoyextensions/builtin/aws-lambda/aws_lambda_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package awslambda diff --git a/agent/envoyextensions/builtin/ext-authz/ext_authz.go b/agent/envoyextensions/builtin/ext-authz/ext_authz.go index 00e1d47640c4a..7400aef13a04c 100644 --- a/agent/envoyextensions/builtin/ext-authz/ext_authz.go +++ b/agent/envoyextensions/builtin/ext-authz/ext_authz.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extauthz @@ -23,8 +23,6 @@ type extAuthz struct { ProxyType api.ServiceKind // InsertOptions controls how the extension inserts the filter. InsertOptions ext_cmn.InsertOptions - // ListenerType controls which listener the extension applies to. It supports "inbound" or "outbound" listeners. - ListenerType string // Config holds the extension configuration. Config extAuthzConfig } @@ -63,14 +61,10 @@ func (a *extAuthz) PatchClusters(cfg *ext_cmn.RuntimeConfig, c ext_cmn.ClusterMa return c, nil } -func (a *extAuthz) matchesListenerDirection(isInboundListener bool) bool { - return (!isInboundListener && a.ListenerType == "outbound") || (isInboundListener && a.ListenerType == "inbound") -} - // PatchFilters inserts an ext-authz filter into the list of network filters or the filter chain of the HTTP connection manager. func (a *extAuthz) PatchFilters(cfg *ext_cmn.RuntimeConfig, filters []*envoy_listener_v3.Filter, isInboundListener bool) ([]*envoy_listener_v3.Filter, error) { // The ext_authz extension only patches filters for inbound listeners. - if !a.matchesListenerDirection(isInboundListener) { + if !isInboundListener { return filters, nil } @@ -135,11 +129,6 @@ func (a *extAuthz) normalize() { if a.ProxyType == "" { a.ProxyType = api.ServiceKindConnectProxy } - - if a.ListenerType == "" { - a.ListenerType = "inbound" - } - a.Config.normalize() } @@ -151,10 +140,6 @@ func (a *extAuthz) validate() error { api.ServiceKindConnectProxy)) } - if a.ListenerType != "inbound" && a.ListenerType != "outbound" { - resultErr = multierror.Append(resultErr, fmt.Errorf(`unexpected ListenerType %q, supported values are "inbound" or "outbound"`, a.ListenerType)) - } - if err := a.Config.validate(); err != nil { resultErr = multierror.Append(resultErr, err) } diff --git a/agent/envoyextensions/builtin/ext-authz/ext_authz_test.go b/agent/envoyextensions/builtin/ext-authz/ext_authz_test.go index 6db284476dd71..88e87d7e9a8f8 100644 --- a/agent/envoyextensions/builtin/ext-authz/ext_authz_test.go +++ b/agent/envoyextensions/builtin/ext-authz/ext_authz_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extauthz diff --git a/agent/envoyextensions/builtin/ext-authz/structs.go b/agent/envoyextensions/builtin/ext-authz/structs.go index 0a7e7dcce43a7..a14cedd63a765 100644 --- a/agent/envoyextensions/builtin/ext-authz/structs.go +++ b/agent/envoyextensions/builtin/ext-authz/structs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extauthz diff --git a/agent/envoyextensions/builtin/lua/lua.go b/agent/envoyextensions/builtin/lua/lua.go index ba08d9d286c01..aefea37e6c496 100644 --- a/agent/envoyextensions/builtin/lua/lua.go +++ b/agent/envoyextensions/builtin/lua/lua.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lua diff --git a/agent/envoyextensions/builtin/lua/lua_test.go b/agent/envoyextensions/builtin/lua/lua_test.go index afe65d067f433..3ea2ba716c1de 100644 --- a/agent/envoyextensions/builtin/lua/lua_test.go +++ b/agent/envoyextensions/builtin/lua/lua_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lua diff --git a/agent/envoyextensions/builtin/otel-access-logging/otel_access_logging.go b/agent/envoyextensions/builtin/otel-access-logging/otel_access_logging.go deleted file mode 100644 index 2f003b5525826..0000000000000 --- a/agent/envoyextensions/builtin/otel-access-logging/otel_access_logging.go +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package otelaccesslogging - -import ( - "fmt" - - envoy_extensions_access_loggers_v3 "github.com/envoyproxy/go-control-plane/envoy/config/accesslog/v3" - envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" - envoy_extensions_access_loggers_otel_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/open_telemetry/v3" - "github.com/mitchellh/mapstructure" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/api" - ext_cmn "github.com/hashicorp/consul/envoyextensions/extensioncommon" - "github.com/hashicorp/go-multierror" - v1 "go.opentelemetry.io/proto/otlp/common/v1" -) - -type otelAccessLogging struct { - ext_cmn.BasicExtensionAdapter - - // ProxyType identifies the type of Envoy proxy that this extension applies to. - // The extension will only be configured for proxies that match this type and - // will be ignored for all other proxy types. - ProxyType api.ServiceKind - // ListenerType controls which listener the extension applies to. It supports "inbound" or "outbound" listeners. - ListenerType string - // Config holds the extension configuration. - Config AccessLog -} - -var _ ext_cmn.BasicExtension = (*otelAccessLogging)(nil) - -func Constructor(ext api.EnvoyExtension) (ext_cmn.EnvoyExtender, error) { - otel, err := newOTELAccessLogging(ext) - if err != nil { - return nil, err - } - return &ext_cmn.BasicEnvoyExtender{ - Extension: otel, - }, nil -} - -// CanApply indicates if the extension can be applied to the given extension runtime configuration. -func (a *otelAccessLogging) CanApply(config *ext_cmn.RuntimeConfig) bool { - return config.Kind == api.ServiceKindConnectProxy -} - -// PatchClusters modifies the cluster resources for the extension. -// -// If the extension is configured to target the OTEL service running on the local host network -// this func will insert a cluster for calling that service. It does nothing if the extension is -// configured to target an upstream service because the existing cluster for the upstream will be -// used directly by the filter. -func (a *otelAccessLogging) PatchClusters(cfg *ext_cmn.RuntimeConfig, c ext_cmn.ClusterMap) (ext_cmn.ClusterMap, error) { - cluster, err := a.Config.toEnvoyCluster(cfg) - if err != nil { - return c, err - } - if cluster != nil { - c[cluster.Name] = cluster - } - return c, nil -} - -func (a *otelAccessLogging) matchesListenerDirection(p ext_cmn.FilterPayload) bool { - isInboundListener := p.IsInbound() - return (!isInboundListener && a.ListenerType == "outbound") || (isInboundListener && a.ListenerType == "inbound") -} - -// PatchFilter adds the OTEL access log in the HTTP connection manager. -func (a *otelAccessLogging) PatchFilter(p ext_cmn.FilterPayload) (*envoy_listener_v3.Filter, bool, error) { - filter := p.Message - // Make sure filter matches extension config. - if !a.matchesListenerDirection(p) { - return filter, false, nil - } - - httpConnectionManager, _, err := ext_cmn.GetHTTPConnectionManager(filter) - if err != nil { - return filter, false, err - } - - accessLog, err := a.toEnvoyAccessLog(p.RuntimeConfig) - if err != nil { - return filter, false, err - } - - httpConnectionManager.AccessLog = append(httpConnectionManager.AccessLog, accessLog) - newHCM, err := ext_cmn.MakeFilter("envoy.filters.network.http_connection_manager", httpConnectionManager) - if err != nil { - return filter, false, err - } - - return newHCM, true, nil -} - -func newOTELAccessLogging(ext api.EnvoyExtension) (*otelAccessLogging, error) { - otel := &otelAccessLogging{} - if ext.Name != api.BuiltinOTELAccessLoggingExtension { - return otel, fmt.Errorf("expected extension name %q but got %q", api.BuiltinOTELAccessLoggingExtension, ext.Name) - } - if err := otel.fromArguments(ext.Arguments); err != nil { - return otel, err - } - - return otel, nil -} - -func (a *otelAccessLogging) fromArguments(args map[string]any) error { - if err := mapstructure.Decode(args, a); err != nil { - return err - } - a.normalize() - return a.validate() -} - -func (a *otelAccessLogging) toEnvoyAccessLog(cfg *ext_cmn.RuntimeConfig) (*envoy_extensions_access_loggers_v3.AccessLog, error) { - commonConfig, err := a.Config.toEnvoyCommonGrpcAccessLogConfig(cfg) - if err != nil { - return nil, err - } - - body, err := toEnvoyAnyValue(a.Config.Body) - if err != nil { - return nil, fmt.Errorf("failed to marshal Body: %w", err) - } - - attributes, err := toEnvoyKeyValueList(a.Config.Attributes) - if err != nil { - return nil, fmt.Errorf("failed to marshal Attributes: %w", err) - } - - resourceAttributes, err := toEnvoyKeyValueList(a.Config.ResourceAttributes) - if err != nil { - return nil, fmt.Errorf("failed to marshal ResourceAttributes: %w", err) - } - - otelAccessLogConfig := &envoy_extensions_access_loggers_otel_v3.OpenTelemetryAccessLogConfig{ - CommonConfig: commonConfig, - Body: body, - Attributes: attributes, - ResourceAttributes: resourceAttributes, - } - - // Marshal the struct to bytes. - otelAccessLogConfigBytes, err := proto.Marshal(otelAccessLogConfig) - if err != nil { - return nil, fmt.Errorf("failed to marshal OpenTelemetryAccessLogConfig: %w", err) - } - - return &envoy_extensions_access_loggers_v3.AccessLog{ - Name: "envoy.access_loggers.open_telemetry", - ConfigType: &envoy_extensions_access_loggers_v3.AccessLog_TypedConfig{ - TypedConfig: &anypb.Any{ - Value: otelAccessLogConfigBytes, - TypeUrl: "type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig", - }, - }, - }, nil -} - -func (a *otelAccessLogging) normalize() { - if a.ProxyType == "" { - a.ProxyType = api.ServiceKindConnectProxy - } - - if a.ListenerType == "" { - a.ListenerType = "inbound" - } - - if a.Config.LogName == "" { - a.Config.LogName = a.ListenerType - } - - a.Config.normalize() -} - -func (a *otelAccessLogging) validate() error { - var resultErr error - if a.ProxyType != api.ServiceKindConnectProxy { - resultErr = multierror.Append(resultErr, fmt.Errorf("unsupported ProxyType %q, only %q is supported", - a.ProxyType, - api.ServiceKindConnectProxy)) - } - - if a.ListenerType != "inbound" && a.ListenerType != "outbound" { - resultErr = multierror.Append(resultErr, fmt.Errorf(`unexpected ListenerType %q, supported values are "inbound" or "outbound"`, a.ListenerType)) - } - - if err := a.Config.validate(); err != nil { - resultErr = multierror.Append(resultErr, err) - } - - return resultErr -} - -func toEnvoyKeyValueList(attributes map[string]any) (*v1.KeyValueList, error) { - keyValueList := &v1.KeyValueList{} - for key, value := range attributes { - anyValue, err := toEnvoyAnyValue(value) - if err != nil { - return nil, err - } - keyValueList.Values = append(keyValueList.Values, &v1.KeyValue{ - Key: key, - Value: anyValue, - }) - } - - return keyValueList, nil -} - -func toEnvoyAnyValue(value interface{}) (*v1.AnyValue, error) { - if value == nil { - return nil, nil - } - - switch v := value.(type) { - case string: - return &v1.AnyValue{ - Value: &v1.AnyValue_StringValue{ - StringValue: v, - }, - }, nil - case int: - return &v1.AnyValue{ - Value: &v1.AnyValue_IntValue{ - IntValue: int64(v), - }, - }, nil - case int32: - return &v1.AnyValue{ - Value: &v1.AnyValue_IntValue{ - IntValue: int64(v), - }, - }, nil - case int64: - return &v1.AnyValue{ - Value: &v1.AnyValue_IntValue{ - IntValue: v, - }, - }, nil - case float32: - return &v1.AnyValue{ - Value: &v1.AnyValue_DoubleValue{ - DoubleValue: float64(v), - }, - }, nil - case float64: - return &v1.AnyValue{ - Value: &v1.AnyValue_DoubleValue{ - DoubleValue: v, - }, - }, nil - case bool: - return &v1.AnyValue{ - Value: &v1.AnyValue_BoolValue{ - BoolValue: v, - }, - }, nil - case []byte: - return &v1.AnyValue{ - Value: &v1.AnyValue_BytesValue{ - BytesValue: v, - }, - }, nil - default: - return nil, fmt.Errorf("unsupported type %T", v) - } -} diff --git a/agent/envoyextensions/builtin/otel-access-logging/otel_access_logging_test.go b/agent/envoyextensions/builtin/otel-access-logging/otel_access_logging_test.go deleted file mode 100644 index 5c6b9ffa6636c..0000000000000 --- a/agent/envoyextensions/builtin/otel-access-logging/otel_access_logging_test.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package otelaccesslogging - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/envoyextensions/extensioncommon" -) - -func TestConstructor(t *testing.T) { - makeArguments := func(overrides map[string]interface{}) map[string]interface{} { - m := map[string]interface{}{ - "ProxyType": "connect-proxy", - "ListenerType": "inbound", - "Config": AccessLog{ - LogName: "access.log", - GrpcService: &GrpcService{ - Target: &Target{ - Service: api.CompoundServiceName{ - Name: "otel-collector", - Namespace: "default", - Partition: "default", - }, - }, - }, - }, - } - - for k, v := range overrides { - m[k] = v - } - - return m - } - - cases := map[string]struct { - extensionName string - arguments map[string]interface{} - expected otelAccessLogging - ok bool - }{ - "with no arguments": { - arguments: nil, - ok: false, - }, - "with an invalid name": { - arguments: makeArguments(map[string]interface{}{}), - extensionName: "bad", - ok: false, - }, - "invalid proxy type": { - arguments: makeArguments(map[string]interface{}{"ProxyType": "terminating-gateway"}), - ok: false, - }, - "invalid listener": { - arguments: makeArguments(map[string]interface{}{"ListenerType": "invalid"}), - ok: false, - }, - "default proxy type": { - arguments: makeArguments(map[string]interface{}{"ProxyType": ""}), - expected: otelAccessLogging{ - ProxyType: "connect-proxy", - ListenerType: "inbound", - Config: AccessLog{ - LogName: "access.log", - GrpcService: &GrpcService{ - Target: &Target{ - Service: api.CompoundServiceName{ - Name: "otel-collector", - Namespace: "default", - Partition: "default", - }, - }, - }, - }, - }, - ok: true, - }, - } - - for n, tc := range cases { - t.Run(n, func(t *testing.T) { - - extensionName := api.BuiltinOTELAccessLoggingExtension - if tc.extensionName != "" { - extensionName = tc.extensionName - } - - svc := api.CompoundServiceName{Name: "svc"} - ext := extensioncommon.RuntimeConfig{ - ServiceName: svc, - EnvoyExtension: api.EnvoyExtension{ - Name: extensionName, - Arguments: tc.arguments, - }, - } - - e, err := Constructor(ext.EnvoyExtension) - - if tc.ok { - require.NoError(t, err) - require.Equal(t, &extensioncommon.BasicEnvoyExtender{Extension: &tc.expected}, e) - } else { - require.Error(t, err) - } - }) - } -} diff --git a/agent/envoyextensions/builtin/otel-access-logging/structs.go b/agent/envoyextensions/builtin/otel-access-logging/structs.go deleted file mode 100644 index c6078679aa741..0000000000000 --- a/agent/envoyextensions/builtin/otel-access-logging/structs.go +++ /dev/null @@ -1,424 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package otelaccesslogging - -import ( - "fmt" - "strconv" - "strings" - "time" - - envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" - envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" - envoy_extensions_access_loggers_grpc_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/grpc/v3" - envoy_upstreams_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3" - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/api" - cmn "github.com/hashicorp/consul/envoyextensions/extensioncommon" - "github.com/hashicorp/go-multierror" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" -) - -const ( - LocalAccessLogClusterName = "local_access_log" - - localhost = "localhost" - localhostIPv4 = "127.0.0.1" - localhostIPv6 = "::1" -) - -type AccessLog struct { - LogName string - GrpcService *GrpcService - BufferFlushInterval *time.Duration - BufferSizeBytes uint32 - FilterStateObjectsToLog []string - RetryPolicy *RetryPolicy - Body any - Attributes map[string]any - ResourceAttributes map[string]any -} - -func (a *AccessLog) normalize() { - if a.GrpcService != nil { - a.GrpcService.normalize() - } - - if a.RetryPolicy != nil { - a.RetryPolicy.normalize() - } -} - -func (a *AccessLog) validate() error { - a.normalize() - - if a.GrpcService == nil { - return fmt.Errorf("missing GrpcService") - } - - var resultErr error - - var field string - var validate func() error - field = "GrpcService" - validate = a.GrpcService.validate - - if err := validate(); err != nil { - resultErr = multierror.Append(resultErr, fmt.Errorf("failed to validate Config.%s: %w", field, err)) - } - - return resultErr -} - -func (a *AccessLog) envoyGrpcService(cfg *cmn.RuntimeConfig) (*envoy_core_v3.GrpcService, error) { - target := a.GrpcService.Target - clusterName, err := a.getClusterName(cfg, target) - if err != nil { - return nil, err - } - - var initialMetadata []*envoy_core_v3.HeaderValue - for _, meta := range a.GrpcService.InitialMetadata { - initialMetadata = append(initialMetadata, meta.toEnvoy()) - } - - return &envoy_core_v3.GrpcService{ - TargetSpecifier: &envoy_core_v3.GrpcService_EnvoyGrpc_{ - EnvoyGrpc: &envoy_core_v3.GrpcService_EnvoyGrpc{ - ClusterName: clusterName, - Authority: a.GrpcService.Authority, - }, - }, - Timeout: target.timeoutDurationPB(), - InitialMetadata: initialMetadata, - }, nil -} - -// getClusterName returns the name of the cluster for the OpenTelemetry access logging service. -// If the extension is configured with an upstream OpenTelemetry access logging service then the name of the cluster for -// that upstream is returned. If the extension is configured with a URI, the only allowed host is `localhost` -// and the extension will insert a new cluster with the name "local_access_log", so we use that name. -func (a *AccessLog) getClusterName(cfg *cmn.RuntimeConfig, target *Target) (string, error) { - var err error - clusterName := LocalAccessLogClusterName - if target.isService() { - if clusterName, err = target.clusterName(cfg); err != nil { - return "", err - } - } - return clusterName, nil -} - -// toEnvoyCluster returns an Envoy cluster for connecting to the OpenTelemetry access logging service. -// If the extension is configured with the OpenTelemetry access logging service locally via the URI set to localhost, -// this func will return a new cluster definition that will allow the proxy to connect to the OpenTelemetry access logging -// service running on localhost on the configured port. -// -// If the extension is configured with the OpenTelemetry access logging service as an upstream there is no need to insert -// a new cluster so this method returns nil. -func (a *AccessLog) toEnvoyCluster(_ *cmn.RuntimeConfig) (*envoy_cluster_v3.Cluster, error) { - target := a.GrpcService.Target - - // If the target is an upstream we do not need to create a cluster. We will use the cluster of the upstream. - if target.isService() { - return nil, nil - } - - host, port, err := target.addr() - if err != nil { - return nil, err - } - - clusterType := &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_STATIC} - if host == localhost { - // If the host is "localhost" use a STRICT_DNS cluster type to perform DNS lookup. - clusterType = &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_STRICT_DNS} - } - - var typedExtProtoOpts map[string]*anypb.Any - - httpProtoOpts := &envoy_upstreams_http_v3.HttpProtocolOptions{ - UpstreamProtocolOptions: &envoy_upstreams_http_v3.HttpProtocolOptions_ExplicitHttpConfig_{ - ExplicitHttpConfig: &envoy_upstreams_http_v3.HttpProtocolOptions_ExplicitHttpConfig{ - ProtocolConfig: &envoy_upstreams_http_v3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{}, - }, - }, - } - httpProtoOptsAny, err := anypb.New(httpProtoOpts) - if err != nil { - return nil, err - } - typedExtProtoOpts = make(map[string]*anypb.Any) - typedExtProtoOpts["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"] = httpProtoOptsAny - - return &envoy_cluster_v3.Cluster{ - Name: LocalAccessLogClusterName, - ClusterDiscoveryType: clusterType, - ConnectTimeout: target.timeoutDurationPB(), - LoadAssignment: &envoy_endpoint_v3.ClusterLoadAssignment{ - ClusterName: LocalAccessLogClusterName, - Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{ - { - LbEndpoints: []*envoy_endpoint_v3.LbEndpoint{{ - HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ - Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: &envoy_core_v3.Address{ - Address: &envoy_core_v3.Address_SocketAddress{ - SocketAddress: &envoy_core_v3.SocketAddress{ - Address: host, - PortSpecifier: &envoy_core_v3.SocketAddress_PortValue{ - PortValue: uint32(port), - }, - }, - }, - }, - }, - }, - }}, - }, - }, - }, - TypedExtensionProtocolOptions: typedExtProtoOpts, - }, nil -} - -func (a *AccessLog) toEnvoyCommonGrpcAccessLogConfig(cfg *cmn.RuntimeConfig) (*envoy_extensions_access_loggers_grpc_v3.CommonGrpcAccessLogConfig, error) { - config := &envoy_extensions_access_loggers_grpc_v3.CommonGrpcAccessLogConfig{ - LogName: a.LogName, - BufferSizeBytes: wrapperspb.UInt32(a.BufferSizeBytes), - FilterStateObjectsToLog: a.FilterStateObjectsToLog, - TransportApiVersion: envoy_core_v3.ApiVersion_V3, - } - - if a.BufferFlushInterval != nil { - config.BufferFlushInterval = durationpb.New(*a.BufferFlushInterval) - } - - if a.RetryPolicy != nil { - config.GrpcStreamRetryPolicy = a.RetryPolicy.toEnvoy() - } - - grpcSvc, err := a.envoyGrpcService(cfg) - if err != nil { - return nil, err - } - config.GrpcService = grpcSvc - - return config, nil -} - -type GrpcService struct { - Target *Target - Authority string - InitialMetadata []*HeaderValue -} - -func (v *GrpcService) normalize() { - if v == nil { - return - } - v.Target.normalize() -} - -func (v *GrpcService) validate() error { - var resultErr error - if v == nil { - return resultErr - } - - if v.Target == nil { - resultErr = multierror.Append(resultErr, fmt.Errorf("GrpcService.Target must be set")) - } - if err := v.Target.validate(); err != nil { - resultErr = multierror.Append(resultErr, err) - } - return resultErr -} - -type HeaderValue struct { - Key string - Value string -} - -func (h *HeaderValue) toEnvoy() *envoy_core_v3.HeaderValue { - if h == nil { - return nil - } - return &envoy_core_v3.HeaderValue{Key: h.Key, Value: h.Value} -} - -type Target struct { - Service api.CompoundServiceName - URI string - Timeout string - - timeout *time.Duration - host string - port int -} - -// addr returns the host and port for the target when the target is a URI. -// It returns a non-nil error if the target is not a URI. -func (t Target) addr() (string, int, error) { - if !t.isURI() { - return "", 0, fmt.Errorf("target is not configured with a URI, set Target.URI") - } - return t.host, t.port, nil -} - -// clusterName returns the cluster name for the target when the target is an upstream service. -// It searches through the upstreams in the provided runtime configuration and returns the name -// of the cluster for the first upstream service that matches the target service. -// It returns a non-nil error if a matching cluster is not found or if the target is not an -// upstream service. -func (t Target) clusterName(cfg *cmn.RuntimeConfig) (string, error) { - if !t.isService() { - return "", fmt.Errorf("target is not configured with an upstream service, set Target.Service") - } - - for service, upstream := range cfg.Upstreams { - if service == t.Service { - for sni := range upstream.SNIs { - return sni, nil - } - } - } - return "", fmt.Errorf("no upstream definition found for service %q", t.Service.Name) -} - -func (t Target) isService() bool { - return t.Service.Name != "" -} - -func (t Target) isURI() bool { - return t.URI != "" -} - -func (t *Target) normalize() { - if t == nil { - return - } - t.Service.Namespace = acl.NamespaceOrDefault(t.Service.Namespace) - t.Service.Partition = acl.PartitionOrDefault(t.Service.Partition) -} - -// timeoutDurationPB returns the target's timeout as a *durationpb.Duration. -// It returns nil if the timeout has not been explicitly set. -func (t *Target) timeoutDurationPB() *durationpb.Duration { - if t == nil || t.timeout == nil { - return nil - } - return durationpb.New(*t.timeout) -} - -func (t *Target) validate() error { - var err, resultErr error - if t == nil { - return resultErr - } - - if t.isURI() == t.isService() { - resultErr = multierror.Append(resultErr, fmt.Errorf("exactly one of Target.Service or Target.URI must be set")) - } - - if t.isURI() { - t.host, t.port, err = parseAddr(t.URI) - if err == nil { - switch t.host { - case localhost, localhostIPv4, localhostIPv6: - default: - resultErr = multierror.Append(resultErr, - fmt.Errorf("invalid host for Target.URI %q: expected %q, %q, or %q", t.URI, localhost, localhostIPv4, localhostIPv6)) - } - } else { - resultErr = multierror.Append(resultErr, fmt.Errorf("invalid format for Target.URI %q: expected host:port", t.URI)) - } - } - - if t.Timeout != "" { - if d, err := time.ParseDuration(t.Timeout); err == nil { - t.timeout = &d - } else { - resultErr = multierror.Append(resultErr, fmt.Errorf("failed to parse Target.Timeout %q as a duration: %w", t.Timeout, err)) - } - } - return resultErr -} - -type RetryPolicy struct { - RetryBackOff *RetryBackOff - NumRetries uint32 -} - -func (r *RetryPolicy) normalize() { - if r == nil { - return - } - r.RetryBackOff.normalize() -} - -func (r *RetryPolicy) toEnvoy() *envoy_core_v3.RetryPolicy { - if r == nil { - return nil - } - - return &envoy_core_v3.RetryPolicy{ - RetryBackOff: r.RetryBackOff.toEnvoy(), - NumRetries: wrapperspb.UInt32(r.NumRetries), - } -} - -type RetryBackOff struct { - BaseInterval *time.Duration - MaxInterval *time.Duration -} - -func (v *RetryBackOff) normalize() { - if v == nil { - return - } - - if v.BaseInterval == nil { - v.BaseInterval = new(time.Duration) - *v.BaseInterval = time.Second - } - - if v.MaxInterval == nil { - v.MaxInterval = new(time.Duration) - *v.MaxInterval = time.Second * 30 - } -} - -func (r *RetryBackOff) toEnvoy() *envoy_core_v3.BackoffStrategy { - if r == nil { - return nil - } - - return &envoy_core_v3.BackoffStrategy{ - BaseInterval: durationpb.New(*r.BaseInterval), - MaxInterval: durationpb.New(*r.MaxInterval), - } -} - -func parseAddr(s string) (host string, port int, err error) { - // Strip the protocol if one was provided - if _, addr, hasProto := strings.Cut(s, "://"); hasProto { - s = addr - } - idx := strings.LastIndex(s, ":") - switch idx { - case -1, len(s) - 1: - err = fmt.Errorf("invalid input format %q: expected host:port", s) - case 0: - host = localhost - port, err = strconv.Atoi(s[idx+1:]) - default: - host = s[:idx] - port, err = strconv.Atoi(s[idx+1:]) - } - return -} diff --git a/agent/envoyextensions/builtin/property-override/property_override.go b/agent/envoyextensions/builtin/property-override/property_override.go index 70577a56e3d40..41e98074b7a23 100644 --- a/agent/envoyextensions/builtin/property-override/property_override.go +++ b/agent/envoyextensions/builtin/property-override/property_override.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package propertyoverride import ( diff --git a/agent/envoyextensions/builtin/property-override/property_override_test.go b/agent/envoyextensions/builtin/property-override/property_override_test.go index 20febc21074db..0e4317f9ddb72 100644 --- a/agent/envoyextensions/builtin/property-override/property_override_test.go +++ b/agent/envoyextensions/builtin/property-override/property_override_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package propertyoverride import ( diff --git a/agent/envoyextensions/builtin/property-override/structpatcher.go b/agent/envoyextensions/builtin/property-override/structpatcher.go index 76fe3be1a8570..91de4cf7f86d1 100644 --- a/agent/envoyextensions/builtin/property-override/structpatcher.go +++ b/agent/envoyextensions/builtin/property-override/structpatcher.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package propertyoverride import ( diff --git a/agent/envoyextensions/builtin/property-override/structpatcher_test.go b/agent/envoyextensions/builtin/property-override/structpatcher_test.go index 4916f0c505c7d..ac7379f9f1868 100644 --- a/agent/envoyextensions/builtin/property-override/structpatcher_test.go +++ b/agent/envoyextensions/builtin/property-override/structpatcher_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package propertyoverride import ( diff --git a/agent/envoyextensions/builtin/wasm/structs.go b/agent/envoyextensions/builtin/wasm/structs.go index 67540fee56c94..012099ab62036 100644 --- a/agent/envoyextensions/builtin/wasm/structs.go +++ b/agent/envoyextensions/builtin/wasm/structs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package wasm diff --git a/agent/envoyextensions/builtin/wasm/wasm.go b/agent/envoyextensions/builtin/wasm/wasm.go index da1e0a7ceaa95..c16ac4da81c0e 100644 --- a/agent/envoyextensions/builtin/wasm/wasm.go +++ b/agent/envoyextensions/builtin/wasm/wasm.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package wasm diff --git a/agent/envoyextensions/builtin/wasm/wasm_test.go b/agent/envoyextensions/builtin/wasm/wasm_test.go index fd348d59a73d4..93f3a4b5e0aff 100644 --- a/agent/envoyextensions/builtin/wasm/wasm_test.go +++ b/agent/envoyextensions/builtin/wasm/wasm_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package wasm @@ -18,6 +18,7 @@ import ( envoy_network_wasm_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/wasm/v3" envoy_wasm_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/durationpb" @@ -137,8 +138,8 @@ func TestHttpWasmExtension(t *testing.T) { t.Logf("cfg =\n%s\n\n", cfg.toJSON(t)) require.Equal(t, len(expFilters), len(obsFilters)) for idx, expFilter := range expFilters { - t.Logf("expFilterJSON[%d] =\n%s\n\n", idx, prototest.ProtoToJSON(t, expFilter)) - t.Logf("obsfilterJSON[%d] =\n%s\n\n", idx, prototest.ProtoToJSON(t, obsFilters[idx])) + t.Logf("expFilterJSON[%d] =\n%s\n\n", idx, protoToJSON(t, expFilter)) + t.Logf("obsfilterJSON[%d] =\n%s\n\n", idx, protoToJSON(t, obsFilters[idx])) } } @@ -650,6 +651,16 @@ func newTestWasmConfig(protocol string, enterprise bool) *testWasmConfig { return cfg } +func protoToJSON(t *testing.T, pb proto.Message) string { + t.Helper() + m := protojson.MarshalOptions{ + Indent: " ", + } + gotJSON, err := m.Marshal(pb) + require.NoError(t, err) + return string(gotJSON) +} + func setField(m map[string]any, path string, value any) { upsertField(m, path, value, 0) } diff --git a/agent/envoyextensions/registered_extensions.go b/agent/envoyextensions/registered_extensions.go index b2bb2aeeaaa9e..7b0f2ae61da14 100644 --- a/agent/envoyextensions/registered_extensions.go +++ b/agent/envoyextensions/registered_extensions.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoyextensions @@ -12,7 +12,6 @@ import ( awslambda "github.com/hashicorp/consul/agent/envoyextensions/builtin/aws-lambda" extauthz "github.com/hashicorp/consul/agent/envoyextensions/builtin/ext-authz" "github.com/hashicorp/consul/agent/envoyextensions/builtin/lua" - otelaccesslogging "github.com/hashicorp/consul/agent/envoyextensions/builtin/otel-access-logging" propertyoverride "github.com/hashicorp/consul/agent/envoyextensions/builtin/property-override" "github.com/hashicorp/consul/agent/envoyextensions/builtin/wasm" "github.com/hashicorp/consul/api" @@ -22,25 +21,22 @@ import ( type extensionConstructor func(api.EnvoyExtension) (extensioncommon.EnvoyExtender, error) var extensionConstructors = map[string]extensionConstructor{ - api.BuiltinOTELAccessLoggingExtension: otelaccesslogging.Constructor, - api.BuiltinLuaExtension: lua.Constructor, - api.BuiltinAWSLambdaExtension: awslambda.Constructor, - api.BuiltinPropertyOverrideExtension: propertyoverride.Constructor, - api.BuiltinWasmExtension: wasm.Constructor, - api.BuiltinExtAuthzExtension: extauthz.Constructor, + api.BuiltinLuaExtension: lua.Constructor, + api.BuiltinAWSLambdaExtension: awslambda.Constructor, + api.BuiltinPropertyOverrideExtension: propertyoverride.Constructor, + api.BuiltinWasmExtension: wasm.Constructor, + api.BuiltinExtAuthzExtension: extauthz.Constructor, } // ConstructExtension attempts to lookup and build an extension from the registry with the // given config. Returns an error if the extension does not exist, or if the extension fails // to be constructed properly. func ConstructExtension(ext api.EnvoyExtension) (extensioncommon.EnvoyExtender, error) { - if constructor, ok := extensionConstructors[ext.Name]; ok { - return constructor(ext) + constructor, ok := extensionConstructors[ext.Name] + if !ok { + return nil, fmt.Errorf("name %q is not a built-in extension", ext.Name) } - if constructor, ok := enterpriseExtensionConstructors[ext.Name]; ok { - return constructor(ext) - } - return nil, fmt.Errorf("name %q is not a built-in extension", ext.Name) + return constructor(ext) } // ValidateExtensions will attempt to construct each instance of the given envoy extension configurations diff --git a/agent/envoyextensions/registered_extensions_ce.go b/agent/envoyextensions/registered_extensions_ce.go deleted file mode 100644 index 4b9e07e50ba46..0000000000000 --- a/agent/envoyextensions/registered_extensions_ce.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package envoyextensions - -var enterpriseExtensionConstructors = map[string]extensionConstructor{} diff --git a/agent/envoyextensions/registered_extensions_test.go b/agent/envoyextensions/registered_extensions_test.go index 818db87fafea8..7f3cb6bbac7dc 100644 --- a/agent/envoyextensions/registered_extensions_test.go +++ b/agent/envoyextensions/registered_extensions_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoyextensions diff --git a/agent/event_endpoint.go b/agent/event_endpoint.go index da589632c75af..034dec305619b 100644 --- a/agent/event_endpoint.go +++ b/agent/event_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/event_endpoint_test.go b/agent/event_endpoint_test.go index a041088c448c7..4be21a6914b91 100644 --- a/agent/event_endpoint_test.go +++ b/agent/event_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/exec/exec.go b/agent/exec/exec.go index 408dc6bb8110d..d4b4bfafd1fed 100644 --- a/agent/exec/exec.go +++ b/agent/exec/exec.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package exec diff --git a/agent/exec/exec_unix.go b/agent/exec/exec_unix.go index e0ec556771c0b..32ff23249e3b0 100644 --- a/agent/exec/exec_unix.go +++ b/agent/exec/exec_unix.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !windows +// +build !windows package exec diff --git a/agent/exec/exec_windows.go b/agent/exec/exec_windows.go index d85ea09d785e6..1a0cb4c82c806 100644 --- a/agent/exec/exec_windows.go +++ b/agent/exec/exec_windows.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build windows +// +build windows package exec diff --git a/agent/federation_state_endpoint.go b/agent/federation_state_endpoint.go index 40a3df1ff1cd9..0bec145ae60cd 100644 --- a/agent/federation_state_endpoint.go +++ b/agent/federation_state_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/grpc-external/forward.go b/agent/grpc-external/forward.go index 395fb6aa479d0..c0ed064ac808c 100644 --- a/agent/grpc-external/forward.go +++ b/agent/grpc-external/forward.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package external diff --git a/agent/grpc-external/limiter/limiter.go b/agent/grpc-external/limiter/limiter.go index 44aaac616f99f..f995f963049be 100644 --- a/agent/grpc-external/limiter/limiter.go +++ b/agent/grpc-external/limiter/limiter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // package limiter provides primatives for limiting the number of concurrent // operations in-flight. diff --git a/agent/grpc-external/limiter/limiter_test.go b/agent/grpc-external/limiter/limiter_test.go index 3cfa3ad263273..fa165a66706bb 100644 --- a/agent/grpc-external/limiter/limiter_test.go +++ b/agent/grpc-external/limiter/limiter_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package limiter diff --git a/agent/grpc-external/options.go b/agent/grpc-external/options.go index 04e5c10efb513..a25a4482990f6 100644 --- a/agent/grpc-external/options.go +++ b/agent/grpc-external/options.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package external diff --git a/agent/grpc-external/options_test.go b/agent/grpc-external/options_test.go index ccc0ad12fd697..b2edb8fbf1f50 100644 --- a/agent/grpc-external/options_test.go +++ b/agent/grpc-external/options_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package external diff --git a/agent/grpc-external/querymeta.go b/agent/grpc-external/querymeta.go index 0f4dd52adb867..55b960255fffa 100644 --- a/agent/grpc-external/querymeta.go +++ b/agent/grpc-external/querymeta.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package external import ( diff --git a/agent/grpc-external/querymeta_test.go b/agent/grpc-external/querymeta_test.go index 4406929648179..66c7136a3dd48 100644 --- a/agent/grpc-external/querymeta_test.go +++ b/agent/grpc-external/querymeta_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package external import ( diff --git a/agent/grpc-external/server.go b/agent/grpc-external/server.go index 30af8f2e6e1ad..fedffde8f4dc8 100644 --- a/agent/grpc-external/server.go +++ b/agent/grpc-external/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package external diff --git a/agent/grpc-external/services/acl/login.go b/agent/grpc-external/services/acl/login.go index 1e44acf8a1712..c8c399d108be3 100644 --- a/agent/grpc-external/services/acl/login.go +++ b/agent/grpc-external/services/acl/login.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/agent/grpc-external/services/acl/login_test.go b/agent/grpc-external/services/acl/login_test.go index 3b956d7c8c71e..e858618a906b4 100644 --- a/agent/grpc-external/services/acl/login_test.go +++ b/agent/grpc-external/services/acl/login_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/agent/grpc-external/services/acl/logout.go b/agent/grpc-external/services/acl/logout.go index 691ac7b888949..bd3bb5e3e42a2 100644 --- a/agent/grpc-external/services/acl/logout.go +++ b/agent/grpc-external/services/acl/logout.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/agent/grpc-external/services/acl/logout_test.go b/agent/grpc-external/services/acl/logout_test.go index df5c39628297c..69491db5e3b0a 100644 --- a/agent/grpc-external/services/acl/logout_test.go +++ b/agent/grpc-external/services/acl/logout_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/agent/grpc-external/services/acl/server.go b/agent/grpc-external/services/acl/server.go index 2393f11aa1068..5513950e02ec8 100644 --- a/agent/grpc-external/services/acl/server.go +++ b/agent/grpc-external/services/acl/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/agent/grpc-external/services/acl/server_test.go b/agent/grpc-external/services/acl/server_test.go index 1b6cd066001ef..89c49bf226a13 100644 --- a/agent/grpc-external/services/acl/server_test.go +++ b/agent/grpc-external/services/acl/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/agent/grpc-external/services/connectca/server.go b/agent/grpc-external/services/connectca/server.go index 4ef91705f7a14..c90962e180c84 100644 --- a/agent/grpc-external/services/connectca/server.go +++ b/agent/grpc-external/services/connectca/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connectca diff --git a/agent/grpc-external/services/connectca/server_test.go b/agent/grpc-external/services/connectca/server_test.go index 27c8d17c0c9dc..84636e9e75886 100644 --- a/agent/grpc-external/services/connectca/server_test.go +++ b/agent/grpc-external/services/connectca/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connectca diff --git a/agent/grpc-external/services/connectca/sign.go b/agent/grpc-external/services/connectca/sign.go index 148bf675b0570..59c1a6f28354a 100644 --- a/agent/grpc-external/services/connectca/sign.go +++ b/agent/grpc-external/services/connectca/sign.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connectca diff --git a/agent/grpc-external/services/connectca/sign_test.go b/agent/grpc-external/services/connectca/sign_test.go index 07be304081ebb..e43978e0b906d 100644 --- a/agent/grpc-external/services/connectca/sign_test.go +++ b/agent/grpc-external/services/connectca/sign_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connectca diff --git a/agent/grpc-external/services/connectca/watch_roots.go b/agent/grpc-external/services/connectca/watch_roots.go index ddd02ca56e0f9..14927e2188a18 100644 --- a/agent/grpc-external/services/connectca/watch_roots.go +++ b/agent/grpc-external/services/connectca/watch_roots.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connectca diff --git a/agent/grpc-external/services/connectca/watch_roots_test.go b/agent/grpc-external/services/connectca/watch_roots_test.go index 171e00324643c..bfdb76f33bdd8 100644 --- a/agent/grpc-external/services/connectca/watch_roots_test.go +++ b/agent/grpc-external/services/connectca/watch_roots_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connectca diff --git a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go index ea4852efab2be..13bbd1c9f94b9 100644 --- a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go +++ b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dataplane @@ -8,17 +8,11 @@ import ( "errors" "strings" - "github.com/hashicorp/go-hclog" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/structpb" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/consul/state" @@ -29,11 +23,7 @@ import ( ) func (s *Server) GetEnvoyBootstrapParams(ctx context.Context, req *pbdataplane.GetEnvoyBootstrapParamsRequest) (*pbdataplane.GetEnvoyBootstrapParamsResponse, error) { - proxyID := req.ProxyId - if req.GetServiceId() != "" { - proxyID = req.GetServiceId() - } - logger := s.Logger.Named("get-envoy-bootstrap-params").With("proxy_id", proxyID, "request_id", external.TraceID()) + logger := s.Logger.Named("get-envoy-bootstrap-params").With("service_id", req.GetServiceId(), "request_id", external.TraceID()) logger.Trace("Started processing request") defer logger.Trace("Finished processing request") @@ -50,75 +40,9 @@ func (s *Server) GetEnvoyBootstrapParams(ctx context.Context, req *pbdataplane.G return nil, status.Error(codes.Unauthenticated, err.Error()) } - if s.EnableV2 { - // Get the workload. - workloadId := &pbresource.ID{ - Name: proxyID, - Tenancy: &pbresource.Tenancy{ - Namespace: req.Namespace, - Partition: req.Partition, - }, - Type: pbcatalog.WorkloadType, - } - workloadRsp, err := s.ResourceAPIClient.Read(ctx, &pbresource.ReadRequest{ - Id: workloadId, - }) - if err != nil { - // This error should already include the gRPC status code and so we don't need to wrap it - // in status.Error. - logger.Error("Error looking up workload", "error", err) - return nil, err - } - var workload pbcatalog.Workload - err = workloadRsp.Resource.Data.UnmarshalTo(&workload) - if err != nil { - return nil, status.Error(codes.Internal, "failed to parse workload data") - } - - // Only workloads that have an associated identity can ask for proxy bootstrap parameters. - if workload.Identity == "" { - return nil, status.Errorf(codes.InvalidArgument, "workload %q doesn't have identity associated with it", req.ProxyId) - } - - // verify identity:write is allowed. if not, give permission denied error. - if err := authz.ToAllowAuthorizer().IdentityWriteAllowed(workload.Identity, &authzContext); err != nil { - return nil, err - } - - computedProxyConfig, err := resource.GetDecodedResource[*pbmesh.ComputedProxyConfiguration]( - ctx, - s.ResourceAPIClient, - resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, workloadId)) - - if err != nil { - logger.Error("Error looking up ComputedProxyConfiguration for this workload", "error", err) - return nil, err - } - - rsp := &pbdataplane.GetEnvoyBootstrapParamsResponse{ - Identity: workload.Identity, - Partition: workloadRsp.Resource.Id.Tenancy.Partition, - Namespace: workloadRsp.Resource.Id.Tenancy.Namespace, - Datacenter: s.Datacenter, - NodeName: workload.NodeName, - } - - if computedProxyConfig != nil { - if computedProxyConfig.GetData().GetDynamicConfig() != nil { - rsp.AccessLogs = makeAccessLogs(computedProxyConfig.GetData().GetDynamicConfig().GetAccessLogs(), logger) - } - - rsp.BootstrapConfig = computedProxyConfig.GetData().GetBootstrapConfig() - } - - return rsp, nil - } - - // The remainder of this file focuses on v1 implementation of this endpoint. - store := s.GetStore() - _, svc, err := store.ServiceNode(req.GetNodeId(), req.GetNodeName(), proxyID, &entMeta, structs.DefaultPeerKeyword) + _, svc, err := store.ServiceNode(req.GetNodeId(), req.GetNodeName(), req.GetServiceId(), &entMeta, structs.DefaultPeerKeyword) if err != nil { logger.Error("Error looking up service", "error", err) if errors.Is(err, state.ErrNodeNotFound) { @@ -157,34 +81,8 @@ func (s *Server) GetEnvoyBootstrapParams(ctx context.Context, req *pbdataplane.G // Inspect access logging // This is non-essential, and don't want to return an error unless there is a more serious issue var accessLogs []string - if ns != nil { - accessLogs = makeAccessLogs(&ns.Proxy.AccessLogs, logger) - } - - // Build out the response - var serviceName string - if svc.ServiceKind == structs.ServiceKindConnectProxy { - serviceName = svc.ServiceProxy.DestinationServiceName - } else { - serviceName = svc.ServiceName - } - - return &pbdataplane.GetEnvoyBootstrapParamsResponse{ - Identity: serviceName, - Service: serviceName, - Partition: svc.EnterpriseMeta.PartitionOrDefault(), - Namespace: svc.EnterpriseMeta.NamespaceOrDefault(), - Config: bootstrapConfig, - Datacenter: s.Datacenter, - NodeName: svc.Node, - AccessLogs: accessLogs, - }, nil -} - -func makeAccessLogs(logs structs.AccessLogs, logger hclog.Logger) []string { - var accessLogs []string - if logs.GetEnabled() { - envoyLoggers, err := accesslogs.MakeAccessLogs(logs, false) + if ns != nil && ns.Proxy.AccessLogs.Enabled { + envoyLoggers, err := accesslogs.MakeAccessLogs(&ns.Proxy.AccessLogs, false) if err != nil { logger.Warn("Error creating the envoy access log config", "error", err) } @@ -200,5 +98,41 @@ func makeAccessLogs(logs structs.AccessLogs, logger hclog.Logger) []string { } } - return accessLogs + // Build out the response + var serviceName string + if svc.ServiceKind == structs.ServiceKindConnectProxy { + serviceName = svc.ServiceProxy.DestinationServiceName + } else { + serviceName = svc.ServiceName + } + + return &pbdataplane.GetEnvoyBootstrapParamsResponse{ + Service: serviceName, + Partition: svc.EnterpriseMeta.PartitionOrDefault(), + Namespace: svc.EnterpriseMeta.NamespaceOrDefault(), + Config: bootstrapConfig, + Datacenter: s.Datacenter, + ServiceKind: convertToResponseServiceKind(svc.ServiceKind), + NodeName: svc.Node, + NodeId: string(svc.ID), + AccessLogs: accessLogs, + }, nil +} + +func convertToResponseServiceKind(serviceKind structs.ServiceKind) (respKind pbdataplane.ServiceKind) { + switch serviceKind { + case structs.ServiceKindConnectProxy: + respKind = pbdataplane.ServiceKind_SERVICE_KIND_CONNECT_PROXY + case structs.ServiceKindMeshGateway: + respKind = pbdataplane.ServiceKind_SERVICE_KIND_MESH_GATEWAY + case structs.ServiceKindTerminatingGateway: + respKind = pbdataplane.ServiceKind_SERVICE_KIND_TERMINATING_GATEWAY + case structs.ServiceKindIngressGateway: + respKind = pbdataplane.ServiceKind_SERVICE_KIND_INGRESS_GATEWAY + case structs.ServiceKindAPIGateway: + respKind = pbdataplane.ServiceKind_SERVICE_KIND_API_GATEWAY + case structs.ServiceKindTypical: + respKind = pbdataplane.ServiceKind_SERVICE_KIND_TYPICAL + } + return } diff --git a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params_test.go b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params_test.go index 3ae0670e5cf08..322d2f6527459 100644 --- a/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params_test.go +++ b/agent/grpc-external/services/dataplane/get_envoy_bootstrap_params_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dataplane @@ -14,26 +14,16 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/structpb" - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/mesh" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" external "github.com/hashicorp/consul/agent/grpc-external" "github.com/hashicorp/consul/agent/grpc-external/testutils" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/proto-public/pbdataplane" + "github.com/hashicorp/consul/types" ) const ( - testIdentity = "test-identity" testToken = "acl-token-get-envoy-bootstrap-params" testServiceName = "web" proxyServiceID = "web-proxy" @@ -51,15 +41,13 @@ const ( proxyDefaultsRequestTimeout = 1111 serviceDefaultsProtocol = "tcp" serviceDefaultsConnectTimeout = 4444 - - testAccessLogs = "{\"name\":\"Consul Listener Filter Log\",\"typedConfig\":{\"@type\":\"type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog\",\"logFormat\":{\"jsonFormat\":{\"custom_field\":\"%START_TIME%\"}}}}" ) func testRegisterRequestProxy(t *testing.T) *structs.RegisterRequest { return &structs.RegisterRequest{ Datacenter: serverDC, Node: nodeName, - ID: nodeID, + ID: types.NodeID(nodeID), Address: "127.0.0.1", Service: &structs.NodeService{ Kind: structs.ServiceKindConnectProxy, @@ -80,7 +68,7 @@ func testRegisterRequestProxy(t *testing.T) *structs.RegisterRequest { func testRegisterIngressGateway(t *testing.T) *structs.RegisterRequest { registerReq := structs.TestRegisterIngressGateway(t) - registerReq.ID = "2980b72b-bd9d-9d7b-d4f9-951bf7508d95" + registerReq.ID = types.NodeID("2980b72b-bd9d-9d7b-d4f9-951bf7508d95") registerReq.Service.ID = registerReq.Service.Service registerReq.Service.Proxy.Config = map[string]interface{}{ proxyConfigKey: proxyConfigValue, @@ -179,7 +167,9 @@ func TestGetEnvoyBootstrapParams_Success(t *testing.T) { require.Equal(t, tc.registerReq.EnterpriseMeta.PartitionOrDefault(), resp.Partition) require.Equal(t, tc.registerReq.EnterpriseMeta.NamespaceOrDefault(), resp.Namespace) requireConfigField(t, resp, proxyConfigKey, structpb.NewStringValue(proxyConfigValue)) + require.Equal(t, convertToResponseServiceKind(tc.registerReq.Service.Kind), resp.ServiceKind) require.Equal(t, tc.registerReq.Node, resp.NodeName) + require.Equal(t, string(tc.registerReq.ID), resp.NodeId) if tc.serviceDefaults != nil && tc.proxyDefaults != nil { // service-defaults take precedence over proxy-defaults @@ -252,154 +242,6 @@ func TestGetEnvoyBootstrapParams_Success(t *testing.T) { } } -func TestGetEnvoyBootstrapParams_Success_EnableV2(t *testing.T) { - type testCase struct { - name string - workloadData *pbcatalog.Workload - proxyCfg *pbmesh.ComputedProxyConfiguration - expBootstrapCfg *pbmesh.BootstrapConfig - expAccessLogs string - } - - run := func(t *testing.T, tc testCase) { - resourceClient := svctest.RunResourceService(t, catalog.RegisterTypes, mesh.RegisterTypes) - - options := structs.QueryOptions{Token: testToken} - ctx, err := external.ContextWithQueryOptions(context.Background(), options) - require.NoError(t, err) - - aclResolver := &MockACLResolver{} - - server := NewServer(Config{ - Logger: hclog.NewNullLogger(), - ACLResolver: aclResolver, - Datacenter: serverDC, - EnableV2: true, - ResourceAPIClient: resourceClient, - }) - client := testClient(t, server) - - // Add required fields to workload data. - tc.workloadData.Addresses = []*pbcatalog.WorkloadAddress{ - { - Host: "127.0.0.1", - }, - } - tc.workloadData.Ports = map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - } - workloadResource := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). - WithData(t, tc.workloadData). - WithTenancy(resource.DefaultNamespacedTenancy()). - Write(t, resourceClient) - - // Create computed proxy cfg resource. - resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, workloadResource.Id.Name). - WithData(t, tc.proxyCfg). - WithTenancy(resource.DefaultNamespacedTenancy()). - Write(t, resourceClient) - - req := &pbdataplane.GetEnvoyBootstrapParamsRequest{ - ProxyId: workloadResource.Id.Name, - Namespace: workloadResource.Id.Tenancy.Namespace, - Partition: workloadResource.Id.Tenancy.Partition, - } - - aclResolver.On("ResolveTokenAndDefaultMeta", testToken, mock.Anything, mock.Anything). - Return(testutils.ACLUseProvidedPolicy(t, - &acl.Policy{ - PolicyRules: acl.PolicyRules{ - Services: []*acl.ServiceRule{ - { - Name: workloadResource.Id.Name, - Policy: acl.PolicyRead, - }, - }, - Identities: []*acl.IdentityRule{ - { - Name: testIdentity, - Policy: acl.PolicyWrite, - }, - }, - }, - }), nil) - - resp, err := client.GetEnvoyBootstrapParams(ctx, req) - require.NoError(t, err) - - require.Equal(t, tc.workloadData.Identity, resp.Identity) - require.Equal(t, serverDC, resp.Datacenter) - require.Equal(t, workloadResource.Id.Tenancy.Partition, resp.Partition) - require.Equal(t, workloadResource.Id.Tenancy.Namespace, resp.Namespace) - require.Equal(t, resp.NodeName, tc.workloadData.NodeName) - prototest.AssertDeepEqual(t, tc.expBootstrapCfg, resp.BootstrapConfig) - if tc.expAccessLogs != "" { - require.JSONEq(t, tc.expAccessLogs, resp.AccessLogs[0]) - } - } - - testCases := []testCase{ - { - name: "workload without node", - workloadData: &pbcatalog.Workload{ - Identity: testIdentity, - }, - expBootstrapCfg: nil, - }, - { - name: "workload with node", - workloadData: &pbcatalog.Workload{ - Identity: testIdentity, - NodeName: "test-node", - }, - expBootstrapCfg: nil, - }, - { - name: "single proxy configuration", - workloadData: &pbcatalog.Workload{ - Identity: testIdentity, - }, - proxyCfg: &pbmesh.ComputedProxyConfiguration{ - BootstrapConfig: &pbmesh.BootstrapConfig{ - DogstatsdUrl: "dogstats-url", - }, - }, - expBootstrapCfg: &pbmesh.BootstrapConfig{ - DogstatsdUrl: "dogstats-url", - }, - }, - { - name: "multiple proxy configurations", - workloadData: &pbcatalog.Workload{ - Identity: testIdentity, - }, - proxyCfg: &pbmesh.ComputedProxyConfiguration{ - BootstrapConfig: &pbmesh.BootstrapConfig{ - DogstatsdUrl: "dogstats-url", - StatsdUrl: "stats-url", - }, - DynamicConfig: &pbmesh.DynamicConfig{ - AccessLogs: &pbmesh.AccessLogsConfig{ - Enabled: true, - JsonFormat: "{ \"custom_field\": \"%START_TIME%\" }", - }, - }, - }, - expBootstrapCfg: &pbmesh.BootstrapConfig{ - DogstatsdUrl: "dogstats-url", - StatsdUrl: "stats-url", - }, - expAccessLogs: testAccessLogs, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - run(t, tc) - }) - } -} - func TestGetEnvoyBootstrapParams_Error(t *testing.T) { type testCase struct { name string @@ -481,98 +323,6 @@ func TestGetEnvoyBootstrapParams_Error(t *testing.T) { } -func TestGetEnvoyBootstrapParams_Error_EnableV2(t *testing.T) { - type testCase struct { - name string - expectedErrCode codes.Code - expecteErrMsg string - workload *pbresource.Resource - } - - run := func(t *testing.T, tc testCase) { - resourceClient := svctest.RunResourceService(t, catalog.RegisterTypes, mesh.RegisterTypes) - - options := structs.QueryOptions{Token: testToken} - ctx, err := external.ContextWithQueryOptions(context.Background(), options) - require.NoError(t, err) - - aclResolver := &MockACLResolver{} - aclResolver.On("ResolveTokenAndDefaultMeta", testToken, mock.Anything, mock.Anything). - Return(testutils.ACLServiceRead(t, "doesn't matter"), nil) - - server := NewServer(Config{ - Logger: hclog.NewNullLogger(), - ACLResolver: aclResolver, - Datacenter: serverDC, - EnableV2: true, - ResourceAPIClient: resourceClient, - }) - client := testClient(t, server) - - var req pbdataplane.GetEnvoyBootstrapParamsRequest - // Write the workload resource. - if tc.workload != nil { - _, err = resourceClient.Write(context.Background(), &pbresource.WriteRequest{ - Resource: tc.workload, - }) - require.NoError(t, err) - - req = pbdataplane.GetEnvoyBootstrapParamsRequest{ - ProxyId: tc.workload.Id.Name, - Namespace: tc.workload.Id.Tenancy.Namespace, - Partition: tc.workload.Id.Tenancy.Partition, - } - } else { - req = pbdataplane.GetEnvoyBootstrapParamsRequest{ - ProxyId: "not-found", - Namespace: "default", - Partition: "default", - } - } - - resp, err := client.GetEnvoyBootstrapParams(ctx, &req) - require.Nil(t, resp) - require.Error(t, err) - errStatus, ok := status.FromError(err) - require.True(t, ok) - require.Equal(t, tc.expectedErrCode.String(), errStatus.Code().String()) - require.Equal(t, tc.expecteErrMsg, errStatus.Message()) - } - - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - - testCases := []testCase{ - { - name: "workload doesn't exist", - expectedErrCode: codes.NotFound, - expecteErrMsg: "resource not found", - }, - { - name: "workload without identity", - expectedErrCode: codes.InvalidArgument, - expecteErrMsg: "workload \"test-workload\" doesn't have identity associated with it", - workload: workload, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - run(t, tc) - }) - } - -} - func TestGetEnvoyBootstrapParams_Unauthenticated(t *testing.T) { // Mock the ACL resolver to return ErrNotFound. aclResolver := &MockACLResolver{} diff --git a/agent/grpc-external/services/dataplane/get_supported_features.go b/agent/grpc-external/services/dataplane/get_supported_features.go index 09ee1c7ed4c51..ea638715338a3 100644 --- a/agent/grpc-external/services/dataplane/get_supported_features.go +++ b/agent/grpc-external/services/dataplane/get_supported_features.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dataplane @@ -14,7 +14,7 @@ import ( "github.com/hashicorp/consul/version" ) -func (s *Server) GetSupportedDataplaneFeatures(ctx context.Context, _ *pbdataplane.GetSupportedDataplaneFeaturesRequest) (*pbdataplane.GetSupportedDataplaneFeaturesResponse, error) { +func (s *Server) GetSupportedDataplaneFeatures(ctx context.Context, req *pbdataplane.GetSupportedDataplaneFeaturesRequest) (*pbdataplane.GetSupportedDataplaneFeaturesResponse, error) { logger := s.Logger.Named("get-supported-dataplane-features").With("request_id", external.TraceID()) logger.Trace("Started processing request") diff --git a/agent/grpc-external/services/dataplane/get_supported_features_test.go b/agent/grpc-external/services/dataplane/get_supported_features_test.go index 4761ccb3cb38a..329b5df0f68f1 100644 --- a/agent/grpc-external/services/dataplane/get_supported_features_test.go +++ b/agent/grpc-external/services/dataplane/get_supported_features_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dataplane diff --git a/agent/grpc-external/services/dataplane/server.go b/agent/grpc-external/services/dataplane/server.go index fbce372f0efa0..8772893863840 100644 --- a/agent/grpc-external/services/dataplane/server.go +++ b/agent/grpc-external/services/dataplane/server.go @@ -1,10 +1,9 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dataplane import ( - "github.com/hashicorp/consul/proto-public/pbresource" "google.golang.org/grpc" "github.com/hashicorp/go-hclog" @@ -27,10 +26,6 @@ type Config struct { ACLResolver ACLResolver // Datacenter of the Consul server this gRPC server is hosted on Datacenter string - - // EnableV2 indicates whether a feature flag for v2 APIs is provided. - EnableV2 bool - ResourceAPIClient pbresource.ResourceServiceClient } type StateStore interface { diff --git a/agent/grpc-external/services/dataplane/server_test.go b/agent/grpc-external/services/dataplane/server_test.go index ec57396bcb791..15ac272871e85 100644 --- a/agent/grpc-external/services/dataplane/server_test.go +++ b/agent/grpc-external/services/dataplane/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dataplane diff --git a/agent/grpc-external/services/dns/server.go b/agent/grpc-external/services/dns/server.go index a6f2249733c11..a9733c40666be 100644 --- a/agent/grpc-external/services/dns/server.go +++ b/agent/grpc-external/services/dns/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dns diff --git a/agent/grpc-external/services/dns/server_test.go b/agent/grpc-external/services/dns/server_test.go index a6576b51adcfd..0144eccc0cd1f 100644 --- a/agent/grpc-external/services/dns/server_test.go +++ b/agent/grpc-external/services/dns/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dns diff --git a/agent/grpc-external/services/peerstream/health_snapshot.go b/agent/grpc-external/services/peerstream/health_snapshot.go index efd60a7f1039e..dd9a10c67469b 100644 --- a/agent/grpc-external/services/peerstream/health_snapshot.go +++ b/agent/grpc-external/services/peerstream/health_snapshot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/health_snapshot_test.go b/agent/grpc-external/services/peerstream/health_snapshot_test.go index 6759db252d2cc..7ea404f3854c3 100644 --- a/agent/grpc-external/services/peerstream/health_snapshot_test.go +++ b/agent/grpc-external/services/peerstream/health_snapshot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/replication.go b/agent/grpc-external/services/peerstream/replication.go index 692a475235be0..a0c1e4387f1c6 100644 --- a/agent/grpc-external/services/peerstream/replication.go +++ b/agent/grpc-external/services/peerstream/replication.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/server.go b/agent/grpc-external/services/peerstream/server.go index 4127312fe72cd..58e436bd1f5cd 100644 --- a/agent/grpc-external/services/peerstream/server.go +++ b/agent/grpc-external/services/peerstream/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/server_test.go b/agent/grpc-external/services/peerstream/server_test.go index 836b09d89b2b1..cb7c60e3cf0a2 100644 --- a/agent/grpc-external/services/peerstream/server_test.go +++ b/agent/grpc-external/services/peerstream/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/stream_resources.go b/agent/grpc-external/services/peerstream/stream_resources.go index 9f2d9cf896f3d..61c98d3f07894 100644 --- a/agent/grpc-external/services/peerstream/stream_resources.go +++ b/agent/grpc-external/services/peerstream/stream_resources.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/stream_test.go b/agent/grpc-external/services/peerstream/stream_test.go index ad3399b79f5a9..44eaef55450eb 100644 --- a/agent/grpc-external/services/peerstream/stream_test.go +++ b/agent/grpc-external/services/peerstream/stream_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/stream_tracker.go b/agent/grpc-external/services/peerstream/stream_tracker.go index c74a1b284f09e..abb5a003a3992 100644 --- a/agent/grpc-external/services/peerstream/stream_tracker.go +++ b/agent/grpc-external/services/peerstream/stream_tracker.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/stream_tracker_test.go b/agent/grpc-external/services/peerstream/stream_tracker_test.go index 33ea536469d8a..d676587a2520e 100644 --- a/agent/grpc-external/services/peerstream/stream_tracker_test.go +++ b/agent/grpc-external/services/peerstream/stream_tracker_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/subscription_blocking.go b/agent/grpc-external/services/peerstream/subscription_blocking.go index a1257d3d33819..7fa8bc1eff59f 100644 --- a/agent/grpc-external/services/peerstream/subscription_blocking.go +++ b/agent/grpc-external/services/peerstream/subscription_blocking.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/subscription_manager.go b/agent/grpc-external/services/peerstream/subscription_manager.go index bd2d36ffd942c..4fcd27635b81d 100644 --- a/agent/grpc-external/services/peerstream/subscription_manager.go +++ b/agent/grpc-external/services/peerstream/subscription_manager.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/subscription_manager_test.go b/agent/grpc-external/services/peerstream/subscription_manager_test.go index 2abd40be956ab..9e34756dbd4bc 100644 --- a/agent/grpc-external/services/peerstream/subscription_manager_test.go +++ b/agent/grpc-external/services/peerstream/subscription_manager_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/subscription_state.go b/agent/grpc-external/services/peerstream/subscription_state.go index a1a370a3ec4c6..dba315370de7f 100644 --- a/agent/grpc-external/services/peerstream/subscription_state.go +++ b/agent/grpc-external/services/peerstream/subscription_state.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/subscription_state_test.go b/agent/grpc-external/services/peerstream/subscription_state_test.go index cc3e49ab4c9cb..3cba66c9c2be4 100644 --- a/agent/grpc-external/services/peerstream/subscription_state_test.go +++ b/agent/grpc-external/services/peerstream/subscription_state_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/subscription_view.go b/agent/grpc-external/services/peerstream/subscription_view.go index 575729bc71df9..c85c82b15e5c8 100644 --- a/agent/grpc-external/services/peerstream/subscription_view.go +++ b/agent/grpc-external/services/peerstream/subscription_view.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/subscription_view_test.go b/agent/grpc-external/services/peerstream/subscription_view_test.go index cd2f61e60feb7..a51ca57e2902c 100644 --- a/agent/grpc-external/services/peerstream/subscription_view_test.go +++ b/agent/grpc-external/services/peerstream/subscription_view_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/peerstream/testing.go b/agent/grpc-external/services/peerstream/testing.go index 47cc8d1dbec64..2208249dc6fc8 100644 --- a/agent/grpc-external/services/peerstream/testing.go +++ b/agent/grpc-external/services/peerstream/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peerstream diff --git a/agent/grpc-external/services/resource/delete.go b/agent/grpc-external/services/resource/delete.go index f19d4a52492cf..b3045b3d6d294 100644 --- a/agent/grpc-external/services/resource/delete.go +++ b/agent/grpc-external/services/resource/delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -7,7 +7,6 @@ import ( "context" "errors" "fmt" - "strings" "time" "github.com/oklog/ulid/v2" @@ -21,45 +20,28 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -// Delete deletes a resource. +// Deletes a resource. // - To delete a resource regardless of the stored version, set Version = "" // - Supports deleting a resource by name, hence Id.Uid may be empty. // - Delete of a previously deleted or non-existent resource is a no-op to support idempotency. // - Errors with Aborted if the requested Version does not match the stored Version. // - Errors with PermissionDenied if ACL check fails func (s *Server) Delete(ctx context.Context, req *pbresource.DeleteRequest) (*pbresource.DeleteResponse, error) { - reg, err := s.validateDeleteRequest(req) - if err != nil { + if err := validateDeleteRequest(req); err != nil { return nil, err } - entMeta := v2TenancyToV1EntMeta(req.Id.Tenancy) - authz, authzContext, err := s.getAuthorizer(tokenFromContext(ctx), entMeta) + reg, err := s.resolveType(req.Id.Type) if err != nil { return nil, err } - // Retrieve resource since ACL hook requires it. Furthermore, we'll need the - // read to be strongly consistent if the passed in Version or Uid are empty. - consistency := storage.EventualConsistency - if req.Version == "" || req.Id.Uid == "" { - consistency = storage.StrongConsistency - } - - // Apply defaults when tenancy units empty. - v1EntMetaToV2Tenancy(reg, entMeta, req.Id.Tenancy) - - existing, err := s.Backend.Read(ctx, consistency, req.Id) - switch { - case errors.Is(err, storage.ErrNotFound): - // Deletes are idempotent so no-op when not found - return &pbresource.DeleteResponse{}, nil - case err != nil: - return nil, status.Errorf(codes.Internal, "failed read: %v", err) + authz, err := s.getAuthorizer(tokenFromContext(ctx)) + if err != nil { + return nil, err } - // Check ACLs - err = reg.ACLs.Write(authz, authzContext, existing) + err = reg.ACLs.Write(authz, req.Id) switch { case acl.IsErrPermissionDenied(err): return nil, status.Error(codes.PermissionDenied, err.Error()) @@ -67,11 +49,27 @@ func (s *Server) Delete(ctx context.Context, req *pbresource.DeleteRequest) (*pb return nil, status.Errorf(codes.Internal, "failed write acl: %v", err) } + // The storage backend requires a Version and Uid to delete a resource based + // on CAS semantics. When either are not provided, the resource must be read + // with a strongly consistent read to retrieve either or both. + // + // n.b.: There is a chance DeleteCAS may fail with a storage.ErrCASFailure + // if an update occurs between the Read and DeleteCAS. Consider refactoring + // to use retryCAS() similar to the Write endpoint to close this gap. deleteVersion := req.Version deleteId := req.Id if deleteVersion == "" || deleteId.Uid == "" { - deleteVersion = existing.Version - deleteId = existing.Id + existing, err := s.Backend.Read(ctx, storage.StrongConsistency, req.Id) + switch { + case err == nil: + deleteVersion = existing.Version + deleteId = existing.Id + case errors.Is(err, storage.ErrNotFound): + // Deletes are idempotent so no-op when not found + return &pbresource.DeleteResponse{}, nil + default: + return nil, status.Errorf(codes.Internal, "failed read: %v", err) + } } if err := s.maybeCreateTombstone(ctx, deleteId); err != nil { @@ -145,40 +143,20 @@ func (s *Server) maybeCreateTombstone(ctx context.Context, deleteId *pbresource. } } -func (s *Server) validateDeleteRequest(req *pbresource.DeleteRequest) (*resource.Registration, error) { +func validateDeleteRequest(req *pbresource.DeleteRequest) error { if req.Id == nil { - return nil, status.Errorf(codes.InvalidArgument, "id is required") + return status.Errorf(codes.InvalidArgument, "id is required") } if err := validateId(req.Id, "id"); err != nil { - return nil, err + return err } - - reg, err := s.resolveType(req.Id.Type) - if err != nil { - return nil, err - } - - if err = checkV2Tenancy(s.UseV2Tenancy, req.Id.Type); err != nil { - return nil, err - } - - // Check scope - if reg.Scope == resource.ScopePartition && req.Id.Tenancy.Namespace != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "partition scoped resource %s cannot have a namespace. got: %s", - resource.ToGVK(req.Id.Type), - req.Id.Tenancy.Namespace, - ) - } - - return reg, nil + return nil } // Maintains a deterministic mapping between a resource and it's tombstone's // name by embedding the resources's Uid in the name. func tombstoneName(deleteId *pbresource.ID) string { // deleteId.Name is just included for easier identification - return fmt.Sprintf("tombstone-%v-%v", deleteId.Name, strings.ToLower(deleteId.Uid)) + return fmt.Sprintf("tombstone-%v-%v", deleteId.Name, deleteId.Uid) } diff --git a/agent/grpc-external/services/resource/delete_test.go b/agent/grpc-external/services/resource/delete_test.go index 3bdbb0581d106..0e98d3fd57a7a 100644 --- a/agent/grpc-external/services/resource/delete_test.go +++ b/agent/grpc-external/services/resource/delete_test.go @@ -1,120 +1,60 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource import ( "context" - "strings" "testing" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" "github.com/hashicorp/consul/acl/resolver" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" + "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" ) func TestDelete_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(artistId, recordLabelId *pbresource.ID) *pbresource.ID - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no id": { - modFn: func(_, _ *pbresource.ID) *pbresource.ID { - return nil - }, - errContains: "id is required", - }, - "no type": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Type = nil - return artistId - }, - errContains: "id.type is required", - }, - "no name": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "" - return artistId - }, - errContains: "id.name invalid", + testCases := map[string]func(*pbresource.DeleteRequest){ + "no id": func(req *pbresource.DeleteRequest) { req.Id = nil }, + "no type": func(req *pbresource.DeleteRequest) { req.Id.Type = nil }, + "no tenancy": func(req *pbresource.DeleteRequest) { req.Id.Tenancy = nil }, + "no name": func(req *pbresource.DeleteRequest) { req.Id.Name = "" }, + // clone necessary to not pollute DefaultTenancy + "tenancy partition not default": func(req *pbresource.DeleteRequest) { + req.Id.Tenancy = clone(req.Id.Tenancy) + req.Id.Tenancy.Partition = "" }, - "mixed case name": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "DepecheMode" - return artistId - }, - errContains: "id.name invalid", + "tenancy namespace not default": func(req *pbresource.DeleteRequest) { + req.Id.Tenancy = clone(req.Id.Tenancy) + req.Id.Tenancy.Namespace = "" }, - "name too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.name invalid", - }, - "partition mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = "Default" - return artistId - }, - errContains: "id.tenancy.partition invalid", - }, - "partition name too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.tenancy.partition invalid", - }, - "namespace mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = "Default" - return artistId - }, - errContains: "id.tenancy.namespace invalid", - }, - "namespace name too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.tenancy.namespace invalid", - }, - "partition scoped resource with namespace": { - modFn: func(_, recordLabelId *pbresource.ID) *pbresource.ID { - recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" - return recordLabelId - }, - errContains: "cannot have a namespace", + "tenancy peername not local": func(req *pbresource.DeleteRequest) { + req.Id.Tenancy = clone(req.Id.Tenancy) + req.Id.Tenancy.PeerName = "" }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - - artist, err := demo.GenerateV2Artist() + res, err := demo.GenerateV2Artist() require.NoError(t, err) - req := &pbresource.DeleteRequest{Id: tc.modFn(artist.Id, recordLabel.Id), Version: ""} + req := &pbresource.DeleteRequest{Id: res.Id, Version: ""} + modFn(req) _, err = client.Delete(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -157,23 +97,21 @@ func TestDelete_ACLs(t *testing.T) { t.Run(desc, func(t *testing.T) { server := testServer(t) client := testClient(t, server) + + mockACLResolver := &MockACLResolver{} + mockACLResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything). + Return(tc.authz, nil) + server.ACLResolver = mockACLResolver demo.RegisterTypes(server.Registry) artist, err := demo.GenerateV2Artist() require.NoError(t, err) - // Write test resource to delete. - rsp, err := client.Write(context.Background(), &pbresource.WriteRequest{Resource: artist}) + artist, err = server.Backend.WriteCAS(context.Background(), artist) require.NoError(t, err) - // Mock is put in place after the above "write" since the "write" must also pass the ACL check. - mockACLResolver := &MockACLResolver{} - mockACLResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything). - Return(tc.authz, nil) - server.ACLResolver = mockACLResolver - - // Exercise ACL. - _, err = client.Delete(testContext(t), &pbresource.DeleteRequest{Id: rsp.Resource.Id}) + // exercise ACL + _, err = client.Delete(testContext(t), &pbresource.DeleteRequest{Id: artist.Id}) tc.assertErrFn(err) }) } @@ -184,59 +122,34 @@ func TestDelete_Success(t *testing.T) { for desc, tc := range deleteTestCases() { t.Run(desc, func(t *testing.T) { - for tenancyDesc, modFn := range tenancyCases() { - t.Run(tenancyDesc, func(t *testing.T) { - server, client, ctx := testDeps(t) - demo.RegisterTypes(server.Registry) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - writeRsp, err := client.Write(ctx, &pbresource.WriteRequest{Resource: recordLabel}) - require.NoError(t, err) - recordLabel = writeRsp.Resource - originalRecordLabelId := clone(recordLabel.Id) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - writeRsp, err = client.Write(ctx, &pbresource.WriteRequest{Resource: artist}) - require.NoError(t, err) - artist = writeRsp.Resource - originalArtistId := clone(artist.Id) - - // Pick the resource to be deleted based on type's scope and mod tenancy - // based on the tenancy test case. - deleteId := modFn(artist.Id, recordLabel.Id) - deleteReq := tc.deleteReqFn(recordLabel) - if proto.Equal(deleteId.Type, demo.TypeV2Artist) { - deleteReq = tc.deleteReqFn(artist) - } - - // Delete - _, err = client.Delete(ctx, deleteReq) - require.NoError(t, err) - - // Verify deleted - _, err = client.Read(ctx, &pbresource.ReadRequest{Id: deleteId}) - require.Error(t, err) - require.Equal(t, codes.NotFound.String(), status.Code(err).String()) - - // Derive tombstone name from resource that was deleted. - tname := tombstoneName(originalRecordLabelId) - if proto.Equal(deleteId.Type, demo.TypeV2Artist) { - tname = tombstoneName(originalArtistId) - } - - // Verify tombstone created - _, err = client.Read(ctx, &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Name: tname, - Type: resource.TypeV1Tombstone, - Tenancy: deleteReq.Id.Tenancy, - }, - }) - require.NoError(t, err, "expected tombstone to be found") - }) - } + server, client, ctx := testDeps(t) + demo.RegisterTypes(server.Registry) + artist, err := demo.GenerateV2Artist() + require.NoError(t, err) + + rsp, err := client.Write(ctx, &pbresource.WriteRequest{Resource: artist}) + require.NoError(t, err) + artistId := clone(rsp.Resource.Id) + artist = rsp.Resource + + // delete + _, err = client.Delete(ctx, tc.deleteReqFn(artist)) + require.NoError(t, err) + + // verify deleted + _, err = server.Backend.Read(ctx, storage.StrongConsistency, artistId) + require.Error(t, err) + require.ErrorIs(t, err, storage.ErrNotFound) + + // verify tombstone created + _, err = client.Read(ctx, &pbresource.ReadRequest{ + Id: &pbresource.ID{ + Name: tombstoneName(artistId), + Type: resource.TypeV1Tombstone, + Tenancy: artist.Id.Tenancy, + }, + }) + require.NoError(t, err) }) } } diff --git a/agent/grpc-external/services/resource/list.go b/agent/grpc-external/services/resource/list.go index 8bdfc4fb3cfe4..77269e74688ff 100644 --- a/agent/grpc-external/services/resource/list.go +++ b/agent/grpc-external/services/resource/list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -10,27 +10,28 @@ import ( "google.golang.org/grpc/status" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" ) func (s *Server) List(ctx context.Context, req *pbresource.ListRequest) (*pbresource.ListResponse, error) { - reg, err := s.validateListRequest(req) + if err := validateListRequest(req); err != nil { + return nil, err + } + + // check type + reg, err := s.resolveType(req.Type) if err != nil { return nil, err } - // v1 ACL subsystem is "wildcard" aware so just pass on through. - entMeta := v2TenancyToV1EntMeta(req.Tenancy) - token := tokenFromContext(ctx) - authz, authzContext, err := s.getAuthorizer(token, entMeta) + authz, err := s.getAuthorizer(tokenFromContext(ctx)) if err != nil { return nil, err } - // Check ACLs. - err = reg.ACLs.List(authz, authzContext) + // check acls + err = reg.ACLs.List(authz, req.Tenancy) switch { case acl.IsErrPermissionDenied(err): return nil, status.Error(codes.PermissionDenied, err.Error()) @@ -38,9 +39,6 @@ func (s *Server) List(ctx context.Context, req *pbresource.ListRequest) (*pbreso return nil, status.Errorf(codes.Internal, "failed list acl: %v", err) } - // Ensure we're defaulting correctly when request tenancy units are empty. - v1EntMetaToV2Tenancy(reg, entMeta, req.Tenancy) - resources, err := s.Backend.List( ctx, readConsistencyFrom(ctx), @@ -54,22 +52,13 @@ func (s *Server) List(ctx context.Context, req *pbresource.ListRequest) (*pbreso result := make([]*pbresource.Resource, 0) for _, resource := range resources { - // Filter out non-matching GroupVersion. + // filter out non-matching GroupVersion if resource.Id.Type.GroupVersion != req.Type.GroupVersion { continue } - // Need to rebuild authorizer per resource since wildcard inputs may - // result in different tenancies. Consider caching per tenancy if this - // is deemed expensive. - entMeta = v2TenancyToV1EntMeta(resource.Id.Tenancy) - authz, authzContext, err = s.getAuthorizer(token, entMeta) - if err != nil { - return nil, err - } - - // Filter out items that don't pass read ACLs. - err = reg.ACLs.Read(authz, authzContext, resource.Id, resource) + // filter out items that don't pass read ACLs + err = reg.ACLs.Read(authz, resource.Id) switch { case acl.IsErrPermissionDenied(err): continue @@ -81,42 +70,15 @@ func (s *Server) List(ctx context.Context, req *pbresource.ListRequest) (*pbreso return &pbresource.ListResponse{Resources: result}, nil } -func (s *Server) validateListRequest(req *pbresource.ListRequest) (*resource.Registration, error) { +func validateListRequest(req *pbresource.ListRequest) error { var field string switch { case req.Type == nil: field = "type" case req.Tenancy == nil: field = "tenancy" + default: + return nil } - - if field != "" { - return nil, status.Errorf(codes.InvalidArgument, "%s is required", field) - } - - // Check type exists. - reg, err := s.resolveType(req.Type) - if err != nil { - return nil, err - } - - if err = checkV2Tenancy(s.UseV2Tenancy, req.Type); err != nil { - return nil, err - } - - if err := validateWildcardTenancy(req.Tenancy, req.NamePrefix); err != nil { - return nil, err - } - - // Error when partition scoped and namespace not empty. - if reg.Scope == resource.ScopePartition && req.Tenancy.Namespace != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "partition scoped type %s cannot have a namespace. got: %s", - resource.ToGVK(req.Type), - req.Tenancy.Namespace, - ) - } - - return reg, nil + return status.Errorf(codes.InvalidArgument, "%s is required", field) } diff --git a/agent/grpc-external/services/resource/list_by_owner.go b/agent/grpc-external/services/resource/list_by_owner.go index 1f69787901280..2cc203e72c30b 100644 --- a/agent/grpc-external/services/resource/list_by_owner.go +++ b/agent/grpc-external/services/resource/list_by_owner.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -10,71 +10,38 @@ import ( "google.golang.org/grpc/status" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/proto-public/pbresource" ) func (s *Server) ListByOwner(ctx context.Context, req *pbresource.ListByOwnerRequest) (*pbresource.ListByOwnerResponse, error) { - reg, err := s.validateListByOwnerRequest(req) - if err != nil { + if err := validateListByOwnerRequest(req); err != nil { return nil, err } - // Convert v2 request tenancy to v1 for ACL subsystem. - entMeta := v2TenancyToV1EntMeta(req.Owner.Tenancy) - token := tokenFromContext(ctx) - - // Fill entMeta with token tenancy when empty. - authz, authzContext, err := s.getAuthorizer(token, entMeta) + _, err := s.resolveType(req.Owner.Type) if err != nil { return nil, err } - // Handle defaulting empty tenancy units from request. - v1EntMetaToV2Tenancy(reg, entMeta, req.Owner.Tenancy) - - // Check list ACL before verifying tenancy exists to not leak tenancy existence. - err = reg.ACLs.List(authz, authzContext) - switch { - case acl.IsErrPermissionDenied(err): - return nil, status.Error(codes.PermissionDenied, err.Error()) - case err != nil: - return nil, status.Errorf(codes.Internal, "failed list acl: %v", err) - } - - // Check tenancy exists for the v2 resource. - if err = tenancyExists(reg, s.TenancyBridge, req.Owner.Tenancy, codes.InvalidArgument); err != nil { - return nil, err - } - - // Get owned resources. children, err := s.Backend.ListByOwner(ctx, req.Owner) if err != nil { return nil, status.Errorf(codes.Internal, "failed list by owner: %v", err) } + authz, err := s.getAuthorizer(tokenFromContext(ctx)) + if err != nil { + return nil, err + } + result := make([]*pbresource.Resource, 0) for _, child := range children { - // Retrieve child type's registration to access read ACL hook. - childReg, err := s.resolveType(child.Id.Type) + reg, err := s.resolveType(child.Id.Type) if err != nil { return nil, err } - // Rebuild authorizer if tenancy not identical between owner and child (child scope - // may be narrower). - childAuthz := authz - childAuthzContext := authzContext - if !resource.EqualTenancy(req.Owner.Tenancy, child.Id.Tenancy) { - childEntMeta := v2TenancyToV1EntMeta(child.Id.Tenancy) - childAuthz, childAuthzContext, err = s.getAuthorizer(token, childEntMeta) - if err != nil { - return nil, err - } - } - - // Filter out children that fail real ACL. - err = childReg.ACLs.Read(childAuthz, childAuthzContext, child.Id, child) + // ACL filter + err = reg.ACLs.Read(authz, child.Id) switch { case acl.IsErrPermissionDenied(err): continue @@ -87,37 +54,17 @@ func (s *Server) ListByOwner(ctx context.Context, req *pbresource.ListByOwnerReq return &pbresource.ListByOwnerResponse{Resources: result}, nil } -func (s *Server) validateListByOwnerRequest(req *pbresource.ListByOwnerRequest) (*resource.Registration, error) { +func validateListByOwnerRequest(req *pbresource.ListByOwnerRequest) error { if req.Owner == nil { - return nil, status.Errorf(codes.InvalidArgument, "owner is required") + return status.Errorf(codes.InvalidArgument, "owner is required") } if err := validateId(req.Owner, "owner"); err != nil { - return nil, err + return err } if req.Owner.Uid == "" { - return nil, status.Errorf(codes.InvalidArgument, "owner uid is required") - } - - reg, err := s.resolveType(req.Owner.Type) - if err != nil { - return nil, err + return status.Errorf(codes.InvalidArgument, "owner uid is required") } - - if err = checkV2Tenancy(s.UseV2Tenancy, req.Owner.Type); err != nil { - return nil, err - } - - // Error when partition scoped and namespace not empty. - if reg.Scope == resource.ScopePartition && req.Owner.Tenancy.Namespace != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "partition scoped type %s cannot have a namespace. got: %s", - resource.ToGVK(req.Owner.Type), - req.Owner.Tenancy.Namespace, - ) - } - - return reg, nil + return nil } diff --git a/agent/grpc-external/services/resource/list_by_owner_test.go b/agent/grpc-external/services/resource/list_by_owner_test.go index 78024e68d0fb2..218971a050daa 100644 --- a/agent/grpc-external/services/resource/list_by_owner_test.go +++ b/agent/grpc-external/services/resource/list_by_owner_test.go @@ -1,131 +1,61 @@ // // Copyright (c) HashiCorp, Inc. -// // SPDX-License-Identifier: BUSL-1.1 +// // SPDX-License-Identifier: MPL-2.0 package resource import ( "context" "fmt" - "strings" "testing" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" - "github.com/oklog/ulid/v2" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" ) func TestListByOwner_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) + demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(artistId, recordlabelId *pbresource.ID) *pbresource.ID - errContains string - } - testCases := map[string]testCase{ - "no owner": { - modFn: func(artistId, recordLabelId *pbresource.ID) *pbresource.ID { - return nil - }, - errContains: "owner is required", - }, - "no type": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Type = nil - return artistId - }, - errContains: "owner.type is required", - }, - "no name": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "" - return artistId - }, - errContains: "owner.name invalid", - }, - "name mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "U2" - return artistId - }, - errContains: "owner.name invalid", - }, - "name too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "owner.name invalid", + testCases := map[string]func(*pbresource.ListByOwnerRequest){ + "no owner": func(req *pbresource.ListByOwnerRequest) { req.Owner = nil }, + "no type": func(req *pbresource.ListByOwnerRequest) { req.Owner.Type = nil }, + "no tenancy": func(req *pbresource.ListByOwnerRequest) { req.Owner.Tenancy = nil }, + "no name": func(req *pbresource.ListByOwnerRequest) { req.Owner.Name = "" }, + "no uid": func(req *pbresource.ListByOwnerRequest) { req.Owner.Uid = "" }, + // clone necessary to not pollute DefaultTenancy + "tenancy partition not default": func(req *pbresource.ListByOwnerRequest) { + req.Owner.Tenancy = clone(req.Owner.Tenancy) + req.Owner.Tenancy.Partition = "" }, - "partition mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = "Default" - return artistId - }, - errContains: "owner.tenancy.partition invalid", + "tenancy namespace not default": func(req *pbresource.ListByOwnerRequest) { + req.Owner.Tenancy = clone(req.Owner.Tenancy) + req.Owner.Tenancy.Namespace = "" }, - "partition too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - return artistId - }, - errContains: "owner.tenancy.partition invalid", - }, - "namespace mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = "Default" - return artistId - }, - errContains: "owner.tenancy.namespace invalid", - }, - "namespace too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "owner.tenancy.namespace invalid", - }, - "no uid": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Uid = "" - return artistId - }, - errContains: "owner uid is required", - }, - "partition scope with non-empty namespace": { - modFn: func(_, recordLabelId *pbresource.ID) *pbresource.ID { - recordLabelId.Uid = ulid.Make().String() - recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" - return recordLabelId - }, - errContains: "cannot have a namespace", + "tenancy peername not local": func(req *pbresource.ListByOwnerRequest) { + req.Owner.Tenancy = clone(req.Owner.Tenancy) + req.Owner.Tenancy.PeerName = "" }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + res, err := demo.GenerateV2Artist() require.NoError(t, err) - // Each test case picks which resource to use based on the resource type's scope. - req := &pbresource.ListByOwnerRequest{Owner: tc.modFn(artist.Id, recordLabel.Id)} + req := &pbresource.ListByOwnerRequest{Owner: res.Id} + modFn(req) _, err = client.ListByOwner(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -137,7 +67,7 @@ func TestListByOwner_TypeNotRegistered(t *testing.T) { _, err := client.ListByOwner(context.Background(), &pbresource.ListByOwnerRequest{ Owner: &pbresource.ID{ Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, Uid: "bogus", Name: "bogus", }, @@ -195,121 +125,8 @@ func TestListByOwner_Many(t *testing.T) { prototest.AssertElementsMatch(t, albums, rsp3.Resources) } -func TestListByOwner_OwnerTenancyDoesNotExist(t *testing.T) { - type testCase struct { - modFn func(artistId, recordlabelId *pbresource.ID) *pbresource.ID - errContains string - } - tenancyCases := map[string]testCase{ - "partition not found when namespace scoped": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Uid = "doesnotmatter" - id.Tenancy.Partition = "boguspartition" - return id - }, - errContains: "partition not found", - }, - "namespace not found when namespace scoped": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Uid = "doesnotmatter" - id.Tenancy.Namespace = "bogusnamespace" - return id - }, - errContains: "namespace not found", - }, - "partition not found when partition scoped": { - modFn: func(_, recordLabelId *pbresource.ID) *pbresource.ID { - id := clone(recordLabelId) - id.Uid = "doesnotmatter" - id.Tenancy.Partition = "boguspartition" - return id - }, - errContains: "partition not found", - }, - } - for desc, tc := range tenancyCases { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - demo.RegisterTypes(server.Registry) - client := testClient(t, server) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - recordLabel, err = server.Backend.WriteCAS(testContext(t), recordLabel) - require.NoError(t, err) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - artist, err = server.Backend.WriteCAS(testContext(t), artist) - require.NoError(t, err) - - // Verify non-existant tenancy units in owner err with invalid arg. - _, err = client.ListByOwner(testContext(t), &pbresource.ListByOwnerRequest{Owner: tc.modFn(artist.Id, recordLabel.Id)}) - require.Error(t, err) - require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) - }) - } -} - -func TestListByOwner_Tenancy_Defaults_And_Normalization(t *testing.T) { - for tenancyDesc, modFn := range tenancyCases() { - t.Run(tenancyDesc, func(t *testing.T) { - server := testServer(t) - demo.RegisterTypes(server.Registry) - client := testClient(t, server) - - // Create partition scoped recordLabel. - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - rsp1, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: recordLabel}) - require.NoError(t, err) - recordLabel = rsp1.Resource - - // Create namespace scoped artist. - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - rsp2, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: artist}) - require.NoError(t, err) - artist = rsp2.Resource - - // Owner will be either partition scoped (recordLabel) or namespace scoped (artist) based on testcase. - moddedOwnerId := modFn(artist.Id, recordLabel.Id) - var ownerId *pbresource.ID - - // Avoid using the modded id when linking owner to child. - switch { - case proto.Equal(moddedOwnerId.Type, demo.TypeV2Artist): - ownerId = artist.Id - case proto.Equal(moddedOwnerId.Type, demo.TypeV1RecordLabel): - ownerId = recordLabel.Id - default: - require.Fail(t, "unexpected resource type") - } - - // Link owner to child. - album, err := demo.GenerateV2Album(ownerId) - require.NoError(t, err) - rsp3, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: album}) - require.NoError(t, err) - album = rsp3.Resource - - // Test - listRsp, err := client.ListByOwner(testContext(t), &pbresource.ListByOwnerRequest{ - Owner: moddedOwnerId, - }) - require.NoError(t, err) - - // Verify child album always returned. - prototest.AssertDeepEqual(t, album, listRsp.Resources[0]) - }) - } -} - func TestListByOwner_ACL_PerTypeDenied(t *testing.T) { - authz := AuthorizerFrom(t, `key_prefix "resource/demo.v2.Album/" { policy = "deny" }`, demo.ArtistV2ListPolicy) + authz := AuthorizerFrom(t, `key_prefix "resource/demo.v2.Album/" { policy = "deny" }`) _, rsp, err := roundTripListByOwner(t, authz) // verify resource filtered out, hence no results @@ -318,7 +135,7 @@ func TestListByOwner_ACL_PerTypeDenied(t *testing.T) { } func TestListByOwner_ACL_PerTypeAllowed(t *testing.T) { - authz := AuthorizerFrom(t, `key_prefix "resource/demo.v2.Album/" { policy = "read" }`, demo.ArtistV2ListPolicy) + authz := AuthorizerFrom(t, `key_prefix "resource/demo.v2.Album/" { policy = "read" }`) album, rsp, err := roundTripListByOwner(t, authz) // verify resource not filtered out diff --git a/agent/grpc-external/services/resource/list_test.go b/agent/grpc-external/services/resource/list_test.go index 5af6747f84444..4d6b50951b758 100644 --- a/agent/grpc-external/services/resource/list_test.go +++ b/agent/grpc-external/services/resource/list_test.go @@ -1,18 +1,15 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource import ( "context" "fmt" - "strconv" - "strings" "testing" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/grpc-external/testutils" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" @@ -28,66 +25,24 @@ import ( func TestList_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - demo.RegisterTypes(server.Registry) - type testCase struct { - modReqFn func(req *pbresource.ListRequest) - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no type": { - modReqFn: func(req *pbresource.ListRequest) { req.Type = nil }, - errContains: "type is required", - }, - "no tenancy": { - modReqFn: func(req *pbresource.ListRequest) { req.Tenancy = nil }, - errContains: "tenancy is required", - }, - "partition mixed case": { - modReqFn: func(req *pbresource.ListRequest) { req.Tenancy.Partition = "Default" }, - errContains: "tenancy.partition invalid", - }, - "partition too long": { - modReqFn: func(req *pbresource.ListRequest) { - req.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errContains: "tenancy.partition invalid", - }, - "namespace mixed case": { - modReqFn: func(req *pbresource.ListRequest) { req.Tenancy.Namespace = "Default" }, - errContains: "tenancy.namespace invalid", - }, - "namespace too long": { - modReqFn: func(req *pbresource.ListRequest) { - req.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errContains: "tenancy.namespace invalid", - }, - "name_prefix mixed case": { - modReqFn: func(req *pbresource.ListRequest) { req.NamePrefix = "Violator" }, - errContains: "name_prefix invalid", - }, - "partitioned resource provides non-empty namespace": { - modReqFn: func(req *pbresource.ListRequest) { - req.Type = demo.TypeV1RecordLabel - req.Tenancy.Namespace = "bad" - }, - errContains: "cannot have a namespace", - }, + testCases := map[string]func(*pbresource.ListRequest){ + "no type": func(req *pbresource.ListRequest) { req.Type = nil }, + "no tenancy": func(req *pbresource.ListRequest) { req.Tenancy = nil }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { req := &pbresource.ListRequest{ Type: demo.TypeV2Album, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, } - tc.modReqFn(req) + modFn(req) _, err := client.List(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -98,7 +53,7 @@ func TestList_TypeNotFound(t *testing.T) { _, err := client.List(context.Background(), &pbresource.ListRequest{ Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, NamePrefix: "", }) require.Error(t, err) @@ -115,7 +70,7 @@ func TestList_Empty(t *testing.T) { rsp, err := client.List(tc.ctx, &pbresource.ListRequest{ Type: demo.TypeV1Artist, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, NamePrefix: "", }) require.NoError(t, err) @@ -147,7 +102,7 @@ func TestList_Many(t *testing.T) { rsp, err := client.List(tc.ctx, &pbresource.ListRequest{ Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, NamePrefix: "", }) require.NoError(t, err) @@ -156,83 +111,6 @@ func TestList_Many(t *testing.T) { } } -func TestList_NamePrefix(t *testing.T) { - for desc, tc := range listTestCases() { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - demo.RegisterTypes(server.Registry) - client := testClient(t, server) - - expectedResources := []*pbresource.Resource{} - - namePrefixIndex := 0 - // create a name prefix that is always present - namePrefix := fmt.Sprintf("%s-", strconv.Itoa(namePrefixIndex)) - for i := 0; i < 10; i++ { - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - // Prevent test flakes if the generated names collide. - artist.Id.Name = fmt.Sprintf("%d-%s", i, artist.Id.Name) - - rsp, err := client.Write(tc.ctx, &pbresource.WriteRequest{Resource: artist}) - require.NoError(t, err) - - // only matching name prefix are expected - if i == namePrefixIndex { - expectedResources = append(expectedResources, rsp.Resource) - } - } - - rsp, err := client.List(tc.ctx, &pbresource.ListRequest{ - Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - NamePrefix: namePrefix, - }) - - require.NoError(t, err) - prototest.AssertElementsMatch(t, expectedResources, rsp.Resources) - }) - } -} - -func TestList_Tenancy_Defaults_And_Normalization(t *testing.T) { - // Test units of tenancy get defaulted correctly when empty. - ctx := context.Background() - for desc, tc := range wildcardTenancyCases() { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - demo.RegisterTypes(server.Registry) - client := testClient(t, server) - - // Write partition scoped record label - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - recordLabelRsp, err := client.Write(ctx, &pbresource.WriteRequest{Resource: recordLabel}) - require.NoError(t, err) - - // Write namespace scoped artist - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - artistRsp, err := client.Write(ctx, &pbresource.WriteRequest{Resource: artist}) - require.NoError(t, err) - - // List and verify correct resource returned for empty tenancy units. - listRsp, err := client.List(ctx, &pbresource.ListRequest{ - Type: tc.typ, - Tenancy: tc.tenancy, - }) - require.NoError(t, err) - require.Len(t, listRsp.Resources, 1) - if tc.typ == demo.TypeV1RecordLabel { - prototest.AssertDeepEqual(t, recordLabelRsp.Resource, listRsp.Resources[0]) - } else { - prototest.AssertDeepEqual(t, artistRsp.Resource, listRsp.Resources[0]) - } - }) - } -} - func TestList_GroupVersionMismatch(t *testing.T) { for desc, tc := range listTestCases() { t.Run(desc, func(t *testing.T) { diff --git a/agent/grpc-external/services/resource/mock_TenancyBridge.go b/agent/grpc-external/services/resource/mock_TenancyBridge.go deleted file mode 100644 index 662b4004b99f7..0000000000000 --- a/agent/grpc-external/services/resource/mock_TenancyBridge.go +++ /dev/null @@ -1,121 +0,0 @@ -// Code generated by mockery v2.20.0. DO NOT EDIT. - -package resource - -import mock "github.com/stretchr/testify/mock" - -// MockTenancyBridge is an autogenerated mock type for the TenancyBridge type -type MockTenancyBridge struct { - mock.Mock -} - -// IsNamespaceMarkedForDeletion provides a mock function with given fields: partition, namespace -func (_m *MockTenancyBridge) IsNamespaceMarkedForDeletion(partition string, namespace string) (bool, error) { - ret := _m.Called(partition, namespace) - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(string, string) (bool, error)); ok { - return rf(partition, namespace) - } - if rf, ok := ret.Get(0).(func(string, string) bool); ok { - r0 = rf(partition, namespace) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(partition, namespace) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// IsPartitionMarkedForDeletion provides a mock function with given fields: partition -func (_m *MockTenancyBridge) IsPartitionMarkedForDeletion(partition string) (bool, error) { - ret := _m.Called(partition) - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(string) (bool, error)); ok { - return rf(partition) - } - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(partition) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(partition) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NamespaceExists provides a mock function with given fields: partition, namespace -func (_m *MockTenancyBridge) NamespaceExists(partition string, namespace string) (bool, error) { - ret := _m.Called(partition, namespace) - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(string, string) (bool, error)); ok { - return rf(partition, namespace) - } - if rf, ok := ret.Get(0).(func(string, string) bool); ok { - r0 = rf(partition, namespace) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(partition, namespace) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PartitionExists provides a mock function with given fields: partition -func (_m *MockTenancyBridge) PartitionExists(partition string) (bool, error) { - ret := _m.Called(partition) - - var r0 bool - var r1 error - if rf, ok := ret.Get(0).(func(string) (bool, error)); ok { - return rf(partition) - } - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(partition) - } else { - r0 = ret.Get(0).(bool) - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(partition) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewMockTenancyBridge interface { - mock.TestingT - Cleanup(func()) -} - -// NewMockTenancyBridge creates a new instance of MockTenancyBridge. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewMockTenancyBridge(t mockConstructorTestingTNewMockTenancyBridge) *MockTenancyBridge { - mock := &MockTenancyBridge{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/agent/grpc-external/services/resource/read.go b/agent/grpc-external/services/resource/read.go index 3c413bc13870b..c75779183cb8d 100644 --- a/agent/grpc-external/services/resource/read.go +++ b/agent/grpc-external/services/resource/read.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -11,127 +11,55 @@ import ( "google.golang.org/grpc/status" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" ) func (s *Server) Read(ctx context.Context, req *pbresource.ReadRequest) (*pbresource.ReadResponse, error) { - // Light first pass validation based on what user passed in and not much more. - reg, err := s.validateReadRequest(req) - if err != nil { + if err := validateReadRequest(req); err != nil { return nil, err } - // acl.EnterpriseMeta acl.AuthorizerContext follow rules for V1 resources since they integrate with the V1 acl subsystem. - // pbresource.Tenacy follows rules for V2 resources and the Resource service. - // Example: - // - // A CE namespace scoped resource: - // V1: EnterpriseMeta{} - // V2: Tenancy {Partition: "default", Namespace: "default"} - // - // An ENT namespace scoped resource: - // V1: EnterpriseMeta{Partition: "default", Namespace: "default"} - // V2: Tenancy {Partition: "default", Namespace: "default"} - // - // It is necessary to convert back and forth depending on which component supports which version, V1 or V2. - entMeta := v2TenancyToV1EntMeta(req.Id.Tenancy) - authz, authzContext, err := s.getAuthorizer(tokenFromContext(ctx), entMeta) + // check type exists + reg, err := s.resolveType(req.Id.Type) if err != nil { return nil, err } - v1EntMetaToV2Tenancy(reg, entMeta, req.Id.Tenancy) + authz, err := s.getAuthorizer(tokenFromContext(ctx)) + if err != nil { + return nil, err + } - // ACL check usually comes before tenancy existence checks to not leak - // tenancy "existence", unless the ACL check requires the data payload - // to function. - authzNeedsData := false - err = reg.ACLs.Read(authz, authzContext, req.Id, nil) + // check acls + err = reg.ACLs.Read(authz, req.Id) switch { - case errors.Is(err, resource.ErrNeedResource): - authzNeedsData = true - err = nil case acl.IsErrPermissionDenied(err): return nil, status.Error(codes.PermissionDenied, err.Error()) case err != nil: return nil, status.Errorf(codes.Internal, "failed read acl: %v", err) } - // Check tenancy exists for the V2 resource. - if err = tenancyExists(reg, s.TenancyBridge, req.Id.Tenancy, codes.NotFound); err != nil { - return nil, err - } - resource, err := s.Backend.Read(ctx, readConsistencyFrom(ctx), req.Id) switch { + case err == nil: + return &pbresource.ReadResponse{Resource: resource}, nil case errors.Is(err, storage.ErrNotFound): return nil, status.Error(codes.NotFound, err.Error()) case errors.As(err, &storage.GroupVersionMismatchError{}): return nil, status.Error(codes.InvalidArgument, err.Error()) - case err != nil: + default: return nil, status.Errorf(codes.Internal, "failed read: %v", err) } - - if authzNeedsData { - err = reg.ACLs.Read(authz, authzContext, req.Id, resource) - switch { - case acl.IsErrPermissionDenied(err): - return nil, status.Error(codes.PermissionDenied, err.Error()) - case err != nil: - return nil, status.Errorf(codes.Internal, "failed read acl: %v", err) - } - } - - return &pbresource.ReadResponse{Resource: resource}, nil } -func (s *Server) validateReadRequest(req *pbresource.ReadRequest) (*resource.Registration, error) { +func validateReadRequest(req *pbresource.ReadRequest) error { if req.Id == nil { - return nil, status.Errorf(codes.InvalidArgument, "id is required") + return status.Errorf(codes.InvalidArgument, "id is required") } if err := validateId(req.Id, "id"); err != nil { - return nil, err - } - - // Check type exists. - reg, err := s.resolveType(req.Id.Type) - if err != nil { - return nil, err - } - - if err = checkV2Tenancy(s.UseV2Tenancy, req.Id.Type); err != nil { - return nil, err - } - - // Check scope - if reg.Scope == resource.ScopePartition && req.Id.Tenancy.Namespace != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "partition scoped resource %s cannot have a namespace. got: %s", - resource.ToGVK(req.Id.Type), - req.Id.Tenancy.Namespace, - ) - } - if reg.Scope == resource.ScopeCluster { - if req.Id.Tenancy.Partition != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "cluster scoped resource %s cannot have a partition: %s", - resource.ToGVK(req.Id.Type), - req.Id.Tenancy.Partition, - ) - } - if req.Id.Tenancy.Namespace != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "cluster scoped resource %s cannot have a namespace: %s", - resource.ToGVK(req.Id.Type), - req.Id.Tenancy.Namespace, - ) - } + return err } - return reg, nil + return nil } diff --git a/agent/grpc-external/services/resource/read_test.go b/agent/grpc-external/services/resource/read_test.go index 2afdfeab0e1ea..cca911ec15b5b 100644 --- a/agent/grpc-external/services/resource/read_test.go +++ b/agent/grpc-external/services/resource/read_test.go @@ -1,13 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource import ( "context" - "fmt" - "strings" - "sync" "testing" "github.com/stretchr/testify/mock" @@ -15,134 +12,51 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" - "github.com/hashicorp/consul/agent/grpc-external/testutils" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/internal/storage" - "github.com/hashicorp/consul/internal/tenancy" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" ) func TestRead_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - tenancy.RegisterTypes(server.Registry) - demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(artistId, recordlabelId, executiveId *pbresource.ID) *pbresource.ID - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no id": { - modFn: func(_, _, _ *pbresource.ID) *pbresource.ID { - return nil - }, - errContains: "id is required", - }, - "no type": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Type = nil - return artistId - }, - errContains: "id.type is required", - }, - "no name": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "" - return artistId - }, - errContains: "id.name invalid", - }, - "name is mixed case": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "MixedCaseNotAllowed" - return artistId - }, - errContains: "id.name invalid", - }, - "name too long": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Name = strings.Repeat("a", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.name invalid", + testCases := map[string]func(*pbresource.ReadRequest){ + "no id": func(req *pbresource.ReadRequest) { req.Id = nil }, + "no type": func(req *pbresource.ReadRequest) { req.Id.Type = nil }, + "no tenancy": func(req *pbresource.ReadRequest) { req.Id.Tenancy = nil }, + "no name": func(req *pbresource.ReadRequest) { req.Id.Name = "" }, + // clone necessary to not pollute DefaultTenancy + "tenancy partition not default": func(req *pbresource.ReadRequest) { + req.Id.Tenancy = clone(req.Id.Tenancy) + req.Id.Tenancy.Partition = "" }, - "partition is mixed case": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = "Default" - return artistId - }, - errContains: "id.tenancy.partition invalid", + "tenancy namespace not default": func(req *pbresource.ReadRequest) { + req.Id.Tenancy = clone(req.Id.Tenancy) + req.Id.Tenancy.Namespace = "" }, - "partition too long": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.tenancy.partition invalid", - }, - "namespace is mixed case": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = "Default" - return artistId - }, - errContains: "id.tenancy.namespace invalid", - }, - "namespace too long": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.tenancy.namespace invalid", - }, - "partition scope with non-empty namespace": { - modFn: func(_, recordLabelId, _ *pbresource.ID) *pbresource.ID { - recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" - return recordLabelId - }, - errContains: "cannot have a namespace", - }, - "cluster scope with non-empty partition": { - modFn: func(_, _, executiveId *pbresource.ID) *pbresource.ID { - executiveId.Tenancy = &pbresource.Tenancy{Partition: resource.DefaultPartitionName} - return executiveId - }, - errContains: "cannot have a partition", - }, - "cluster scope with non-empty namespace": { - modFn: func(_, _, executiveId *pbresource.ID) *pbresource.ID { - executiveId.Tenancy = &pbresource.Tenancy{Namespace: resource.DefaultNamespaceName} - return executiveId - }, - errContains: "cannot have a namespace", + "tenancy peername not local": func(req *pbresource.ReadRequest) { + req.Id.Tenancy = clone(req.Id.Tenancy) + req.Id.Tenancy.PeerName = "" }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { - artist, err := demo.GenerateV2Artist() + res, err := demo.GenerateV2Artist() require.NoError(t, err) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - - executive, err := demo.GenerateV1Executive("music-man", "CEO") - require.NoError(t, err) - - // Each test case picks which resource to use based on the resource type's scope. - req := &pbresource.ReadRequest{Id: tc.modFn(artist.Id, recordLabel.Id, executive.Id)} + req := &pbresource.ReadRequest{Id: res.Id} + modFn(req) _, err = client.Read(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -163,66 +77,18 @@ func TestRead_TypeNotFound(t *testing.T) { func TestRead_ResourceNotFound(t *testing.T) { for desc, tc := range readTestCases() { t.Run(desc, func(t *testing.T) { - type tenancyCase struct { - modFn func(artistId, recordlabelId *pbresource.ID) *pbresource.ID - errContains string - } - tenancyCases := map[string]tenancyCase{ - "resource not found by name": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "bogusname" - return artistId - }, - errContains: "resource not found", - }, - "partition not found when namespace scoped": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Tenancy.Partition = "boguspartition" - return id - }, - errContains: "partition not found", - }, - "namespace not found when namespace scoped": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Tenancy.Namespace = "bogusnamespace" - return id - }, - errContains: "namespace not found", - }, - "partition not found when partition scoped": { - modFn: func(_, recordLabelId *pbresource.ID) *pbresource.ID { - id := clone(recordLabelId) - id.Tenancy.Partition = "boguspartition" - return id - }, - errContains: "partition not found", - }, - } - for tenancyDesc, tenancyCase := range tenancyCases { - t.Run(tenancyDesc, func(t *testing.T) { - server := testServer(t) - demo.RegisterTypes(server.Registry) - client := testClient(t, server) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - recordLabel, err = server.Backend.WriteCAS(tc.ctx, recordLabel) - require.NoError(t, err) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - artist, err = server.Backend.WriteCAS(tc.ctx, artist) - require.NoError(t, err) - - // Each tenancy test case picks which resource to use based on the resource type's scope. - _, err = client.Read(tc.ctx, &pbresource.ReadRequest{Id: tenancyCase.modFn(artist.Id, recordLabel.Id)}) - require.Error(t, err) - require.Equal(t, codes.NotFound.String(), status.Code(err).String()) - require.ErrorContains(t, err, tenancyCase.errContains) - }) - } + server := testServer(t) + + demo.RegisterTypes(server.Registry) + client := testClient(t, server) + + artist, err := demo.GenerateV2Artist() + require.NoError(t, err) + + _, err = client.Read(tc.ctx, &pbresource.ReadRequest{Id: artist.Id}) + require.Error(t, err) + require.Equal(t, codes.NotFound.String(), status.Code(err).String()) + require.Contains(t, err.Error(), "resource not found") }) } } @@ -255,37 +121,20 @@ func TestRead_GroupVersionMismatch(t *testing.T) { func TestRead_Success(t *testing.T) { for desc, tc := range readTestCases() { t.Run(desc, func(t *testing.T) { - for tenancyDesc, modFn := range tenancyCases() { - t.Run(tenancyDesc, func(t *testing.T) { - server := testServer(t) - demo.RegisterTypes(server.Registry) - client := testClient(t, server) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - recordLabel, err = server.Backend.WriteCAS(tc.ctx, recordLabel) - require.NoError(t, err) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - artist, err = server.Backend.WriteCAS(tc.ctx, artist) - require.NoError(t, err) - - // Each tenancy test case picks which resource to use based on the resource type's scope. - req := &pbresource.ReadRequest{Id: modFn(artist.Id, recordLabel.Id)} - rsp, err := client.Read(tc.ctx, req) - require.NoError(t, err) - - switch { - case proto.Equal(rsp.Resource.Id.Type, demo.TypeV2Artist): - prototest.AssertDeepEqual(t, artist, rsp.Resource) - case proto.Equal(rsp.Resource.Id.Type, demo.TypeV1RecordLabel): - prototest.AssertDeepEqual(t, recordLabel, rsp.Resource) - default: - require.Fail(t, "unexpected resource type") - } - }) - } + server := testServer(t) + + demo.RegisterTypes(server.Registry) + client := testClient(t, server) + + artist, err := demo.GenerateV2Artist() + require.NoError(t, err) + + resource1, err := server.Backend.WriteCAS(tc.ctx, artist) + require.NoError(t, err) + + rsp, err := client.Read(tc.ctx, &pbresource.ReadRequest{Id: artist.Id}) + require.NoError(t, err) + prototest.AssertDeepEqual(t, resource1, rsp.Resource) }) } } @@ -316,114 +165,42 @@ func TestRead_VerifyReadConsistencyArg(t *testing.T) { // N.B. Uses key ACLs for now. See demo.RegisterTypes() func TestRead_ACLs(t *testing.T) { type testCase struct { - res *pbresource.Resource - authz resolver.Result - codeNotExist codes.Code - codeExists codes.Code + authz resolver.Result + code codes.Code } - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - label, err := demo.GenerateV1RecordLabel("blink1982") - require.NoError(t, err) - testcases := map[string]testCase{ - "artist-v1/read hook denied": { - res: artist, - authz: AuthorizerFrom(t, demo.ArtistV1ReadPolicy), - codeNotExist: codes.PermissionDenied, - codeExists: codes.PermissionDenied, - }, - "artist-v2/read hook allowed": { - res: artist, - authz: AuthorizerFrom(t, demo.ArtistV2ReadPolicy), - codeNotExist: codes.NotFound, - codeExists: codes.OK, + "read hook denied": { + authz: AuthorizerFrom(t, demo.ArtistV1ReadPolicy), + code: codes.PermissionDenied, }, - // Labels have the read ACL that requires reading the data. - "label-v1/read hook denied": { - res: label, - authz: AuthorizerFrom(t, demo.LabelV1ReadPolicy), - codeNotExist: codes.NotFound, - codeExists: codes.PermissionDenied, + "read hook allowed": { + authz: AuthorizerFrom(t, demo.ArtistV2ReadPolicy), + code: codes.NotFound, }, } - adminAuthz := AuthorizerFrom(t, `key_prefix "" { policy = "write" }`) - - idx := 0 - nextTokenContext := func(t *testing.T) context.Context { - // Each query should use a distinct token string to avoid caching so we can - // change the behavior each call. - token := fmt.Sprintf("token-%d", idx) - idx++ - //nolint:staticcheck - return context.WithValue(testContext(t), "x-consul-token", token) - } - for desc, tc := range testcases { t.Run(desc, func(t *testing.T) { server := testServer(t) client := testClient(t, server) - dr := &dummyACLResolver{ - result: testutils.ACLsDisabled(t), - } - server.ACLResolver = dr - + mockACLResolver := &MockACLResolver{} + mockACLResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything). + Return(tc.authz, nil) + server.ACLResolver = mockACLResolver demo.RegisterTypes(server.Registry) - dr.SetResult(tc.authz) - testutil.RunStep(t, "does not exist", func(t *testing.T) { - _, err = client.Read(nextTokenContext(t), &pbresource.ReadRequest{Id: tc.res.Id}) - if tc.codeNotExist == codes.OK { - require.NoError(t, err) - } else { - require.Error(t, err) - } - require.Equal(t, tc.codeNotExist.String(), status.Code(err).String(), "%v", err) - }) - - // Create it. - dr.SetResult(adminAuthz) - _, err = client.Write(nextTokenContext(t), &pbresource.WriteRequest{Resource: tc.res}) - require.NoError(t, err, "could not write resource") - - dr.SetResult(tc.authz) - testutil.RunStep(t, "does exist", func(t *testing.T) { - // exercise ACL when the data does exist - _, err = client.Read(nextTokenContext(t), &pbresource.ReadRequest{Id: tc.res.Id}) - if tc.codeExists == codes.OK { - require.NoError(t, err) - } else { - require.Error(t, err) - } - require.Equal(t, tc.codeExists.String(), status.Code(err).String()) - }) + artist, err := demo.GenerateV2Artist() + require.NoError(t, err) + + // exercise ACL + _, err = client.Read(testContext(t), &pbresource.ReadRequest{Id: artist.Id}) + require.Error(t, err) + require.Equal(t, tc.code.String(), status.Code(err).String()) }) } } -type dummyACLResolver struct { - lock sync.Mutex - result resolver.Result -} - -var _ ACLResolver = (*dummyACLResolver)(nil) - -func (r *dummyACLResolver) SetResult(result resolver.Result) { - r.lock.Lock() - defer r.lock.Unlock() - r.result = result -} - -func (r *dummyACLResolver) ResolveTokenAndDefaultMeta(string, *acl.EnterpriseMeta, *acl.AuthorizerContext) (resolver.Result, error) { - r.lock.Lock() - defer r.lock.Unlock() - return r.result, nil -} - type readTestCase struct { consistency storage.ReadConsistency ctx context.Context diff --git a/agent/grpc-external/services/resource/server.go b/agent/grpc-external/services/resource/server.go index 88237633edb75..51bb4610d527f 100644 --- a/agent/grpc-external/services/resource/server.go +++ b/agent/grpc-external/services/resource/server.go @@ -1,11 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource import ( "context" - "strings" "github.com/hashicorp/go-hclog" "google.golang.org/grpc" @@ -32,14 +31,6 @@ type Config struct { // Backend is the storage backend that will be used for resource persistence. Backend Backend ACLResolver ACLResolver - // TenancyBridge temporarily allows us to use V1 implementations of - // partitions and namespaces until V2 implementations are available. - TenancyBridge TenancyBridge - - // UseV2Tenancy is true if the "v2tenancy" experiement is active, false otherwise. - // Attempts to create v2 tenancy resources (partition or namespace) will fail when the - // flag is false. - UseV2Tenancy bool } //go:generate mockery --name Registry --inpackage @@ -57,14 +48,6 @@ type ACLResolver interface { ResolveTokenAndDefaultMeta(string, *acl.EnterpriseMeta, *acl.AuthorizerContext) (resolver.Result, error) } -//go:generate mockery --name TenancyBridge --inpackage -type TenancyBridge interface { - PartitionExists(partition string) (bool, error) - IsPartitionMarkedForDeletion(partition string) (bool, error) - NamespaceExists(partition, namespace string) (bool, error) - IsNamespaceMarkedForDeletion(partition, namespace string) (bool, error) -} - func NewServer(cfg Config) *Server { return &Server{cfg} } @@ -117,13 +100,12 @@ func readConsistencyFrom(ctx context.Context) storage.ReadConsistency { return storage.EventualConsistency } -func (s *Server) getAuthorizer(token string, entMeta *acl.EnterpriseMeta) (acl.Authorizer, *acl.AuthorizerContext, error) { - authzContext := &acl.AuthorizerContext{} - authz, err := s.ACLResolver.ResolveTokenAndDefaultMeta(token, entMeta, authzContext) +func (s *Server) getAuthorizer(token string) (acl.Authorizer, error) { + authz, err := s.ACLResolver.ResolveTokenAndDefaultMeta(token, nil, nil) if err != nil { - return nil, nil, status.Errorf(codes.Internal, "failed getting authorizer: %v", err) + return nil, status.Errorf(codes.Internal, "failed getting authorizer: %v", err) } - return authz, authzContext, nil + return authz, nil } func isGRPCStatusError(err error) bool { @@ -135,133 +117,33 @@ func isGRPCStatusError(err error) bool { } func validateId(id *pbresource.ID, errorPrefix string) error { - if id.Type == nil { - return status.Errorf(codes.InvalidArgument, "%s.type is required", errorPrefix) - } - - if err := resource.ValidateName(id.Name); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.name invalid: %v", errorPrefix, err) - } - - // Better UX: Allow callers to pass in nil tenancy. Defaulting and inheritance of tenancy - // from the request token will take place further down in the call flow. - if id.Tenancy == nil { - id.Tenancy = &pbresource.Tenancy{ - Partition: "", - Namespace: "", - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - PeerName: "local", - } - } - - if id.Tenancy.Partition != "" { - if err := resource.ValidateName(id.Tenancy.Partition); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.tenancy.partition invalid: %v", errorPrefix, err) - } - } - if id.Tenancy.Namespace != "" { - if err := resource.ValidateName(id.Tenancy.Namespace); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.tenancy.namespace invalid: %v", errorPrefix, err) - } - } - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - if id.Tenancy.PeerName == "" { - id.Tenancy.PeerName = resource.DefaultPeerName - } - - return nil -} - -func validateRef(ref *pbresource.Reference, errorPrefix string) error { - if ref.Type == nil { - return status.Errorf(codes.InvalidArgument, "%s.type is required", errorPrefix) - } - if err := resource.ValidateName(ref.Name); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.name invalid: %v", errorPrefix, err) - } - if err := resource.ValidateName(ref.Tenancy.Partition); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.tenancy.partition invalid: %v", errorPrefix, err) - } - if err := resource.ValidateName(ref.Tenancy.Namespace); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.tenancy.namespace invalid: %v", errorPrefix, err) - } - return nil -} - -func validateWildcardTenancy(tenancy *pbresource.Tenancy, namePrefix string) error { - // Partition has to be a valid name if not wildcard or empty - if tenancy.Partition != "" && tenancy.Partition != "*" { - if err := resource.ValidateName(tenancy.Partition); err != nil { - return status.Errorf(codes.InvalidArgument, "tenancy.partition invalid: %v", err) - } - } - - // Namespace has to be a valid name if not wildcard or empty - if tenancy.Namespace != "" && tenancy.Namespace != "*" { - if err := resource.ValidateName(tenancy.Namespace); err != nil { - return status.Errorf(codes.InvalidArgument, "tenancy.namespace invalid: %v", err) - } - } - - // Not doing a strict resource name validation here because the prefix can be - // something like "foo-" which is a valid prefix but not valid resource name. - // relax validation to just check for lowercasing - if namePrefix != strings.ToLower(namePrefix) { - return status.Errorf(codes.InvalidArgument, "name_prefix invalid: must be lowercase alphanumeric, got: %v", namePrefix) + var field string + switch { + case id.Type == nil: + field = "type" + case id.Tenancy == nil: + field = "tenancy" + case id.Name == "": + field = "name" } - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - if tenancy.PeerName == "" { - tenancy.PeerName = resource.DefaultPeerName + if field != "" { + return status.Errorf(codes.InvalidArgument, "%s.%s is required", errorPrefix, field) } - return nil -} - -// tenancyExists return an error with the passed in gRPC status code when tenancy partition or namespace do not exist. -func tenancyExists(reg *resource.Registration, tenancyBridge TenancyBridge, tenancy *pbresource.Tenancy, errCode codes.Code) error { - if reg.Scope == resource.ScopePartition || reg.Scope == resource.ScopeNamespace { - exists, err := tenancyBridge.PartitionExists(tenancy.Partition) - switch { - case err != nil: - return err - case !exists: - return status.Errorf(errCode, "partition not found: %v", tenancy.Partition) - } - } - - if reg.Scope == resource.ScopeNamespace { - exists, err := tenancyBridge.NamespaceExists(tenancy.Partition, tenancy.Namespace) - switch { - case err != nil: - return err - case !exists: - return status.Errorf(errCode, "namespace not found: %v", tenancy.Namespace) - } - } - return nil -} - -// tenancyMarkedForDeletion returns a gRPC InvalidArgument when either partition or namespace is marked for deletion. -func tenancyMarkedForDeletion(reg *resource.Registration, tenancyBridge TenancyBridge, tenancy *pbresource.Tenancy) error { - if reg.Scope == resource.ScopePartition || reg.Scope == resource.ScopeNamespace { - marked, err := tenancyBridge.IsPartitionMarkedForDeletion(tenancy.Partition) - switch { - case err != nil: - return err - case marked: - return status.Errorf(codes.InvalidArgument, "partition marked for deletion: %v", tenancy.Partition) - } + // Revisit defaulting and non-namespaced resources post-1.16 + var expected string + switch { + case id.Tenancy.Partition != "default": + field, expected = "partition", "default" + case id.Tenancy.Namespace != "default": + field, expected = "namespace", "default" + case id.Tenancy.PeerName != "local": + field, expected = "peername", "local" } - if reg.Scope == resource.ScopeNamespace { - marked, err := tenancyBridge.IsNamespaceMarkedForDeletion(tenancy.Partition, tenancy.Namespace) - switch { - case err != nil: - return err - case marked: - return status.Errorf(codes.InvalidArgument, "namespace marked for deletion: %v", tenancy.Namespace) - } + if field != "" { + return status.Errorf(codes.InvalidArgument, "%s.tenancy.%s must be %s", errorPrefix, field, expected) } return nil } diff --git a/agent/grpc-external/services/resource/server_ce.go b/agent/grpc-external/services/resource/server_ce.go deleted file mode 100644 index 2e3f792fe1d10..0000000000000 --- a/agent/grpc-external/services/resource/server_ce.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package resource - -import ( - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" -) - -func v2TenancyToV1EntMeta(tenancy *pbresource.Tenancy) *acl.EnterpriseMeta { - return acl.DefaultEnterpriseMeta() -} - -func v1EntMetaToV2Tenancy(reg *resource.Registration, entMeta *acl.EnterpriseMeta, tenancy *pbresource.Tenancy) { - if (reg.Scope == resource.ScopeNamespace || reg.Scope == resource.ScopePartition) && tenancy.Partition == "" { - tenancy.Partition = entMeta.PartitionOrDefault() - } - - if reg.Scope == resource.ScopeNamespace && tenancy.Namespace == "" { - tenancy.Namespace = entMeta.NamespaceOrDefault() - } -} - -// checkV2Tenancy returns FailedPrecondition error for namespace resource type -// when the "v2tenancy" feature flag is not enabled. -func checkV2Tenancy(useV2Tenancy bool, rtype *pbresource.Type) error { - if resource.EqualType(rtype, pbtenancy.NamespaceType) && !useV2Tenancy { - return status.Errorf(codes.FailedPrecondition, "use of the v2 namespace resource requires the \"v2tenancy\" feature flag") - } - return nil -} diff --git a/agent/grpc-external/services/resource/server_ce_test.go b/agent/grpc-external/services/resource/server_ce_test.go deleted file mode 100644 index c385b65f3ceb4..0000000000000 --- a/agent/grpc-external/services/resource/server_ce_test.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package resource - -import "github.com/hashicorp/consul/acl" - -func fillEntMeta(entMeta *acl.EnterpriseMeta) { - return -} - -func fillAuthorizerContext(authzContext *acl.AuthorizerContext) { - return -} diff --git a/agent/grpc-external/services/resource/server_test.go b/agent/grpc-external/services/resource/server_test.go index e0b52263901fe..a92fff38a3266 100644 --- a/agent/grpc-external/services/resource/server_test.go +++ b/agent/grpc-external/services/resource/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -20,7 +20,6 @@ import ( "github.com/hashicorp/consul/agent/grpc-external/testutils" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/internal/storage/inmem" "github.com/hashicorp/consul/proto-public/pbresource" pbdemov2 "github.com/hashicorp/consul/proto/private/pbdemo/v2" @@ -58,38 +57,16 @@ func testServer(t *testing.T) *Server { require.NoError(t, err) go backend.Run(testContext(t)) - // Mock the ACL Resolver to "allow all" for testing. + // Mock the ACL Resolver to allow everything for testing mockACLResolver := &MockACLResolver{} mockACLResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything). - Return(testutils.ACLsDisabled(t), nil). - Run(func(args mock.Arguments) { - // Caller expecting passed in tokenEntMeta and authorizerContext to be filled in. - tokenEntMeta := args.Get(1).(*acl.EnterpriseMeta) - if tokenEntMeta != nil { - fillEntMeta(tokenEntMeta) - } - - authzContext := args.Get(2).(*acl.AuthorizerContext) - if authzContext != nil { - fillAuthorizerContext(authzContext) - } - }) - - // Mock the tenancy bridge since we can't use the real thing. - mockTenancyBridge := &MockTenancyBridge{} - mockTenancyBridge.On("PartitionExists", resource.DefaultPartitionName).Return(true, nil) - mockTenancyBridge.On("NamespaceExists", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(true, nil) - mockTenancyBridge.On("PartitionExists", mock.Anything).Return(false, nil) - mockTenancyBridge.On("NamespaceExists", mock.Anything, mock.Anything).Return(false, nil) - mockTenancyBridge.On("IsPartitionMarkedForDeletion", resource.DefaultPartitionName).Return(false, nil) - mockTenancyBridge.On("IsNamespaceMarkedForDeletion", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(false, nil) + Return(testutils.ACLsDisabled(t), nil) return NewServer(Config{ - Logger: testutil.Logger(t), - Registry: resource.NewRegistry(), - Backend: backend, - ACLResolver: mockACLResolver, - TenancyBridge: mockTenancyBridge, + Logger: testutil.Logger(t), + Registry: resource.NewRegistry(), + Backend: backend, + ACLResolver: mockACLResolver, }) } @@ -130,126 +107,3 @@ func modifyArtist(t *testing.T, res *pbresource.Resource) *pbresource.Resource { res.Data = data return res } - -// wildcardTenancyCases returns permutations of tenancy and type scope used as input -// to endpoints that accept wildcards for tenancy. -func wildcardTenancyCases() map[string]struct { - typ *pbresource.Type - tenancy *pbresource.Tenancy -} { - return map[string]struct { - typ *pbresource.Type - tenancy *pbresource.Tenancy - }{ - "namespaced type with empty partition": { - typ: demo.TypeV2Artist, - tenancy: &pbresource.Tenancy{ - Partition: "", - Namespace: resource.DefaultNamespaceName, - PeerName: "local", - }, - }, - "namespaced type with empty namespace": { - typ: demo.TypeV2Artist, - tenancy: &pbresource.Tenancy{ - Partition: resource.DefaultPartitionName, - Namespace: "", - PeerName: "local", - }, - }, - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - "namespaced type with empty peername": { - typ: demo.TypeV2Artist, - tenancy: &pbresource.Tenancy{ - Partition: resource.DefaultPartitionName, - Namespace: resource.DefaultNamespaceName, - PeerName: "", - }, - }, - "namespaced type with empty partition and namespace": { - typ: demo.TypeV2Artist, - tenancy: &pbresource.Tenancy{ - Partition: "", - Namespace: "", - PeerName: "local", - }, - }, - "namespaced type with wildcard partition and empty namespace": { - typ: demo.TypeV2Artist, - tenancy: &pbresource.Tenancy{ - Partition: "*", - Namespace: "", - PeerName: "local", - }, - }, - "namespaced type with empty partition and wildcard namespace": { - typ: demo.TypeV2Artist, - tenancy: &pbresource.Tenancy{ - Partition: "", - Namespace: "*", - PeerName: "local", - }, - }, - "partitioned type with empty partition": { - typ: demo.TypeV1RecordLabel, - tenancy: &pbresource.Tenancy{ - Partition: "", - Namespace: "", - PeerName: "local", - }, - }, - "partitioned type with wildcard partition": { - typ: demo.TypeV1RecordLabel, - tenancy: &pbresource.Tenancy{ - Partition: "*", - PeerName: "local", - }, - }, - } -} - -// tenancyCases returns permutations of valid tenancy structs in a resource id to use as inputs. -// - the id is for a recordLabel when the resource is partition scoped -// - the id is for an artist when the resource is namespace scoped -func tenancyCases() map[string]func(artistId, recordlabelId *pbresource.ID) *pbresource.ID { - tenancyCases := map[string]func(artistId, recordlabelId *pbresource.ID) *pbresource.ID{ - "namespaced resource provides nonempty partition and namespace": func(artistId, recordLabelId *pbresource.ID) *pbresource.ID { - return artistId - }, - "namespaced resource inherits tokens partition when empty": func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Tenancy.Partition = "" - return id - }, - "namespaced resource inherits tokens namespace when empty": func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Tenancy.Namespace = "" - return id - }, - "namespaced resource inherits tokens partition and namespace when empty": func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Tenancy.Partition = "" - id.Tenancy.Namespace = "" - return id - }, - "namespaced resource inherits tokens partition and namespace when tenacy nil": func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Tenancy = nil - return id - }, - "partitioned resource provides nonempty partition": func(_, recordLabelId *pbresource.ID) *pbresource.ID { - return recordLabelId - }, - "partitioned resource inherits tokens partition when empty": func(_, recordLabelId *pbresource.ID) *pbresource.ID { - id := clone(recordLabelId) - id.Tenancy.Partition = "" - return id - }, - "partitioned resource inherits tokens partition when tenancy nil": func(_, recordLabelId *pbresource.ID) *pbresource.ID { - id := clone(recordLabelId) - id.Tenancy = nil - return id - }, - } - return tenancyCases -} diff --git a/agent/grpc-external/services/resource/testing/testing.go b/agent/grpc-external/services/resource/testing/testing.go index c9f03bea1a259..5bcbc148e7bb6 100644 --- a/agent/grpc-external/services/resource/testing/testing.go +++ b/agent/grpc-external/services/resource/testing/testing.go @@ -1,140 +1,47 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package testing import ( "context" "testing" - "github.com/hashicorp/go-uuid" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" svc "github.com/hashicorp/consul/agent/grpc-external/services/resource" - "github.com/hashicorp/consul/agent/grpc-external/testutils" internal "github.com/hashicorp/consul/agent/grpc-internal" - "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/storage/inmem" - "github.com/hashicorp/consul/internal/tenancy" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil" ) -func randomACLIdentity(t *testing.T) structs.ACLIdentity { - id, err := uuid.GenerateUUID() - require.NoError(t, err) - - return &structs.ACLToken{AccessorID: id} -} - -func AuthorizerFrom(t *testing.T, policyStrs ...string) resolver.Result { - policies := []*acl.Policy{} - for _, policyStr := range policyStrs { - policy, err := acl.NewPolicyFromSource(policyStr, nil, nil) - require.NoError(t, err) - policies = append(policies, policy) - } - - authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), policies, nil) - require.NoError(t, err) - - return resolver.Result{ - Authorizer: authz, - ACLIdentity: randomACLIdentity(t), - } -} - // RunResourceService runs a Resource Service for the duration of the test and -// returns a client to interact with it. ACLs will be disabled and only the -// default partition and namespace are available. +// returns a client to interact with it. ACLs will be disabled. func RunResourceService(t *testing.T, registerFns ...func(resource.Registry)) pbresource.ResourceServiceClient { - return RunResourceServiceWithConfig(t, svc.Config{}, registerFns...) -} - -// RunResourceServiceWithConfig runs a ResourceService with caller injectable config to ease mocking dependencies. -// Any nil config field is replaced with a reasonable default with the following behavior: -// -// config.Backend - cannot be configured and must be nil -// config.Registry - empty registry -// config.TenancyBridge - mock provided with only the default partition and namespace -// config.ACLResolver - mock provided with ACLs disabled. Fills entMeta and authzContext with default partition and namespace -func RunResourceServiceWithConfig(t *testing.T, config svc.Config, registerFns ...func(resource.Registry)) pbresource.ResourceServiceClient { t.Helper() - if config.Backend != nil { - panic("backend can not be configured") - } - backend, err := inmem.NewBackend() require.NoError(t, err) ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) go backend.Run(ctx) - config.Backend = backend - - if config.Registry == nil { - config.Registry = resource.NewRegistry() - } + registry := resource.NewRegistry() for _, fn := range registerFns { - fn(config.Registry) + fn(registry) } server := grpc.NewServer() - if config.TenancyBridge == nil { - mockTenancyBridge := &svc.MockTenancyBridge{} - mockTenancyBridge.On("PartitionExists", resource.DefaultPartitionName).Return(true, nil) - mockTenancyBridge.On("PartitionExists", "foo").Return(true, nil) - mockTenancyBridge.On("NamespaceExists", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(true, nil) - mockTenancyBridge.On("PartitionExists", "foo").Return(true, nil) - mockTenancyBridge.On("IsPartitionMarkedForDeletion", resource.DefaultPartitionName).Return(false, nil) - mockTenancyBridge.On("IsPartitionMarkedForDeletion", "foo").Return(false, nil) - mockTenancyBridge.On("IsNamespaceMarkedForDeletion", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(false, nil) - config.TenancyBridge = mockTenancyBridge - } else { - switch config.TenancyBridge.(type) { - case *tenancy.V2TenancyBridge: - err = initTenancy(ctx, backend) - require.NoError(t, err) - } - } - - if config.ACLResolver == nil { - // Provide a resolver which will default partition and namespace when not provided. This is similar to user - // initiated requests. - // - // Controllers under test should be providing full tenancy since they will run with the DANGER_NO_AUTH. - mockACLResolver := &svc.MockACLResolver{} - mockACLResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything). - Return(testutils.ACLsDisabled(t), nil). - Run(func(args mock.Arguments) { - // Caller expecting passed in tokenEntMeta and authorizerContext to be filled in. - tokenEntMeta := args.Get(1).(*acl.EnterpriseMeta) - if tokenEntMeta != nil { - FillEntMeta(tokenEntMeta) - } - - authzContext := args.Get(2).(*acl.AuthorizerContext) - if authzContext != nil { - FillAuthorizerContext(authzContext) - } - }) - config.ACLResolver = mockACLResolver - } - - if config.Logger == nil { - config.Logger = testutil.Logger(t) - } - - svc.NewServer(config).Register(server) + svc.NewServer(svc.Config{ + Backend: backend, + Registry: registry, + Logger: testutil.Logger(t), + ACLResolver: resolver.DANGER_NO_AUTH{}, + }).Register(server) pipe := internal.NewPipeListener() go server.Serve(pipe) @@ -147,14 +54,6 @@ func RunResourceServiceWithConfig(t *testing.T, config svc.Config, registerFns . ) require.NoError(t, err) t.Cleanup(func() { _ = conn.Close() }) - client := pbresource.NewResourceServiceClient(conn) - if config.TenancyBridge != nil { - switch config.TenancyBridge.(type) { - case *tenancy.V2TenancyBridge: - config.TenancyBridge.(*tenancy.V2TenancyBridge).WithClient(client) - } - - } - return client + return pbresource.NewResourceServiceClient(conn) } diff --git a/agent/grpc-external/services/resource/testing/testing_ce.go b/agent/grpc-external/services/resource/testing/testing_ce.go deleted file mode 100644 index da20be3533d44..0000000000000 --- a/agent/grpc-external/services/resource/testing/testing_ce.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package testing - -import ( - "context" - "errors" - "time" - - "github.com/oklog/ulid/v2" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/storage" - "github.com/hashicorp/consul/internal/storage/inmem" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" -) - -func FillEntMeta(entMeta *acl.EnterpriseMeta) { - // nothing to to in CE. -} - -func FillAuthorizerContext(authzContext *acl.AuthorizerContext) { - // nothing to to in CE. -} - -// initTenancy create the base tenancy objects (default/default) -func initTenancy(ctx context.Context, b *inmem.Backend) error { - //TODO(dhiaayachi): This is now called for testing purpose but at some point we need to add something similar - // when bootstrapping a server, probably in the tenancy controllers. - nsData, err := anypb.New(&pbtenancy.Namespace{Description: "default namespace in default partition"}) - if err != nil { - return err - } - nsID := &pbresource.ID{ - Type: pbtenancy.NamespaceType, - Name: resource.DefaultNamespaceName, - Tenancy: resource.DefaultPartitionedTenancy(), - Uid: ulid.Make().String(), - } - read, err := b.Read(ctx, storage.StrongConsistency, nsID) - if err != nil && !errors.Is(err, storage.ErrNotFound) { - return err - } - if read == nil && errors.Is(err, storage.ErrNotFound) { - _, err = b.WriteCAS(ctx, &pbresource.Resource{ - Id: nsID, - Generation: ulid.Make().String(), - Data: nsData, - Metadata: map[string]string{ - "generated_at": time.Now().Format(time.RFC3339), - }, - }) - if err != nil { - return err - } - } - return nil - -} diff --git a/agent/grpc-external/services/resource/watch.go b/agent/grpc-external/services/resource/watch.go index a984194ca2062..35ec14513ac37 100644 --- a/agent/grpc-external/services/resource/watch.go +++ b/agent/grpc-external/services/resource/watch.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -10,27 +10,28 @@ import ( "google.golang.org/grpc/status" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" ) func (s *Server) WatchList(req *pbresource.WatchListRequest, stream pbresource.ResourceService_WatchListServer) error { - reg, err := s.validateWatchListRequest(req) + if err := validateWatchListRequest(req); err != nil { + return err + } + + // check type exists + reg, err := s.resolveType(req.Type) if err != nil { return err } - // v1 ACL subsystem is "wildcard" aware so just pass on through. - entMeta := v2TenancyToV1EntMeta(req.Tenancy) - token := tokenFromContext(stream.Context()) - authz, authzContext, err := s.getAuthorizer(token, entMeta) + authz, err := s.getAuthorizer(tokenFromContext(stream.Context())) if err != nil { return err } - // Check list ACL. - err = reg.ACLs.List(authz, authzContext) + // check acls + err = reg.ACLs.List(authz, req.Tenancy) switch { case acl.IsErrPermissionDenied(err): return status.Error(codes.PermissionDenied, err.Error()) @@ -38,9 +39,6 @@ func (s *Server) WatchList(req *pbresource.WatchListRequest, stream pbresource.R return status.Errorf(codes.Internal, "failed list acl: %v", err) } - // Ensure we're defaulting correctly when request tenancy units are empty. - v1EntMetaToV2Tenancy(reg, entMeta, req.Tenancy) - unversionedType := storage.UnversionedTypeFrom(req.Type) watch, err := s.Backend.WatchList( stream.Context(), @@ -67,17 +65,8 @@ func (s *Server) WatchList(req *pbresource.WatchListRequest, stream pbresource.R continue } - // Need to rebuild authorizer per resource since wildcard inputs may - // result in different tenancies. Consider caching per tenancy if this - // is deemed expensive. - entMeta = v2TenancyToV1EntMeta(event.Resource.Id.Tenancy) - authz, authzContext, err = s.getAuthorizer(token, entMeta) - if err != nil { - return err - } - // filter out items that don't pass read ACLs - err = reg.ACLs.Read(authz, authzContext, event.Resource.Id, event.Resource) + err = reg.ACLs.Read(authz, event.Resource.Id) switch { case acl.IsErrPermissionDenied(err): continue @@ -91,42 +80,15 @@ func (s *Server) WatchList(req *pbresource.WatchListRequest, stream pbresource.R } } -func (s *Server) validateWatchListRequest(req *pbresource.WatchListRequest) (*resource.Registration, error) { +func validateWatchListRequest(req *pbresource.WatchListRequest) error { var field string switch { case req.Type == nil: field = "type" case req.Tenancy == nil: field = "tenancy" + default: + return nil } - - if field != "" { - return nil, status.Errorf(codes.InvalidArgument, "%s is required", field) - } - - // Check type exists. - reg, err := s.resolveType(req.Type) - if err != nil { - return nil, err - } - - if err = checkV2Tenancy(s.UseV2Tenancy, req.Type); err != nil { - return nil, err - } - - if err := validateWildcardTenancy(req.Tenancy, req.NamePrefix); err != nil { - return nil, err - } - - // Error when partition scoped and namespace not empty. - if reg.Scope == resource.ScopePartition && req.Tenancy.Namespace != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "partition scoped type %s cannot have a namespace. got: %s", - resource.ToGVK(req.Type), - req.Tenancy.Namespace, - ) - } - - return reg, nil + return status.Errorf(codes.InvalidArgument, "%s is required", field) } diff --git a/agent/grpc-external/services/resource/watch_test.go b/agent/grpc-external/services/resource/watch_test.go index 5e5590d3f9fdc..95695f295ebd4 100644 --- a/agent/grpc-external/services/resource/watch_test.go +++ b/agent/grpc-external/services/resource/watch_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -7,13 +7,11 @@ import ( "context" "errors" "io" - "strings" "testing" "time" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/grpc-external/testutils" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" @@ -22,67 +20,25 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" ) func TestWatchList_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(*pbresource.WatchListRequest) - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no type": { - modFn: func(req *pbresource.WatchListRequest) { req.Type = nil }, - errContains: "type is required", - }, - "no tenancy": { - modFn: func(req *pbresource.WatchListRequest) { req.Tenancy = nil }, - errContains: "tenancy is required", - }, - "partition mixed case": { - modFn: func(req *pbresource.WatchListRequest) { req.Tenancy.Partition = "Default" }, - errContains: "tenancy.partition invalid", - }, - "partition too long": { - modFn: func(req *pbresource.WatchListRequest) { - req.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errContains: "tenancy.partition invalid", - }, - "namespace mixed case": { - modFn: func(req *pbresource.WatchListRequest) { req.Tenancy.Namespace = "Default" }, - errContains: "tenancy.namespace invalid", - }, - "namespace too long": { - modFn: func(req *pbresource.WatchListRequest) { - req.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errContains: "tenancy.namespace invalid", - }, - "name_prefix mixed case": { - modFn: func(req *pbresource.WatchListRequest) { req.NamePrefix = "Smashing" }, - errContains: "name_prefix invalid", - }, - "partitioned type provides non-empty namespace": { - modFn: func(req *pbresource.WatchListRequest) { - req.Type = demo.TypeV1RecordLabel - req.Tenancy.Namespace = "bad" - }, - errContains: "cannot have a namespace", - }, + testCases := map[string]func(*pbresource.WatchListRequest){ + "no type": func(req *pbresource.WatchListRequest) { req.Type = nil }, + "no tenancy": func(req *pbresource.WatchListRequest) { req.Tenancy = nil }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { req := &pbresource.WatchListRequest{ Type: demo.TypeV2Album, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, } - tc.modFn(req) + modFn(req) stream, err := client.WatchList(testContext(t), req) require.NoError(t, err) @@ -90,7 +46,6 @@ func TestWatchList_InputValidation(t *testing.T) { _, err = stream.Recv() require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -103,7 +58,7 @@ func TestWatchList_TypeNotFound(t *testing.T) { stream, err := client.WatchList(context.Background(), &pbresource.WatchListRequest{ Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, NamePrefix: "", }) require.NoError(t, err) @@ -125,7 +80,7 @@ func TestWatchList_GroupVersionMatches(t *testing.T) { // create a watch stream, err := client.WatchList(ctx, &pbresource.WatchListRequest{ Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, NamePrefix: "", }) require.NoError(t, err) @@ -156,54 +111,6 @@ func TestWatchList_GroupVersionMatches(t *testing.T) { require.Equal(t, pbresource.WatchEvent_OPERATION_DELETE, rsp.Operation) } -func TestWatchList_Tenancy_Defaults_And_Normalization(t *testing.T) { - // Test units of tenancy get lowercased and defaulted correctly when empty. - for desc, tc := range wildcardTenancyCases() { - t.Run(desc, func(t *testing.T) { - ctx := context.Background() - server := testServer(t) - client := testClient(t, server) - demo.RegisterTypes(server.Registry) - - // Create a watch. - stream, err := client.WatchList(ctx, &pbresource.WatchListRequest{ - Type: tc.typ, - Tenancy: tc.tenancy, - NamePrefix: "", - }) - require.NoError(t, err) - rspCh := handleResourceStream(t, stream) - - // Testcase will pick one of recordLabel or artist based on scope of type. - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - // Create and verify upsert event received. - recordLabel, err = server.Backend.WriteCAS(ctx, recordLabel) - require.NoError(t, err) - artist, err = server.Backend.WriteCAS(ctx, artist) - require.NoError(t, err) - - var expected *pbresource.Resource - switch { - case proto.Equal(tc.typ, demo.TypeV1RecordLabel): - expected = recordLabel - case proto.Equal(tc.typ, demo.TypeV2Artist): - expected = artist - default: - require.Fail(t, "unsupported type", tc.typ) - } - - rsp := mustGetResource(t, rspCh) - require.Equal(t, pbresource.WatchEvent_OPERATION_UPSERT, rsp.Operation) - prototest.AssertDeepEqual(t, expected, rsp.Resource) - }) - - } -} - func TestWatchList_GroupVersionMismatch(t *testing.T) { // Given a watch on TypeArtistV1 that only differs from TypeArtistV2 by GroupVersion // When a resource of TypeArtistV2 is created/updated/deleted @@ -218,7 +125,7 @@ func TestWatchList_GroupVersionMismatch(t *testing.T) { // create a watch for TypeArtistV1 stream, err := client.WatchList(ctx, &pbresource.WatchListRequest{ Type: demo.TypeV1Artist, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: demo.TenancyDefault, NamePrefix: "", }) require.NoError(t, err) diff --git a/agent/grpc-external/services/resource/write.go b/agent/grpc-external/services/resource/write.go index 7b1bd8a73d8f5..34799ae8d82ec 100644 --- a/agent/grpc-external/services/resource/write.go +++ b/agent/grpc-external/services/resource/write.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -37,20 +37,31 @@ import ( var errUseWriteStatus = status.Error(codes.InvalidArgument, "resource.status can only be set using the WriteStatus endpoint") func (s *Server) Write(ctx context.Context, req *pbresource.WriteRequest) (*pbresource.WriteResponse, error) { - reg, err := s.validateWriteRequest(req) + if err := validateWriteRequest(req); err != nil { + return nil, err + } + + reg, err := s.resolveType(req.Resource.Id.Type) if err != nil { return nil, err } - v1EntMeta := v2TenancyToV1EntMeta(req.Resource.Id.Tenancy) - authz, authzContext, err := s.getAuthorizer(tokenFromContext(ctx), v1EntMeta) + authz, err := s.getAuthorizer(tokenFromContext(ctx)) if err != nil { return nil, err } - v1EntMetaToV2Tenancy(reg, v1EntMeta, req.Resource.Id.Tenancy) + + // check acls + err = reg.ACLs.Write(authz, req.Resource.Id) + switch { + case acl.IsErrPermissionDenied(err): + return nil, status.Error(codes.PermissionDenied, err.Error()) + case err != nil: + return nil, status.Errorf(codes.Internal, "failed write acl: %v", err) + } // Check the user sent the correct type of data. - if req.Resource.Data != nil && !req.Resource.Data.MessageIs(reg.Proto) { + if !req.Resource.Data.MessageIs(reg.Proto) { got := strings.TrimPrefix(req.Resource.Data.TypeUrl, "type.googleapis.com/") return nil, status.Errorf( @@ -61,31 +72,12 @@ func (s *Server) Write(ctx context.Context, req *pbresource.WriteRequest) (*pbre ) } - if err = reg.Mutate(req.Resource); err != nil { - return nil, status.Errorf(codes.Internal, "failed mutate hook: %v", err.Error()) - } - if err = reg.Validate(req.Resource); err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) } - // ACL check comes before tenancy existence checks to not leak tenancy "existence". - err = reg.ACLs.Write(authz, authzContext, req.Resource) - switch { - case acl.IsErrPermissionDenied(err): - return nil, status.Error(codes.PermissionDenied, err.Error()) - case err != nil: - return nil, status.Errorf(codes.Internal, "failed write acl: %v", err) - } - - // Check tenancy exists for the V2 resource - if err = tenancyExists(reg, s.TenancyBridge, req.Resource.Id.Tenancy, codes.InvalidArgument); err != nil { - return nil, err - } - - // Check tenancy not marked for deletion. - if err = tenancyMarkedForDeletion(reg, s.TenancyBridge, req.Resource.Id.Tenancy); err != nil { - return nil, err + if err = reg.Mutate(req.Resource); err != nil { + return nil, status.Errorf(codes.Internal, "failed mutate hook: %v", err.Error()) } // At the storage backend layer, all writes are CAS operations. @@ -265,48 +257,29 @@ func (s *Server) retryCAS(ctx context.Context, vsn string, cas func() error) err return err } -func (s *Server) validateWriteRequest(req *pbresource.WriteRequest) (*resource.Registration, error) { +func validateWriteRequest(req *pbresource.WriteRequest) error { var field string switch { case req.Resource == nil: field = "resource" case req.Resource.Id == nil: field = "resource.id" + case req.Resource.Data == nil: + field = "resource.data" } if field != "" { - return nil, status.Errorf(codes.InvalidArgument, "%s is required", field) + return status.Errorf(codes.InvalidArgument, "%s is required", field) } if err := validateId(req.Resource.Id, "resource.id"); err != nil { - return nil, err + return err } if req.Resource.Owner != nil { if err := validateId(req.Resource.Owner, "resource.owner"); err != nil { - return nil, err + return err } } - - // Check type exists. - reg, err := s.resolveType(req.Resource.Id.Type) - if err != nil { - return nil, err - } - - if err = checkV2Tenancy(s.UseV2Tenancy, req.Resource.Id.Type); err != nil { - return nil, err - } - - // Check scope - if reg.Scope == resource.ScopePartition && req.Resource.Id.Tenancy.Namespace != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "partition scoped resource %s cannot have a namespace. got: %s", - resource.ToGVK(req.Resource.Id.Type), - req.Resource.Id.Tenancy.Namespace, - ) - } - - return reg, nil + return nil } diff --git a/agent/grpc-external/services/resource/write_status.go b/agent/grpc-external/services/resource/write_status.go index 7009a7fd72bb2..205918e1dc2b7 100644 --- a/agent/grpc-external/services/resource/write_status.go +++ b/agent/grpc-external/services/resource/write_status.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -8,49 +8,25 @@ import ( "errors" "fmt" - "github.com/oklog/ulid/v2" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/oklog/ulid/v2" + "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" ) func (s *Server) WriteStatus(ctx context.Context, req *pbresource.WriteStatusRequest) (*pbresource.WriteStatusResponse, error) { - reg, err := s.validateWriteStatusRequest(req) - if err != nil { - return nil, err - } - - entMeta := v2TenancyToV1EntMeta(req.Id.Tenancy) - authz, authzContext, err := s.getAuthorizer(tokenFromContext(ctx), entMeta) + authz, err := s.getAuthorizer(tokenFromContext(ctx)) if err != nil { return nil, err } - // Apply defaults when tenancy units empty. - v1EntMetaToV2Tenancy(reg, entMeta, req.Id.Tenancy) - - // Check tenancy exists for the V2 resource. Ignore "marked for deletion" since status updates - // should still work regardless. - if err = tenancyExists(reg, s.TenancyBridge, req.Id.Tenancy, codes.InvalidArgument); err != nil { - return nil, err - } - - // Retrieve resource since ACL hook requires it. - existing, err := s.Backend.Read(ctx, storage.EventualConsistency, req.Id) - switch { - case errors.Is(err, storage.ErrNotFound): - return nil, status.Errorf(codes.NotFound, err.Error()) - case err != nil: - return nil, status.Errorf(codes.Internal, "failed read: %v", err) - } - - // Check write ACL. - err = reg.ACLs.Write(authz, authzContext, existing) + // check acls + err = authz.ToAllowAuthorizer().OperatorWriteAllowed(&acl.AuthorizerContext{}) switch { case acl.IsErrPermissionDenied(err): return nil, status.Error(codes.PermissionDenied, err.Error()) @@ -58,6 +34,15 @@ func (s *Server) WriteStatus(ctx context.Context, req *pbresource.WriteStatusReq return nil, status.Errorf(codes.Internal, "failed operator:write allowed acl: %v", err) } + if err := validateWriteStatusRequest(req); err != nil { + return nil, err + } + + _, err = s.resolveType(req.Id.Type) + if err != nil { + return nil, err + } + // At the storage backend layer, all writes are CAS operations. // // See comment in write.go for more information. @@ -113,13 +98,15 @@ func (s *Server) WriteStatus(ctx context.Context, req *pbresource.WriteStatusReq return &pbresource.WriteStatusResponse{Resource: result}, nil } -func (s *Server) validateWriteStatusRequest(req *pbresource.WriteStatusRequest) (*resource.Registration, error) { +func validateWriteStatusRequest(req *pbresource.WriteStatusRequest) error { var field string switch { case req.Id == nil: field = "id" case req.Id.Type == nil: field = "id.type" + case req.Id.Tenancy == nil: + field = "id.tenancy" case req.Id.Name == "": field = "id.name" case req.Id.Uid == "": @@ -156,55 +143,16 @@ func (s *Server) validateWriteStatusRequest(req *pbresource.WriteStatusRequest) } } if field != "" { - return nil, status.Errorf(codes.InvalidArgument, "%s is required", field) + return status.Errorf(codes.InvalidArgument, "%s is required", field) } if req.Status.UpdatedAt != nil { - return nil, status.Error(codes.InvalidArgument, "status.updated_at is automatically set and cannot be provided") + return status.Error(codes.InvalidArgument, "status.updated_at is automatically set and cannot be provided") } if _, err := ulid.ParseStrict(req.Status.ObservedGeneration); err != nil { - return nil, status.Error(codes.InvalidArgument, "status.observed_generation is not valid") - } - - // Better UX: Allow callers to pass in nil tenancy. Defaulting and inheritance of tenancy - // from the request token will take place further down in the call flow. - if req.Id.Tenancy == nil { - req.Id.Tenancy = &pbresource.Tenancy{ - Partition: "", - Namespace: "", - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - PeerName: "local", - } - } - - if err := validateId(req.Id, "id"); err != nil { - return nil, err - } - - for i, condition := range req.Status.Conditions { - if condition.Resource != nil { - if err := validateRef(condition.Resource, fmt.Sprintf("status.conditions[%d].resource", i)); err != nil { - return nil, err - } - } - } - - // Check type exists. - reg, err := s.resolveType(req.Id.Type) - if err != nil { - return nil, err - } - - // Check scope. - if reg.Scope == resource.ScopePartition && req.Id.Tenancy.Namespace != "" { - return nil, status.Errorf( - codes.InvalidArgument, - "partition scoped resource %s cannot have a namespace. got: %s", - resource.ToGVK(req.Id.Type), - req.Id.Tenancy.Namespace, - ) + return status.Error(codes.InvalidArgument, "status.observed_generation is not valid") } - return reg, nil + return nil } diff --git a/agent/grpc-external/services/resource/write_status_test.go b/agent/grpc-external/services/resource/write_status_test.go index 1ddf738632365..aa26330176df7 100644 --- a/agent/grpc-external/services/resource/write_status_test.go +++ b/agent/grpc-external/services/resource/write_status_test.go @@ -1,11 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource import ( "fmt" - "strings" "testing" "github.com/oklog/ulid/v2" @@ -28,7 +27,7 @@ func TestWriteStatus_ACL(t *testing.T) { } testcases := map[string]testCase{ "denied": { - authz: AuthorizerFrom(t, demo.ArtistV2ReadPolicy), + authz: AuthorizerFrom(t, demo.ArtistV2WritePolicy), assertErrFn: func(err error) { require.Error(t, err) require.Equal(t, codes.PermissionDenied.String(), status.Code(err).String()) @@ -46,6 +45,11 @@ func TestWriteStatus_ACL(t *testing.T) { t.Run(desc, func(t *testing.T) { server := testServer(t) client := testClient(t, server) + + mockACLResolver := &MockACLResolver{} + mockACLResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything). + Return(tc.authz, nil) + server.ACLResolver = mockACLResolver demo.RegisterTypes(server.Registry) artist, err := demo.GenerateV2Artist() @@ -55,12 +59,6 @@ func TestWriteStatus_ACL(t *testing.T) { require.NoError(t, err) artist = rsp.Resource - // Defer mocking out authz since above write is necessary to set up the test resource. - mockACLResolver := &MockACLResolver{} - mockACLResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything). - Return(tc.authz, nil) - server.ACLResolver = mockACLResolver - // exercise ACL _, err = client.WriteStatus(testContext(t), validWriteStatusRequest(t, artist)) tc.assertErrFn(err) @@ -71,184 +69,39 @@ func TestWriteStatus_ACL(t *testing.T) { func TestWriteStatus_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) + demo.RegisterTypes(server.Registry) - testCases := map[string]struct { - typ *pbresource.Type - modFn func(req *pbresource.WriteStatusRequest) - errContains string - }{ - "no id": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id = nil }, - errContains: "id is required", - }, - "no type": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Type = nil }, - errContains: "id.type is required", - }, - "no name": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Name = "" }, - errContains: "id.name is required", - }, - "no uid": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Uid = "" }, - errContains: "id.uid is required", - }, - "name mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Name = "U2" }, - errContains: "id.name invalid", - }, - "name too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Id.Name = strings.Repeat("a", resource.MaxNameLength+1) - }, - errContains: "id.name invalid", - }, - "partition mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Partition = "Default" }, - errContains: "id.tenancy.partition invalid", - }, - "partition too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Id.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errContains: "id.tenancy.partition invalid", - }, - "namespace mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Namespace = "Default" }, - errContains: "id.tenancy.namespace invalid", - }, - "namespace too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Id.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errContains: "id.tenancy.namespace invalid", - }, - "no key": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Key = "" }, - errContains: "key is required", - }, - "no status": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status = nil }, - errContains: "status is required", - }, - "no observed generation": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.ObservedGeneration = "" }, - errContains: "status.observed_generation is required", - }, - "bad observed generation": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.ObservedGeneration = "bogus" }, - errContains: "status.observed_generation is not valid", - }, - "no condition type": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Type = "" }, - errContains: "status.conditions[0].type is required", - }, - "no reference type": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Type = nil }, - errContains: "status.conditions[0].resource.type is required", - }, - "no reference tenancy": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Tenancy = nil }, - errContains: "status.conditions[0].resource.tenancy is required", - }, - "no reference name": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Name = "" }, - errContains: "status.conditions[0].resource.name is required", - }, - "reference name mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Name = "U2" }, - errContains: "status.conditions[0].resource.name invalid", - }, - "reference name too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Name = strings.Repeat("r", resource.MaxNameLength+1) - }, - errContains: "status.conditions[0].resource.name invalid", - }, - "reference partition mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Tenancy.Partition = "Default" - }, - errContains: "status.conditions[0].resource.tenancy.partition invalid", - }, - "reference partition too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errContains: "status.conditions[0].resource.tenancy.partition invalid", - }, - "reference namespace mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Tenancy.Namespace = "Default" - }, - errContains: "status.conditions[0].resource.tenancy.namespace invalid", - }, - "reference namespace too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errContains: "status.conditions[0].resource.tenancy.namespace invalid", - }, - "updated at provided": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.UpdatedAt = timestamppb.Now() }, - errContains: "status.updated_at is automatically set and cannot be provided", - }, - "partition scoped type provides namespace in tenancy": { - typ: demo.TypeV1RecordLabel, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Namespace = "bad" }, - errContains: "cannot have a namespace", - }, + testCases := map[string]func(*pbresource.WriteStatusRequest){ + "no id": func(req *pbresource.WriteStatusRequest) { req.Id = nil }, + "no type": func(req *pbresource.WriteStatusRequest) { req.Id.Type = nil }, + "no tenancy": func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy = nil }, + "no name": func(req *pbresource.WriteStatusRequest) { req.Id.Name = "" }, + "no uid": func(req *pbresource.WriteStatusRequest) { req.Id.Uid = "" }, + "no key": func(req *pbresource.WriteStatusRequest) { req.Key = "" }, + "no status": func(req *pbresource.WriteStatusRequest) { req.Status = nil }, + "no observed generation": func(req *pbresource.WriteStatusRequest) { req.Status.ObservedGeneration = "" }, + "bad observed generation": func(req *pbresource.WriteStatusRequest) { req.Status.ObservedGeneration = "bogus" }, + "no condition type": func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Type = "" }, + "no reference type": func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Type = nil }, + "no reference tenancy": func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Tenancy = nil }, + "no reference name": func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Name = "" }, + "updated at provided": func(req *pbresource.WriteStatusRequest) { req.Status.UpdatedAt = timestamppb.Now() }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { - var res *pbresource.Resource - var err error - switch { - case resource.EqualType(demo.TypeV2Artist, tc.typ): - res, err = demo.GenerateV2Artist() - case resource.EqualType(demo.TypeV1RecordLabel, tc.typ): - res, err = demo.GenerateV1RecordLabel("looney-tunes") - default: - t.Fatal("unsupported type", tc.typ) - } + res, err := demo.GenerateV2Artist() require.NoError(t, err) res.Id.Uid = ulid.Make().String() res.Generation = ulid.Make().String() req := validWriteStatusRequest(t, res) - tc.modFn(req) + modFn(req) _, err = client.WriteStatus(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -261,6 +114,7 @@ func TestWriteStatus_Success(t *testing.T) { t.Run(desc, func(t *testing.T) { server := testServer(t) client := testClient(t, server) + demo.RegisterTypes(server.Registry) res, err := demo.GenerateV2Artist() @@ -293,140 +147,6 @@ func TestWriteStatus_Success(t *testing.T) { } } -func TestWriteStatus_Tenancy_Defaults(t *testing.T) { - for desc, tc := range map[string]struct { - scope resource.Scope - modFn func(req *pbresource.WriteStatusRequest) - }{ - "namespaced resource provides nonempty partition and namespace": { - scope: resource.ScopeNamespace, - modFn: func(req *pbresource.WriteStatusRequest) {}, - }, - "namespaced resource inherits tokens partition when empty": { - scope: resource.ScopeNamespace, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Partition = "" }, - }, - "namespaced resource inherits tokens namespace when empty": { - scope: resource.ScopeNamespace, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Namespace = "" }, - }, - "namespaced resource inherits tokens partition and namespace when empty": { - scope: resource.ScopeNamespace, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Id.Tenancy.Partition = "" - req.Id.Tenancy.Namespace = "" - }, - }, - "namespaced resource inherits tokens partition and namespace when tenancy nil": { - scope: resource.ScopeNamespace, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy = nil }, - }, - "partitioned resource provides nonempty partition": { - scope: resource.ScopePartition, - modFn: func(req *pbresource.WriteStatusRequest) {}, - }, - "partitioned resource inherits tokens partition when empty": { - scope: resource.ScopePartition, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Partition = "" }, - }, - } { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - client := testClient(t, server) - demo.RegisterTypes(server.Registry) - - // Pick resource based on scope of type in testcase. - var res *pbresource.Resource - var err error - switch tc.scope { - case resource.ScopeNamespace: - res, err = demo.GenerateV2Artist() - case resource.ScopePartition: - res, err = demo.GenerateV1RecordLabel("looney-tunes") - } - require.NoError(t, err) - - // Write resource so we can update status later. - writeRsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: res}) - require.NoError(t, err) - res = writeRsp.Resource - require.Nil(t, res.Status) - - // Write status with tenancy modded by testcase. - req := validWriteStatusRequest(t, res) - tc.modFn(req) - rsp, err := client.WriteStatus(testContext(t), req) - require.NoError(t, err) - res = rsp.Resource - - // Re-read resource and verify status successfully written (not nil) - _, err = client.Read(testContext(t), &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - res = rsp.Resource - require.NotNil(t, res.Status) - }) - } -} - -func TestWriteStatus_Tenancy_NotFound(t *testing.T) { - for desc, tc := range map[string]struct { - scope resource.Scope - modFn func(req *pbresource.WriteStatusRequest) - errCode codes.Code - errContains string - }{ - "namespaced resource provides nonexistant partition": { - scope: resource.ScopeNamespace, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Partition = "bad" }, - errCode: codes.InvalidArgument, - errContains: "partition", - }, - "namespaced resource provides nonexistant namespace": { - scope: resource.ScopeNamespace, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Namespace = "bad" }, - errCode: codes.InvalidArgument, - errContains: "namespace", - }, - "partitioned resource provides nonexistant partition": { - scope: resource.ScopePartition, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Partition = "bad" }, - errCode: codes.InvalidArgument, - errContains: "partition", - }, - } { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - client := testClient(t, server) - demo.RegisterTypes(server.Registry) - - // Pick resource based on scope of type in testcase. - var res *pbresource.Resource - var err error - switch tc.scope { - case resource.ScopeNamespace: - res, err = demo.GenerateV2Artist() - case resource.ScopePartition: - res, err = demo.GenerateV1RecordLabel("looney-tunes") - } - require.NoError(t, err) - - // Fill in required fields so validation continues until tenancy is checked - req := validWriteStatusRequest(t, res) - req.Id.Uid = ulid.Make().String() - req.Status.ObservedGeneration = ulid.Make().String() - - // Write status with tenancy modded by testcase. - tc.modFn(req) - _, err = client.WriteStatus(testContext(t), req) - - // Verify non-existant tenancy field is the cause of the error. - require.Error(t, err) - require.Equal(t, tc.errCode.String(), status.Code(err).String()) - require.Contains(t, err.Error(), tc.errContains) - }) - } -} - func TestWriteStatus_CASFailure(t *testing.T) { server := testServer(t) client := testClient(t, server) @@ -548,49 +268,24 @@ func TestWriteStatus_NonCASUpdate_Retry(t *testing.T) { func validWriteStatusRequest(t *testing.T, res *pbresource.Resource) *pbresource.WriteStatusRequest { t.Helper() - switch { - case resource.EqualType(res.Id.Type, demo.TypeV2Artist): - album, err := demo.GenerateV2Album(res.Id) - require.NoError(t, err) - return &pbresource.WriteStatusRequest{ - Id: res.Id, - Version: res.Version, - Key: "consul.io/artist-controller", - Status: &pbresource.Status{ - ObservedGeneration: res.Generation, - Conditions: []*pbresource.Condition{ - { - Type: "AlbumCreated", - State: pbresource.Condition_STATE_TRUE, - Reason: "AlbumCreated", - Message: fmt.Sprintf("Album '%s' created", album.Id.Name), - Resource: resource.Reference(album.Id, ""), - }, - }, - }, - } - case resource.EqualType(res.Id.Type, demo.TypeV1RecordLabel): - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - return &pbresource.WriteStatusRequest{ - Id: res.Id, - Version: res.Version, - Key: "consul.io/recordlabel-controller", - Status: &pbresource.Status{ - ObservedGeneration: res.Generation, - Conditions: []*pbresource.Condition{ - { - Type: "ArtistCreated", - State: pbresource.Condition_STATE_TRUE, - Reason: "ArtistCreated", - Message: fmt.Sprintf("Artist '%s' created", artist.Id.Name), - Resource: resource.Reference(artist.Id, ""), - }, + album, err := demo.GenerateV2Album(res.Id) + require.NoError(t, err) + + return &pbresource.WriteStatusRequest{ + Id: res.Id, + Version: res.Version, + Key: "consul.io/artist-controller", + Status: &pbresource.Status{ + ObservedGeneration: res.Generation, + Conditions: []*pbresource.Condition{ + { + Type: "AlbumCreated", + State: pbresource.Condition_STATE_TRUE, + Reason: "AlbumCreated", + Message: fmt.Sprintf("Album '%s' created", album.Id.Name), + Resource: resource.Reference(album.Id, ""), }, }, - } - default: - t.Fatal("unsupported type", res.Id.Type) + }, } - return nil } diff --git a/agent/grpc-external/services/resource/write_test.go b/agent/grpc-external/services/resource/write_test.go index 9f7704b52b97c..4ec25ee26c0c7 100644 --- a/agent/grpc-external/services/resource/write_test.go +++ b/agent/grpc-external/services/resource/write_test.go @@ -1,11 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource import ( "context" - "strings" "sync/atomic" "testing" @@ -17,135 +16,62 @@ import ( "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/consul/acl/resolver" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" pbdemov1 "github.com/hashicorp/consul/proto/private/pbdemo/v1" pbdemov2 "github.com/hashicorp/consul/proto/private/pbdemo/v2" - "github.com/hashicorp/consul/proto/private/prototest" ) func TestWrite_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(artist, recordLabel *pbresource.Resource) *pbresource.Resource - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no resource": { - modFn: func(_, _ *pbresource.Resource) *pbresource.Resource { - return nil - }, - errContains: "resource is required", - }, - "no id": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id = nil - return artist - }, - errContains: "resource.id is required", - }, - "no type": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Type = nil - return artist - }, - errContains: "resource.id.type is required", - }, - "no name": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Name = "" - return artist - }, - errContains: "resource.id.name invalid", - }, - "name is mixed case": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Name = "MixedCaseNotAllowed" - return artist - }, - errContains: "resource.id.name invalid", - }, - "name too long": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Name = strings.Repeat("a", resource.MaxNameLength+1) - return artist - }, - errContains: "resource.id.name invalid", - }, - "wrong data type": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - var err error - artist.Data, err = anypb.New(&pbdemov2.Album{}) - require.NoError(t, err) - return artist - }, - errContains: "resource.data is of wrong type", - }, - "partition is mixed case": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Partition = "Default" - return artist - }, - errContains: "resource.id.tenancy.partition invalid", - }, - "partition too long": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - return artist - }, - errContains: "resource.id.tenancy.partition invalid", - }, - "namespace is mixed case": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Namespace = "Default" - return artist - }, - errContains: "resource.id.tenancy.namespace invalid", - }, - "namespace too long": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - return artist - }, - errContains: "resource.id.tenancy.namespace invalid", - }, - "fail validation hook": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - buffer := &pbdemov2.Artist{} - require.NoError(t, artist.Data.UnmarshalTo(buffer)) - buffer.Name = "" // name cannot be empty - require.NoError(t, artist.Data.MarshalFrom(buffer)) - return artist - }, - errContains: "artist.name required", + testCases := map[string]func(*pbresource.WriteRequest){ + "no resource": func(req *pbresource.WriteRequest) { req.Resource = nil }, + "no id": func(req *pbresource.WriteRequest) { req.Resource.Id = nil }, + "no type": func(req *pbresource.WriteRequest) { req.Resource.Id.Type = nil }, + "no tenancy": func(req *pbresource.WriteRequest) { req.Resource.Id.Tenancy = nil }, + "no name": func(req *pbresource.WriteRequest) { req.Resource.Id.Name = "" }, + "no data": func(req *pbresource.WriteRequest) { req.Resource.Data = nil }, + // clone necessary to not pollute DefaultTenancy + "tenancy partition not default": func(req *pbresource.WriteRequest) { + req.Resource.Id.Tenancy = clone(req.Resource.Id.Tenancy) + req.Resource.Id.Tenancy.Partition = "" + }, + "tenancy namespace not default": func(req *pbresource.WriteRequest) { + req.Resource.Id.Tenancy = clone(req.Resource.Id.Tenancy) + req.Resource.Id.Tenancy.Namespace = "" + }, + "tenancy peername not local": func(req *pbresource.WriteRequest) { + req.Resource.Id.Tenancy = clone(req.Resource.Id.Tenancy) + req.Resource.Id.Tenancy.PeerName = "" + }, + "wrong data type": func(req *pbresource.WriteRequest) { + var err error + req.Resource.Data, err = anypb.New(&pbdemov2.Album{}) + require.NoError(t, err) }, - "partition scope with non-empty namespace": { - modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { - recordLabel.Id.Tenancy.Namespace = "bogus" - return recordLabel - }, - errContains: "cannot have a namespace", + "fail validation hook": func(req *pbresource.WriteRequest) { + artist := &pbdemov2.Artist{} + require.NoError(t, req.Resource.Data.UnmarshalTo(artist)) + artist.Name = "" // name cannot be empty + require.NoError(t, req.Resource.Data.MarshalFrom(artist)) }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { - artist, err := demo.GenerateV2Artist() + res, err := demo.GenerateV2Artist() require.NoError(t, err) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) + req := &pbresource.WriteRequest{Resource: res} + modFn(req) - req := &pbresource.WriteRequest{Resource: tc.modFn(artist, recordLabel)} _, err = client.Write(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -153,6 +79,7 @@ func TestWrite_InputValidation(t *testing.T) { func TestWrite_OwnerValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) + demo.RegisterTypes(server.Registry) type testCase struct { @@ -162,49 +89,37 @@ func TestWrite_OwnerValidation(t *testing.T) { testCases := map[string]testCase{ "no owner type": { modReqFn: func(req *pbresource.WriteRequest) { req.Resource.Owner.Type = nil }, - errorContains: "resource.owner.type is required", + errorContains: "resource.owner.type", }, "no owner tenancy": { modReqFn: func(req *pbresource.WriteRequest) { req.Resource.Owner.Tenancy = nil }, - errorContains: "resource.owner does not exist", + errorContains: "resource.owner.tenancy", }, "no owner name": { modReqFn: func(req *pbresource.WriteRequest) { req.Resource.Owner.Name = "" }, - errorContains: "resource.owner.name invalid", + errorContains: "resource.owner.name", }, - "mixed case owner name": { - modReqFn: func(req *pbresource.WriteRequest) { req.Resource.Owner.Name = strings.ToUpper(req.Resource.Owner.Name) }, - errorContains: "resource.owner.name invalid", - }, - "owner name too long": { + // clone necessary to not pollute DefaultTenancy + "owner tenancy partition not default": { modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Name = strings.Repeat("a", resource.MaxNameLength+1) + req.Resource.Owner.Tenancy = clone(req.Resource.Owner.Tenancy) + req.Resource.Owner.Tenancy.Partition = "" }, - errorContains: "resource.owner.name invalid", + errorContains: "resource.owner.tenancy.partition", }, - "owner partition is mixed case": { + "owner tenancy namespace not default": { modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Tenancy.Partition = "Default" + req.Resource.Owner.Tenancy = clone(req.Resource.Owner.Tenancy) + req.Resource.Owner.Tenancy.Namespace = "" }, - errorContains: "resource.owner.tenancy.partition invalid", + errorContains: "resource.owner.tenancy.namespace", }, - "owner partition too long": { + "owner tenancy peername not local": { modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) + req.Resource.Owner.Tenancy = clone(req.Resource.Owner.Tenancy) + req.Resource.Owner.Tenancy.PeerName = "" }, - errorContains: "resource.owner.tenancy.partition invalid", - }, - "owner namespace is mixed case": { - modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Tenancy.Namespace = "Default" - }, - errorContains: "resource.owner.tenancy.namespace invalid", - }, - "owner namespace too long": { - modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errorContains: "resource.owner.tenancy.namespace invalid", + errorContains: "resource.owner.tenancy.peername", }, } for desc, tc := range testCases { @@ -306,211 +221,20 @@ func TestWrite_Mutate(t *testing.T) { require.Equal(t, pbdemov2.Genre_GENRE_DISCO, artistData.Genre) } -func TestWrite_Create_Success(t *testing.T) { - testCases := map[string]struct { - modFn func(artist, recordLabel *pbresource.Resource) *pbresource.Resource - expectedTenancy *pbresource.Tenancy - }{ - "namespaced resource provides nonempty partition and namespace": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - return artist - }, - expectedTenancy: resource.DefaultNamespacedTenancy(), - }, - "namespaced resource inherits tokens partition when empty": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Partition = "" - return artist - }, - expectedTenancy: resource.DefaultNamespacedTenancy(), - }, - "namespaced resource inherits tokens namespace when empty": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Namespace = "" - return artist - }, - expectedTenancy: resource.DefaultNamespacedTenancy(), - }, - "namespaced resource inherits tokens partition and namespace when empty": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Partition = "" - artist.Id.Tenancy.Namespace = "" - return artist - }, - expectedTenancy: resource.DefaultNamespacedTenancy(), - }, - "namespaced resource inherits tokens partition and namespace when tenancy nil": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy = nil - return artist - }, - expectedTenancy: resource.DefaultNamespacedTenancy(), - }, - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - "namespaced resource defaults peername to local when empty": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.PeerName = "" - return artist - }, - expectedTenancy: resource.DefaultNamespacedTenancy(), - }, - "partitioned resource provides nonempty partition": { - modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { - return recordLabel - }, - expectedTenancy: resource.DefaultPartitionedTenancy(), - }, - "partitioned resource inherits tokens partition when empty": { - modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { - recordLabel.Id.Tenancy.Partition = "" - return recordLabel - }, - expectedTenancy: resource.DefaultPartitionedTenancy(), - }, - "partitioned resource inherits tokens partition when tenancy nil": { - modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { - recordLabel.Id.Tenancy = nil - return recordLabel - }, - expectedTenancy: resource.DefaultPartitionedTenancy(), - }, - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - "partitioned resource defaults peername to local when empty": { - modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { - recordLabel.Id.Tenancy.PeerName = "" - return recordLabel - }, - expectedTenancy: resource.DefaultPartitionedTenancy(), - }, - // TODO(spatel): Add cluster scope tests when we have an actual cluster scoped resource (e.g. partition) - } - for desc, tc := range testCases { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - client := testClient(t, server) - demo.RegisterTypes(server.Registry) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - rsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: tc.modFn(artist, recordLabel)}) - require.NoError(t, err) - require.NotEmpty(t, rsp.Resource.Version, "resource should have version") - require.NotEmpty(t, rsp.Resource.Id.Uid, "resource id should have uid") - require.NotEmpty(t, rsp.Resource.Generation, "resource should have generation") - prototest.AssertDeepEqual(t, tc.expectedTenancy, rsp.Resource.Id.Tenancy) - }) - } -} - -func TestWrite_Create_Tenancy_NotFound(t *testing.T) { - testCases := map[string]struct { - modFn func(artist, recordLabel *pbresource.Resource) *pbresource.Resource - errCode codes.Code - errContains string - }{ - "namespaced resource provides nonexistant partition": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Partition = "boguspartition" - return artist - }, - errCode: codes.InvalidArgument, - errContains: "partition not found", - }, - "namespaced resource provides nonexistant namespace": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Namespace = "bogusnamespace" - return artist - }, - errCode: codes.InvalidArgument, - errContains: "namespace not found", - }, - "partitioned resource provides nonexistant partition": { - modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { - recordLabel.Id.Tenancy.Partition = "boguspartition" - return recordLabel - }, - errCode: codes.InvalidArgument, - errContains: "partition not found", - }, - } - for desc, tc := range testCases { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - client := testClient(t, server) - demo.RegisterTypes(server.Registry) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - _, err = client.Write(testContext(t), &pbresource.WriteRequest{Resource: tc.modFn(artist, recordLabel)}) - require.Error(t, err) - require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.Contains(t, err.Error(), tc.errContains) - }) - } -} - -func TestWrite_Tenancy_MarkedForDeletion(t *testing.T) { - // Verify resource write fails when its partition or namespace is marked for deletion. - testCases := map[string]struct { - modFn func(artist, recordLabel *pbresource.Resource, mockTenancyBridge *MockTenancyBridge) *pbresource.Resource - errContains string - }{ - "namespaced resources partition marked for deletion": { - modFn: func(artist, _ *pbresource.Resource, mockTenancyBridge *MockTenancyBridge) *pbresource.Resource { - mockTenancyBridge.On("IsPartitionMarkedForDeletion", "ap1").Return(true, nil) - return artist - }, - errContains: "partition marked for deletion", - }, - "namespaced resources namespace marked for deletion": { - modFn: func(artist, _ *pbresource.Resource, mockTenancyBridge *MockTenancyBridge) *pbresource.Resource { - mockTenancyBridge.On("IsPartitionMarkedForDeletion", "ap1").Return(false, nil) - mockTenancyBridge.On("IsNamespaceMarkedForDeletion", "ap1", "ns1").Return(true, nil) - return artist - }, - errContains: "namespace marked for deletion", - }, - "partitioned resources partition marked for deletion": { - modFn: func(_, recordLabel *pbresource.Resource, mockTenancyBridge *MockTenancyBridge) *pbresource.Resource { - mockTenancyBridge.On("IsPartitionMarkedForDeletion", "ap1").Return(true, nil) - return recordLabel - }, - errContains: "partition marked for deletion", - }, - } - for desc, tc := range testCases { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - client := testClient(t, server) - demo.RegisterTypes(server.Registry) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - recordLabel.Id.Tenancy.Partition = "ap1" +func TestWrite_ResourceCreation_Success(t *testing.T) { + server := testServer(t) + client := testClient(t, server) - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - artist.Id.Tenancy.Partition = "ap1" - artist.Id.Tenancy.Namespace = "ns1" + demo.RegisterTypes(server.Registry) - mockTenancyBridge := &MockTenancyBridge{} - mockTenancyBridge.On("PartitionExists", "ap1").Return(true, nil) - mockTenancyBridge.On("NamespaceExists", "ap1", "ns1").Return(true, nil) - server.TenancyBridge = mockTenancyBridge + res, err := demo.GenerateV2Artist() + require.NoError(t, err) - _, err = client.Write(testContext(t), &pbresource.WriteRequest{Resource: tc.modFn(artist, recordLabel, mockTenancyBridge)}) - require.Error(t, err) - require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.Contains(t, err.Error(), tc.errContains) - }) - } + rsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: res}) + require.NoError(t, err) + require.NotEmpty(t, rsp.Resource.Version, "resource should have version") + require.NotEmpty(t, rsp.Resource.Id.Uid, "resource id should have uid") + require.NotEmpty(t, rsp.Resource.Generation, "resource should have generation") } func TestWrite_CASUpdate_Success(t *testing.T) { @@ -767,21 +491,6 @@ func TestWrite_NonCASUpdate_Retry(t *testing.T) { require.NoError(t, <-errCh) } -func TestWrite_NoData(t *testing.T) { - server := testServer(t) - client := testClient(t, server) - - demo.RegisterTypes(server.Registry) - - res, err := demo.GenerateV1Concept("jazz") - require.NoError(t, err) - - rsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: res}) - require.NoError(t, err) - require.NotEmpty(t, rsp.Resource.Version) - require.Equal(t, rsp.Resource.Id.Name, "jazz") -} - func TestWrite_Owner_Immutable(t *testing.T) { // Use of proto.Equal(..) in implementation covers all permutations // (nil -> non-nil, non-nil -> nil, owner1 -> owner2) so only the first one diff --git a/agent/grpc-external/services/serverdiscovery/server.go b/agent/grpc-external/services/serverdiscovery/server.go index 99011c6d076ff..477617122120c 100644 --- a/agent/grpc-external/services/serverdiscovery/server.go +++ b/agent/grpc-external/services/serverdiscovery/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package serverdiscovery diff --git a/agent/grpc-external/services/serverdiscovery/server_test.go b/agent/grpc-external/services/serverdiscovery/server_test.go index a9fd65b7cbdce..cac32bd31ee30 100644 --- a/agent/grpc-external/services/serverdiscovery/server_test.go +++ b/agent/grpc-external/services/serverdiscovery/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package serverdiscovery diff --git a/agent/grpc-external/services/serverdiscovery/watch_servers.go b/agent/grpc-external/services/serverdiscovery/watch_servers.go index 94ed7ac58aef6..31a2cb92c8370 100644 --- a/agent/grpc-external/services/serverdiscovery/watch_servers.go +++ b/agent/grpc-external/services/serverdiscovery/watch_servers.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package serverdiscovery diff --git a/agent/grpc-external/services/serverdiscovery/watch_servers_test.go b/agent/grpc-external/services/serverdiscovery/watch_servers_test.go index 0df48f3bb35c4..d58d0be407c3f 100644 --- a/agent/grpc-external/services/serverdiscovery/watch_servers_test.go +++ b/agent/grpc-external/services/serverdiscovery/watch_servers_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package serverdiscovery diff --git a/agent/grpc-external/stats_test.go b/agent/grpc-external/stats_test.go index 3bd5c777cd16d..3328001f332e8 100644 --- a/agent/grpc-external/stats_test.go +++ b/agent/grpc-external/stats_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package external diff --git a/agent/grpc-external/testutils/acl.go b/agent/grpc-external/testutils/acl.go index 72e0897e71fd5..440a837682817 100644 --- a/agent/grpc-external/testutils/acl.go +++ b/agent/grpc-external/testutils/acl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package testutils @@ -84,18 +84,6 @@ func ACLServiceRead(t *testing.T, serviceName string) resolver.Result { } } -func ACLUseProvidedPolicy(t *testing.T, aclPolicy *acl.Policy) resolver.Result { - t.Helper() - - authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{aclPolicy}, nil) - require.NoError(t, err) - - return resolver.Result{ - Authorizer: authz, - ACLIdentity: randomACLIdentity(t), - } -} - func ACLOperatorRead(t *testing.T) resolver.Result { t.Helper() diff --git a/agent/grpc-external/testutils/fsm.go b/agent/grpc-external/testutils/fsm.go index fdec1b109ed36..0e7b645a65ec5 100644 --- a/agent/grpc-external/testutils/fsm.go +++ b/agent/grpc-external/testutils/fsm.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package testutils diff --git a/agent/grpc-external/testutils/server.go b/agent/grpc-external/testutils/server.go index 13cbb985e564e..eecb10bb954f3 100644 --- a/agent/grpc-external/testutils/server.go +++ b/agent/grpc-external/testutils/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package testutils diff --git a/agent/grpc-external/utils.go b/agent/grpc-external/utils.go index 13c84c75c1ce4..b3a3d3d20264a 100644 --- a/agent/grpc-external/utils.go +++ b/agent/grpc-external/utils.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package external diff --git a/agent/grpc-internal/balancer/balancer.go b/agent/grpc-internal/balancer/balancer.go index 884c2a1dec3dc..4941a80873188 100644 --- a/agent/grpc-internal/balancer/balancer.go +++ b/agent/grpc-internal/balancer/balancer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // package balancer implements a custom gRPC load balancer. // diff --git a/agent/grpc-internal/balancer/balancer_test.go b/agent/grpc-internal/balancer/balancer_test.go index f0c6db9f53296..35912aab269a1 100644 --- a/agent/grpc-internal/balancer/balancer_test.go +++ b/agent/grpc-internal/balancer/balancer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package balancer diff --git a/agent/grpc-internal/balancer/registry.go b/agent/grpc-internal/balancer/registry.go index 53b2e6555ac30..f11ea6c8cebeb 100644 --- a/agent/grpc-internal/balancer/registry.go +++ b/agent/grpc-internal/balancer/registry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package balancer diff --git a/agent/grpc-internal/client.go b/agent/grpc-internal/client.go index 1d49bc23cdd31..98a6f1fd81c5d 100644 --- a/agent/grpc-internal/client.go +++ b/agent/grpc-internal/client.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/client_test.go b/agent/grpc-internal/client_test.go index 134a62aa4aae3..a3b99e78ad1b7 100644 --- a/agent/grpc-internal/client_test.go +++ b/agent/grpc-internal/client_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/handler.go b/agent/grpc-internal/handler.go index b0eeaa8a4f0c2..3278d744436f9 100644 --- a/agent/grpc-internal/handler.go +++ b/agent/grpc-internal/handler.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/handler_test.go b/agent/grpc-internal/handler_test.go index 2027c055866de..80c026113d1f5 100644 --- a/agent/grpc-internal/handler_test.go +++ b/agent/grpc-internal/handler_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/listener.go b/agent/grpc-internal/listener.go index a1c226613778c..bcbf121c733e8 100644 --- a/agent/grpc-internal/listener.go +++ b/agent/grpc-internal/listener.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/pipe.go b/agent/grpc-internal/pipe.go index 555f6d2162aa3..188defd085ed9 100644 --- a/agent/grpc-internal/pipe.go +++ b/agent/grpc-internal/pipe.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/pipe_test.go b/agent/grpc-internal/pipe_test.go index f51d1581292b2..e6ce286d1f867 100644 --- a/agent/grpc-internal/pipe_test.go +++ b/agent/grpc-internal/pipe_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/resolver/registry.go b/agent/grpc-internal/resolver/registry.go index aab369c501314..5151cfd46ce0f 100644 --- a/agent/grpc-internal/resolver/registry.go +++ b/agent/grpc-internal/resolver/registry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resolver diff --git a/agent/grpc-internal/resolver/resolver.go b/agent/grpc-internal/resolver/resolver.go index 8d1436bf7aff2..d04f1e657e61f 100644 --- a/agent/grpc-internal/resolver/resolver.go +++ b/agent/grpc-internal/resolver/resolver.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resolver diff --git a/agent/grpc-internal/resolver/resolver_test.go b/agent/grpc-internal/resolver/resolver_test.go index 0914eba147bae..2bd3f24f9936b 100644 --- a/agent/grpc-internal/resolver/resolver_test.go +++ b/agent/grpc-internal/resolver/resolver_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package resolver import ( diff --git a/agent/grpc-internal/server_test.go b/agent/grpc-internal/server_test.go index 12f420979b6ee..83774c712fc6a 100644 --- a/agent/grpc-internal/server_test.go +++ b/agent/grpc-internal/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/services/subscribe/logger.go b/agent/grpc-internal/services/subscribe/logger.go index 11c18f6adfa48..faaa63ff84270 100644 --- a/agent/grpc-internal/services/subscribe/logger.go +++ b/agent/grpc-internal/services/subscribe/logger.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package subscribe diff --git a/agent/grpc-internal/services/subscribe/subscribe.go b/agent/grpc-internal/services/subscribe/subscribe.go index a728b0164c977..08c501b6dd032 100644 --- a/agent/grpc-internal/services/subscribe/subscribe.go +++ b/agent/grpc-internal/services/subscribe/subscribe.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package subscribe diff --git a/agent/grpc-internal/services/subscribe/subscribe_test.go b/agent/grpc-internal/services/subscribe/subscribe_test.go index 910862d4cfbd4..54a267f7c40d1 100644 --- a/agent/grpc-internal/services/subscribe/subscribe_test.go +++ b/agent/grpc-internal/services/subscribe/subscribe_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package subscribe diff --git a/agent/grpc-internal/stats_test.go b/agent/grpc-internal/stats_test.go index d14c4c46bc451..5da26f512ccbe 100644 --- a/agent/grpc-internal/stats_test.go +++ b/agent/grpc-internal/stats_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-internal/tracker.go b/agent/grpc-internal/tracker.go index 251fe48f95399..a313f88e53501 100644 --- a/agent/grpc-internal/tracker.go +++ b/agent/grpc-internal/tracker.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package internal diff --git a/agent/grpc-middleware/auth_interceptor.go b/agent/grpc-middleware/auth_interceptor.go index af85e5c6f94c2..0472b71f00ece 100644 --- a/agent/grpc-middleware/auth_interceptor.go +++ b/agent/grpc-middleware/auth_interceptor.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/grpc-middleware/auth_interceptor_test.go b/agent/grpc-middleware/auth_interceptor_test.go index 0c447499bcb2f..18f9334cc9b80 100644 --- a/agent/grpc-middleware/auth_interceptor_test.go +++ b/agent/grpc-middleware/auth_interceptor_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/grpc-middleware/handshake.go b/agent/grpc-middleware/handshake.go index 893421e0e7f1b..82b352bb5ac30 100644 --- a/agent/grpc-middleware/handshake.go +++ b/agent/grpc-middleware/handshake.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/grpc-middleware/handshake_test.go b/agent/grpc-middleware/handshake_test.go index 178451a31464c..f987a6689af22 100644 --- a/agent/grpc-middleware/handshake_test.go +++ b/agent/grpc-middleware/handshake_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/grpc-middleware/rate.go b/agent/grpc-middleware/rate.go index bdb63cd244a97..6f84fd36c16e6 100644 --- a/agent/grpc-middleware/rate.go +++ b/agent/grpc-middleware/rate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/grpc-middleware/rate_test.go b/agent/grpc-middleware/rate_test.go index 16c84734a9edd..0a71d232465cf 100644 --- a/agent/grpc-middleware/rate_test.go +++ b/agent/grpc-middleware/rate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/grpc-middleware/recovery.go b/agent/grpc-middleware/recovery.go index 04b918ee9b3a2..cf1cbabe4e085 100644 --- a/agent/grpc-middleware/recovery.go +++ b/agent/grpc-middleware/recovery.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/grpc-middleware/stats.go b/agent/grpc-middleware/stats.go index a6bf1d2c59bec..564d14a844b95 100644 --- a/agent/grpc-middleware/stats.go +++ b/agent/grpc-middleware/stats.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/grpc-middleware/testutil/fake_sink.go b/agent/grpc-middleware/testutil/fake_sink.go index be7623c774a2c..c121481ee24fb 100644 --- a/agent/grpc-middleware/testutil/fake_sink.go +++ b/agent/grpc-middleware/testutil/fake_sink.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package testutil diff --git a/agent/grpc-middleware/testutil/testservice/buf.gen.yaml b/agent/grpc-middleware/testutil/testservice/buf.gen.yaml index 8d8a6c7dbfc09..b8ba317a333a9 100644 --- a/agent/grpc-middleware/testutil/testservice/buf.gen.yaml +++ b/agent/grpc-middleware/testutil/testservice/buf.gen.yaml @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 version: v1 managed: diff --git a/agent/grpc-middleware/testutil/testservice/fake_service.go b/agent/grpc-middleware/testutil/testservice/fake_service.go index ca21d286f0b35..4428e173740bb 100644 --- a/agent/grpc-middleware/testutil/testservice/fake_service.go +++ b/agent/grpc-middleware/testutil/testservice/fake_service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package testservice diff --git a/agent/grpc-middleware/testutil/testservice/simple.pb.go b/agent/grpc-middleware/testutil/testservice/simple.pb.go index b4f664bf1ca73..18022b3dad3d1 100644 --- a/agent/grpc-middleware/testutil/testservice/simple.pb.go +++ b/agent/grpc-middleware/testutil/testservice/simple.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/agent/grpc-middleware/testutil/testservice/simple.proto b/agent/grpc-middleware/testutil/testservice/simple.proto index d005a45aa1138..c8ce3d58118d3 100644 --- a/agent/grpc-middleware/testutil/testservice/simple.proto +++ b/agent/grpc-middleware/testutil/testservice/simple.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/agent/hcp/bootstrap/bootstrap.go b/agent/hcp/bootstrap/bootstrap.go index 8e544bdec3128..191859ea002b4 100644 --- a/agent/hcp/bootstrap/bootstrap.go +++ b/agent/hcp/bootstrap/bootstrap.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package bootstrap handles bootstrapping an agent's config from HCP. It must be a // separate package from other HCP components because it has a dependency on diff --git a/agent/hcp/bootstrap/bootstrap_test.go b/agent/hcp/bootstrap/bootstrap_test.go index b475223ff8cf3..74b57e5f50abd 100644 --- a/agent/hcp/bootstrap/bootstrap_test.go +++ b/agent/hcp/bootstrap/bootstrap_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package bootstrap import ( diff --git a/agent/hcp/bootstrap/testing.go b/agent/hcp/bootstrap/testing.go index f073d17183444..a10a5d2bc8add 100644 --- a/agent/hcp/bootstrap/testing.go +++ b/agent/hcp/bootstrap/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bootstrap diff --git a/agent/hcp/client/client.go b/agent/hcp/client/client.go index c0526c0e4acf0..f04767e983c7b 100644 --- a/agent/hcp/client/client.go +++ b/agent/hcp/client/client.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package client diff --git a/agent/hcp/client/client_test.go b/agent/hcp/client/client_test.go index 5571630ad45a3..d4bae2ae4cb52 100644 --- a/agent/hcp/client/client_test.go +++ b/agent/hcp/client/client_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package client import ( diff --git a/agent/hcp/client/metrics_client.go b/agent/hcp/client/metrics_client.go index b3c1c6a6b3dc8..3c5b5c4fb9d69 100644 --- a/agent/hcp/client/metrics_client.go +++ b/agent/hcp/client/metrics_client.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package client import ( diff --git a/agent/hcp/client/metrics_client_test.go b/agent/hcp/client/metrics_client_test.go index 20a5f010ec4cd..4119e326e9dc0 100644 --- a/agent/hcp/client/metrics_client_test.go +++ b/agent/hcp/client/metrics_client_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package client import ( diff --git a/agent/hcp/client/mock_CloudConfig.go b/agent/hcp/client/mock_CloudConfig.go index 574f83e55fd59..5f2ef50046d70 100644 --- a/agent/hcp/client/mock_CloudConfig.go +++ b/agent/hcp/client/mock_CloudConfig.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package client import ( diff --git a/agent/hcp/client/telemetry_config.go b/agent/hcp/client/telemetry_config.go index 0745f1b7c6197..55c2264380306 100644 --- a/agent/hcp/client/telemetry_config.go +++ b/agent/hcp/client/telemetry_config.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package client import ( @@ -20,7 +17,7 @@ import ( var ( // defaultMetricFilters is a regex that matches all metric names. - DefaultMetricFilters = regexp.MustCompile(".+") + defaultMetricFilters = regexp.MustCompile(".+") // Validation errors for AgentTelemetryConfigOK response. errMissingPayload = errors.New("missing payload") @@ -29,7 +26,6 @@ var ( errMissingMetricsConfig = errors.New("missing metrics config") errInvalidRefreshInterval = errors.New("invalid refresh interval") errInvalidEndpoint = errors.New("invalid metrics endpoint") - errEmptyEndpoint = errors.New("empty metrics endpoint") ) // TelemetryConfig contains configuration for telemetry data forwarded by Consul servers @@ -44,7 +40,6 @@ type MetricsConfig struct { Labels map[string]string Filters *regexp.Regexp Endpoint *url.URL - Disabled bool } // RefreshConfig contains configuration for the periodic fetch of configuration from HCP. @@ -52,6 +47,11 @@ type RefreshConfig struct { RefreshInterval time.Duration } +// MetricsEnabled returns true if metrics export is enabled, i.e. a valid metrics endpoint exists. +func (t *TelemetryConfig) MetricsEnabled() bool { + return t.MetricsConfig.Endpoint != nil +} + // validateAgentTelemetryConfigPayload ensures the returned payload from HCP is valid. func validateAgentTelemetryConfigPayload(resp *hcptelemetry.AgentTelemetryConfigOK) error { if resp.Payload == nil { @@ -83,7 +83,7 @@ func convertAgentTelemetryResponse(ctx context.Context, resp *hcptelemetry.Agent telemetryConfig := resp.Payload.TelemetryConfig metricsEndpoint, err := convertMetricEndpoint(telemetryConfig.Endpoint, telemetryConfig.Metrics.Endpoint) if err != nil { - return nil, err + return nil, errInvalidEndpoint } metricsFilters := convertMetricFilters(ctx, telemetryConfig.Metrics.IncludeList) @@ -94,7 +94,6 @@ func convertAgentTelemetryResponse(ctx context.Context, resp *hcptelemetry.Agent Endpoint: metricsEndpoint, Labels: metricLabels, Filters: metricsFilters, - Disabled: telemetryConfig.Metrics.Disabled, }, RefreshConfig: &RefreshConfig{ RefreshInterval: refreshInterval, @@ -112,8 +111,9 @@ func convertMetricEndpoint(telemetryEndpoint string, metricsEndpoint string) (*u endpoint = metricsEndpoint } + // If endpoint is empty, server not registered with CCM, no error returned. if endpoint == "" { - return nil, errEmptyEndpoint + return nil, nil } // Endpoint from CTW has no metrics path, so it must be added. @@ -142,7 +142,7 @@ func convertMetricFilters(ctx context.Context, payloadFilters []string) *regexp. if len(validFilters) == 0 { logger.Error("no valid filters") - return DefaultMetricFilters + return defaultMetricFilters } // Combine the valid regex strings with OR. @@ -150,7 +150,7 @@ func convertMetricFilters(ctx context.Context, payloadFilters []string) *regexp. composedRegex, err := regexp.Compile(finalRegex) if err != nil { logger.Error("failed to compile final regex", "error", err) - return DefaultMetricFilters + return defaultMetricFilters } return composedRegex diff --git a/agent/hcp/client/telemetry_config_test.go b/agent/hcp/client/telemetry_config_test.go index d43024400779a..42d3ee649802a 100644 --- a/agent/hcp/client/telemetry_config_test.go +++ b/agent/hcp/client/telemetry_config_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package client import ( @@ -88,6 +85,7 @@ func TestConvertAgentTelemetryResponse(t *testing.T) { resp *consul_telemetry_service.AgentTelemetryConfigOK expectedTelemetryCfg *TelemetryConfig wantErr error + expectedEnabled bool }{ "success": { resp: &consul_telemetry_service.AgentTelemetryConfigOK{ @@ -114,6 +112,34 @@ func TestConvertAgentTelemetryResponse(t *testing.T) { RefreshInterval: 2 * time.Second, }, }, + expectedEnabled: true, + }, + "successNoEndpoint": { + resp: &consul_telemetry_service.AgentTelemetryConfigOK{ + Payload: &models.HashicorpCloudConsulTelemetry20230414AgentTelemetryConfigResponse{ + TelemetryConfig: &models.HashicorpCloudConsulTelemetry20230414TelemetryConfig{ + Endpoint: "", + Labels: map[string]string{"test": "test"}, + Metrics: &models.HashicorpCloudConsulTelemetry20230414TelemetryMetricsConfig{ + IncludeList: []string{"test", "consul"}, + }, + }, + RefreshConfig: &models.HashicorpCloudConsulTelemetry20230414RefreshConfig{ + RefreshInterval: "2s", + }, + }, + }, + expectedTelemetryCfg: &TelemetryConfig{ + MetricsConfig: &MetricsConfig{ + Endpoint: nil, + Labels: map[string]string{"test": "test"}, + Filters: validTestFilters, + }, + RefreshConfig: &RefreshConfig{ + RefreshInterval: 2 * time.Second, + }, + }, + expectedEnabled: false, }, "successBadFilters": { resp: &consul_telemetry_service.AgentTelemetryConfigOK{ @@ -134,12 +160,13 @@ func TestConvertAgentTelemetryResponse(t *testing.T) { MetricsConfig: &MetricsConfig{ Endpoint: validTestURL, Labels: map[string]string{"test": "test"}, - Filters: DefaultMetricFilters, + Filters: defaultMetricFilters, }, RefreshConfig: &RefreshConfig{ RefreshInterval: 2 * time.Second, }, }, + expectedEnabled: true, }, "errorsWithInvalidRefreshInterval": { resp: &consul_telemetry_service.AgentTelemetryConfigOK{ @@ -179,6 +206,7 @@ func TestConvertAgentTelemetryResponse(t *testing.T) { } require.NoError(t, err) require.Equal(t, tc.expectedTelemetryCfg, telemetryCfg) + require.Equal(t, tc.expectedEnabled, telemetryCfg.MetricsEnabled()) }) } } @@ -200,10 +228,10 @@ func TestConvertMetricEndpoint(t *testing.T) { override: "https://override.com", expected: "https://override.com/v1/metrics", }, - "errorWithEmptyEndpoints": { + "noErrorWithEmptyEndpoints": { endpoint: "", override: "", - wantErr: errEmptyEndpoint, + expected: "", }, "errorWithInvalidURL": { endpoint: " ", @@ -221,6 +249,12 @@ func TestConvertMetricEndpoint(t *testing.T) { return } + if tc.expected == "" { + require.Nil(t, u) + require.NoError(t, err) + return + } + require.NotNil(t, u) require.NoError(t, err) require.Equal(t, tc.expected, u.String()) @@ -240,13 +274,13 @@ func TestConvertMetricFilters(t *testing.T) { }{ "badFilterRegex": { filters: []string{"(*LF)"}, - expectedRegexString: DefaultMetricFilters.String(), + expectedRegexString: defaultMetricFilters.String(), matches: []string{"consul.raft.peers", "consul.mem.heap_size"}, wantMatch: true, }, "emptyRegex": { filters: []string{}, - expectedRegexString: DefaultMetricFilters.String(), + expectedRegexString: defaultMetricFilters.String(), matches: []string{"consul.raft.peers", "consul.mem.heap_size"}, wantMatch: true, }, diff --git a/agent/hcp/config/config.go b/agent/hcp/config/config.go index 59977ef46f37d..319c39e40e94c 100644 --- a/agent/hcp/config/config.go +++ b/agent/hcp/config/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/agent/hcp/deps.go b/agent/hcp/deps.go index 7bf384747dbd3..ab8288e344d11 100644 --- a/agent/hcp/deps.go +++ b/agent/hcp/deps.go @@ -1,24 +1,24 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package hcp import ( "context" "fmt" + "time" "github.com/armon/go-metrics" - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/agent/hcp/client" + hcpclient "github.com/hashicorp/consul/agent/hcp/client" "github.com/hashicorp/consul/agent/hcp/config" "github.com/hashicorp/consul/agent/hcp/scada" "github.com/hashicorp/consul/agent/hcp/telemetry" + "github.com/hashicorp/go-hclog" ) // Deps contains the interfaces that the rest of Consul core depends on for HCP integration. type Deps struct { - Client client.Client + Client hcpclient.Client Provider scada.Provider Sink metrics.MetricSink } @@ -27,7 +27,7 @@ func NewDeps(cfg config.CloudConfig, logger hclog.Logger) (Deps, error) { ctx := context.Background() ctx = hclog.WithContext(ctx, logger) - hcpClient, err := client.NewClient(cfg) + client, err := hcpclient.NewClient(cfg) if err != nil { return Deps{}, fmt.Errorf("failed to init client: %w", err) } @@ -37,33 +37,50 @@ func NewDeps(cfg config.CloudConfig, logger hclog.Logger) (Deps, error) { return Deps{}, fmt.Errorf("failed to init scada: %w", err) } - metricsClient, err := client.NewMetricsClient(ctx, &cfg) + metricsClient, err := hcpclient.NewMetricsClient(ctx, &cfg) if err != nil { logger.Error("failed to init metrics client", "error", err) return Deps{}, fmt.Errorf("failed to init metrics client: %w", err) } - sink, err := sink(ctx, metricsClient, NewHCPProvider(ctx, hcpClient)) + sink, err := sink(ctx, client, metricsClient) if err != nil { // Do not prevent server start if sink init fails, only log error. logger.Error("failed to init sink", "error", err) } return Deps{ - Client: hcpClient, + Client: client, Provider: provider, Sink: sink, }, nil } // sink initializes an OTELSink which forwards Consul metrics to HCP. +// The sink is only initialized if the server is registered with the management plane (CCM). // This step should not block server initialization, errors are returned, only to be logged. func sink( ctx context.Context, + hcpClient hcpclient.Client, metricsClient telemetry.MetricsClient, - cfgProvider *hcpProviderImpl, ) (metrics.MetricSink, error) { - logger := hclog.FromContext(ctx) + logger := hclog.FromContext(ctx).Named("sink") + reqCtx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + telemetryCfg, err := hcpClient.FetchTelemetryConfig(reqCtx) + if err != nil { + return nil, fmt.Errorf("failed to fetch telemetry config: %w", err) + } + + if !telemetryCfg.MetricsEnabled() { + return nil, nil + } + + cfgProvider, err := NewHCPProvider(ctx, hcpClient, telemetryCfg) + if err != nil { + return nil, fmt.Errorf("failed to init config provider: %w", err) + } reader := telemetry.NewOTELReader(metricsClient, cfgProvider) sinkOpts := &telemetry.OTELSinkOpts{ @@ -73,7 +90,7 @@ func sink( sink, err := telemetry.NewOTELSink(ctx, sinkOpts) if err != nil { - return nil, fmt.Errorf("failed to create OTELSink: %w", err) + return nil, fmt.Errorf("failed create OTELSink: %w", err) } logger.Debug("initialized HCP metrics sink") diff --git a/agent/hcp/deps_test.go b/agent/hcp/deps_test.go index 7375dad68cb76..8bab66bac3f3c 100644 --- a/agent/hcp/deps_test.go +++ b/agent/hcp/deps_test.go @@ -1,14 +1,17 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package hcp import ( "context" + "fmt" + "net/url" + "regexp" "testing" + "time" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/agent/hcp/client" "github.com/hashicorp/consul/agent/hcp/telemetry" ) @@ -18,11 +21,79 @@ type mockMetricsClient struct { func TestSink(t *testing.T) { t.Parallel() + for name, test := range map[string]struct { + expect func(*client.MockClient) + wantErr string + expectedSink bool + }{ + "success": { + expect: func(mockClient *client.MockClient) { + u, _ := url.Parse("https://test.com/v1/metrics") + filters, _ := regexp.Compile("test") + mt := mockTelemetryConfig(1*time.Second, u, filters) + mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mt, nil) + }, + expectedSink: true, + }, + "noSinkWhenFetchTelemetryConfigFails": { + expect: func(mockClient *client.MockClient) { + mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(nil, fmt.Errorf("fetch failed")) + }, + wantErr: "failed to fetch telemetry config", + }, + "noSinkWhenServerNotRegisteredWithCCM": { + expect: func(mockClient *client.MockClient) { + mt := mockTelemetryConfig(1*time.Second, nil, nil) + mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mt, nil) + }, + }, + "noSinkWhenTelemetryConfigProviderInitFails": { + expect: func(mockClient *client.MockClient) { + u, _ := url.Parse("https://test.com/v1/metrics") + // Bad refresh interval forces ConfigProvider creation failure. + mt := mockTelemetryConfig(0*time.Second, u, nil) + mockClient.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mt, nil) + }, + wantErr: "failed to init config provider", + }, + } { + test := test + t.Run(name, func(t *testing.T) { + t.Parallel() + c := client.NewMockClient(t) + mc := mockMetricsClient{} + + test.expect(c) + ctx := context.Background() + + s, err := sink(ctx, c, mc) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - s, err := sink(ctx, mockMetricsClient{}, &hcpProviderImpl{}) + if test.wantErr != "" { + require.NotNil(t, err) + require.Contains(t, err.Error(), test.wantErr) + require.Nil(t, s) + return + } + + if !test.expectedSink { + require.Nil(t, s) + require.Nil(t, err) + return + } + + require.NotNil(t, s) + }) + } +} - require.NotNil(t, s) - require.NoError(t, err) +func mockTelemetryConfig(refreshInterval time.Duration, metricsEndpoint *url.URL, filters *regexp.Regexp) *client.TelemetryConfig { + return &client.TelemetryConfig{ + MetricsConfig: &client.MetricsConfig{ + Endpoint: metricsEndpoint, + Filters: filters, + }, + RefreshConfig: &client.RefreshConfig{ + RefreshInterval: refreshInterval, + }, + } } diff --git a/agent/hcp/discover/discover.go b/agent/hcp/discover/discover.go index 981400c38b478..12024b7dd6a0b 100644 --- a/agent/hcp/discover/discover.go +++ b/agent/hcp/discover/discover.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package discover diff --git a/agent/hcp/manager.go b/agent/hcp/manager.go index a3664b0608dfe..0dc9db95da295 100644 --- a/agent/hcp/manager.go +++ b/agent/hcp/manager.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package hcp diff --git a/agent/hcp/manager_test.go b/agent/hcp/manager_test.go index 8432e63ed5288..48ace166618bf 100644 --- a/agent/hcp/manager_test.go +++ b/agent/hcp/manager_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package hcp diff --git a/agent/hcp/scada/capabilities.go b/agent/hcp/scada/capabilities.go index bbb6ea6266dc3..c18192ae6e94a 100644 --- a/agent/hcp/scada/capabilities.go +++ b/agent/hcp/scada/capabilities.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package scada diff --git a/agent/hcp/scada/scada.go b/agent/hcp/scada/scada.go index 151e1b6862efa..5aba819bda499 100644 --- a/agent/hcp/scada/scada.go +++ b/agent/hcp/scada/scada.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package scada diff --git a/agent/hcp/telemetry/custom_metrics.go b/agent/hcp/telemetry/custom_metrics.go index 39df765b9204b..d691dccde2078 100644 --- a/agent/hcp/telemetry/custom_metrics.go +++ b/agent/hcp/telemetry/custom_metrics.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry // Keys for custom Go Metrics metrics emitted only for the OTEL diff --git a/agent/hcp/telemetry/doc.go b/agent/hcp/telemetry/doc.go index d982a37c0f3e5..4ef18f39bd309 100644 --- a/agent/hcp/telemetry/doc.go +++ b/agent/hcp/telemetry/doc.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - // Package telemetry implements functionality to collect, aggregate, convert and export // telemetry data in OpenTelemetry Protocol (OTLP) format. // diff --git a/agent/hcp/telemetry/gauge_store.go b/agent/hcp/telemetry/gauge_store.go index bb7030dae852b..76dfb78066683 100644 --- a/agent/hcp/telemetry/gauge_store.go +++ b/agent/hcp/telemetry/gauge_store.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry import ( diff --git a/agent/hcp/telemetry/gauge_store_test.go b/agent/hcp/telemetry/gauge_store_test.go index 4ccac624dbd99..1171ee379c325 100644 --- a/agent/hcp/telemetry/gauge_store_test.go +++ b/agent/hcp/telemetry/gauge_store_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry import ( diff --git a/agent/hcp/telemetry/otel_exporter.go b/agent/hcp/telemetry/otel_exporter.go index 050d5660668d2..ba92d4419157a 100644 --- a/agent/hcp/telemetry/otel_exporter.go +++ b/agent/hcp/telemetry/otel_exporter.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry import ( @@ -23,9 +20,7 @@ type MetricsClient interface { // EndpointProvider provides the endpoint where metrics are exported to by the OTELExporter. // EndpointProvider exposes the GetEndpoint() interface method to fetch the endpoint. // This abstraction layer offers flexibility, in particular for dynamic configuration or changes to the endpoint. -// The OTELExporter calls the Disabled interface to verify that it should actually export metrics. type EndpointProvider interface { - Disabled GetEndpoint() *url.URL } @@ -70,10 +65,6 @@ func (e *otelExporter) Aggregation(kind metric.InstrumentKind) aggregation.Aggre // Export serializes and transmits metric data to a receiver. func (e *otelExporter) Export(ctx context.Context, metrics *metricdata.ResourceMetrics) error { - if e.endpointProvider.IsDisabled() { - return nil - } - endpoint := e.endpointProvider.GetEndpoint() if endpoint == nil { return nil diff --git a/agent/hcp/telemetry/otel_exporter_test.go b/agent/hcp/telemetry/otel_exporter_test.go index ebe6486abca85..704817f6407d2 100644 --- a/agent/hcp/telemetry/otel_exporter_test.go +++ b/agent/hcp/telemetry/otel_exporter_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry import ( @@ -34,11 +31,9 @@ func (m *mockMetricsClient) ExportMetrics(ctx context.Context, protoMetrics *met type mockEndpointProvider struct { endpoint *url.URL - disabled bool } func (m *mockEndpointProvider) GetEndpoint() *url.URL { return m.endpoint } -func (m *mockEndpointProvider) IsDisabled() bool { return m.disabled } func TestTemporality(t *testing.T) { t.Parallel() @@ -82,20 +77,13 @@ func TestExport(t *testing.T) { client MetricsClient provider EndpointProvider }{ - "earlyReturnDisabledProvider": { - client: &mockMetricsClient{}, - provider: &mockEndpointProvider{ - disabled: true, - }, - }, "earlyReturnWithoutEndpoint": { client: &mockMetricsClient{}, provider: &mockEndpointProvider{}, }, "earlyReturnWithoutScopeMetrics": { - client: &mockMetricsClient{}, - metrics: mutateMetrics(nil), - provider: &mockEndpointProvider{}, + client: &mockMetricsClient{}, + metrics: mutateMetrics(nil), }, "earlyReturnWithoutMetrics": { client: &mockMetricsClient{}, @@ -103,7 +91,6 @@ func TestExport(t *testing.T) { {Metrics: []metricdata.Metrics{}}, }, ), - provider: &mockEndpointProvider{}, }, "errorWithExportFailure": { client: &mockMetricsClient{ @@ -120,9 +107,6 @@ func TestExport(t *testing.T) { }, }, ), - provider: &mockEndpointProvider{ - endpoint: &url.URL{}, - }, wantErr: "failed to export metrics", }, } { diff --git a/agent/hcp/telemetry/otel_sink.go b/agent/hcp/telemetry/otel_sink.go index 12aae982016c2..a35b1827d60c7 100644 --- a/agent/hcp/telemetry/otel_sink.go +++ b/agent/hcp/telemetry/otel_sink.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry import ( @@ -36,15 +33,8 @@ const ( defaultExportTimeout = 30 * time.Second ) -// Disabled should be implemented to turn on/off metrics processing -type Disabled interface { - // IsDisabled() can return true disallow the sink from accepting metrics. - IsDisabled() bool -} - // ConfigProvider is required to provide custom metrics processing. type ConfigProvider interface { - Disabled // GetLabels should return a set of OTEL attributes added by default all metrics. GetLabels() map[string]string @@ -154,11 +144,8 @@ func (o *OTELSink) IncrCounter(key []string, val float32) { // AddSampleWithLabels emits a Consul gauge metric that gets // registed by an OpenTelemetry Histogram instrument. func (o *OTELSink) SetGaugeWithLabels(key []string, val float32, labels []gometrics.Label) { - if o.cfgProvider.IsDisabled() { - return - } - k := o.flattenKey(key) + if !o.allowedMetric(k) { return } @@ -185,11 +172,8 @@ func (o *OTELSink) SetGaugeWithLabels(key []string, val float32, labels []gometr // AddSampleWithLabels emits a Consul sample metric that gets registed by an OpenTelemetry Histogram instrument. func (o *OTELSink) AddSampleWithLabels(key []string, val float32, labels []gometrics.Label) { - if o.cfgProvider.IsDisabled() { - return - } - k := o.flattenKey(key) + if !o.allowedMetric(k) { return } @@ -214,11 +198,8 @@ func (o *OTELSink) AddSampleWithLabels(key []string, val float32, labels []gomet // IncrCounterWithLabels emits a Consul counter metric that gets registed by an OpenTelemetry Histogram instrument. func (o *OTELSink) IncrCounterWithLabels(key []string, val float32, labels []gometrics.Label) { - if o.cfgProvider.IsDisabled() { - return - } - k := o.flattenKey(key) + if !o.allowedMetric(k) { return } diff --git a/agent/hcp/telemetry/otel_sink_test.go b/agent/hcp/telemetry/otel_sink_test.go index 683f33a3a40d6..509dde299d627 100644 --- a/agent/hcp/telemetry/otel_sink_test.go +++ b/agent/hcp/telemetry/otel_sink_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry import ( @@ -21,9 +18,8 @@ import ( ) type mockConfigProvider struct { - filter *regexp.Regexp - labels map[string]string - disabled bool + filter *regexp.Regexp + labels map[string]string } func (m *mockConfigProvider) GetLabels() map[string]string { @@ -34,10 +30,6 @@ func (m *mockConfigProvider) GetFilters() *regexp.Regexp { return m.filter } -func (m *mockConfigProvider) IsDisabled() bool { - return m.disabled -} - var ( expectedResource = resource.NewSchemaless() @@ -228,29 +220,6 @@ func TestOTELSink(t *testing.T) { isSame(t, expectedSinkMetrics, collected) } -func TestOTELSinkDisabled(t *testing.T) { - reader := metric.NewManualReader() - ctx := context.Background() - - sink, err := NewOTELSink(ctx, &OTELSinkOpts{ - ConfigProvider: &mockConfigProvider{ - filter: regexp.MustCompile("raft"), - disabled: true, - }, - Reader: reader, - }) - require.NoError(t, err) - - sink.SetGauge([]string{"consul", "raft", "gauge"}, 1) - sink.IncrCounter([]string{"consul", "raft", "counter"}, 1) - sink.AddSample([]string{"consul", "raft", "sample"}, 1) - - var collected metricdata.ResourceMetrics - err = reader.Collect(ctx, &collected) - require.NoError(t, err) - require.Empty(t, collected.ScopeMetrics) -} - func TestLabelsToAttributes(t *testing.T) { for name, test := range map[string]struct { providerLabels map[string]string @@ -334,7 +303,7 @@ func TestLabelsToAttributes(t *testing.T) { sink, err := NewOTELSink(ctx, opts) require.NoError(t, err) - require.ElementsMatch(t, test.expectedOTELAttributes, sink.labelsToAttributes(test.goMetricsLabels)) + require.Equal(t, test.expectedOTELAttributes, sink.labelsToAttributes(test.goMetricsLabels)) }) } } diff --git a/agent/hcp/telemetry/otlp_transform.go b/agent/hcp/telemetry/otlp_transform.go index 907e7922ad98d..76e20552a0d4e 100644 --- a/agent/hcp/telemetry/otlp_transform.go +++ b/agent/hcp/telemetry/otlp_transform.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry import ( @@ -16,8 +13,8 @@ import ( ) var ( - errAggregaton = errors.New("unsupported aggregation") - errTemporality = errors.New("unsupported temporality") + aggregationErr = errors.New("unsupported aggregation") + temporalityErr = errors.New("unsupported temporality") ) // isEmpty verifies if the given OTLP protobuf metrics contains metric data. @@ -99,7 +96,7 @@ func metricTypeToPB(m metricdata.Metrics) (*mpb.Metric, error) { } case metricdata.Sum[float64]: if a.Temporality != metricdata.CumulativeTemporality { - return out, fmt.Errorf("failed to convert metric to otel format: %w: %T", errTemporality, a) + return out, fmt.Errorf("error: %w: %T", temporalityErr, a) } out.Data = &mpb.Metric_Sum{ Sum: &mpb.Sum{ @@ -110,7 +107,7 @@ func metricTypeToPB(m metricdata.Metrics) (*mpb.Metric, error) { } case metricdata.Histogram[float64]: if a.Temporality != metricdata.CumulativeTemporality { - return out, fmt.Errorf("failed to convert metric to otel format: %w: %T", errTemporality, a) + return out, fmt.Errorf("error: %w: %T", temporalityErr, a) } out.Data = &mpb.Metric_Histogram{ Histogram: &mpb.Histogram{ @@ -119,7 +116,7 @@ func metricTypeToPB(m metricdata.Metrics) (*mpb.Metric, error) { }, } default: - return out, fmt.Errorf("failed to convert metric to otel format: %w: %T", errAggregaton, a) + return out, fmt.Errorf("error: %w: %T", aggregationErr, a) } return out, nil } diff --git a/agent/hcp/telemetry/otlp_transform_test.go b/agent/hcp/telemetry/otlp_transform_test.go index d67df73d83433..8f6beb7d489db 100644 --- a/agent/hcp/telemetry/otlp_transform_test.go +++ b/agent/hcp/telemetry/otlp_transform_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package telemetry import ( @@ -260,15 +257,15 @@ func TestTransformOTLP(t *testing.T) { // MetricType Error Test Cases _, err := metricTypeToPB(invalidHistTemporality) require.Error(t, err) - require.ErrorIs(t, err, errTemporality) + require.ErrorIs(t, err, temporalityErr) _, err = metricTypeToPB(invalidSumTemporality) require.Error(t, err) - require.ErrorIs(t, err, errTemporality) + require.ErrorIs(t, err, temporalityErr) _, err = metricTypeToPB(invalidSumAgg) require.Error(t, err) - require.ErrorIs(t, err, errAggregaton) + require.ErrorIs(t, err, aggregationErr) // Metrics Test Case m := metricsToPB(inputMetrics) diff --git a/agent/hcp/telemetry_provider.go b/agent/hcp/telemetry_provider.go index 22bb0f2f00b81..eb0f23e804f3c 100644 --- a/agent/hcp/telemetry_provider.go +++ b/agent/hcp/telemetry_provider.go @@ -1,17 +1,14 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package hcp import ( "context" + "fmt" "net/url" "regexp" "sync" "time" "github.com/armon/go-metrics" - "github.com/go-openapi/runtime" "github.com/hashicorp/go-hclog" "github.com/hashicorp/consul/agent/hcp/client" @@ -23,8 +20,6 @@ var ( internalMetricRefreshFailure []string = []string{"hcp", "telemetry_config_provider", "refresh", "failure"} // internalMetricRefreshSuccess is a metric to monitor refresh successes. internalMetricRefreshSuccess []string = []string{"hcp", "telemetry_config_provider", "refresh", "success"} - // defaultTelemetryConfigRefreshInterval is a default fallback in case the first HCP fetch fails. - defaultTelemetryConfigRefreshInterval = 1 * time.Minute ) // Ensure hcpProviderImpl implements telemetry provider interfaces. @@ -48,50 +43,47 @@ type hcpProviderImpl struct { // dynamicConfig is a set of configurable settings for metrics collection, processing and export. // fields MUST be exported to compute hash for equals method. type dynamicConfig struct { - disabled bool - endpoint *url.URL - labels map[string]string - filters *regexp.Regexp + Endpoint *url.URL + Labels map[string]string + Filters *regexp.Regexp // refreshInterval controls the interval at which configuration is fetched from HCP to refresh config. - refreshInterval time.Duration + RefreshInterval time.Duration } -// defaultDisabledCfg disables metric collection and contains default config values. -func defaultDisabledCfg() *dynamicConfig { - return &dynamicConfig{ - labels: map[string]string{}, - filters: client.DefaultMetricFilters, - refreshInterval: defaultTelemetryConfigRefreshInterval, - endpoint: nil, - disabled: true, +// NewHCPProvider initializes and starts a HCP Telemetry provider with provided params. +func NewHCPProvider(ctx context.Context, hcpClient client.Client, telemetryCfg *client.TelemetryConfig) (*hcpProviderImpl, error) { + refreshInterval := telemetryCfg.RefreshConfig.RefreshInterval + // refreshInterval must be greater than 0, otherwise time.Ticker panics. + if refreshInterval <= 0 { + return nil, fmt.Errorf("invalid refresh interval: %d", refreshInterval) + } + + cfg := &dynamicConfig{ + Endpoint: telemetryCfg.MetricsConfig.Endpoint, + Labels: telemetryCfg.MetricsConfig.Labels, + Filters: telemetryCfg.MetricsConfig.Filters, + RefreshInterval: refreshInterval, } -} -// NewHCPProvider initializes and starts a HCP Telemetry provider. -func NewHCPProvider(ctx context.Context, hcpClient client.Client) *hcpProviderImpl { - h := &hcpProviderImpl{ - // Initialize with default config values. - cfg: defaultDisabledCfg(), + t := &hcpProviderImpl{ + cfg: cfg, hcpClient: hcpClient, } - go h.run(ctx) + go t.run(ctx, refreshInterval) - return h + return t, nil } // run continously checks for updates to the telemetry configuration by making a request to HCP. -func (h *hcpProviderImpl) run(ctx context.Context) { - // Try to initialize config once before starting periodic fetch. - h.updateConfig(ctx) - - ticker := time.NewTicker(h.cfg.refreshInterval) +func (h *hcpProviderImpl) run(ctx context.Context, refreshInterval time.Duration) { + ticker := time.NewTicker(refreshInterval) defer ticker.Stop() for { select { case <-ticker.C: - if newRefreshInterval := h.updateConfig(ctx); newRefreshInterval > 0 { - ticker.Reset(newRefreshInterval) + if newCfg := h.getUpdate(ctx); newCfg != nil { + ticker.Reset(newCfg.RefreshInterval) } case <-ctx.Done(): return @@ -99,8 +91,9 @@ func (h *hcpProviderImpl) run(ctx context.Context) { } } -// updateConfig makes a HTTP request to HCP to update metrics configuration held in the provider. -func (h *hcpProviderImpl) updateConfig(ctx context.Context) time.Duration { +// getUpdate makes a HTTP request to HCP to return a new metrics configuration +// and updates the hcpProviderImpl. +func (h *hcpProviderImpl) getUpdate(ctx context.Context) *dynamicConfig { logger := hclog.FromContext(ctx).Named("telemetry_config_provider") ctx, cancel := context.WithTimeout(ctx, 5*time.Second) @@ -108,18 +101,9 @@ func (h *hcpProviderImpl) updateConfig(ctx context.Context) time.Duration { telemetryCfg, err := h.hcpClient.FetchTelemetryConfig(ctx) if err != nil { - // Only disable metrics on 404 or 401 to handle the case of an unlinked cluster. - // For other errors such as 5XX ones, we continue metrics collection, as these are potentially transient server-side errors. - apiErr, ok := err.(*runtime.APIError) - if ok && apiErr.IsClientError() { - disabledMetricsCfg := defaultDisabledCfg() - h.modifyDynamicCfg(disabledMetricsCfg) - return disabledMetricsCfg.refreshInterval - } - logger.Error("failed to fetch telemetry config from HCP", "error", err) metrics.IncrCounter(internalMetricRefreshFailure, 1) - return 0 + return nil } // newRefreshInterval of 0 or less can cause ticker Reset() panic. @@ -127,29 +111,24 @@ func (h *hcpProviderImpl) updateConfig(ctx context.Context) time.Duration { if newRefreshInterval <= 0 { logger.Error("invalid refresh interval duration", "refreshInterval", newRefreshInterval) metrics.IncrCounter(internalMetricRefreshFailure, 1) - return 0 + return nil } - newCfg := &dynamicConfig{ - filters: telemetryCfg.MetricsConfig.Filters, - endpoint: telemetryCfg.MetricsConfig.Endpoint, - labels: telemetryCfg.MetricsConfig.Labels, - refreshInterval: telemetryCfg.RefreshConfig.RefreshInterval, - disabled: telemetryCfg.MetricsConfig.Disabled, + newDynamicConfig := &dynamicConfig{ + Filters: telemetryCfg.MetricsConfig.Filters, + Endpoint: telemetryCfg.MetricsConfig.Endpoint, + Labels: telemetryCfg.MetricsConfig.Labels, + RefreshInterval: newRefreshInterval, } - h.modifyDynamicCfg(newCfg) - - return newCfg.refreshInterval -} - -// modifyDynamicCfg acquires a write lock to update new configuration and emits a success metric. -func (h *hcpProviderImpl) modifyDynamicCfg(newCfg *dynamicConfig) { + // Acquire write lock to update new configuration. h.rw.Lock() - h.cfg = newCfg + h.cfg = newDynamicConfig h.rw.Unlock() metrics.IncrCounter(internalMetricRefreshSuccess, 1) + + return newDynamicConfig } // GetEndpoint acquires a read lock to return endpoint configuration for consumers. @@ -157,7 +136,7 @@ func (h *hcpProviderImpl) GetEndpoint() *url.URL { h.rw.RLock() defer h.rw.RUnlock() - return h.cfg.endpoint + return h.cfg.Endpoint } // GetFilters acquires a read lock to return filters configuration for consumers. @@ -165,7 +144,7 @@ func (h *hcpProviderImpl) GetFilters() *regexp.Regexp { h.rw.RLock() defer h.rw.RUnlock() - return h.cfg.filters + return h.cfg.Filters } // GetLabels acquires a read lock to return labels configuration for consumers. @@ -173,13 +152,5 @@ func (h *hcpProviderImpl) GetLabels() map[string]string { h.rw.RLock() defer h.rw.RUnlock() - return h.cfg.labels -} - -// IsDisabled acquires a read lock and return true if metrics are enabled. -func (h *hcpProviderImpl) IsDisabled() bool { - h.rw.RLock() - defer h.rw.RUnlock() - - return h.cfg.disabled + return h.cfg.Labels } diff --git a/agent/hcp/telemetry_provider_test.go b/agent/hcp/telemetry_provider_test.go index a147183df44d6..e20215faae427 100644 --- a/agent/hcp/telemetry_provider_test.go +++ b/agent/hcp/telemetry_provider_test.go @@ -1,11 +1,7 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package hcp import ( "context" - "errors" "fmt" "net/url" "regexp" @@ -15,7 +11,6 @@ import ( "time" "github.com/armon/go-metrics" - "github.com/go-openapi/runtime" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -41,49 +36,64 @@ type testConfig struct { endpoint string labels map[string]string refreshInterval time.Duration - disabled bool } -func TestNewTelemetryConfigProvider_DefaultConfig(t *testing.T) { +func TestNewTelemetryConfigProvider(t *testing.T) { t.Parallel() - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + for name, tc := range map[string]struct { + testInputs *testConfig + wantErr string + }{ + "success": { + testInputs: &testConfig{ + refreshInterval: 1 * time.Second, + }, + }, + "failsWithInvalidRefreshInterval": { + testInputs: &testConfig{ + refreshInterval: 0 * time.Second, + }, + wantErr: "invalid refresh interval", + }, + } { + tc := tc + t.Run(name, func(t *testing.T) { + t.Parallel() - // Initialize new provider, but fail all HCP fetches. - mc := client.NewMockClient(t) - mc.EXPECT().FetchTelemetryConfig(mock.Anything).Return(nil, errors.New("failed to fetch config")) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - provider := NewHCPProvider(ctx, mc) - provider.updateConfig(ctx) + testCfg, err := testTelemetryCfg(tc.testInputs) + require.NoError(t, err) - // Assert provider has default configuration and metrics processing is disabled. - defaultCfg := &dynamicConfig{ - labels: map[string]string{}, - filters: client.DefaultMetricFilters, - refreshInterval: defaultTelemetryConfigRefreshInterval, - endpoint: nil, - disabled: true, + cfgProvider, err := NewHCPProvider(ctx, client.NewMockClient(t), testCfg) + if tc.wantErr != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tc.wantErr) + require.Nil(t, cfgProvider) + return + } + require.NotNil(t, cfgProvider) + }) } - require.Equal(t, defaultCfg, provider.cfg) } -func TestTelemetryConfigProvider_UpdateConfig(t *testing.T) { +func TestTelemetryConfigProviderGetUpdate(t *testing.T) { for name, tc := range map[string]struct { - mockExpect func(*client.MockClient) - metricKey string - initCfg *dynamicConfig - expected *dynamicConfig - expectedInterval time.Duration + mockExpect func(*client.MockClient) + metricKey string + optsInputs *testConfig + expected *testConfig }{ "noChanges": { - initCfg: testDynamicCfg(&testConfig{ + optsInputs: &testConfig{ endpoint: "http://test.com/v1/metrics", filters: "test", labels: map[string]string{ "test_label": "123", }, refreshInterval: testRefreshInterval, - }), + }, mockExpect: func(m *client.MockClient) { mockCfg, _ := testTelemetryCfg(&testConfig{ endpoint: "http://test.com/v1/metrics", @@ -95,26 +105,25 @@ func TestTelemetryConfigProvider_UpdateConfig(t *testing.T) { }) m.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mockCfg, nil) }, - expected: testDynamicCfg(&testConfig{ + expected: &testConfig{ endpoint: "http://test.com/v1/metrics", labels: map[string]string{ "test_label": "123", }, filters: "test", refreshInterval: testRefreshInterval, - }), - metricKey: testMetricKeySuccess, - expectedInterval: testRefreshInterval, + }, + metricKey: testMetricKeySuccess, }, "newConfig": { - initCfg: testDynamicCfg(&testConfig{ + optsInputs: &testConfig{ endpoint: "http://test.com/v1/metrics", filters: "test", labels: map[string]string{ "test_label": "123", }, refreshInterval: 2 * time.Second, - }), + }, mockExpect: func(m *client.MockClient) { mockCfg, _ := testTelemetryCfg(&testConfig{ endpoint: "http://newendpoint/v1/metrics", @@ -126,136 +135,83 @@ func TestTelemetryConfigProvider_UpdateConfig(t *testing.T) { }) m.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mockCfg, nil) }, - expected: testDynamicCfg(&testConfig{ + expected: &testConfig{ endpoint: "http://newendpoint/v1/metrics", filters: "consul", labels: map[string]string{ "new_label": "1234", }, refreshInterval: 2 * time.Second, - }), - expectedInterval: 2 * time.Second, - metricKey: testMetricKeySuccess, - }, - "newConfigMetricsDisabled": { - initCfg: testDynamicCfg(&testConfig{ - endpoint: "http://test.com/v1/metrics", - filters: "test", - labels: map[string]string{ - "test_label": "123", - }, - refreshInterval: 2 * time.Second, - }), - mockExpect: func(m *client.MockClient) { - mockCfg, _ := testTelemetryCfg(&testConfig{ - endpoint: "", - filters: "consul", - labels: map[string]string{ - "new_label": "1234", - }, - refreshInterval: 2 * time.Second, - disabled: true, - }) - m.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mockCfg, nil) }, - expected: testDynamicCfg(&testConfig{ - endpoint: "", - filters: "consul", - labels: map[string]string{ - "new_label": "1234", - }, - refreshInterval: 2 * time.Second, - disabled: true, - }), - metricKey: testMetricKeySuccess, - expectedInterval: 2 * time.Second, + metricKey: testMetricKeySuccess, }, "sameConfigInvalidRefreshInterval": { - initCfg: testDynamicCfg(&testConfig{ + optsInputs: &testConfig{ endpoint: "http://test.com/v1/metrics", filters: "test", labels: map[string]string{ "test_label": "123", }, refreshInterval: testRefreshInterval, - }), + }, mockExpect: func(m *client.MockClient) { mockCfg, _ := testTelemetryCfg(&testConfig{ refreshInterval: 0 * time.Second, }) m.EXPECT().FetchTelemetryConfig(mock.Anything).Return(mockCfg, nil) }, - expected: testDynamicCfg(&testConfig{ + expected: &testConfig{ endpoint: "http://test.com/v1/metrics", labels: map[string]string{ "test_label": "123", }, filters: "test", refreshInterval: testRefreshInterval, - }), - metricKey: testMetricKeyFailure, - expectedInterval: 0, + }, + metricKey: testMetricKeyFailure, }, "sameConfigHCPClientFailure": { - initCfg: testDynamicCfg(&testConfig{ + optsInputs: &testConfig{ endpoint: "http://test.com/v1/metrics", filters: "test", labels: map[string]string{ "test_label": "123", }, refreshInterval: testRefreshInterval, - }), + }, mockExpect: func(m *client.MockClient) { m.EXPECT().FetchTelemetryConfig(mock.Anything).Return(nil, fmt.Errorf("failure")) }, - expected: testDynamicCfg(&testConfig{ - endpoint: "http://test.com/v1/metrics", - filters: "test", - labels: map[string]string{ - "test_label": "123", - }, - refreshInterval: testRefreshInterval, - }), - metricKey: testMetricKeyFailure, - expectedInterval: 0, - }, - "disableMetrics404": { - initCfg: testDynamicCfg(&testConfig{ + expected: &testConfig{ endpoint: "http://test.com/v1/metrics", filters: "test", labels: map[string]string{ "test_label": "123", }, refreshInterval: testRefreshInterval, - }), - mockExpect: func(m *client.MockClient) { - err := runtime.NewAPIError("404 failure", nil, 404) - m.EXPECT().FetchTelemetryConfig(mock.Anything).Return(nil, err) }, - expected: defaultDisabledCfg(), - metricKey: testMetricKeySuccess, - expectedInterval: defaultTelemetryConfigRefreshInterval, + metricKey: testMetricKeyFailure, }, } { - tc := tc t.Run(name, func(t *testing.T) { sink := initGlobalSink() mockClient := client.NewMockClient(t) tc.mockExpect(mockClient) + dynamicCfg, err := testDynamicCfg(tc.optsInputs) + require.NoError(t, err) + provider := &hcpProviderImpl{ hcpClient: mockClient, - cfg: tc.initCfg, + cfg: dynamicCfg, } - newInterval := provider.updateConfig(context.Background()) - require.Equal(t, tc.expectedInterval, newInterval) + provider.getUpdate(context.Background()) // Verify endpoint provider returns correct config values. - require.Equal(t, tc.expected.endpoint, provider.GetEndpoint()) - require.Equal(t, tc.expected.filters, provider.GetFilters()) + require.Equal(t, tc.expected.endpoint, provider.GetEndpoint().String()) + require.Equal(t, tc.expected.filters, provider.GetFilters().String()) require.Equal(t, tc.expected.labels, provider.GetLabels()) - require.Equal(t, tc.expected.disabled, provider.IsDisabled()) // Verify count for transform success metric. interval := sink.Data()[0] @@ -335,7 +291,8 @@ func TestTelemetryConfigProvider_Race(t *testing.T) { } // Start the provider goroutine, which fetches client TelemetryConfig every RefreshInterval. - provider := NewHCPProvider(ctx, m) + provider, err := NewHCPProvider(ctx, m, m.cfg) + require.NoError(t, err) for count := 0; count < testRaceWriteSampleCount; count++ { // Force a TelemetryConfig value change in the mockRaceClient. @@ -343,7 +300,7 @@ func TestTelemetryConfigProvider_Race(t *testing.T) { require.NoError(t, err) // Force provider to obtain new client TelemetryConfig immediately. // This call is necessary to guarantee TelemetryConfig changes to assert on expected values below. - provider.updateConfig(context.Background()) + provider.getUpdate(context.Background()) // Start goroutines to access label configuration. wg := &sync.WaitGroup{} @@ -387,20 +344,22 @@ func initGlobalSink() *metrics.InmemSink { } // testDynamicCfg converts testConfig inputs to a dynamicConfig to be used in tests. -func testDynamicCfg(testCfg *testConfig) *dynamicConfig { - filters, _ := regexp.Compile(testCfg.filters) +func testDynamicCfg(testCfg *testConfig) (*dynamicConfig, error) { + filters, err := regexp.Compile(testCfg.filters) + if err != nil { + return nil, err + } - var endpoint *url.URL - if testCfg.endpoint != "" { - endpoint, _ = url.Parse(testCfg.endpoint) + endpoint, err := url.Parse(testCfg.endpoint) + if err != nil { + return nil, err } return &dynamicConfig{ - endpoint: endpoint, - filters: filters, - labels: testCfg.labels, - refreshInterval: testCfg.refreshInterval, - disabled: testCfg.disabled, - } + Endpoint: endpoint, + Filters: filters, + Labels: testCfg.labels, + RefreshInterval: testCfg.refreshInterval, + }, nil } // testTelemetryCfg converts testConfig inputs to a TelemetryConfig to be used in tests. @@ -410,21 +369,15 @@ func testTelemetryCfg(testCfg *testConfig) (*client.TelemetryConfig, error) { return nil, err } - var endpoint *url.URL - if testCfg.endpoint != "" { - u, err := url.Parse(testCfg.endpoint) - if err != nil { - return nil, err - } - endpoint = u + endpoint, err := url.Parse(testCfg.endpoint) + if err != nil { + return nil, err } - return &client.TelemetryConfig{ MetricsConfig: &client.MetricsConfig{ Endpoint: endpoint, Filters: filters, Labels: testCfg.labels, - Disabled: testCfg.disabled, }, RefreshConfig: &client.RefreshConfig{ RefreshInterval: testCfg.refreshInterval, diff --git a/agent/hcp/testing.go b/agent/hcp/testing.go index 30f7ba7bcdeb3..94f3122c33d2d 100644 --- a/agent/hcp/testing.go +++ b/agent/hcp/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package hcp diff --git a/agent/hcp/testserver/main.go b/agent/hcp/testserver/main.go index e0db7670ef99f..ffdd4cac51afa 100644 --- a/agent/hcp/testserver/main.go +++ b/agent/hcp/testserver/main.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package main diff --git a/agent/health_endpoint.go b/agent/health_endpoint.go index 3b888988d2730..ea3d315f6b8b5 100644 --- a/agent/health_endpoint.go +++ b/agent/health_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/health_endpoint_test.go b/agent/health_endpoint_test.go index 4c491e9cb2761..4f1bd1c485457 100644 --- a/agent/health_endpoint_test.go +++ b/agent/health_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -28,25 +28,6 @@ import ( "github.com/hashicorp/consul/types" ) -func TestHealthEndpointsFailInV2(t *testing.T) { - t.Parallel() - - a := NewTestAgent(t, `experiments = ["resource-apis"]`) - - checkRequest := func(method, url string) { - t.Run(method+" "+url, func(t *testing.T) { - assertV1CatalogEndpointDoesNotWorkWithV2(t, a, method, url, "{}") - }) - } - - checkRequest("GET", "/v1/health/node/web") - checkRequest("GET", "/v1/health/checks/web") - checkRequest("GET", "/v1/health/state/web") - checkRequest("GET", "/v1/health/service/web") - checkRequest("GET", "/v1/health/connect/web") - checkRequest("GET", "/v1/health/ingress/web") -} - func TestHealthChecksInState(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") @@ -461,21 +442,19 @@ func TestHealthServiceChecks_NodeMetaFilter(t *testing.T) { t.Fatalf("err: %v", err) } - retry.Run(t, func(r *retry.R) { - req, _ = http.NewRequest("GET", "/v1/health/checks/consul?dc=dc1&node-meta=somekey:somevalue", nil) - resp = httptest.NewRecorder() - obj, err = a.srv.HealthServiceChecks(resp, req) - if err != nil { - r.Fatalf("err: %v", err) - } - assertIndex(r, resp) + req, _ = http.NewRequest("GET", "/v1/health/checks/consul?dc=dc1&node-meta=somekey:somevalue", nil) + resp = httptest.NewRecorder() + obj, err = a.srv.HealthServiceChecks(resp, req) + if err != nil { + t.Fatalf("err: %v", err) + } + assertIndex(t, resp) - // Should be 1 health check for consul - nodes = obj.(structs.HealthChecks) - if len(nodes) != 1 { - r.Fatalf("bad: %v", obj) - } - }) + // Should be 1 health check for consul + nodes = obj.(structs.HealthChecks) + if len(nodes) != 1 { + t.Fatalf("bad: %v", obj) + } } func TestHealthServiceChecks_Filtering(t *testing.T) { diff --git a/agent/http.go b/agent/http.go index aed7c920cdf9b..32010c343a6c5 100644 --- a/agent/http.go +++ b/agent/http.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -36,7 +36,6 @@ import ( "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/uiserver" "github.com/hashicorp/consul/api" - resourcehttp "github.com/hashicorp/consul/internal/resource/http" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/logging" "github.com/hashicorp/consul/proto/private/pbcommon" @@ -260,17 +259,6 @@ func (s *HTTPHandlers) handler() http.Handler { handlePProf("/debug/pprof/symbol", pprof.Symbol) handlePProf("/debug/pprof/trace", pprof.Trace) - mux.Handle("/api/", - http.StripPrefix("/api", - resourcehttp.NewHandler( - s.agent.delegate.ResourceServiceClient(), - s.agent.baseDeps.Registry, - s.parseToken, - s.agent.logger.Named(logging.HTTP), - ), - ), - ) - if s.IsUIEnabled() { // Note that we _don't_ support reloading ui_config.{enabled, content_dir, // content_path} since this only runs at initial startup. @@ -394,11 +382,6 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc } logURL = aclEndpointRE.ReplaceAllString(logURL, "$1$4") - rejectCatalogV1Endpoint := false - if s.agent.baseDeps.UseV2Resources() { - rejectCatalogV1Endpoint = isV1CatalogRequest(req.URL.Path) - } - if s.denylist.Block(req.URL.Path) { errMsg := "Endpoint is blocked by agent configuration" httpLogger.Error("Request error", @@ -460,14 +443,6 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc return strings.Contains(err.Error(), rate.ErrRetryLater.Error()) } - isUsingV2CatalogExperiment := func(err error) bool { - if err == nil { - return false - } - - return structs.IsErrUsingV2CatalogExperiment(err) - } - isMethodNotAllowed := func(err error) bool { _, ok := err.(MethodNotAllowedError) return ok @@ -503,10 +478,6 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc msg = s.Message() } - if isUsingV2CatalogExperiment(err) && !isHTTPError(err) { - err = newRejectV1RequestWhenV2EnabledError() - } - switch { case isForbidden(err): resp.WriteHeader(http.StatusForbidden) @@ -583,12 +554,7 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc if err == nil { // Invoke the handler - if rejectCatalogV1Endpoint { - obj = nil - err = s.rejectV1RequestWhenV2Enabled() - } else { - obj, err = handler(resp, req) - } + obj, err = handler(resp, req) } } contentType := "application/json" @@ -630,46 +596,6 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc } } -func isV1CatalogRequest(logURL string) bool { - switch { - case strings.HasPrefix(logURL, "/v1/catalog/"), - strings.HasPrefix(logURL, "/v1/health/"), - strings.HasPrefix(logURL, "/v1/config/"): - return true - - case strings.HasPrefix(logURL, "/v1/agent/token/"), - logURL == "/v1/agent/self", - logURL == "/v1/agent/host", - logURL == "/v1/agent/version", - logURL == "/v1/agent/reload", - logURL == "/v1/agent/monitor", - logURL == "/v1/agent/metrics", - logURL == "/v1/agent/metrics/stream", - logURL == "/v1/agent/members", - strings.HasPrefix(logURL, "/v1/agent/join/"), - logURL == "/v1/agent/leave", - strings.HasPrefix(logURL, "/v1/agent/force-leave/"), - logURL == "/v1/agent/connect/authorize", - logURL == "/v1/agent/connect/ca/roots", - strings.HasPrefix(logURL, "/v1/agent/connect/ca/leaf/"): - return false - - case strings.HasPrefix(logURL, "/v1/agent/"): - return true - - case logURL == "/v1/internal/acl/authorize", - logURL == "/v1/internal/service-virtual-ip", - logURL == "/v1/internal/ui/oidc-auth-methods", - strings.HasPrefix(logURL, "/v1/internal/ui/metrics-proxy/"): - return false - - case strings.HasPrefix(logURL, "/v1/internal/"): - return true - default: - return false - } -} - // marshalJSON marshals the object into JSON, respecting the user's pretty-ness // configuration. func (s *HTTPHandlers) marshalJSON(req *http.Request, obj interface{}) ([]byte, error) { @@ -678,9 +604,7 @@ func (s *HTTPHandlers) marshalJSON(req *http.Request, obj interface{}) ([]byte, if err != nil { return nil, err } - if ok { - buf = append(buf, "\n"...) - } + buf = append(buf, "\n"...) return buf, nil } @@ -1146,20 +1070,6 @@ func (s *HTTPHandlers) parseToken(req *http.Request, token *string) { s.parseTokenWithDefault(req, token) } -func (s *HTTPHandlers) rejectV1RequestWhenV2Enabled() error { - if s.agent.baseDeps.UseV2Resources() { - return newRejectV1RequestWhenV2EnabledError() - } - return nil -} - -func newRejectV1RequestWhenV2EnabledError() error { - return HTTPError{ - StatusCode: http.StatusBadRequest, - Reason: structs.ErrUsingV2CatalogExperiment.Error(), - } -} - func sourceAddrFromRequest(req *http.Request) string { xff := req.Header.Get("X-Forwarded-For") forwardHosts := strings.Split(xff, ",") diff --git a/agent/http_ce.go b/agent/http_ce.go index da6bef7237766..d9c233226c491 100644 --- a/agent/http_ce.go +++ b/agent/http_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/http_ce_test.go b/agent/http_ce_test.go index ea1d2af61d7a4..bf085ca8c29c7 100644 --- a/agent/http_ce_test.go +++ b/agent/http_ce_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/http_decode_test.go b/agent/http_decode_test.go index 6aece784c0b2d..03d1b9191fa74 100644 --- a/agent/http_decode_test.go +++ b/agent/http_decode_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/http_register.go b/agent/http_register.go index 340f7ef0fe048..b3f0dfea3f3a6 100644 --- a/agent/http_register.go +++ b/agent/http_register.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -26,9 +26,6 @@ func init() { registerEndpoint("/v1/acl/token", []string{"PUT"}, (*HTTPHandlers).ACLTokenCreate) registerEndpoint("/v1/acl/token/self", []string{"GET"}, (*HTTPHandlers).ACLTokenSelf) registerEndpoint("/v1/acl/token/", []string{"GET", "PUT", "DELETE"}, (*HTTPHandlers).ACLTokenCRUD) - registerEndpoint("/v1/acl/templated-policies", []string{"GET"}, (*HTTPHandlers).ACLTemplatedPoliciesList) - registerEndpoint("/v1/acl/templated-policy/name/", []string{"GET"}, (*HTTPHandlers).ACLTemplatedPolicyRead) - registerEndpoint("/v1/acl/templated-policy/preview/", []string{"POST"}, (*HTTPHandlers).ACLTemplatedPolicyPreview) registerEndpoint("/v1/agent/token/", []string{"PUT"}, (*HTTPHandlers).AgentToken) registerEndpoint("/v1/agent/self", []string{"GET"}, (*HTTPHandlers).AgentSelf) registerEndpoint("/v1/agent/host", []string{"GET"}, (*HTTPHandlers).AgentHost) diff --git a/agent/http_test.go b/agent/http_test.go index f2469acc83526..99100c5fbc8e8 100644 --- a/agent/http_test.go +++ b/agent/http_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -1628,10 +1628,8 @@ func TestAllowedNets(t *testing.T) { } // assertIndex tests that X-Consul-Index is set and non-zero -func assertIndex(t require.TestingT, resp *httptest.ResponseRecorder) { - if tt, ok := t.(*testing.T); ok { - tt.Helper() - } +func assertIndex(t *testing.T, resp *httptest.ResponseRecorder) { + t.Helper() require.NoError(t, checkIndex(resp)) } diff --git a/agent/intentions_endpoint.go b/agent/intentions_endpoint.go index 4f0b188a0cc43..2353c5bdac2ee 100644 --- a/agent/intentions_endpoint.go +++ b/agent/intentions_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/intentions_endpoint_ce_test.go b/agent/intentions_endpoint_ce_test.go index 10a540bf1869c..fb6a47f5e53d4 100644 --- a/agent/intentions_endpoint_ce_test.go +++ b/agent/intentions_endpoint_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/intentions_endpoint_test.go b/agent/intentions_endpoint_test.go index b1309feb9d2cd..161b8b5139d54 100644 --- a/agent/intentions_endpoint_test.go +++ b/agent/intentions_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/keyring.go b/agent/keyring.go index f30680774b340..3d96880f03aaa 100644 --- a/agent/keyring.go +++ b/agent/keyring.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/keyring_test.go b/agent/keyring_test.go index 1a9332a8a7393..7ce5d2cd4b93b 100644 --- a/agent/keyring_test.go +++ b/agent/keyring_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/kvs_endpoint.go b/agent/kvs_endpoint.go index e60567cd5b807..d5ad8cabc3de8 100644 --- a/agent/kvs_endpoint.go +++ b/agent/kvs_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/kvs_endpoint_test.go b/agent/kvs_endpoint_test.go index 2b3563000815b..6ea5efced20d2 100644 --- a/agent/kvs_endpoint_test.go +++ b/agent/kvs_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/leafcert/cached_roots.go b/agent/leafcert/cached_roots.go index 4b0612416a549..b973b6dc660ca 100644 --- a/agent/leafcert/cached_roots.go +++ b/agent/leafcert/cached_roots.go @@ -1,18 +1,16 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( "context" "errors" - "github.com/hashicorp/consul/agent/cacheshim" + "github.com/hashicorp/consul/agent/cache" + cachetype "github.com/hashicorp/consul/agent/cache-types" "github.com/hashicorp/consul/agent/structs" ) // NewCachedRootsReader returns a RootsReader that sources data from the agent cache. -func NewCachedRootsReader(cache cacheshim.Cache, dc string) RootsReader { +func NewCachedRootsReader(cache *cache.Cache, dc string) RootsReader { return &agentCacheRootsReader{ cache: cache, datacenter: dc, @@ -20,7 +18,7 @@ func NewCachedRootsReader(cache cacheshim.Cache, dc string) RootsReader { } type agentCacheRootsReader struct { - cache cacheshim.Cache + cache *cache.Cache datacenter string } @@ -29,7 +27,7 @@ var _ RootsReader = (*agentCacheRootsReader)(nil) func (r *agentCacheRootsReader) Get() (*structs.IndexedCARoots, error) { // Background is fine here because this isn't a blocking query as no index is set. // Therefore this will just either be a cache hit or return once the non-blocking query returns. - rawRoots, _, err := r.cache.Get(context.Background(), cacheshim.ConnectCARootName, &structs.DCSpecificRequest{ + rawRoots, _, err := r.cache.Get(context.Background(), cachetype.ConnectCARootName, &structs.DCSpecificRequest{ Datacenter: r.datacenter, }) if err != nil { @@ -42,8 +40,8 @@ func (r *agentCacheRootsReader) Get() (*structs.IndexedCARoots, error) { return roots, nil } -func (r *agentCacheRootsReader) Notify(ctx context.Context, correlationID string, ch chan<- cacheshim.UpdateEvent) error { - return r.cache.Notify(ctx, cacheshim.ConnectCARootName, &structs.DCSpecificRequest{ +func (r *agentCacheRootsReader) Notify(ctx context.Context, correlationID string, ch chan<- cache.UpdateEvent) error { + return r.cache.Notify(ctx, cachetype.ConnectCARootName, &structs.DCSpecificRequest{ Datacenter: r.datacenter, }, correlationID, ch) } diff --git a/agent/leafcert/cert.go b/agent/leafcert/cert.go index b6236a4a14ac1..0230685737756 100644 --- a/agent/leafcert/cert.go +++ b/agent/leafcert/cert.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( diff --git a/agent/leafcert/generate.go b/agent/leafcert/generate.go index 19dbdbbaf4bbb..0e397cdc2d52f 100644 --- a/agent/leafcert/generate.go +++ b/agent/leafcert/generate.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( @@ -11,6 +8,7 @@ import ( "time" "github.com/hashicorp/consul/agent/connect" + "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/lib" ) @@ -230,15 +228,6 @@ func (m *Manager) generateNewLeaf( var ipAddresses []net.IP switch { - case req.WorkloadIdentity != "": - id = &connect.SpiffeIDWorkloadIdentity{ - TrustDomain: roots.TrustDomain, - Partition: req.TargetPartition(), - Namespace: req.TargetNamespace(), - WorkloadIdentity: req.WorkloadIdentity, - } - dnsNames = append(dnsNames, req.DNSSAN...) - case req.Service != "": id = &connect.SpiffeIDService{ Host: roots.TrustDomain, @@ -281,7 +270,7 @@ func (m *Manager) generateNewLeaf( dnsNames = append(dnsNames, connect.PeeringServerSAN(req.Datacenter, roots.TrustDomain)) default: - return nil, newState, errors.New("URI must be either workload identity, service, agent, server, or kind") + return nil, newState, errors.New("URI must be either service, agent, server, or kind") } // Create a new private key @@ -316,7 +305,7 @@ func (m *Manager) generateNewLeaf( reply, err := m.certSigner.SignCert(context.Background(), &args) if err != nil { - if err.Error() == structs.ErrRateLimited.Error() { + if err.Error() == consul.ErrRateLimited.Error() { if firstTime { // This was a first fetch - we have no good value in cache. In this case // we just return the error to the caller rather than rely on surprising diff --git a/agent/leafcert/leafcert.go b/agent/leafcert/leafcert.go index 34759b6fdc7a7..9cd0c08db13d0 100644 --- a/agent/leafcert/leafcert.go +++ b/agent/leafcert/leafcert.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( @@ -15,7 +12,7 @@ import ( "golang.org/x/sync/singleflight" "golang.org/x/time/rate" - "github.com/hashicorp/consul/agent/cacheshim" + "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/lib/ttlcache" ) @@ -104,7 +101,7 @@ type Deps struct { type RootsReader interface { Get() (*structs.IndexedCARoots, error) - Notify(ctx context.Context, correlationID string, ch chan<- cacheshim.UpdateEvent) error + Notify(ctx context.Context, correlationID string, ch chan<- cache.UpdateEvent) error } type CertSigner interface { @@ -237,7 +234,7 @@ func (m *Manager) Stop() { // index is retrieved, the last known value (maybe nil) is returned. No // error is returned on timeout. This matches the behavior of Consul blocking // queries. -func (m *Manager) Get(ctx context.Context, req *ConnectCALeafRequest) (*structs.IssuedCert, cacheshim.ResultMeta, error) { +func (m *Manager) Get(ctx context.Context, req *ConnectCALeafRequest) (*structs.IssuedCert, cache.ResultMeta, error) { // Lightweight copy this object so that manipulating req doesn't race. dup := *req req = &dup @@ -254,10 +251,10 @@ func (m *Manager) Get(ctx context.Context, req *ConnectCALeafRequest) (*structs. return m.internalGet(ctx, req) } -func (m *Manager) internalGet(ctx context.Context, req *ConnectCALeafRequest) (*structs.IssuedCert, cacheshim.ResultMeta, error) { +func (m *Manager) internalGet(ctx context.Context, req *ConnectCALeafRequest) (*structs.IssuedCert, cache.ResultMeta, error) { key := req.Key() if key == "" { - return nil, cacheshim.ResultMeta{}, fmt.Errorf("a key is required") + return nil, cache.ResultMeta{}, fmt.Errorf("a key is required") } if req.MaxQueryTime <= 0 { @@ -310,7 +307,7 @@ func (m *Manager) internalGet(ctx context.Context, req *ConnectCALeafRequest) (* } if !shouldReplaceCert { - meta := cacheshim.ResultMeta{ + meta := cache.ResultMeta{ Index: existingIndex, } @@ -347,7 +344,7 @@ func (m *Manager) internalGet(ctx context.Context, req *ConnectCALeafRequest) (* // other words valid fetches should reset the error. See // https://github.com/hashicorp/consul/issues/4480. if !first && lastFetchErr != nil { - return existing, cacheshim.ResultMeta{Index: existingIndex}, lastFetchErr + return existing, cache.ResultMeta{Index: existingIndex}, lastFetchErr } notifyCh := m.triggerCertRefreshInGroup(req, cd) @@ -357,14 +354,14 @@ func (m *Manager) internalGet(ctx context.Context, req *ConnectCALeafRequest) (* select { case <-ctx.Done(): - return nil, cacheshim.ResultMeta{}, ctx.Err() + return nil, cache.ResultMeta{}, ctx.Err() case <-notifyCh: // Our fetch returned, retry the get from the cache. req.MustRevalidate = false case <-timeoutTimer.C: // Timeout on the cache read, just return whatever we have. - return existing, cacheshim.ResultMeta{Index: existingIndex}, nil + return existing, cache.ResultMeta{Index: existingIndex}, nil } } } diff --git a/agent/leafcert/leafcert_test.go b/agent/leafcert/leafcert_test.go index f23ecfef62f99..0db683a816e1a 100644 --- a/agent/leafcert/leafcert_test.go +++ b/agent/leafcert/leafcert_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( @@ -9,6 +6,7 @@ import ( "crypto/x509" "encoding/pem" "fmt" + "sync" "sync/atomic" "testing" "time" @@ -16,8 +14,9 @@ import ( "github.com/stretchr/testify/require" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/cacheshim" + "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/agent/connect" + "github.com/hashicorp/consul/agent/consul" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" @@ -32,7 +31,7 @@ func TestManager_changingRoots(t *testing.T) { t.Parallel() - m, signer := NewTestManager(t, nil) + m, signer := testManager(t, nil) caRoot := signer.UpdateCA(t, nil) @@ -96,7 +95,7 @@ func TestManager_changingRootsJitterBetweenCalls(t *testing.T) { const TestOverrideCAChangeInitialDelay = 100 * time.Millisecond - m, signer := NewTestManager(t, func(cfg *Config) { + m, signer := testManager(t, func(cfg *Config) { // Override the root-change delay so we will timeout first. We can't set it to // a crazy high value otherwise we'll have to wait that long in the test to // see if it actually happens on subsequent calls. We instead reduce the @@ -224,7 +223,7 @@ func testObserveLeafCert[T any](m *Manager, req *ConnectCALeafRequest, cb func(* func TestManager_changingRootsBetweenBlockingCalls(t *testing.T) { t.Parallel() - m, signer := NewTestManager(t, nil) + m, signer := testManager(t, nil) caRoot := signer.UpdateCA(t, nil) @@ -295,7 +294,7 @@ func TestManager_CSRRateLimiting(t *testing.T) { t.Parallel() - m, signer := NewTestManager(t, func(cfg *Config) { + m, signer := testManager(t, func(cfg *Config) { // Each jitter window will be only 100 ms long to make testing quick but // highly likely not to fail based on scheduling issues. cfg.TestOverrideCAChangeInitialDelay = 100 * time.Millisecond @@ -307,13 +306,13 @@ func TestManager_CSRRateLimiting(t *testing.T) { // First call return rate limit error. This is important as it checks // behavior when cache is empty and we have to return a nil Value but need to // save state to do the right thing for retry. - structs.ErrRateLimited, // inc + consul.ErrRateLimited, // inc // Then succeed on second call nil, // Then be rate limited again on several further calls - structs.ErrRateLimited, // inc - structs.ErrRateLimited, // inc - // Then fine after that + consul.ErrRateLimited, // inc + consul.ErrRateLimited, // inc + // Then fine after that ) req := &ConnectCALeafRequest{ @@ -330,7 +329,7 @@ func TestManager_CSRRateLimiting(t *testing.T) { t.Fatal("shouldn't block longer than one jitter window for success") case result := <-getCh: require.Error(t, result.Err) - require.Equal(t, structs.ErrRateLimited.Error(), result.Err.Error()) + require.Equal(t, consul.ErrRateLimited.Error(), result.Err.Error()) } // Second call should return correct cert immediately. @@ -427,7 +426,7 @@ func TestManager_watchRootsDedupingMultipleCallers(t *testing.T) { t.Parallel() - m, signer := NewTestManager(t, nil) + m, signer := testManager(t, nil) caRoot := signer.UpdateCA(t, nil) @@ -575,7 +574,7 @@ func TestManager_expiringLeaf(t *testing.T) { t.Parallel() - m, signer := NewTestManager(t, nil) + m, signer := testManager(t, nil) caRoot := signer.UpdateCA(t, nil) @@ -635,7 +634,7 @@ func TestManager_expiringLeaf(t *testing.T) { func TestManager_DNSSANForService(t *testing.T) { t.Parallel() - m, signer := NewTestManager(t, nil) + m, signer := testManager(t, nil) _ = signer.UpdateCA(t, nil) @@ -667,7 +666,7 @@ func TestManager_workflow_good(t *testing.T) { const TestOverrideCAChangeInitialDelay = 1 * time.Nanosecond - m, signer := NewTestManager(t, func(cfg *Config) { + m, signer := testManager(t, func(cfg *Config) { cfg.TestOverrideCAChangeInitialDelay = TestOverrideCAChangeInitialDelay }) @@ -709,7 +708,7 @@ func TestManager_workflow_good(t *testing.T) { type reply struct { cert *structs.IssuedCert - meta cacheshim.ResultMeta + meta cache.ResultMeta err error } @@ -816,7 +815,7 @@ func TestManager_workflow_goodNotLocal(t *testing.T) { const TestOverrideCAChangeInitialDelay = 1 * time.Nanosecond - m, signer := NewTestManager(t, func(cfg *Config) { + m, signer := testManager(t, func(cfg *Config) { cfg.TestOverrideCAChangeInitialDelay = TestOverrideCAChangeInitialDelay }) @@ -933,7 +932,7 @@ func TestManager_workflow_nonBlockingQuery_after_blockingQuery_shouldNotBlock(t ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) - m, signer := NewTestManager(t, nil) + m, signer := testManager(t, nil) _ = signer.UpdateCA(t, nil) @@ -1018,6 +1017,98 @@ func requireLeafValidUnderCA(t require.TestingT, issued *structs.IssuedCert, ca require.NoError(t, err) } +// testManager returns a *Manager that is pre-configured to use a mock RPC +// implementation that can sign certs, and an in-memory CA roots reader that +// interacts well with it. +func testManager(t *testing.T, mut func(*Config)) (*Manager, *testSigner) { + signer := newTestSigner(t, nil, nil) + + deps := Deps{ + Logger: testutil.Logger(t), + RootsReader: signer.RootsReader, + CertSigner: signer, + Config: Config{ + // Override the root-change spread so we don't have to wait up to 20 seconds + // to see root changes work. Can be changed back for specific tests that + // need to test this, Note it's not 0 since that used default but is + // effectively the same. + TestOverrideCAChangeInitialDelay: 1 * time.Microsecond, + }, + } + if mut != nil { + mut(&deps.Config) + } + + m := NewManager(deps) + t.Cleanup(m.Stop) + + return m, signer +} + +type testRootsReader struct { + mu sync.Mutex + index uint64 + roots *structs.IndexedCARoots + watcher chan struct{} +} + +func newTestRootsReader(t *testing.T) *testRootsReader { + r := &testRootsReader{ + watcher: make(chan struct{}), + } + t.Cleanup(func() { + r.mu.Lock() + watcher := r.watcher + r.mu.Unlock() + close(watcher) + }) + return r +} + +var _ RootsReader = (*testRootsReader)(nil) + +func (r *testRootsReader) Set(roots *structs.IndexedCARoots) { + r.mu.Lock() + oldWatcher := r.watcher + r.watcher = make(chan struct{}) + r.roots = roots + if roots == nil { + r.index = 1 + } else { + r.index = roots.Index + } + r.mu.Unlock() + + close(oldWatcher) +} + +func (r *testRootsReader) Get() (*structs.IndexedCARoots, error) { + r.mu.Lock() + defer r.mu.Unlock() + return r.roots, nil +} + +func (r *testRootsReader) Notify(ctx context.Context, correlationID string, ch chan<- cache.UpdateEvent) error { + r.mu.Lock() + watcher := r.watcher + r.mu.Unlock() + + go func() { + <-watcher + + r.mu.Lock() + defer r.mu.Unlock() + + ch <- cache.UpdateEvent{ + CorrelationID: correlationID, + Result: r.roots, + Meta: cache.ResultMeta{Index: r.index}, + Err: nil, + } + }() + return nil +} + type testGetResult struct { Index uint64 Value *structs.IssuedCert diff --git a/agent/leafcert/roots.go b/agent/leafcert/roots.go index 44fc0ff5b06cb..7f95e0578dccb 100644 --- a/agent/leafcert/roots.go +++ b/agent/leafcert/roots.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( @@ -8,7 +5,7 @@ import ( "sync" "sync/atomic" - "github.com/hashicorp/consul/agent/cacheshim" + "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/agent/structs" ) @@ -100,7 +97,7 @@ func (r *rootWatcher) rootWatcher(ctx context.Context) { atomic.AddUint32(&r.testStartCount, 1) defer atomic.AddUint32(&r.testStopCount, 1) - ch := make(chan cacheshim.UpdateEvent, 1) + ch := make(chan cache.UpdateEvent, 1) if err := r.rootsReader.Notify(ctx, "roots", ch); err != nil { // Trigger all inflight watchers. We don't pass the error, but they will diff --git a/agent/leafcert/signer_netrpc.go b/agent/leafcert/signer_netrpc.go index 0e1a7a7487f88..2d6b490a9ea8c 100644 --- a/agent/leafcert/signer_netrpc.go +++ b/agent/leafcert/signer_netrpc.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( diff --git a/agent/leafcert/leafcert_test_helpers.go b/agent/leafcert/signer_test.go similarity index 56% rename from agent/leafcert/leafcert_test_helpers.go rename to agent/leafcert/signer_test.go index 0779033dccfd4..21e3388f5a1c4 100644 --- a/agent/leafcert/leafcert_test_helpers.go +++ b/agent/leafcert/signer_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( @@ -17,42 +14,12 @@ import ( "testing" "time" - "github.com/hashicorp/consul/agent/cacheshim" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/sdk/testutil" ) -// NewTestManager returns a *Manager that is pre-configured to use a mock RPC -// implementation that can sign certs, and an in-memory CA roots reader that -// interacts well with it. -func NewTestManager(t *testing.T, mut func(*Config)) (*Manager, *TestSigner) { - signer := newTestSigner(t, nil, nil) - - deps := Deps{ - Logger: testutil.Logger(t), - RootsReader: signer.RootsReader, - CertSigner: signer, - Config: Config{ - // Override the root-change spread so we don't have to wait up to 20 seconds - // to see root changes work. Can be changed back for specific tests that - // need to test this, Note it's not 0 since that used default but is - // effectively the same. - TestOverrideCAChangeInitialDelay: 1 * time.Microsecond, - }, - } - if mut != nil { - mut(&deps.Config) - } - - m := NewManager(deps) - t.Cleanup(m.Stop) - - return m, signer -} - -// TestSigner implements NetRPC and handles leaf signing operations -type TestSigner struct { +// testSigner implements NetRPC and handles leaf signing operations +type testSigner struct { caLock sync.Mutex ca *structs.CARoot prevRoots []*structs.CARoot // remember prior ones @@ -66,37 +33,37 @@ type TestSigner struct { signCallCapture []*structs.CASignRequest } -var _ CertSigner = (*TestSigner)(nil) +var _ CertSigner = (*testSigner)(nil) var ReplyWithExpiredCert = errors.New("reply with expired cert") -func newTestSigner(t *testing.T, idGenerator *atomic.Uint64, rootsReader *testRootsReader) *TestSigner { +func newTestSigner(t *testing.T, idGenerator *atomic.Uint64, rootsReader *testRootsReader) *testSigner { if idGenerator == nil { idGenerator = &atomic.Uint64{} } if rootsReader == nil { rootsReader = newTestRootsReader(t) } - s := &TestSigner{ + s := &testSigner{ IDGenerator: idGenerator, RootsReader: rootsReader, } return s } -func (s *TestSigner) SetSignCallErrors(errs ...error) { +func (s *testSigner) SetSignCallErrors(errs ...error) { s.signCallLock.Lock() defer s.signCallLock.Unlock() s.signCallErrors = append(s.signCallErrors, errs...) } -func (s *TestSigner) GetSignCallErrorCount() uint64 { +func (s *testSigner) GetSignCallErrorCount() uint64 { s.signCallLock.Lock() defer s.signCallLock.Unlock() return s.signCallErrorCount } -func (s *TestSigner) UpdateCA(t *testing.T, ca *structs.CARoot) *structs.CARoot { +func (s *testSigner) UpdateCA(t *testing.T, ca *structs.CARoot) *structs.CARoot { if ca == nil { ca = connect.TestCA(t, nil) } @@ -125,17 +92,17 @@ func (s *TestSigner) UpdateCA(t *testing.T, ca *structs.CARoot) *structs.CARoot return ca } -func (s *TestSigner) nextIndex() uint64 { +func (s *testSigner) nextIndex() uint64 { return s.IDGenerator.Add(1) } -func (s *TestSigner) getCA() *structs.CARoot { +func (s *testSigner) getCA() *structs.CARoot { s.caLock.Lock() defer s.caLock.Unlock() return s.ca } -func (s *TestSigner) GetCapture(idx int) *structs.CASignRequest { +func (s *testSigner) GetCapture(idx int) *structs.CASignRequest { s.signCallLock.Lock() defer s.signCallLock.Unlock() if len(s.signCallCapture) > idx { @@ -145,7 +112,7 @@ func (s *TestSigner) GetCapture(idx int) *structs.CASignRequest { return nil } -func (s *TestSigner) SignCert(ctx context.Context, req *structs.CASignRequest) (*structs.IssuedCert, error) { +func (s *testSigner) SignCert(ctx context.Context, req *structs.CASignRequest) (*structs.IssuedCert, error) { useExpiredCert := false s.signCallLock.Lock() s.signCallCapture = append(s.signCallCapture, req) @@ -180,17 +147,8 @@ func (s *TestSigner) SignCert(ctx context.Context, req *structs.CASignRequest) ( return nil, fmt.Errorf("error parsing CSR URI: %w", err) } - var isService bool - var serviceID *connect.SpiffeIDService - var workloadID *connect.SpiffeIDWorkloadIdentity - - switch spiffeID.(type) { - case *connect.SpiffeIDService: - isService = true - serviceID = spiffeID.(*connect.SpiffeIDService) - case *connect.SpiffeIDWorkloadIdentity: - workloadID = spiffeID.(*connect.SpiffeIDWorkloadIdentity) - default: + serviceID, isService := spiffeID.(*connect.SpiffeIDService) + if !isService { return nil, fmt.Errorf("unexpected spiffeID type %T", spiffeID) } @@ -270,97 +228,16 @@ func (s *TestSigner) SignCert(ctx context.Context, req *structs.CASignRequest) ( } index := s.nextIndex() - if isService { - // Service Spiffe ID case - return &structs.IssuedCert{ - SerialNumber: connect.EncodeSerialNumber(leafCert.SerialNumber), - CertPEM: leafPEM, - Service: serviceID.Service, - ServiceURI: leafCert.URIs[0].String(), - ValidAfter: leafCert.NotBefore, - ValidBefore: leafCert.NotAfter, - RaftIndex: structs.RaftIndex{ - CreateIndex: index, - ModifyIndex: index, - }, - }, nil - } else { - // Workload identity Spiffe ID case - return &structs.IssuedCert{ - SerialNumber: connect.EncodeSerialNumber(leafCert.SerialNumber), - CertPEM: leafPEM, - WorkloadIdentity: workloadID.WorkloadIdentity, - WorkloadIdentityURI: leafCert.URIs[0].String(), - ValidAfter: leafCert.NotBefore, - ValidBefore: leafCert.NotAfter, - RaftIndex: structs.RaftIndex{ - CreateIndex: index, - ModifyIndex: index, - }, - }, nil - } -} - -type testRootsReader struct { - mu sync.Mutex - index uint64 - roots *structs.IndexedCARoots - watcher chan struct{} -} - -func newTestRootsReader(t *testing.T) *testRootsReader { - r := &testRootsReader{ - watcher: make(chan struct{}), - } - t.Cleanup(func() { - r.mu.Lock() - watcher := r.watcher - r.mu.Unlock() - close(watcher) - }) - return r -} - -var _ RootsReader = (*testRootsReader)(nil) - -func (r *testRootsReader) Set(roots *structs.IndexedCARoots) { - r.mu.Lock() - oldWatcher := r.watcher - r.watcher = make(chan struct{}) - r.roots = roots - if roots == nil { - r.index = 1 - } else { - r.index = roots.Index - } - r.mu.Unlock() - - close(oldWatcher) -} - -func (r *testRootsReader) Get() (*structs.IndexedCARoots, error) { - r.mu.Lock() - defer r.mu.Unlock() - return r.roots, nil -} - -func (r *testRootsReader) Notify(ctx context.Context, correlationID string, ch chan<- cacheshim.UpdateEvent) error { - r.mu.Lock() - watcher := r.watcher - r.mu.Unlock() - - go func() { - <-watcher - - r.mu.Lock() - defer r.mu.Unlock() - - ch <- cacheshim.UpdateEvent{ - CorrelationID: correlationID, - Result: r.roots, - Meta: cacheshim.ResultMeta{Index: r.index}, - Err: nil, - } - }() - return nil + return &structs.IssuedCert{ + SerialNumber: connect.EncodeSerialNumber(leafCert.SerialNumber), + CertPEM: leafPEM, + Service: serviceID.Service, + ServiceURI: leafCert.URIs[0].String(), + ValidAfter: leafCert.NotBefore, + ValidBefore: leafCert.NotAfter, + RaftIndex: structs.RaftIndex{ + CreateIndex: index, + ModifyIndex: index, + }, + }, nil } diff --git a/agent/leafcert/structs.go b/agent/leafcert/structs.go index 685756c8dc8c5..531d35c897e68 100644 --- a/agent/leafcert/structs.go +++ b/agent/leafcert/structs.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( @@ -11,7 +8,7 @@ import ( "github.com/mitchellh/hashstructure" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/cacheshim" + "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/agent/structs" ) @@ -31,27 +28,16 @@ type ConnectCALeafRequest struct { // The following flags indicate the entity we are requesting a cert for. // Only one of these must be specified. - WorkloadIdentity string // Given a WorkloadIdentity name, the request is for a SpiffeIDWorkload. - Service string // Given a Service name, not ID, the request is for a SpiffeIDService. - Agent string // Given an Agent name, not ID, the request is for a SpiffeIDAgent. - Kind structs.ServiceKind // Given "mesh-gateway", the request is for a SpiffeIDMeshGateway. No other kinds supported. - Server bool // If true, the request is for a SpiffeIDServer. + Service string // Given a Service name, not ID, the request is for a SpiffeIDService. + Agent string // Given an Agent name, not ID, the request is for a SpiffeIDAgent. + Kind structs.ServiceKind // Given "mesh-gateway", the request is for a SpiffeIDMeshGateway. No other kinds supported. + Server bool // If true, the request is for a SpiffeIDServer. } func (r *ConnectCALeafRequest) Key() string { r.EnterpriseMeta.Normalize() switch { - case r.WorkloadIdentity != "": - v, err := hashstructure.Hash([]any{ - r.WorkloadIdentity, - r.EnterpriseMeta, - r.DNSSAN, - r.IPSAN, - }, nil) - if err == nil { - return fmt.Sprintf("workloadidentity:%d", v) - } case r.Agent != "": v, err := hashstructure.Hash([]any{ r.Agent, @@ -105,8 +91,8 @@ func (req *ConnectCALeafRequest) TargetPartition() string { return req.PartitionOrDefault() } -func (r *ConnectCALeafRequest) CacheInfo() cacheshim.RequestInfo { - return cacheshim.RequestInfo{ +func (r *ConnectCALeafRequest) CacheInfo() cache.RequestInfo { + return cache.RequestInfo{ Token: r.Token, Key: r.Key(), Datacenter: r.Datacenter, diff --git a/agent/leafcert/structs_test.go b/agent/leafcert/structs_test.go index 6a8e034700313..bb131f10ed7c6 100644 --- a/agent/leafcert/structs_test.go +++ b/agent/leafcert/structs_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( diff --git a/agent/leafcert/util.go b/agent/leafcert/util.go index 795aa62ac11c8..a7453df37b4f9 100644 --- a/agent/leafcert/util.go +++ b/agent/leafcert/util.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( diff --git a/agent/leafcert/util_test.go b/agent/leafcert/util_test.go index 0716a9af88f24..be89ad5936c19 100644 --- a/agent/leafcert/util_test.go +++ b/agent/leafcert/util_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( diff --git a/agent/leafcert/watch.go b/agent/leafcert/watch.go index 93d027b90c124..62a7260c42875 100644 --- a/agent/leafcert/watch.go +++ b/agent/leafcert/watch.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package leafcert import ( @@ -8,7 +5,7 @@ import ( "fmt" "time" - "github.com/hashicorp/consul/agent/cacheshim" + "github.com/hashicorp/consul/agent/cache" "github.com/hashicorp/consul/lib" ) @@ -43,9 +40,9 @@ func (m *Manager) Notify( ctx context.Context, req *ConnectCALeafRequest, correlationID string, - ch chan<- cacheshim.UpdateEvent, + ch chan<- cache.UpdateEvent, ) error { - return m.NotifyCallback(ctx, req, correlationID, func(ctx context.Context, event cacheshim.UpdateEvent) { + return m.NotifyCallback(ctx, req, correlationID, func(ctx context.Context, event cache.UpdateEvent) { select { case ch <- event: case <-ctx.Done(): @@ -60,7 +57,7 @@ func (m *Manager) NotifyCallback( ctx context.Context, req *ConnectCALeafRequest, correlationID string, - cb cacheshim.Callback, + cb cache.Callback, ) error { if req.Key() == "" { return fmt.Errorf("a key is required") @@ -81,7 +78,7 @@ func (m *Manager) notifyBlockingQuery( ctx context.Context, req *ConnectCALeafRequest, correlationID string, - cb cacheshim.Callback, + cb cache.Callback, ) { // Always start at 0 index to deliver the initial (possibly currently cached // value). @@ -106,7 +103,7 @@ func (m *Manager) notifyBlockingQuery( // Check the index of the value returned in the cache entry to be sure it // changed if index == 0 || index < meta.Index { - cb(ctx, cacheshim.UpdateEvent{ + cb(ctx, cache.UpdateEvent{ CorrelationID: correlationID, Result: newValue, Meta: meta, diff --git a/agent/local/state.go b/agent/local/state.go index 67e72aece0b4d..6cd5b0c82a584 100644 --- a/agent/local/state.go +++ b/agent/local/state.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package local diff --git a/agent/local/state_internal_test.go b/agent/local/state_internal_test.go index 61fc2c0273a80..ba68e20f287a6 100644 --- a/agent/local/state_internal_test.go +++ b/agent/local/state_internal_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package local diff --git a/agent/local/state_test.go b/agent/local/state_test.go index ced73201e72bd..4751352ec1c8f 100644 --- a/agent/local/state_test.go +++ b/agent/local/state_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package local_test diff --git a/agent/local/testing.go b/agent/local/testing.go index 5e9ae15ac3763..5303cb6b0c4ac 100644 --- a/agent/local/testing.go +++ b/agent/local/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package local diff --git a/agent/log-drop/log-drop.go b/agent/log-drop/log-drop.go index ea08f88d890b0..54bc09c5a8c3b 100644 --- a/agent/log-drop/log-drop.go +++ b/agent/log-drop/log-drop.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logdrop diff --git a/agent/log-drop/log-drop_test.go b/agent/log-drop/log-drop_test.go index c050a734be4a8..fdb61a059e525 100644 --- a/agent/log-drop/log-drop_test.go +++ b/agent/log-drop/log-drop_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logdrop diff --git a/agent/metadata/build.go b/agent/metadata/build.go index 76a432d9a380b..b50fa96acc7af 100644 --- a/agent/metadata/build.go +++ b/agent/metadata/build.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package metadata diff --git a/agent/metadata/build_test.go b/agent/metadata/build_test.go index 888b9b0210c4b..4688db2e1850f 100644 --- a/agent/metadata/build_test.go +++ b/agent/metadata/build_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package metadata diff --git a/agent/metadata/server.go b/agent/metadata/server.go index 2e626787bdff7..64c9936909892 100644 --- a/agent/metadata/server.go +++ b/agent/metadata/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package metadata diff --git a/agent/metadata/server_internal_test.go b/agent/metadata/server_internal_test.go index bb0561ab2d193..5f3d47724ee91 100644 --- a/agent/metadata/server_internal_test.go +++ b/agent/metadata/server_internal_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package metadata diff --git a/agent/metadata/server_test.go b/agent/metadata/server_test.go index 78b16f2599b2f..8ee63fa3b413f 100644 --- a/agent/metadata/server_test.go +++ b/agent/metadata/server_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package metadata_test diff --git a/agent/metrics.go b/agent/metrics.go index 58f9e3c829e10..d9294eb25cb95 100644 --- a/agent/metrics.go +++ b/agent/metrics.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/metrics/testing.go b/agent/metrics/testing.go index 3663d6834c16d..0fc3455ab5e70 100644 --- a/agent/metrics/testing.go +++ b/agent/metrics/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package metrics diff --git a/agent/metrics_test.go b/agent/metrics_test.go index f7e15ca40e3b9..da853c56b067e 100644 --- a/agent/metrics_test.go +++ b/agent/metrics_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -20,7 +20,6 @@ import ( "github.com/hashicorp/consul/agent/rpc/middleware" "github.com/hashicorp/consul/lib/retry" "github.com/hashicorp/consul/sdk/testutil" - testretry "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/testrpc" "github.com/hashicorp/consul/tlsutil" ) @@ -31,16 +30,14 @@ func skipIfShortTesting(t *testing.T) { } } -func recordPromMetrics(t require.TestingT, a *TestAgent, respRec *httptest.ResponseRecorder) { - if tt, ok := t.(*testing.T); ok { - tt.Helper() - } - +func recordPromMetrics(t *testing.T, a *TestAgent, respRec *httptest.ResponseRecorder) { + t.Helper() req, err := http.NewRequest("GET", "/v1/agent/metrics?format=prometheus", nil) require.NoError(t, err, "Failed to generate new http request.") - a.srv.h.ServeHTTP(respRec, req) - require.Equalf(t, 200, respRec.Code, "expected 200, got %d, body: %s", respRec.Code, respRec.Body.String()) + _, err = a.srv.AgentMetrics(respRec, req) + require.NoError(t, err, "Failed to serve agent metrics") + } func assertMetricExists(t *testing.T, respRec *httptest.ResponseRecorder, metric string) { @@ -487,24 +484,28 @@ func TestHTTPHandlers_AgentMetrics_WAL_Prometheus(t *testing.T) { defer a.Shutdown() testrpc.WaitForLeader(t, a.RPC, "dc1") - testretry.Run(t, func(r *testretry.R) { - respRec := httptest.NewRecorder() - recordPromMetrics(r, a, respRec) - - out := respRec.Body.String() - require.Contains(r, out, "agent_5_raft_wal_head_truncations") - require.Contains(r, out, "agent_5_raft_wal_last_segment_age_seconds") - require.Contains(r, out, "agent_5_raft_wal_log_appends") - require.Contains(r, out, "agent_5_raft_wal_log_entries_read") - require.Contains(r, out, "agent_5_raft_wal_log_entries_written") - require.Contains(r, out, "agent_5_raft_wal_log_entry_bytes_read") - require.Contains(r, out, "agent_5_raft_wal_log_entry_bytes_written") - require.Contains(r, out, "agent_5_raft_wal_segment_rotations") - require.Contains(r, out, "agent_5_raft_wal_stable_gets") - require.Contains(r, out, "agent_5_raft_wal_stable_sets") - require.Contains(r, out, "agent_5_raft_wal_tail_truncations") - }) + respRec := httptest.NewRecorder() + recordPromMetrics(t, a, respRec) + out := respRec.Body.String() + defer func() { + if t.Failed() { + t.Log("--- Failed output START ---") + t.Log(out) + t.Log("--- Failed output END ---") + } + }() + require.Contains(t, out, "agent_5_raft_wal_head_truncations") + require.Contains(t, out, "agent_5_raft_wal_last_segment_age_seconds") + require.Contains(t, out, "agent_5_raft_wal_log_appends") + require.Contains(t, out, "agent_5_raft_wal_log_entries_read") + require.Contains(t, out, "agent_5_raft_wal_log_entries_written") + require.Contains(t, out, "agent_5_raft_wal_log_entry_bytes_read") + require.Contains(t, out, "agent_5_raft_wal_log_entry_bytes_written") + require.Contains(t, out, "agent_5_raft_wal_segment_rotations") + require.Contains(t, out, "agent_5_raft_wal_stable_gets") + require.Contains(t, out, "agent_5_raft_wal_stable_sets") + require.Contains(t, out, "agent_5_raft_wal_tail_truncations") }) t.Run("server without WAL enabled emits no WAL metrics", func(t *testing.T) { @@ -590,17 +591,22 @@ func TestHTTPHandlers_AgentMetrics_LogVerifier_Prometheus(t *testing.T) { defer a.Shutdown() testrpc.WaitForLeader(t, a.RPC, "dc1") - testretry.Run(t, func(r *testretry.R) { - respRec := httptest.NewRecorder() - recordPromMetrics(r, a, respRec) - - out := respRec.Body.String() - require.Contains(r, out, "agent_5_raft_logstore_verifier_checkpoints_written") - require.Contains(r, out, "agent_5_raft_logstore_verifier_dropped_reports") - require.Contains(r, out, "agent_5_raft_logstore_verifier_ranges_verified") - require.Contains(r, out, "agent_5_raft_logstore_verifier_read_checksum_failures") - require.Contains(r, out, "agent_5_raft_logstore_verifier_write_checksum_failures") - }) + respRec := httptest.NewRecorder() + recordPromMetrics(t, a, respRec) + + out := respRec.Body.String() + defer func() { + if t.Failed() { + t.Log("--- Failed output START ---") + t.Log(out) + t.Log("--- Failed output END ---") + } + }() + require.Contains(t, out, "agent_5_raft_logstore_verifier_checkpoints_written") + require.Contains(t, out, "agent_5_raft_logstore_verifier_dropped_reports") + require.Contains(t, out, "agent_5_raft_logstore_verifier_ranges_verified") + require.Contains(t, out, "agent_5_raft_logstore_verifier_read_checksum_failures") + require.Contains(t, out, "agent_5_raft_logstore_verifier_write_checksum_failures") }) t.Run("server with verifier disabled emits no extra metrics", func(t *testing.T) { diff --git a/agent/mock/notify.go b/agent/mock/notify.go index 00dc9a3864a7b..1aa700b31d2d3 100644 --- a/agent/mock/notify.go +++ b/agent/mock/notify.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package mock diff --git a/agent/nodeid.go b/agent/nodeid.go index c2192fac9123c..1e5823aef7c6c 100644 --- a/agent/nodeid.go +++ b/agent/nodeid.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/nodeid_test.go b/agent/nodeid_test.go index 73ce601249db3..d48889bf6d8df 100644 --- a/agent/nodeid_test.go +++ b/agent/nodeid_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/notify.go b/agent/notify.go index 80a150b19413a..eec501f098ada 100644 --- a/agent/notify.go +++ b/agent/notify.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/notify_test.go b/agent/notify_test.go index f256ee319ce7d..fe08800ae2ec8 100644 --- a/agent/notify_test.go +++ b/agent/notify_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/operator_endpoint.go b/agent/operator_endpoint.go index f669c13bd5caa..099f3dcfe4b08 100644 --- a/agent/operator_endpoint.go +++ b/agent/operator_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/operator_endpoint_ce.go b/agent/operator_endpoint_ce.go index 3abe7bc9109b0..cf2ba2a2027d9 100644 --- a/agent/operator_endpoint_ce.go +++ b/agent/operator_endpoint_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/operator_endpoint_ce_test.go b/agent/operator_endpoint_ce_test.go index 7ab918c7cc253..f4de46f9050c9 100644 --- a/agent/operator_endpoint_ce_test.go +++ b/agent/operator_endpoint_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/operator_endpoint_test.go b/agent/operator_endpoint_test.go index ffe5c1a53abe6..4d90dbb2249ef 100644 --- a/agent/operator_endpoint_test.go +++ b/agent/operator_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/peering_endpoint.go b/agent/peering_endpoint.go index 2d5cab92be2e7..a1fbd009acc60 100644 --- a/agent/peering_endpoint.go +++ b/agent/peering_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/peering_endpoint_ce_test.go b/agent/peering_endpoint_ce_test.go index 57c3d5289e729..b0395ea968398 100644 --- a/agent/peering_endpoint_ce_test.go +++ b/agent/peering_endpoint_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/peering_endpoint_test.go b/agent/peering_endpoint_test.go index ba3b704b8b5ad..7ec63c1cd73eb 100644 --- a/agent/peering_endpoint_test.go +++ b/agent/peering_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/pool/conn.go b/agent/pool/conn.go index 24d4c2cba4dc9..45a2c09486177 100644 --- a/agent/pool/conn.go +++ b/agent/pool/conn.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pool diff --git a/agent/pool/peek.go b/agent/pool/peek.go index b631134341d9a..d6557bb23db8c 100644 --- a/agent/pool/peek.go +++ b/agent/pool/peek.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pool diff --git a/agent/pool/peek_test.go b/agent/pool/peek_test.go index 29fbe9d4ab72e..cb53c421f9c2e 100644 --- a/agent/pool/peek_test.go +++ b/agent/pool/peek_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pool diff --git a/agent/pool/pool.go b/agent/pool/pool.go index 899cefe2e9740..cadb0e4af4ec6 100644 --- a/agent/pool/pool.go +++ b/agent/pool/pool.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pool diff --git a/agent/prepared_query_endpoint.go b/agent/prepared_query_endpoint.go index 15ab1005e48b5..8d5f9fdc5313f 100644 --- a/agent/prepared_query_endpoint.go +++ b/agent/prepared_query_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/prepared_query_endpoint_test.go b/agent/prepared_query_endpoint_test.go index 07e4b8e68c70e..f96c43ad8b904 100644 --- a/agent/prepared_query_endpoint_test.go +++ b/agent/prepared_query_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/proxycfg-glue/config_entry.go b/agent/proxycfg-glue/config_entry.go index 3a79e228277d7..cd86d91e1e91f 100644 --- a/agent/proxycfg-glue/config_entry.go +++ b/agent/proxycfg-glue/config_entry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/discovery_chain.go b/agent/proxycfg-glue/discovery_chain.go index 518467492d7cc..3b322e6b334f9 100644 --- a/agent/proxycfg-glue/discovery_chain.go +++ b/agent/proxycfg-glue/discovery_chain.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/discovery_chain_test.go b/agent/proxycfg-glue/discovery_chain_test.go index e4156667d36b7..60d48537c684b 100644 --- a/agent/proxycfg-glue/discovery_chain_test.go +++ b/agent/proxycfg-glue/discovery_chain_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/exported_peered_services.go b/agent/proxycfg-glue/exported_peered_services.go index 1b92600451710..8637891f1556b 100644 --- a/agent/proxycfg-glue/exported_peered_services.go +++ b/agent/proxycfg-glue/exported_peered_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/exported_peered_services_test.go b/agent/proxycfg-glue/exported_peered_services_test.go index 91b42323fab8a..a2b99d4d25b5f 100644 --- a/agent/proxycfg-glue/exported_peered_services_test.go +++ b/agent/proxycfg-glue/exported_peered_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/federation_state_list_mesh_gateways.go b/agent/proxycfg-glue/federation_state_list_mesh_gateways.go index c34303552c0a2..f5f32f1c01cba 100644 --- a/agent/proxycfg-glue/federation_state_list_mesh_gateways.go +++ b/agent/proxycfg-glue/federation_state_list_mesh_gateways.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/federation_state_list_mesh_gateways_test.go b/agent/proxycfg-glue/federation_state_list_mesh_gateways_test.go index baf477f4340b2..fd73e19aaf698 100644 --- a/agent/proxycfg-glue/federation_state_list_mesh_gateways_test.go +++ b/agent/proxycfg-glue/federation_state_list_mesh_gateways_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/gateway_services.go b/agent/proxycfg-glue/gateway_services.go index 555b1d5385359..24f4087eea817 100644 --- a/agent/proxycfg-glue/gateway_services.go +++ b/agent/proxycfg-glue/gateway_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/gateway_services_test.go b/agent/proxycfg-glue/gateway_services_test.go index ff89a62c92e45..eb853bd7b49e9 100644 --- a/agent/proxycfg-glue/gateway_services_test.go +++ b/agent/proxycfg-glue/gateway_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/glue.go b/agent/proxycfg-glue/glue.go index a4fa538b92859..817e151b9500b 100644 --- a/agent/proxycfg-glue/glue.go +++ b/agent/proxycfg-glue/glue.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/health.go b/agent/proxycfg-glue/health.go index 6acf5b7023026..f0808da978ce9 100644 --- a/agent/proxycfg-glue/health.go +++ b/agent/proxycfg-glue/health.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/health_blocking.go b/agent/proxycfg-glue/health_blocking.go index 8ed384f837efa..3504e050aa707 100644 --- a/agent/proxycfg-glue/health_blocking.go +++ b/agent/proxycfg-glue/health_blocking.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/health_blocking_test.go b/agent/proxycfg-glue/health_blocking_test.go index 3a2d00c2c5d90..461cd726bc5e1 100644 --- a/agent/proxycfg-glue/health_blocking_test.go +++ b/agent/proxycfg-glue/health_blocking_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package proxycfgglue import ( diff --git a/agent/proxycfg-glue/health_test.go b/agent/proxycfg-glue/health_test.go index 821e22a789085..6f5702ca19c87 100644 --- a/agent/proxycfg-glue/health_test.go +++ b/agent/proxycfg-glue/health_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/helpers_test.go b/agent/proxycfg-glue/helpers_test.go index 3c7eb5b7ad153..0d8bd8c9660d0 100644 --- a/agent/proxycfg-glue/helpers_test.go +++ b/agent/proxycfg-glue/helpers_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/intention_upstreams.go b/agent/proxycfg-glue/intention_upstreams.go index dc6731372271f..07a12c4ddb6c3 100644 --- a/agent/proxycfg-glue/intention_upstreams.go +++ b/agent/proxycfg-glue/intention_upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/intention_upstreams_test.go b/agent/proxycfg-glue/intention_upstreams_test.go index bfaeb55b38646..3028524eb0f29 100644 --- a/agent/proxycfg-glue/intention_upstreams_test.go +++ b/agent/proxycfg-glue/intention_upstreams_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/intentions.go b/agent/proxycfg-glue/intentions.go index f3186c6689ab9..5176054325962 100644 --- a/agent/proxycfg-glue/intentions.go +++ b/agent/proxycfg-glue/intentions.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/intentions_ce.go b/agent/proxycfg-glue/intentions_ce.go index e7efb978dff1c..bd1823adb192d 100644 --- a/agent/proxycfg-glue/intentions_ce.go +++ b/agent/proxycfg-glue/intentions_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package proxycfgglue diff --git a/agent/proxycfg-glue/intentions_test.go b/agent/proxycfg-glue/intentions_test.go index 0e1ab10918865..07d3a8067e34b 100644 --- a/agent/proxycfg-glue/intentions_test.go +++ b/agent/proxycfg-glue/intentions_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/internal_service_dump.go b/agent/proxycfg-glue/internal_service_dump.go index d1c701083d520..e41dc020b1d04 100644 --- a/agent/proxycfg-glue/internal_service_dump.go +++ b/agent/proxycfg-glue/internal_service_dump.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/internal_service_dump_test.go b/agent/proxycfg-glue/internal_service_dump_test.go index 1eba4c043828c..a6e6c3b028607 100644 --- a/agent/proxycfg-glue/internal_service_dump_test.go +++ b/agent/proxycfg-glue/internal_service_dump_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/leafcerts.go b/agent/proxycfg-glue/leafcerts.go index b805586a154a3..24631ffc31134 100644 --- a/agent/proxycfg-glue/leafcerts.go +++ b/agent/proxycfg-glue/leafcerts.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/peered_upstreams.go b/agent/proxycfg-glue/peered_upstreams.go index f345c26df572e..df38b3f0daf4d 100644 --- a/agent/proxycfg-glue/peered_upstreams.go +++ b/agent/proxycfg-glue/peered_upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/peered_upstreams_test.go b/agent/proxycfg-glue/peered_upstreams_test.go index 026fd67a3455f..b0e7c0d8f83c4 100644 --- a/agent/proxycfg-glue/peered_upstreams_test.go +++ b/agent/proxycfg-glue/peered_upstreams_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/peering_list.go b/agent/proxycfg-glue/peering_list.go index 6e7a78c707f15..219bf9b955298 100644 --- a/agent/proxycfg-glue/peering_list.go +++ b/agent/proxycfg-glue/peering_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/peering_list_test.go b/agent/proxycfg-glue/peering_list_test.go index 575d161b4e5d3..f570dbbcc2a86 100644 --- a/agent/proxycfg-glue/peering_list_test.go +++ b/agent/proxycfg-glue/peering_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/resolved_service_config.go b/agent/proxycfg-glue/resolved_service_config.go index 11654cd767b2e..89611bbc07114 100644 --- a/agent/proxycfg-glue/resolved_service_config.go +++ b/agent/proxycfg-glue/resolved_service_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/resolved_service_config_test.go b/agent/proxycfg-glue/resolved_service_config_test.go index 248ab4eab363f..60d39eec205f0 100644 --- a/agent/proxycfg-glue/resolved_service_config_test.go +++ b/agent/proxycfg-glue/resolved_service_config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/service_http_checks.go b/agent/proxycfg-glue/service_http_checks.go index 2d0a9dfcff51f..45521f712ae8b 100644 --- a/agent/proxycfg-glue/service_http_checks.go +++ b/agent/proxycfg-glue/service_http_checks.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/service_http_checks_test.go b/agent/proxycfg-glue/service_http_checks_test.go index 87bdfc7abe609..cfe28c7e89f9f 100644 --- a/agent/proxycfg-glue/service_http_checks_test.go +++ b/agent/proxycfg-glue/service_http_checks_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/service_list.go b/agent/proxycfg-glue/service_list.go index f4a9380df715a..418103aef6fed 100644 --- a/agent/proxycfg-glue/service_list.go +++ b/agent/proxycfg-glue/service_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/service_list_test.go b/agent/proxycfg-glue/service_list_test.go index c6372aaf4ea1d..154c1300a3275 100644 --- a/agent/proxycfg-glue/service_list_test.go +++ b/agent/proxycfg-glue/service_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/trust_bundle.go b/agent/proxycfg-glue/trust_bundle.go index f623d2a5555c9..108e7ea9f9aec 100644 --- a/agent/proxycfg-glue/trust_bundle.go +++ b/agent/proxycfg-glue/trust_bundle.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-glue/trust_bundle_test.go b/agent/proxycfg-glue/trust_bundle_test.go index e2082e3d240be..da77e32a56e86 100644 --- a/agent/proxycfg-glue/trust_bundle_test.go +++ b/agent/proxycfg-glue/trust_bundle_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfgglue diff --git a/agent/proxycfg-sources/catalog/config_source.go b/agent/proxycfg-sources/catalog/config_source.go index 9ded9aa7fd4ed..3fbca88de5087 100644 --- a/agent/proxycfg-sources/catalog/config_source.go +++ b/agent/proxycfg-sources/catalog/config_source.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package catalog @@ -17,8 +17,6 @@ import ( "github.com/hashicorp/consul/agent/local" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - "github.com/hashicorp/consul/proto-public/pbresource" ) const source proxycfg.ProxySource = "catalog" @@ -50,13 +48,11 @@ func NewConfigSource(cfg Config) *ConfigSource { // Watch wraps the underlying proxycfg.Manager and dynamically registers // services from the catalog with it when requested by the xDS server. -func (m *ConfigSource) Watch(id *pbresource.ID, nodeName string, token string) (<-chan proxysnapshot.ProxySnapshot, limiter.SessionTerminatedChan, proxysnapshot.CancelFunc, error) { - // Create service ID - serviceID := structs.NewServiceID(id.Name, GetEnterpriseMetaFromResourceID(id)) +func (m *ConfigSource) Watch(serviceID structs.ServiceID, nodeName string, token string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.CancelFunc, error) { // If the service is registered to the local agent, use the LocalConfigSource // rather than trying to configure it from the catalog. if nodeName == m.NodeName && m.LocalState.ServiceExists(serviceID) { - return m.LocalConfigSource.Watch(id, nodeName, token) + return m.LocalConfigSource.Watch(serviceID, nodeName, token) } // Begin a session with the xDS session concurrency limiter. @@ -280,7 +276,7 @@ type Config struct { //go:generate mockery --name ConfigManager --inpackage type ConfigManager interface { - Watch(req proxycfg.ProxyID) (<-chan proxysnapshot.ProxySnapshot, proxysnapshot.CancelFunc) + Watch(req proxycfg.ProxyID) (<-chan *proxycfg.ConfigSnapshot, proxycfg.CancelFunc) Register(proxyID proxycfg.ProxyID, service *structs.NodeService, source proxycfg.ProxySource, token string, overwrite bool) error Deregister(proxyID proxycfg.ProxyID, source proxycfg.ProxySource) } @@ -293,11 +289,10 @@ type Store interface { //go:generate mockery --name Watcher --inpackage type Watcher interface { - Watch(proxyID *pbresource.ID, nodeName string, token string) (<-chan proxysnapshot.ProxySnapshot, limiter.SessionTerminatedChan, proxysnapshot.CancelFunc, error) + Watch(proxyID structs.ServiceID, nodeName string, token string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.CancelFunc, error) } //go:generate mockery --name SessionLimiter --inpackage type SessionLimiter interface { BeginSession() (limiter.Session, error) - Run(ctx context.Context) } diff --git a/agent/proxycfg-sources/catalog/config_source_oss.go b/agent/proxycfg-sources/catalog/config_source_oss.go deleted file mode 100644 index 233ad64cee8fa..0000000000000 --- a/agent/proxycfg-sources/catalog/config_source_oss.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package catalog - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func GetEnterpriseMetaFromResourceID(id *pbresource.ID) *acl.EnterpriseMeta { - return acl.DefaultEnterpriseMeta() -} diff --git a/agent/proxycfg-sources/catalog/config_source_test.go b/agent/proxycfg-sources/catalog/config_source_test.go index 94d939e8cad5e..661fae9c082b1 100644 --- a/agent/proxycfg-sources/catalog/config_source_test.go +++ b/agent/proxycfg-sources/catalog/config_source_test.go @@ -1,10 +1,9 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package catalog import ( - "context" "errors" "testing" "time" @@ -20,9 +19,6 @@ import ( "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/token" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" ) func TestConfigSource_Success(t *testing.T) { @@ -79,15 +75,15 @@ func TestConfigSource_Success(t *testing.T) { }) t.Cleanup(mgr.Shutdown) - snapCh, termCh, cancelWatch1, err := mgr.Watch(rtest.Resource(pbmesh.ProxyConfigurationType, serviceID.ID).ID(), nodeName, token) + snapCh, termCh, cancelWatch1, err := mgr.Watch(serviceID, nodeName, token) require.NoError(t, err) require.Equal(t, session1TermCh, termCh) // Expect Register to have been called with the proxy's inital port. select { case snap := <-snapCh: - require.Equal(t, 9999, snap.(*proxycfg.ConfigSnapshot).Port) - require.Equal(t, token, snap.(*proxycfg.ConfigSnapshot).ProxyID.Token) + require.Equal(t, 9999, snap.Port) + require.Equal(t, token, snap.ProxyID.Token) case <-time.After(100 * time.Millisecond): t.Fatal("timeout waiting for snapshot") } @@ -111,7 +107,7 @@ func TestConfigSource_Success(t *testing.T) { // Expect Register to have been called again with the proxy's new port. select { case snap := <-snapCh: - require.Equal(t, 8888, snap.(*proxycfg.ConfigSnapshot).Port) + require.Equal(t, 8888, snap.Port) case <-time.After(100 * time.Millisecond): t.Fatal("timeout waiting for snapshot") } @@ -130,13 +126,13 @@ func TestConfigSource_Success(t *testing.T) { require.Equal(t, map[string]any{ "local_connect_timeout_ms": 123, "max_inbound_connections": 321, - }, snap.(*proxycfg.ConfigSnapshot).Proxy.Config) + }, snap.Proxy.Config) case <-time.After(100 * time.Millisecond): t.Fatal("timeout waiting for snapshot") } // Start another watch. - _, termCh2, cancelWatch2, err := mgr.Watch(rtest.Resource(pbmesh.ProxyConfigurationType, serviceID.ID).ID(), nodeName, token) + _, termCh2, cancelWatch2, err := mgr.Watch(serviceID, nodeName, token) require.NoError(t, err) require.Equal(t, session2TermCh, termCh2) @@ -170,7 +166,6 @@ func TestConfigSource_Success(t *testing.T) { func TestConfigSource_LocallyManagedService(t *testing.T) { serviceID := structs.NewServiceID("web-sidecar-proxy-1", nil) - proxyID := rtest.Resource(pbmesh.ProxyConfigurationType, serviceID.ID).ID() nodeName := "node-1" token := "token" @@ -178,8 +173,8 @@ func TestConfigSource_LocallyManagedService(t *testing.T) { localState.AddServiceWithChecks(&structs.NodeService{ID: serviceID.ID}, nil, "", false) localWatcher := NewMockWatcher(t) - localWatcher.On("Watch", proxyID, nodeName, token). - Return(make(<-chan proxysnapshot.ProxySnapshot), nil, proxysnapshot.CancelFunc(func() {}), nil) + localWatcher.On("Watch", serviceID, nodeName, token). + Return(make(<-chan *proxycfg.ConfigSnapshot), nil, proxycfg.CancelFunc(func() {}), nil) mgr := NewConfigSource(Config{ NodeName: nodeName, @@ -191,7 +186,7 @@ func TestConfigSource_LocallyManagedService(t *testing.T) { }) t.Cleanup(mgr.Shutdown) - _, _, _, err := mgr.Watch(proxyID, nodeName, token) + _, _, _, err := mgr.Watch(serviceID, nodeName, token) require.NoError(t, err) } @@ -213,12 +208,12 @@ func TestConfigSource_ErrorRegisteringService(t *testing.T) { })) var canceledWatch bool - cancel := proxysnapshot.CancelFunc(func() { canceledWatch = true }) + cancel := proxycfg.CancelFunc(func() { canceledWatch = true }) cfgMgr := NewMockConfigManager(t) cfgMgr.On("Watch", mock.Anything). - Return(make(<-chan proxysnapshot.ProxySnapshot), cancel) + Return(make(<-chan *proxycfg.ConfigSnapshot), cancel) cfgMgr.On("Register", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(errors.New("KABOOM")) @@ -238,7 +233,7 @@ func TestConfigSource_ErrorRegisteringService(t *testing.T) { }) t.Cleanup(mgr.Shutdown) - _, _, _, err := mgr.Watch(rtest.Resource(pbmesh.ProxyConfigurationType, serviceID.ID).ID(), nodeName, token) + _, _, _, err := mgr.Watch(serviceID, nodeName, token) require.Error(t, err) require.True(t, canceledWatch, "watch should've been canceled") @@ -263,12 +258,12 @@ func TestConfigSource_NotProxyService(t *testing.T) { })) var canceledWatch bool - cancel := proxysnapshot.CancelFunc(func() { canceledWatch = true }) + cancel := proxycfg.CancelFunc(func() { canceledWatch = true }) cfgMgr := NewMockConfigManager(t) cfgMgr.On("Watch", mock.Anything). - Return(make(<-chan proxysnapshot.ProxySnapshot), cancel) + Return(make(<-chan *proxycfg.ConfigSnapshot), cancel) mgr := NewConfigSource(Config{ Manager: cfgMgr, @@ -279,7 +274,7 @@ func TestConfigSource_NotProxyService(t *testing.T) { }) t.Cleanup(mgr.Shutdown) - _, _, _, err := mgr.Watch(rtest.Resource(pbmesh.ProxyConfigurationType, serviceID.ID).ID(), nodeName, token) + _, _, _, err := mgr.Watch(serviceID, nodeName, token) require.Error(t, err) require.Contains(t, err.Error(), "must be a sidecar proxy or gateway") require.True(t, canceledWatch, "watch should've been canceled") @@ -296,7 +291,7 @@ func TestConfigSource_SessionLimiterError(t *testing.T) { t.Cleanup(src.Shutdown) _, _, _, err := src.Watch( - rtest.Resource(pbmesh.ProxyConfigurationType, "web-sidecar-proxy-1").ID(), + structs.NewServiceID("web-sidecar-proxy-1", nil), "node-name", "token", ) @@ -314,9 +309,9 @@ func testConfigManager(t *testing.T, serviceID structs.ServiceID, nodeName strin Token: token, } - snapCh := make(chan proxysnapshot.ProxySnapshot, 1) + snapCh := make(chan *proxycfg.ConfigSnapshot, 1) cfgMgr.On("Watch", proxyID). - Return((<-chan proxysnapshot.ProxySnapshot)(snapCh), proxysnapshot.CancelFunc(func() {}), nil) + Return((<-chan *proxycfg.ConfigSnapshot)(snapCh), proxycfg.CancelFunc(func() {}), nil) cfgMgr.On("Register", mock.Anything, mock.Anything, source, token, false). Run(func(args mock.Arguments) { @@ -360,8 +355,6 @@ func (nullSessionLimiter) BeginSession() (limiter.Session, error) { return nullSession{}, nil } -func (nullSessionLimiter) Run(ctx context.Context) {} - type nullSession struct{} func (nullSession) End() {} diff --git a/agent/proxycfg-sources/catalog/mock_ConfigManager.go b/agent/proxycfg-sources/catalog/mock_ConfigManager.go index 37deffb022d8e..3ae51c5f6a95f 100644 --- a/agent/proxycfg-sources/catalog/mock_ConfigManager.go +++ b/agent/proxycfg-sources/catalog/mock_ConfigManager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.1. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package catalog @@ -6,8 +6,6 @@ import ( proxycfg "github.com/hashicorp/consul/agent/proxycfg" mock "github.com/stretchr/testify/mock" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - structs "github.com/hashicorp/consul/agent/structs" ) @@ -36,39 +34,37 @@ func (_m *MockConfigManager) Register(proxyID proxycfg.ProxyID, service *structs } // Watch provides a mock function with given fields: req -func (_m *MockConfigManager) Watch(req proxycfg.ProxyID) (<-chan proxysnapshot.ProxySnapshot, proxysnapshot.CancelFunc) { +func (_m *MockConfigManager) Watch(req proxycfg.ProxyID) (<-chan *proxycfg.ConfigSnapshot, proxycfg.CancelFunc) { ret := _m.Called(req) - var r0 <-chan proxysnapshot.ProxySnapshot - var r1 proxysnapshot.CancelFunc - if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) (<-chan proxysnapshot.ProxySnapshot, proxysnapshot.CancelFunc)); ok { - return rf(req) - } - if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) <-chan proxysnapshot.ProxySnapshot); ok { + var r0 <-chan *proxycfg.ConfigSnapshot + if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) <-chan *proxycfg.ConfigSnapshot); ok { r0 = rf(req) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(<-chan proxysnapshot.ProxySnapshot) + r0 = ret.Get(0).(<-chan *proxycfg.ConfigSnapshot) } } - if rf, ok := ret.Get(1).(func(proxycfg.ProxyID) proxysnapshot.CancelFunc); ok { + var r1 proxycfg.CancelFunc + if rf, ok := ret.Get(1).(func(proxycfg.ProxyID) proxycfg.CancelFunc); ok { r1 = rf(req) } else { if ret.Get(1) != nil { - r1 = ret.Get(1).(proxysnapshot.CancelFunc) + r1 = ret.Get(1).(proxycfg.CancelFunc) } } return r0, r1 } -// NewMockConfigManager creates a new instance of MockConfigManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockConfigManager(t interface { +type mockConstructorTestingTNewMockConfigManager interface { mock.TestingT Cleanup(func()) -}) *MockConfigManager { +} + +// NewMockConfigManager creates a new instance of MockConfigManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockConfigManager(t mockConstructorTestingTNewMockConfigManager) *MockConfigManager { mock := &MockConfigManager{} mock.Mock.Test(t) diff --git a/agent/proxycfg-sources/catalog/mock_SessionLimiter.go b/agent/proxycfg-sources/catalog/mock_SessionLimiter.go index 39cd430f06d3d..3b7147cb064c6 100644 --- a/agent/proxycfg-sources/catalog/mock_SessionLimiter.go +++ b/agent/proxycfg-sources/catalog/mock_SessionLimiter.go @@ -1,10 +1,8 @@ -// Code generated by mockery v2.33.1. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package catalog import ( - context "context" - limiter "github.com/hashicorp/consul/agent/grpc-external/limiter" mock "github.com/stretchr/testify/mock" ) @@ -19,10 +17,6 @@ func (_m *MockSessionLimiter) BeginSession() (limiter.Session, error) { ret := _m.Called() var r0 limiter.Session - var r1 error - if rf, ok := ret.Get(0).(func() (limiter.Session, error)); ok { - return rf() - } if rf, ok := ret.Get(0).(func() limiter.Session); ok { r0 = rf() } else { @@ -31,6 +25,7 @@ func (_m *MockSessionLimiter) BeginSession() (limiter.Session, error) { } } + var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -40,17 +35,13 @@ func (_m *MockSessionLimiter) BeginSession() (limiter.Session, error) { return r0, r1 } -// Run provides a mock function with given fields: ctx -func (_m *MockSessionLimiter) Run(ctx context.Context) { - _m.Called(ctx) +type mockConstructorTestingTNewMockSessionLimiter interface { + mock.TestingT + Cleanup(func()) } // NewMockSessionLimiter creates a new instance of MockSessionLimiter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockSessionLimiter(t interface { - mock.TestingT - Cleanup(func()) -}) *MockSessionLimiter { +func NewMockSessionLimiter(t mockConstructorTestingTNewMockSessionLimiter) *MockSessionLimiter { mock := &MockSessionLimiter{} mock.Mock.Test(t) diff --git a/agent/proxycfg-sources/catalog/mock_Watcher.go b/agent/proxycfg-sources/catalog/mock_Watcher.go index b77be5d98ea8f..d5ca046a40602 100644 --- a/agent/proxycfg-sources/catalog/mock_Watcher.go +++ b/agent/proxycfg-sources/catalog/mock_Watcher.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.1. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package catalog @@ -6,9 +6,9 @@ import ( limiter "github.com/hashicorp/consul/agent/grpc-external/limiter" mock "github.com/stretchr/testify/mock" - pbresource "github.com/hashicorp/consul/proto-public/pbresource" + proxycfg "github.com/hashicorp/consul/agent/proxycfg" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" + structs "github.com/hashicorp/consul/agent/structs" ) // MockWatcher is an autogenerated mock type for the Watcher type @@ -17,25 +17,20 @@ type MockWatcher struct { } // Watch provides a mock function with given fields: proxyID, nodeName, token -func (_m *MockWatcher) Watch(proxyID *pbresource.ID, nodeName string, token string) (<-chan proxysnapshot.ProxySnapshot, limiter.SessionTerminatedChan, proxysnapshot.CancelFunc, error) { +func (_m *MockWatcher) Watch(proxyID structs.ServiceID, nodeName string, token string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.CancelFunc, error) { ret := _m.Called(proxyID, nodeName, token) - var r0 <-chan proxysnapshot.ProxySnapshot - var r1 limiter.SessionTerminatedChan - var r2 proxysnapshot.CancelFunc - var r3 error - if rf, ok := ret.Get(0).(func(*pbresource.ID, string, string) (<-chan proxysnapshot.ProxySnapshot, limiter.SessionTerminatedChan, proxysnapshot.CancelFunc, error)); ok { - return rf(proxyID, nodeName, token) - } - if rf, ok := ret.Get(0).(func(*pbresource.ID, string, string) <-chan proxysnapshot.ProxySnapshot); ok { + var r0 <-chan *proxycfg.ConfigSnapshot + if rf, ok := ret.Get(0).(func(structs.ServiceID, string, string) <-chan *proxycfg.ConfigSnapshot); ok { r0 = rf(proxyID, nodeName, token) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(<-chan proxysnapshot.ProxySnapshot) + r0 = ret.Get(0).(<-chan *proxycfg.ConfigSnapshot) } } - if rf, ok := ret.Get(1).(func(*pbresource.ID, string, string) limiter.SessionTerminatedChan); ok { + var r1 limiter.SessionTerminatedChan + if rf, ok := ret.Get(1).(func(structs.ServiceID, string, string) limiter.SessionTerminatedChan); ok { r1 = rf(proxyID, nodeName, token) } else { if ret.Get(1) != nil { @@ -43,15 +38,17 @@ func (_m *MockWatcher) Watch(proxyID *pbresource.ID, nodeName string, token stri } } - if rf, ok := ret.Get(2).(func(*pbresource.ID, string, string) proxysnapshot.CancelFunc); ok { + var r2 proxycfg.CancelFunc + if rf, ok := ret.Get(2).(func(structs.ServiceID, string, string) proxycfg.CancelFunc); ok { r2 = rf(proxyID, nodeName, token) } else { if ret.Get(2) != nil { - r2 = ret.Get(2).(proxysnapshot.CancelFunc) + r2 = ret.Get(2).(proxycfg.CancelFunc) } } - if rf, ok := ret.Get(3).(func(*pbresource.ID, string, string) error); ok { + var r3 error + if rf, ok := ret.Get(3).(func(structs.ServiceID, string, string) error); ok { r3 = rf(proxyID, nodeName, token) } else { r3 = ret.Error(3) @@ -60,12 +57,13 @@ func (_m *MockWatcher) Watch(proxyID *pbresource.ID, nodeName string, token stri return r0, r1, r2, r3 } -// NewMockWatcher creates a new instance of MockWatcher. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockWatcher(t interface { +type mockConstructorTestingTNewMockWatcher interface { mock.TestingT Cleanup(func()) -}) *MockWatcher { +} + +// NewMockWatcher creates a new instance of MockWatcher. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockWatcher(t mockConstructorTestingTNewMockWatcher) *MockWatcher { mock := &MockWatcher{} mock.Mock.Test(t) diff --git a/agent/proxycfg-sources/local/config_source.go b/agent/proxycfg-sources/local/config_source.go index 7b3a835fb819d..18b8a045c421b 100644 --- a/agent/proxycfg-sources/local/config_source.go +++ b/agent/proxycfg-sources/local/config_source.go @@ -1,15 +1,12 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package local import ( "github.com/hashicorp/consul/agent/grpc-external/limiter" "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/proxycfg-sources/catalog" structs "github.com/hashicorp/consul/agent/structs" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - "github.com/hashicorp/consul/proto-public/pbresource" ) // ConfigSource wraps a proxycfg.Manager to create watches on services @@ -23,9 +20,7 @@ func NewConfigSource(cfgMgr ConfigManager) *ConfigSource { return &ConfigSource{cfgMgr} } -func (m *ConfigSource) Watch(proxyID *pbresource.ID, nodeName string, _ string) (<-chan proxysnapshot.ProxySnapshot, - limiter.SessionTerminatedChan, proxysnapshot.CancelFunc, error) { - serviceID := structs.NewServiceID(proxyID.Name, catalog.GetEnterpriseMetaFromResourceID(proxyID)) +func (m *ConfigSource) Watch(serviceID structs.ServiceID, nodeName string, _ string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.CancelFunc, error) { watchCh, cancelWatch := m.manager.Watch(proxycfg.ProxyID{ ServiceID: serviceID, NodeName: nodeName, diff --git a/agent/proxycfg-sources/local/local.go b/agent/proxycfg-sources/local/local.go index 44867eb067515..92eefe1eb85f0 100644 --- a/agent/proxycfg-sources/local/local.go +++ b/agent/proxycfg-sources/local/local.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package local integrates the proxycfg Manager with the agent's local state. package local diff --git a/agent/proxycfg-sources/local/mock_ConfigManager.go b/agent/proxycfg-sources/local/mock_ConfigManager.go index e3b2d3a445872..8f2c8fc6c836c 100644 --- a/agent/proxycfg-sources/local/mock_ConfigManager.go +++ b/agent/proxycfg-sources/local/mock_ConfigManager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.33.1. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package local @@ -6,8 +6,6 @@ import ( proxycfg "github.com/hashicorp/consul/agent/proxycfg" mock "github.com/stretchr/testify/mock" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - structs "github.com/hashicorp/consul/agent/structs" ) @@ -52,39 +50,37 @@ func (_m *MockConfigManager) RegisteredProxies(source proxycfg.ProxySource) []pr } // Watch provides a mock function with given fields: id -func (_m *MockConfigManager) Watch(id proxycfg.ProxyID) (<-chan proxysnapshot.ProxySnapshot, proxysnapshot.CancelFunc) { +func (_m *MockConfigManager) Watch(id proxycfg.ProxyID) (<-chan *proxycfg.ConfigSnapshot, proxycfg.CancelFunc) { ret := _m.Called(id) - var r0 <-chan proxysnapshot.ProxySnapshot - var r1 proxysnapshot.CancelFunc - if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) (<-chan proxysnapshot.ProxySnapshot, proxysnapshot.CancelFunc)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) <-chan proxysnapshot.ProxySnapshot); ok { + var r0 <-chan *proxycfg.ConfigSnapshot + if rf, ok := ret.Get(0).(func(proxycfg.ProxyID) <-chan *proxycfg.ConfigSnapshot); ok { r0 = rf(id) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(<-chan proxysnapshot.ProxySnapshot) + r0 = ret.Get(0).(<-chan *proxycfg.ConfigSnapshot) } } - if rf, ok := ret.Get(1).(func(proxycfg.ProxyID) proxysnapshot.CancelFunc); ok { + var r1 proxycfg.CancelFunc + if rf, ok := ret.Get(1).(func(proxycfg.ProxyID) proxycfg.CancelFunc); ok { r1 = rf(id) } else { if ret.Get(1) != nil { - r1 = ret.Get(1).(proxysnapshot.CancelFunc) + r1 = ret.Get(1).(proxycfg.CancelFunc) } } return r0, r1 } -// NewMockConfigManager creates a new instance of MockConfigManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockConfigManager(t interface { +type mockConstructorTestingTNewMockConfigManager interface { mock.TestingT Cleanup(func()) -}) *MockConfigManager { +} + +// NewMockConfigManager creates a new instance of MockConfigManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockConfigManager(t mockConstructorTestingTNewMockConfigManager) *MockConfigManager { mock := &MockConfigManager{} mock.Mock.Test(t) diff --git a/agent/proxycfg-sources/local/sync.go b/agent/proxycfg-sources/local/sync.go index b5583db43a3df..86427c9f005ba 100644 --- a/agent/proxycfg-sources/local/sync.go +++ b/agent/proxycfg-sources/local/sync.go @@ -1,11 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package local import ( "context" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" "time" "github.com/hashicorp/go-hclog" @@ -136,7 +135,7 @@ func sync(cfg SyncConfig) { //go:generate mockery --name ConfigManager --inpackage type ConfigManager interface { - Watch(id proxycfg.ProxyID) (<-chan proxysnapshot.ProxySnapshot, proxysnapshot.CancelFunc) + Watch(id proxycfg.ProxyID) (<-chan *proxycfg.ConfigSnapshot, proxycfg.CancelFunc) Register(proxyID proxycfg.ProxyID, service *structs.NodeService, source proxycfg.ProxySource, token string, overwrite bool) error Deregister(proxyID proxycfg.ProxyID, source proxycfg.ProxySource) RegisteredProxies(source proxycfg.ProxySource) []proxycfg.ProxyID diff --git a/agent/proxycfg-sources/local/sync_test.go b/agent/proxycfg-sources/local/sync_test.go index 5aa030db4cfc2..8fa4883518197 100644 --- a/agent/proxycfg-sources/local/sync_test.go +++ b/agent/proxycfg-sources/local/sync_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package local diff --git a/agent/proxycfg/api_gateway.go b/agent/proxycfg/api_gateway.go index 43798239a3535..b4954cd3973c7 100644 --- a/agent/proxycfg/api_gateway.go +++ b/agent/proxycfg/api_gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -54,11 +54,6 @@ func (h *handlerAPIGateway) initialize(ctx context.Context) (ConfigSnapshot, err return snap, err } - err = watchJWTProviders(ctx, h) - if err != nil { - return snap, err - } - snap.APIGateway.Listeners = make(map[string]structs.APIGatewayListener) snap.APIGateway.BoundListeners = make(map[string]structs.BoundAPIGatewayListener) snap.APIGateway.HTTPRoutes = watch.NewMap[structs.ResourceReference, *structs.HTTPRouteConfigEntry]() @@ -102,33 +97,27 @@ func (h *handlerAPIGateway) handleUpdate(ctx context.Context, u UpdateEvent, sna return fmt.Errorf("error filling agent cache: %v", u.Err) } - switch u.CorrelationID { - case rootsWatchID: + switch { + case u.CorrelationID == rootsWatchID: // Handle change in the CA roots if err := h.handleRootCAUpdate(u, snap); err != nil { return err } - case apiGatewayConfigWatchID, boundGatewayConfigWatchID: + case u.CorrelationID == apiGatewayConfigWatchID || u.CorrelationID == boundGatewayConfigWatchID: // Handle change in the api-gateway or bound-api-gateway config entry if err := h.handleGatewayConfigUpdate(ctx, u, snap, u.CorrelationID); err != nil { return err } - case inlineCertificateConfigWatchID: + case u.CorrelationID == inlineCertificateConfigWatchID: // Handle change in an attached inline-certificate config entry if err := h.handleInlineCertConfigUpdate(ctx, u, snap); err != nil { return err } - case routeConfigWatchID: + case u.CorrelationID == routeConfigWatchID: // Handle change in an attached http-route or tcp-route config entry if err := h.handleRouteConfigUpdate(ctx, u, snap); err != nil { return err } - case jwtProviderID: - err := setJWTProvider(u, snap) - if err != nil { - return err - } - default: if err := (*handlerUpstreams)(h).handleUpdateUpstreams(ctx, u, snap); err != nil { return err diff --git a/agent/proxycfg/api_gateway_ce.go b/agent/proxycfg/api_gateway_ce.go deleted file mode 100644 index c9ef2383979ef..0000000000000 --- a/agent/proxycfg/api_gateway_ce.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package proxycfg - -import "context" - -func watchJWTProviders(cxt context.Context, h *handlerAPIGateway) error { - return nil -} - -func setJWTProvider(u UpdateEvent, snap *ConfigSnapshot) error { - return nil -} diff --git a/agent/proxycfg/config_snapshot_glue.go b/agent/proxycfg/config_snapshot_glue.go deleted file mode 100644 index 6355e0595ec69..0000000000000 --- a/agent/proxycfg/config_snapshot_glue.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxycfg - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/logging" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -// The below functions are added to ConfigSnapshot to allow it to conform to -// the ProxySnapshot interface. -func (s *ConfigSnapshot) AllowEmptyListeners() bool { - // Ingress and API gateways are allowed to inform LDS of no listeners. - return s.Kind == structs.ServiceKindIngressGateway || - s.Kind == structs.ServiceKindAPIGateway -} - -func (s *ConfigSnapshot) AllowEmptyRoutes() bool { - // Ingress and API gateways are allowed to inform RDS of no routes. - return s.Kind == structs.ServiceKindIngressGateway || - s.Kind == structs.ServiceKindAPIGateway -} - -func (s *ConfigSnapshot) AllowEmptyClusters() bool { - // Mesh, Ingress, API and Terminating gateways are allowed to inform CDS of no clusters. - return s.Kind == structs.ServiceKindMeshGateway || - s.Kind == structs.ServiceKindTerminatingGateway || - s.Kind == structs.ServiceKindIngressGateway || - s.Kind == structs.ServiceKindAPIGateway -} - -func (s *ConfigSnapshot) Authorize(authz acl.Authorizer) error { - var authzContext acl.AuthorizerContext - switch s.Kind { - case structs.ServiceKindConnectProxy: - s.ProxyID.EnterpriseMeta.FillAuthzContext(&authzContext) - if err := authz.ToAllowAuthorizer().ServiceWriteAllowed(s.Proxy.DestinationServiceName, &authzContext); err != nil { - return status.Errorf(codes.PermissionDenied, err.Error()) - } - case structs.ServiceKindMeshGateway, structs.ServiceKindTerminatingGateway, structs.ServiceKindIngressGateway, structs.ServiceKindAPIGateway: - s.ProxyID.EnterpriseMeta.FillAuthzContext(&authzContext) - if err := authz.ToAllowAuthorizer().ServiceWriteAllowed(s.Service, &authzContext); err != nil { - return status.Errorf(codes.PermissionDenied, err.Error()) - } - default: - return status.Errorf(codes.Internal, "Invalid service kind") - } - - // Authed OK! - return nil -} - -func (s *ConfigSnapshot) LoggerName() string { - switch s.Kind { - case structs.ServiceKindConnectProxy: - case structs.ServiceKindTerminatingGateway: - return logging.TerminatingGateway - case structs.ServiceKindMeshGateway: - return logging.MeshGateway - case structs.ServiceKindIngressGateway: - return logging.IngressGateway - } - - return "" -} diff --git a/agent/proxycfg/config_snapshot_glue_test.go b/agent/proxycfg/config_snapshot_glue_test.go deleted file mode 100644 index ed7a9afc1ffbe..0000000000000 --- a/agent/proxycfg/config_snapshot_glue_test.go +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxycfg - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/structs" -) - -func TestConfigSnapshot_AllowEmptyClusters(t *testing.T) { - type testCase struct { - description string - cfgSnapshot *ConfigSnapshot - expectedResult bool - } - testsCases := []testCase{ - { - description: "Mesh proxies are not allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindConnectProxy}, - expectedResult: false, - }, - { - description: "Ingress gateways are allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindIngressGateway}, - expectedResult: true, - }, - { - description: "Terminating gateways are allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindTerminatingGateway}, - expectedResult: true, - }, - { - description: "API Gateways are allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindAPIGateway}, - expectedResult: true, - }, - { - description: "Mesh Gateways are allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindMeshGateway}, - expectedResult: true, - }, - } - for _, tc := range testsCases { - t.Run(tc.description, func(t *testing.T) { - require.Equal(t, tc.expectedResult, tc.cfgSnapshot.AllowEmptyClusters()) - }) - } -} - -func TestConfigSnapshot_AllowEmptyListeners(t *testing.T) { - type testCase struct { - description string - cfgSnapshot *ConfigSnapshot - expectedResult bool - } - testsCases := []testCase{ - { - description: "Mesh proxies are not allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindConnectProxy}, - expectedResult: false, - }, - { - description: "Ingress gateways are allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindIngressGateway}, - expectedResult: true, - }, - { - description: "Terminating gateways are not allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindTerminatingGateway}, - expectedResult: false, - }, - { - description: "API Gateways are allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindAPIGateway}, - expectedResult: true, - }, - { - description: "Mesh Gateways are not allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindMeshGateway}, - expectedResult: false, - }, - } - for _, tc := range testsCases { - t.Run(tc.description, func(t *testing.T) { - require.Equal(t, tc.expectedResult, tc.cfgSnapshot.AllowEmptyListeners()) - }) - } -} - -func TestConfigSnapshot_AllowEmptyRoutes(t *testing.T) { - type testCase struct { - description string - cfgSnapshot *ConfigSnapshot - expectedResult bool - } - testsCases := []testCase{ - { - description: "Mesh proxies are not allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindConnectProxy}, - expectedResult: false, - }, - { - description: "Ingress gateways are allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindIngressGateway}, - expectedResult: true, - }, - { - description: "Terminating gateways are not allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindTerminatingGateway}, - expectedResult: false, - }, - { - description: "API Gateways are allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindAPIGateway}, - expectedResult: true, - }, - { - description: "Mesh Gateways are not allowed", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindMeshGateway}, - expectedResult: false, - }, - } - for _, tc := range testsCases { - t.Run(tc.description, func(t *testing.T) { - require.Equal(t, tc.expectedResult, tc.cfgSnapshot.AllowEmptyRoutes()) - }) - } -} - -func TestConfigSnapshot_LoggerName(t *testing.T) { - type testCase struct { - description string - cfgSnapshot *ConfigSnapshot - expectedResult string - } - testsCases := []testCase{ - { - description: "Mesh proxies have a logger named ''", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindConnectProxy}, - expectedResult: "", - }, - { - description: "Ingress gateways have a logger named 'ingress_gateway'", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindIngressGateway}, - expectedResult: "ingress_gateway", - }, - { - description: "Terminating gateways have a logger named 'terminating_gateway'", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindTerminatingGateway}, - expectedResult: "terminating_gateway", - }, - { - description: "API Gateways have a logger named ''", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindAPIGateway}, - expectedResult: "", - }, - { - description: "Mesh Gateways have a logger named 'mesh_gateway'", - cfgSnapshot: &ConfigSnapshot{Kind: structs.ServiceKindMeshGateway}, - expectedResult: "mesh_gateway", - }, - } - for _, tc := range testsCases { - t.Run(tc.description, func(t *testing.T) { - require.Equal(t, tc.expectedResult, tc.cfgSnapshot.LoggerName()) - }) - } -} - -func TestConfigSnapshot_Authorize(t *testing.T) { - type testCase struct { - description string - cfgSnapshot *ConfigSnapshot - configureAuthorizer func(authorizer *acl.MockAuthorizer) - expectedErrorMessage string - } - testsCases := []testCase{ - { - description: "ConnectProxy - if service write is allowed for the DestinationService then allow.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindConnectProxy, - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "DestinationServiceName", - }, - }, - expectedErrorMessage: "", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "DestinationServiceName", mock.Anything).Return(acl.Allow) - }, - }, - { - description: "ConnectProxy - if service write is not allowed for the DestinationService then deny.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindConnectProxy, - Proxy: structs.ConnectProxyConfig{ - DestinationServiceName: "DestinationServiceName", - }, - }, - expectedErrorMessage: "rpc error: code = PermissionDenied desc = Permission denied: token with AccessorID '' lacks permission 'service:write' on \"DestinationServiceName\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "DestinationServiceName", mock.Anything).Return(acl.Deny) - }, - }, - { - description: "Mesh Gateway - if service write is allowed for the Service then allow.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindMeshGateway, - Service: "Service", - }, - expectedErrorMessage: "", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "Service", mock.Anything).Return(acl.Allow) - }, - }, - { - description: "Mesh Gateway - if service write is not allowed for the Service then deny.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindMeshGateway, - Service: "Service", - }, - expectedErrorMessage: "rpc error: code = PermissionDenied desc = Permission denied: token with AccessorID '' lacks permission 'service:write' on \"Service\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "Service", mock.Anything).Return(acl.Deny) - }, - }, - { - description: "Terminating Gateway - if service write is allowed for the Service then allow.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindTerminatingGateway, - Service: "Service", - }, - expectedErrorMessage: "rpc error: code = PermissionDenied desc = Permission denied: token with AccessorID '' lacks permission 'service:write' on \"Service\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "Service", mock.Anything).Return(acl.Deny) - }, - }, - { - description: "Terminating Gateway - if service write is not allowed for the Service then deny.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindTerminatingGateway, - Service: "Service", - }, - expectedErrorMessage: "rpc error: code = PermissionDenied desc = Permission denied: token with AccessorID '' lacks permission 'service:write' on \"Service\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "Service", mock.Anything).Return(acl.Deny) - }, - }, - { - description: "Ingress Gateway - if service write is allowed for the Service then allow.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindIngressGateway, - Service: "Service", - }, - expectedErrorMessage: "rpc error: code = PermissionDenied desc = Permission denied: token with AccessorID '' lacks permission 'service:write' on \"Service\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "Service", mock.Anything).Return(acl.Deny) - }, - }, - { - description: "Ingress Gateway - if service write is not allowed for the Service then deny.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindIngressGateway, - Service: "Service", - }, - expectedErrorMessage: "rpc error: code = PermissionDenied desc = Permission denied: token with AccessorID '' lacks permission 'service:write' on \"Service\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "Service", mock.Anything).Return(acl.Deny) - }, - }, - { - description: "API Gateway - if service write is allowed for the Service then allow.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindAPIGateway, - Service: "Service", - }, - expectedErrorMessage: "rpc error: code = PermissionDenied desc = Permission denied: token with AccessorID '' lacks permission 'service:write' on \"Service\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "Service", mock.Anything).Return(acl.Deny) - }, - }, - { - description: "API Gateway - if service write is not allowed for the Service then deny.", - cfgSnapshot: &ConfigSnapshot{ - Kind: structs.ServiceKindAPIGateway, - Service: "Service", - }, - expectedErrorMessage: "rpc error: code = PermissionDenied desc = Permission denied: token with AccessorID '' lacks permission 'service:write' on \"Service\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("ServiceWrite", "Service", mock.Anything).Return(acl.Deny) - }, - }, - } - for _, tc := range testsCases { - t.Run(tc.description, func(t *testing.T) { - authz := &acl.MockAuthorizer{} - authz.On("ToAllow").Return(acl.AllowAuthorizer{Authorizer: authz}) - tc.configureAuthorizer(authz) - err := tc.cfgSnapshot.Authorize(authz) - errMsg := "" - if err != nil { - errMsg = err.Error() - } - // using contains because Enterprise tests append the parition and namespace - // information to the message. - require.True(t, strings.Contains(errMsg, tc.expectedErrorMessage)) - }) - } -} diff --git a/agent/proxycfg/connect_proxy.go b/agent/proxycfg/connect_proxy.go index 0a8c1737923ee..7dcbe18e71957 100644 --- a/agent/proxycfg/connect_proxy.go +++ b/agent/proxycfg/connect_proxy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/data_sources.go b/agent/proxycfg/data_sources.go index dfb9a70f357b8..ee779dfb6c884 100644 --- a/agent/proxycfg/data_sources.go +++ b/agent/proxycfg/data_sources.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/data_sources_ce.go b/agent/proxycfg/data_sources_ce.go index fce4830d84cea..5a92e9486b0dd 100644 --- a/agent/proxycfg/data_sources_ce.go +++ b/agent/proxycfg/data_sources_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package proxycfg diff --git a/agent/proxycfg/deep-copy.sh b/agent/proxycfg/deep-copy.sh index 2e1f361dd7101..17791e79b1194 100755 --- a/agent/proxycfg/deep-copy.sh +++ b/agent/proxycfg/deep-copy.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 readonly PACKAGE_DIR="$(dirname "${BASH_SOURCE[0]}")" diff --git a/agent/proxycfg/ingress_gateway.go b/agent/proxycfg/ingress_gateway.go index 3ab5828add40a..efb774c9b17c3 100644 --- a/agent/proxycfg/ingress_gateway.go +++ b/agent/proxycfg/ingress_gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/internal/watch/watchmap.go b/agent/proxycfg/internal/watch/watchmap.go index d4fba2ea03eb8..c36ec3237cc66 100644 --- a/agent/proxycfg/internal/watch/watchmap.go +++ b/agent/proxycfg/internal/watch/watchmap.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package watch diff --git a/agent/proxycfg/internal/watch/watchmap_test.go b/agent/proxycfg/internal/watch/watchmap_test.go index 54fb51d4df9ba..c5bef8e471088 100644 --- a/agent/proxycfg/internal/watch/watchmap_test.go +++ b/agent/proxycfg/internal/watch/watchmap_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package watch diff --git a/agent/proxycfg/manager.go b/agent/proxycfg/manager.go index 71b6270fefc41..a942fd1d1e147 100644 --- a/agent/proxycfg/manager.go +++ b/agent/proxycfg/manager.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -12,7 +12,6 @@ import ( "golang.org/x/time/rate" "github.com/hashicorp/consul/agent/structs" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" "github.com/hashicorp/consul/tlsutil" ) @@ -37,6 +36,10 @@ type ProxyID struct { // from overwriting each other's registrations. type ProxySource string +// CancelFunc is a type for a returned function that can be called to cancel a +// watch. +type CancelFunc func() + // Manager provides an API with which proxy services can be registered, and // coordinates the fetching (and refreshing) of intentions, upstreams, discovery // chain, certificates etc. @@ -52,7 +55,7 @@ type Manager struct { mu sync.Mutex proxies map[ProxyID]*state - watchers map[ProxyID]map[uint64]chan proxysnapshot.ProxySnapshot + watchers map[ProxyID]map[uint64]chan *ConfigSnapshot maxWatchID uint64 } @@ -103,7 +106,7 @@ func NewManager(cfg ManagerConfig) (*Manager, error) { m := &Manager{ ManagerConfig: cfg, proxies: make(map[ProxyID]*state), - watchers: make(map[ProxyID]map[uint64]chan proxysnapshot.ProxySnapshot), + watchers: make(map[ProxyID]map[uint64]chan *ConfigSnapshot), rateLimiter: rate.NewLimiter(cfg.UpdateRateLimit, 1), } return m, nil @@ -259,7 +262,7 @@ func (m *Manager) notify(snap *ConfigSnapshot) { // it will drain the chan and then re-attempt delivery so that a slow consumer // gets the latest config earlier. This MUST be called from a method where m.mu // is held to be safe since it assumes we are the only goroutine sending on ch. -func (m *Manager) deliverLatest(snap *ConfigSnapshot, ch chan proxysnapshot.ProxySnapshot) { +func (m *Manager) deliverLatest(snap *ConfigSnapshot, ch chan *ConfigSnapshot) { // Send if chan is empty select { case ch <- snap: @@ -296,16 +299,16 @@ OUTER: // will not fail, but no updates will be delivered until the proxy is // registered. If there is already a valid snapshot in memory, it will be // delivered immediately. -func (m *Manager) Watch(id ProxyID) (<-chan proxysnapshot.ProxySnapshot, proxysnapshot.CancelFunc) { +func (m *Manager) Watch(id ProxyID) (<-chan *ConfigSnapshot, CancelFunc) { m.mu.Lock() defer m.mu.Unlock() // This buffering is crucial otherwise we'd block immediately trying to // deliver the current snapshot below if we already have one. - ch := make(chan proxysnapshot.ProxySnapshot, 1) + ch := make(chan *ConfigSnapshot, 1) watchers, ok := m.watchers[id] if !ok { - watchers = make(map[uint64]chan proxysnapshot.ProxySnapshot) + watchers = make(map[uint64]chan *ConfigSnapshot) } watchID := m.maxWatchID m.maxWatchID++ diff --git a/agent/proxycfg/manager_test.go b/agent/proxycfg/manager_test.go index feaa4e431d033..13dd0f95420cd 100644 --- a/agent/proxycfg/manager_test.go +++ b/agent/proxycfg/manager_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -17,7 +17,6 @@ import ( "github.com/hashicorp/consul/agent/proxycfg/internal/watch" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" "github.com/hashicorp/consul/proto/private/pbpeering" "github.com/hashicorp/consul/sdk/testutil" ) @@ -470,7 +469,7 @@ func testManager_BasicLifecycle( require.Len(t, m.watchers, 0) } -func assertWatchChanBlocks(t *testing.T, ch <-chan proxysnapshot.ProxySnapshot) { +func assertWatchChanBlocks(t *testing.T, ch <-chan *ConfigSnapshot) { t.Helper() select { @@ -480,7 +479,7 @@ func assertWatchChanBlocks(t *testing.T, ch <-chan proxysnapshot.ProxySnapshot) } } -func assertWatchChanRecvs(t *testing.T, ch <-chan proxysnapshot.ProxySnapshot, expect proxysnapshot.ProxySnapshot) { +func assertWatchChanRecvs(t *testing.T, ch <-chan *ConfigSnapshot, expect *ConfigSnapshot) { t.Helper() select { @@ -518,7 +517,7 @@ func TestManager_deliverLatest(t *testing.T) { } // test 1 buffered chan - ch1 := make(chan proxysnapshot.ProxySnapshot, 1) + ch1 := make(chan *ConfigSnapshot, 1) // Sending to an unblocked chan should work m.deliverLatest(snap1, ch1) @@ -534,7 +533,7 @@ func TestManager_deliverLatest(t *testing.T) { require.Equal(t, snap2, <-ch1) // Same again for 5-buffered chan - ch5 := make(chan proxysnapshot.ProxySnapshot, 5) + ch5 := make(chan *ConfigSnapshot, 5) // Sending to an unblocked chan should work m.deliverLatest(snap1, ch5) diff --git a/agent/proxycfg/mesh_gateway.go b/agent/proxycfg/mesh_gateway.go index 0237e84232905..f2fee37d46719 100644 --- a/agent/proxycfg/mesh_gateway.go +++ b/agent/proxycfg/mesh_gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/go-hclog" "github.com/hashicorp/consul/acl" + cachetype "github.com/hashicorp/consul/agent/cache-types" "github.com/hashicorp/consul/agent/leafcert" "github.com/hashicorp/consul/agent/proxycfg/internal/watch" diff --git a/agent/proxycfg/mesh_gateway_ce.go b/agent/proxycfg/mesh_gateway_ce.go index 1c1156232d71c..2959a8383a1e8 100644 --- a/agent/proxycfg/mesh_gateway_ce.go +++ b/agent/proxycfg/mesh_gateway_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package proxycfg diff --git a/agent/proxycfg/naming.go b/agent/proxycfg/naming.go index a9bd5fd8c0ca4..07aa42f2f4dd4 100644 --- a/agent/proxycfg/naming.go +++ b/agent/proxycfg/naming.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/naming_ce.go b/agent/proxycfg/naming_ce.go index 7a375b6df944e..858b8d3553dfd 100644 --- a/agent/proxycfg/naming_ce.go +++ b/agent/proxycfg/naming_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package proxycfg diff --git a/agent/proxycfg/naming_test.go b/agent/proxycfg/naming_test.go index 0615a81281824..caf917f5d9757 100644 --- a/agent/proxycfg/naming_test.go +++ b/agent/proxycfg/naming_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/proxycfg.deepcopy.go b/agent/proxycfg/proxycfg.deepcopy.go index ebe052d1088f6..89e295ecbdce3 100644 --- a/agent/proxycfg/proxycfg.deepcopy.go +++ b/agent/proxycfg/proxycfg.deepcopy.go @@ -13,10 +13,6 @@ import ( // DeepCopy generates a deep copy of *ConfigSnapshot func (o *ConfigSnapshot) DeepCopy() *ConfigSnapshot { var cp ConfigSnapshot = *o - if o.ServiceLocality != nil { - cp.ServiceLocality = new(structs.Locality) - *cp.ServiceLocality = *o.ServiceLocality - } if o.ServiceMeta != nil { cp.ServiceMeta = make(map[string]string, len(o.ServiceMeta)) for k2, v2 := range o.ServiceMeta { diff --git a/agent/proxycfg/proxycfg.go b/agent/proxycfg/proxycfg.go index 9b71156dfe5aa..f73e6ac726ceb 100644 --- a/agent/proxycfg/proxycfg.go +++ b/agent/proxycfg/proxycfg.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package proxycfg contains components for sourcing the data required to // configure Connect proxies. The Manager provides an API with which proxy @@ -45,7 +45,7 @@ // ConfigSource - on a client agent this would be a local config source, on a // server it would be a catalog config source. // 4. On server, the catalog config source will check if service is registered locally. -// 4a. If the service *is* registered locally it hands off the local config +// 4a. If the service *is* registered locally it hands off the the local config // source, which calls Watch on the proxycfg manager (and serves the pre- // fetched data). // 5. Otherwise, it fetches the service from the state store. diff --git a/agent/proxycfg/snapshot.go b/agent/proxycfg/snapshot.go index 8d7aebd456e12..c054c1c32d3a0 100644 --- a/agent/proxycfg/snapshot.go +++ b/agent/proxycfg/snapshot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -934,7 +934,6 @@ func IngressListenerKeyFromListener(l structs.IngressListener) IngressListenerKe type ConfigSnapshot struct { Kind structs.ServiceKind Service string - ServiceLocality *structs.Locality ProxyID ProxyID Address string Port int diff --git a/agent/proxycfg/snapshot_test.go b/agent/proxycfg/snapshot_test.go index b4b0ab57c957a..ea6700cd249da 100644 --- a/agent/proxycfg/snapshot_test.go +++ b/agent/proxycfg/snapshot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/state.go b/agent/proxycfg/state.go index 853dca5a9f1bf..55ba287ef1f25 100644 --- a/agent/proxycfg/state.go +++ b/agent/proxycfg/state.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -126,7 +126,6 @@ type serviceInstance struct { taggedAddresses map[string]structs.ServiceAddress proxyCfg structs.ConnectProxyConfig token string - locality *structs.Locality } func copyProxyConfig(ns *structs.NodeService) (structs.ConnectProxyConfig, error) { @@ -247,7 +246,6 @@ func newServiceInstanceFromNodeService(id ProxyID, ns *structs.NodeService, toke return serviceInstance{ kind: ns.Kind, service: ns.Service, - locality: ns.Locality, proxyID: id, address: ns.Address, port: ns.Port, @@ -307,7 +305,6 @@ func newConfigSnapshotFromServiceInstance(s serviceInstance, config stateConfig) return ConfigSnapshot{ Kind: s.kind, Service: s.service, - ServiceLocality: s.locality, ProxyID: s.proxyID, Address: s.address, Port: s.port, diff --git a/agent/proxycfg/state_ce_test.go b/agent/proxycfg/state_ce_test.go index 61ba1fcc3a536..e817aeef0b13f 100644 --- a/agent/proxycfg/state_ce_test.go +++ b/agent/proxycfg/state_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package proxycfg diff --git a/agent/proxycfg/state_test.go b/agent/proxycfg/state_test.go index 2a6792aa22e93..9065db885dc3b 100644 --- a/agent/proxycfg/state_test.go +++ b/agent/proxycfg/state_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/terminating_gateway.go b/agent/proxycfg/terminating_gateway.go index a465808390ade..4e2f172afb2bb 100644 --- a/agent/proxycfg/terminating_gateway.go +++ b/agent/proxycfg/terminating_gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/testing.go b/agent/proxycfg/testing.go index bdd565ec0454e..ac68994cb8f18 100644 --- a/agent/proxycfg/testing.go +++ b/agent/proxycfg/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -167,7 +167,7 @@ func TestUpstreamNodes(t testing.T, service string) structs.CheckServiceNodes { Datacenter: "dc1", Partition: structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty(), }, - Service: structs.TestNodeServiceWithName(service), + Service: structs.TestNodeServiceWithName(t, service), }, structs.CheckServiceNode{ Node: &structs.Node{ @@ -177,47 +177,7 @@ func TestUpstreamNodes(t testing.T, service string) structs.CheckServiceNodes { Datacenter: "dc1", Partition: structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty(), }, - Service: structs.TestNodeServiceWithName(service), - }, - } -} - -// TestUpstreamNodesWithServiceSubset returns a sample service discovery result with one instance tagged v1 -// and the other tagged v2 -func TestUpstreamNodesWithServiceSubset(t testing.T, service string) structs.CheckServiceNodes { - return structs.CheckServiceNodes{ - structs.CheckServiceNode{ - Node: &structs.Node{ - ID: "test1", - Node: "test1", - Address: "10.10.1.3", - Datacenter: "dc1", - Partition: structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty(), - }, - Service: &structs.NodeService{ - Kind: structs.ServiceKindTypical, - Service: service, - Port: 8080, - Meta: map[string]string{"Version": "1"}, - Weights: &structs.Weights{ - Passing: 300, // Check that this gets normalized to 128 - }, - }, - }, - structs.CheckServiceNode{ - Node: &structs.Node{ - ID: "test2", - Node: "test2", - Address: "10.10.1.4", - Datacenter: "dc1", - Partition: structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty(), - }, - Service: &structs.NodeService{ - Kind: structs.ServiceKindTypical, - Service: service, - Port: 8080, - Meta: map[string]string{"Version": "2"}, - }, + Service: structs.TestNodeServiceWithName(t, service), }, } } @@ -271,7 +231,7 @@ func TestUpstreamNodesInStatus(t testing.T, status string) structs.CheckServiceN Address: "10.10.1.1", Datacenter: "dc1", }, - Service: structs.TestNodeService(), + Service: structs.TestNodeService(t), Checks: structs.HealthChecks{ &structs.HealthCheck{ Node: "test1", @@ -288,7 +248,7 @@ func TestUpstreamNodesInStatus(t testing.T, status string) structs.CheckServiceN Address: "10.10.1.2", Datacenter: "dc1", }, - Service: structs.TestNodeService(), + Service: structs.TestNodeService(t), Checks: structs.HealthChecks{ &structs.HealthCheck{ Node: "test2", @@ -310,7 +270,7 @@ func TestUpstreamNodesDC2(t testing.T) structs.CheckServiceNodes { Address: "10.20.1.1", Datacenter: "dc2", }, - Service: structs.TestNodeService(), + Service: structs.TestNodeService(t), }, structs.CheckServiceNode{ Node: &structs.Node{ @@ -319,7 +279,7 @@ func TestUpstreamNodesDC2(t testing.T) structs.CheckServiceNodes { Address: "10.20.1.2", Datacenter: "dc2", }, - Service: structs.TestNodeService(), + Service: structs.TestNodeService(t), }, } } @@ -333,7 +293,7 @@ func TestUpstreamNodesInStatusDC2(t testing.T, status string) structs.CheckServi Address: "10.20.1.1", Datacenter: "dc2", }, - Service: structs.TestNodeService(), + Service: structs.TestNodeService(t), Checks: structs.HealthChecks{ &structs.HealthCheck{ Node: "test1", @@ -350,7 +310,7 @@ func TestUpstreamNodesInStatusDC2(t testing.T, status string) structs.CheckServi Address: "10.20.1.2", Datacenter: "dc2", }, - Service: structs.TestNodeService(), + Service: structs.TestNodeService(t), Checks: structs.HealthChecks{ &structs.HealthCheck{ Node: "test2", @@ -372,7 +332,7 @@ func TestUpstreamNodesAlternate(t testing.T) structs.CheckServiceNodes { Address: "10.20.1.1", Datacenter: "dc1", }, - Service: structs.TestNodeService(), + Service: structs.TestNodeService(t), }, structs.CheckServiceNode{ Node: &structs.Node{ @@ -381,7 +341,7 @@ func TestUpstreamNodesAlternate(t testing.T) structs.CheckServiceNodes { Address: "10.20.1.2", Datacenter: "dc1", }, - Service: structs.TestNodeService(), + Service: structs.TestNodeService(t), }, } } diff --git a/agent/proxycfg/testing_api_gateway.go b/agent/proxycfg/testing_api_gateway.go index ddfa17dcf6ab2..87ff58fbf0535 100644 --- a/agent/proxycfg/testing_api_gateway.go +++ b/agent/proxycfg/testing_api_gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -8,9 +8,10 @@ import ( "github.com/mitchellh/go-testing-interface" - "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/discoverychain" + + "github.com/hashicorp/consul/agent/configentry" "github.com/hashicorp/consul/agent/structs" ) diff --git a/agent/proxycfg/testing_ce.go b/agent/proxycfg/testing_ce.go index 97c23d82eb3dd..202252a3a7335 100644 --- a/agent/proxycfg/testing_ce.go +++ b/agent/proxycfg/testing_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package proxycfg diff --git a/agent/proxycfg/testing_connect_proxy.go b/agent/proxycfg/testing_connect_proxy.go index cf6f4a479b1eb..a929aa52f167d 100644 --- a/agent/proxycfg/testing_connect_proxy.go +++ b/agent/proxycfg/testing_connect_proxy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -227,14 +227,6 @@ func TestConfigSnapshotExposeConfig(t testing.T, nsFn func(ns *structs.NodeServi } func TestConfigSnapshotExposeChecks(t testing.T) *ConfigSnapshot { - return testConfigSnapshotExposedChecks(t, false) -} - -func TestConfigSnapshotExposeChecksWithBindOverride(t testing.T) *ConfigSnapshot { - return testConfigSnapshotExposedChecks(t, true) -} - -func testConfigSnapshotExposedChecks(t testing.T, overrideBind bool) *ConfigSnapshot { return TestConfigSnapshot(t, func(ns *structs.NodeService) { ns.Address = "1.2.3.4" @@ -243,12 +235,6 @@ func testConfigSnapshotExposedChecks(t testing.T, overrideBind bool) *ConfigSnap ns.Proxy.Expose = structs.ExposeConfig{ Checks: true, } - if overrideBind { - if ns.Proxy.Config == nil { - ns.Proxy.Config = map[string]any{} - } - ns.Proxy.Config["bind_address"] = "6.7.8.9" - } }, []UpdateEvent{ { @@ -267,32 +253,6 @@ func testConfigSnapshotExposedChecks(t testing.T, overrideBind bool) *ConfigSnap ) } -func TestConfigSnapshotExposeChecksGRPC(t testing.T) *ConfigSnapshot { - return TestConfigSnapshot(t, - func(ns *structs.NodeService) { - ns.Address = "1.2.3.4" - ns.Port = 9090 - ns.Proxy.Upstreams = nil - ns.Proxy.Expose = structs.ExposeConfig{ - Checks: true, - } - }, - []UpdateEvent{ - { - CorrelationID: svcChecksWatchIDPrefix + structs.ServiceIDString("web", nil), - Result: []structs.CheckType{{ - CheckID: types.CheckID("grpc"), - Name: "grpc", - GRPC: "localhost:9090/v1.Health", - ProxyGRPC: "localhost:21501/myservice", - Interval: 10 * time.Second, - Timeout: 1 * time.Second, - }}, - }, - }, - ) -} - func TestConfigSnapshotGRPCExposeHTTP1(t testing.T) *ConfigSnapshot { roots, leaf := TestCerts(t) diff --git a/agent/proxycfg/testing_ingress_gateway.go b/agent/proxycfg/testing_ingress_gateway.go index 96918a261bd05..87a3313ecdb50 100644 --- a/agent/proxycfg/testing_ingress_gateway.go +++ b/agent/proxycfg/testing_ingress_gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -1888,8 +1888,8 @@ func TestConfigSnapshotIngressGateway_TLSMixedMinVersionListeners(t testing.T) * entry.TLS.Enabled = true entry.TLS.TLSMinVersion = types.TLSv1_2 - // One listener should inherit TLS minimum version from the gateway config, - // two others each set explicit TLS minimum versions + // One listener disables TLS, one inherits TLS minimum version from the gateway + // config, two others set different versions entry.Listeners = []structs.IngressListener{ { Port: 8080, @@ -1925,6 +1925,8 @@ func TestConfigSnapshotIngressGateway_TLSMixedMinVersionListeners(t testing.T) * { CorrelationID: gatewayServicesWatchID, Result: &structs.IndexedGatewayServices{ + // One listener should inherit TLS minimum version from the gateway config, + // two others each set explicit TLS minimum versions Services: []*structs.GatewayService{ { Service: s1, @@ -1982,208 +1984,3 @@ func TestConfigSnapshotIngressGateway_TLSMixedMinVersionListeners(t testing.T) * }, }) } - -func TestConfigSnapshotIngressGateway_TLSMixedMaxVersionListeners(t testing.T) *ConfigSnapshot { - var ( - s1 = structs.NewServiceName("s1", nil) - s1UID = NewUpstreamIDFromServiceName(s1) - s1Chain = discoverychain.TestCompileConfigEntries(t, "s1", "default", "default", "dc1", connect.TestClusterID+".consul", nil, nil) - - s2 = structs.NewServiceName("s2", nil) - s2UID = NewUpstreamIDFromServiceName(s2) - s2Chain = discoverychain.TestCompileConfigEntries(t, "s2", "default", "default", "dc1", connect.TestClusterID+".consul", nil, nil) - - s3 = structs.NewServiceName("s3", nil) - s3UID = NewUpstreamIDFromServiceName(s3) - s3Chain = discoverychain.TestCompileConfigEntries(t, "s3", "default", "default", "dc1", connect.TestClusterID+".consul", nil, nil) - ) - - return TestConfigSnapshotIngressGateway(t, true, "tcp", "default", nil, - func(entry *structs.IngressGatewayConfigEntry) { - entry.TLS.Enabled = true - entry.TLS.TLSMaxVersion = types.TLSv1_2 - - // One listener should inherit TLS maximum version from the gateway config, - // two others each set explicit TLS maximum versions - entry.Listeners = []structs.IngressListener{ - { - Port: 8080, - Protocol: "http", - Services: []structs.IngressService{ - {Name: "s1"}, - }, - }, - { - Port: 8081, - Protocol: "http", - Services: []structs.IngressService{ - {Name: "s2"}, - }, - TLS: &structs.GatewayTLSConfig{ - Enabled: true, - TLSMaxVersion: types.TLSv1_0, - }, - }, - { - Port: 8082, - Protocol: "http", - Services: []structs.IngressService{ - {Name: "s3"}, - }, - TLS: &structs.GatewayTLSConfig{ - Enabled: true, - TLSMaxVersion: types.TLSv1_3, - }, - }, - } - }, []UpdateEvent{ - { - CorrelationID: gatewayServicesWatchID, - Result: &structs.IndexedGatewayServices{ - Services: []*structs.GatewayService{ - { - Service: s1, - Port: 8080, - Protocol: "http", - }, - { - Service: s2, - Port: 8081, - Protocol: "http", - }, - { - Service: s3, - Port: 8082, - Protocol: "http", - }, - }, - }, - }, - { - CorrelationID: "discovery-chain:" + s1UID.String(), - Result: &structs.DiscoveryChainResponse{ - Chain: s1Chain, - }, - }, - { - CorrelationID: "discovery-chain:" + s2UID.String(), - Result: &structs.DiscoveryChainResponse{ - Chain: s2Chain, - }, - }, - { - CorrelationID: "discovery-chain:" + s3UID.String(), - Result: &structs.DiscoveryChainResponse{ - Chain: s3Chain, - }, - }, - { - CorrelationID: "upstream-target:" + s1Chain.ID() + ":" + s1UID.String(), - Result: &structs.IndexedCheckServiceNodes{ - Nodes: TestUpstreamNodes(t, "s1"), - }, - }, - { - CorrelationID: "upstream-target:" + s2Chain.ID() + ":" + s2UID.String(), - Result: &structs.IndexedCheckServiceNodes{ - Nodes: TestUpstreamNodes(t, "s2"), - }, - }, - { - CorrelationID: "upstream-target:" + s3Chain.ID() + ":" + s3UID.String(), - Result: &structs.IndexedCheckServiceNodes{ - Nodes: TestUpstreamNodes(t, "s3"), - }, - }, - }) -} - -func TestConfigSnapshotIngressGateway_TLSMixedCipherVersionListeners(t testing.T) *ConfigSnapshot { - var ( - s1 = structs.NewServiceName("s1", nil) - s1UID = NewUpstreamIDFromServiceName(s1) - s1Chain = discoverychain.TestCompileConfigEntries(t, "s1", "default", "default", "dc1", connect.TestClusterID+".consul", nil, nil) - - s2 = structs.NewServiceName("s2", nil) - s2UID = NewUpstreamIDFromServiceName(s2) - s2Chain = discoverychain.TestCompileConfigEntries(t, "s2", "default", "default", "dc1", connect.TestClusterID+".consul", nil, nil) - ) - - return TestConfigSnapshotIngressGateway(t, true, "tcp", "default", nil, - func(entry *structs.IngressGatewayConfigEntry) { - entry.TLS.Enabled = true - entry.TLS.CipherSuites = []types.TLSCipherSuite{ - types.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - } - - // One listener should inherit TLS Ciphers from the gateway config, - // the other should be set explicitly from the listener config - entry.Listeners = []structs.IngressListener{ - { - Port: 8080, - Protocol: "http", - Services: []structs.IngressService{ - {Name: "s1"}, - }, - }, - { - Port: 8081, - Protocol: "http", - Services: []structs.IngressService{ - {Name: "s2"}, - }, - TLS: &structs.GatewayTLSConfig{ - Enabled: true, - CipherSuites: []types.TLSCipherSuite{ - types.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - types.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - }, - }, - }, - } - }, []UpdateEvent{ - { - CorrelationID: gatewayServicesWatchID, - Result: &structs.IndexedGatewayServices{ - // One listener should inherit TLS minimum version from the gateway config, - // two others each set explicit TLS minimum versions - Services: []*structs.GatewayService{ - { - Service: s1, - Port: 8080, - Protocol: "http", - }, - { - Service: s2, - Port: 8081, - Protocol: "http", - }, - }, - }, - }, - { - CorrelationID: "discovery-chain:" + s1UID.String(), - Result: &structs.DiscoveryChainResponse{ - Chain: s1Chain, - }, - }, - { - CorrelationID: "discovery-chain:" + s2UID.String(), - Result: &structs.DiscoveryChainResponse{ - Chain: s2Chain, - }, - }, - { - CorrelationID: "upstream-target:" + s1Chain.ID() + ":" + s1UID.String(), - Result: &structs.IndexedCheckServiceNodes{ - Nodes: TestUpstreamNodes(t, "s1"), - }, - }, - { - CorrelationID: "upstream-target:" + s2Chain.ID() + ":" + s2UID.String(), - Result: &structs.IndexedCheckServiceNodes{ - Nodes: TestUpstreamNodes(t, "s2"), - }, - }, - }) -} diff --git a/agent/proxycfg/testing_mesh_gateway.go b/agent/proxycfg/testing_mesh_gateway.go index 865e219cd4350..0ad9d4524afe7 100644 --- a/agent/proxycfg/testing_mesh_gateway.go +++ b/agent/proxycfg/testing_mesh_gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -23,10 +23,9 @@ func TestConfigSnapshotMeshGateway(t testing.T, variant string, nsFn func(ns *st roots, _ := TestCertsForMeshGateway(t) var ( - populateServices = true - useFederationStates = false - deleteCrossDCEntry = false - meshGatewayFederation = false + populateServices = true + useFederationStates = false + deleteCrossDCEntry = false ) switch variant { @@ -35,11 +34,6 @@ func TestConfigSnapshotMeshGateway(t testing.T, variant string, nsFn func(ns *st populateServices = true useFederationStates = true deleteCrossDCEntry = true - case "mesh-gateway-federation": - populateServices = true - useFederationStates = true - deleteCrossDCEntry = true - meshGatewayFederation = true case "newer-info-in-federation-states": populateServices = true useFederationStates = true @@ -453,63 +447,6 @@ func TestConfigSnapshotMeshGateway(t testing.T, variant string, nsFn func(ns *st }) } - var serverSNIFn ServerSNIFunc - if meshGatewayFederation { - - // reproduced from tlsutil/config.go - serverSNIFn = func(dc, nodeName string) string { - // Strip the trailing '.' from the domain if any - domain := "consul" - - if nodeName == "" || nodeName == "*" { - return "server." + dc + "." + domain - } - - return nodeName + ".server." + dc + "." + domain - } - - baseEvents = testSpliceEvents(baseEvents, []UpdateEvent{ - { - CorrelationID: consulServerListWatchID, - Result: &structs.IndexedCheckServiceNodes{ - Nodes: structs.CheckServiceNodes{ - { - Node: &structs.Node{ - Datacenter: "dc1", - Node: "node1", - Address: "127.0.0.1", - }, - Service: &structs.NodeService{ - ID: structs.ConsulServiceID, - Service: structs.ConsulServiceName, - Meta: map[string]string{ - "grpc_port": "8502", - "grpc_tls_port": "8503", - }, - }, - }, - { - Node: &structs.Node{ - Datacenter: "dc1", - Node: "node2", - Address: "127.0.0.2", - }, - Service: &structs.NodeService{ - ID: structs.ConsulServiceID, - Service: structs.ConsulServiceName, - Meta: map[string]string{ - "grpc_port": "8502", - "grpc_tls_port": "8503", - }, - }, - }, - }, - }, - }, - }) - - } - return testConfigSnapshotFixture(t, &structs.NodeService{ Kind: structs.ServiceKindMeshGateway, Service: "mesh-gateway", @@ -529,7 +466,7 @@ func TestConfigSnapshotMeshGateway(t testing.T, variant string, nsFn func(ns *st Port: 443, }, }, - }, nsFn, serverSNIFn, testSpliceEvents(baseEvents, extraUpdates)) + }, nsFn, nil, testSpliceEvents(baseEvents, extraUpdates)) } func TestConfigSnapshotPeeredMeshGateway(t testing.T, variant string, nsFn func(ns *structs.NodeService), extraUpdates []UpdateEvent) *ConfigSnapshot { @@ -747,73 +684,6 @@ func TestConfigSnapshotPeeredMeshGateway(t testing.T, variant string, nsFn func( }, }, ) - case "mgw-peered-upstream": - // This is a modified version of "chain-and-l7-stuff" that adds a peer field to the resolver - // and removes some of the extraneous disco-chain testing. - entries = []structs.ConfigEntry{ - &structs.ProxyConfigEntry{ - Kind: structs.ProxyDefaults, - Name: structs.ProxyConfigGlobal, - Config: map[string]interface{}{ - "protocol": "http", - }, - }, - &structs.ServiceResolverConfigEntry{ - Kind: structs.ServiceResolver, - Name: "db", - Redirect: &structs.ServiceResolverRedirect{ - Service: "alt", - Peer: "peer-b", - }, - ConnectTimeout: 33 * time.Second, - RequestTimeout: 33 * time.Second, - }, - } - for _, entry := range entries { - require.NoError(t, entry.Normalize()) - require.NoError(t, entry.Validate()) - } - - set := configentry.NewDiscoveryChainSet() - set.AddEntries(entries...) - - var ( - dbSN = structs.NewServiceName("db", nil) - altSN = structs.NewServiceName("alt", nil) - - dbChain = discoverychain.TestCompileConfigEntries(t, "db", "default", "default", "dc1", connect.TestClusterID+".consul", nil, set) - ) - - needPeerA = true - needLeaf = true - discoChains[dbSN] = dbChain - endpoints[dbSN] = TestUpstreamNodes(t, "db") - endpoints[altSN] = TestUpstreamNodes(t, "alt") - - extraUpdates = append(extraUpdates, - UpdateEvent{ - CorrelationID: datacentersWatchID, - Result: &[]string{"dc1"}, - }, - UpdateEvent{ - CorrelationID: exportedServiceListWatchID, - Result: &structs.IndexedExportedServiceList{ - Services: map[string]structs.ServiceList{ - "peer-a": []structs.ServiceName{dbSN}, - }, - }, - }, - UpdateEvent{ - CorrelationID: serviceListWatchID, - Result: &structs.IndexedServiceList{ - Services: []structs.ServiceName{ - dbSN, - altSN, - }, - }, - }, - ) - case "chain-and-l7-stuff": entries = []structs.ConfigEntry{ &structs.ProxyConfigEntry{ @@ -833,12 +703,8 @@ func TestConfigSnapshotPeeredMeshGateway(t testing.T, variant string, nsFn func( Kind: structs.ServiceResolver, Name: "api", Subsets: map[string]structs.ServiceResolverSubset{ - "v1": { - Filter: "Service.Meta.Version == 1", - }, "v2": { - Filter: "Service.Meta.Version == 2", - OnlyPassing: true, + Filter: "Service.Meta.version == v2", }, }, }, @@ -888,7 +754,6 @@ func TestConfigSnapshotPeeredMeshGateway(t testing.T, variant string, nsFn func( var ( dbSN = structs.NewServiceName("db", nil) altSN = structs.NewServiceName("alt", nil) - apiSN = structs.NewServiceName("api", nil) dbChain = discoverychain.TestCompileConfigEntries(t, "db", "default", "default", "dc1", connect.TestClusterID+".consul", nil, set) ) @@ -898,7 +763,6 @@ func TestConfigSnapshotPeeredMeshGateway(t testing.T, variant string, nsFn func( discoChains[dbSN] = dbChain endpoints[dbSN] = TestUpstreamNodes(t, "db") endpoints[altSN] = TestUpstreamNodes(t, "alt") - endpoints[apiSN] = TestUpstreamNodesWithServiceSubset(t, "api") extraUpdates = append(extraUpdates, UpdateEvent{ @@ -922,29 +786,7 @@ func TestConfigSnapshotPeeredMeshGateway(t testing.T, variant string, nsFn func( }, }, }, - UpdateEvent{ - CorrelationID: serviceResolversWatchID, - Result: &structs.IndexedConfigEntries{ - Kind: structs.ServiceResolver, - Entries: []structs.ConfigEntry{ - &structs.ServiceResolverConfigEntry{ - Kind: structs.ServiceResolver, - Name: "api", - Subsets: map[string]structs.ServiceResolverSubset{ - "v1": { - Filter: "Service.Meta.Version == 1", - }, - "v2": { - Filter: "Service.Meta.Version == 2", - OnlyPassing: true, - }, - }, - }, - }, - }, - }, ) - case "peer-through-mesh-gateway": extraUpdates = append(extraUpdates, diff --git a/agent/proxycfg/testing_peering.go b/agent/proxycfg/testing_peering.go index 0af8bafa9f086..9b754c977f2f6 100644 --- a/agent/proxycfg/testing_peering.go +++ b/agent/proxycfg/testing_peering.go @@ -1,32 +1,16 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg import ( - "bytes" - "text/template" - "github.com/mitchellh/go-testing-interface" - "github.com/stretchr/testify/require" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/proto/private/pbpeering" ) func TestConfigSnapshotPeering(t testing.T) *ConfigSnapshot { - return testConfigSnapshot(t, false, false) -} - -func TestConfigSnapshotPeeringWithEscapeOverrides(t testing.T) *ConfigSnapshot { - return testConfigSnapshot(t, true, false) -} - -func TestConfigSnapshotPeeringWithHTTP2(t testing.T) *ConfigSnapshot { - return testConfigSnapshot(t, false, true) -} - -func testConfigSnapshot(t testing.T, escapeOverride bool, useHTTP2 bool) *ConfigSnapshot { var ( paymentsUpstream = structs.Upstream{ DestinationName: "payments", @@ -43,11 +27,6 @@ func testConfigSnapshot(t testing.T, escapeOverride bool, useHTTP2 bool) *Config refundsUID = NewUpstreamID(&refundsUpstream) ) - protocol := "tcp" - if useHTTP2 { - protocol = "http2" - } - const peerTrustDomain = "1c053652-8512-4373-90cf-5a7f6263a994.consul" return TestConfigSnapshot(t, func(ns *structs.NodeService) { @@ -55,24 +34,6 @@ func testConfigSnapshot(t testing.T, escapeOverride bool, useHTTP2 bool) *Config paymentsUpstream, refundsUpstream, } - - if escapeOverride { - if ns.Proxy.Upstreams[0].Config == nil { - ns.Proxy.Upstreams[0].Config = map[string]interface{}{} - } - - uid := NewUpstreamID(&ns.Proxy.Upstreams[0]) - - ns.Proxy.Upstreams[0].Config["envoy_listener_json"] = - customListenerJSON(t, customListenerJSONOptions{ - Name: uid.EnvoyID() + ":custom-upstream", - }) - ns.Proxy.Upstreams[0].Config["envoy_cluster_json"] = - customClusterJSON(t, customClusterJSONOptions{ - Name: uid.EnvoyID() + ":custom-upstream", - }) - } - }, []UpdateEvent{ { CorrelationID: peerTrustBundleIDPrefix + "cloud", @@ -111,7 +72,7 @@ func testConfigSnapshot(t testing.T, escapeOverride bool, useHTTP2 bool) *Config SpiffeID: []string{ "spiffe://" + peerTrustDomain + "/ns/default/dc/cloud-dc/svc/payments", }, - Protocol: protocol, + Protocol: "tcp", }, }, }, @@ -140,7 +101,7 @@ func testConfigSnapshot(t testing.T, escapeOverride bool, useHTTP2 bool) *Config SpiffeID: []string{ "spiffe://" + peerTrustDomain + "/ns/default/dc/cloud-dc/svc/refunds", }, - Protocol: protocol, + Protocol: "tcp", }, }, }, @@ -419,93 +380,3 @@ func TestConfigSnapshotPeeringLocalMeshGateway(t testing.T) *ConfigSnapshot { }, }) } - -var ( - customListenerJSONTemplate = template.Must(template.New("").Parse(customListenerJSONTpl)) -) - -func customListenerJSON(t testing.T, opts customListenerJSONOptions) string { - t.Helper() - var buf bytes.Buffer - require.NoError(t, customListenerJSONTemplate.Execute(&buf, opts)) - return buf.String() -} - -type customListenerJSONOptions struct { - Name string - TLSContext string -} - -const customListenerJSONTpl = `{ - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "{{ .Name }}", - "address": { - "socketAddress": { - "address": "11.11.11.11", - "portValue": 11111 - } - }, - "filterChains": [ - { - {{ if .TLSContext -}} - "transport_socket": { - "name": "tls", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - {{ .TLSContext }} - } - }, - {{- end }} - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "random-cluster", - "statPrefix": "foo-stats" - } - } - ] - } - ] -}` - -type customClusterJSONOptions struct { - Name string - TLSContext string -} - -var customClusterJSONTpl = `{ - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "{{ .Name }}", - "connectTimeout": "15s", - "loadAssignment": { - "clusterName": "{{ .Name }}", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8443 - } - } - } - } - ] - } - ] - } -}` - -var customClusterJSONTemplate = template.Must(template.New("").Parse(customClusterJSONTpl)) - -func customClusterJSON(t testing.T, opts customClusterJSONOptions) string { - t.Helper() - var buf bytes.Buffer - err := customClusterJSONTemplate.Execute(&buf, opts) - require.NoError(t, err) - return buf.String() -} diff --git a/agent/proxycfg/testing_terminating_gateway.go b/agent/proxycfg/testing_terminating_gateway.go index 6a718779943f6..2bfdd8fca043a 100644 --- a/agent/proxycfg/testing_terminating_gateway.go +++ b/agent/proxycfg/testing_terminating_gateway.go @@ -1,11 +1,9 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg import ( - "time" - "github.com/mitchellh/go-testing-interface" "github.com/hashicorp/consul/agent/structs" @@ -650,7 +648,6 @@ func testConfigSnapshotTerminatingGatewayLBConfig(t testing.T, variant string) * OnlyPassing: true, }, }, - RequestTimeout: 200 * time.Millisecond, LoadBalancer: &structs.LoadBalancer{ Policy: "ring_hash", RingHashConfig: &structs.RingHashConfig{ diff --git a/agent/proxycfg/testing_tproxy.go b/agent/proxycfg/testing_tproxy.go index 9c1c0934e2b87..52bbf2f5ec3e4 100644 --- a/agent/proxycfg/testing_tproxy.go +++ b/agent/proxycfg/testing_tproxy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg/testing_upstreams.go b/agent/proxycfg/testing_upstreams.go index aa8c6c2e04d65..f9b77c4d62d5c 100644 --- a/agent/proxycfg/testing_upstreams.go +++ b/agent/proxycfg/testing_upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg @@ -256,9 +256,6 @@ func setupTestVariationConfigEntriesAndSnapshot( case "chain-and-router": case "lb-resolver": case "register-to-terminating-gateway": - case "redirect-to-lb-node": - case "resolver-with-lb": - case "splitter-overweight": default: extraEvents := extraUpdateEvents(t, variation, dbUID) events = append(events, extraEvents...) @@ -583,61 +580,6 @@ func setupTestVariationDiscoveryChain( }, }, ) - case "splitter-overweight": - entries = append(entries, - &structs.ServiceResolverConfigEntry{ - Kind: structs.ServiceResolver, - Name: "db", - EnterpriseMeta: entMeta, - ConnectTimeout: 33 * time.Second, - RequestTimeout: 33 * time.Second, - }, - &structs.ProxyConfigEntry{ - Kind: structs.ProxyDefaults, - Name: structs.ProxyConfigGlobal, - EnterpriseMeta: entMeta, - Config: map[string]interface{}{ - "protocol": "http", - }, - }, - &structs.ServiceSplitterConfigEntry{ - Kind: structs.ServiceSplitter, - Name: "db", - EnterpriseMeta: entMeta, - Splits: []structs.ServiceSplit{ - { - Weight: 100.0, - Service: "big-side", - RequestHeaders: &structs.HTTPHeaderModifiers{ - Set: map[string]string{"x-split-leg": "big"}, - }, - ResponseHeaders: &structs.HTTPHeaderModifiers{ - Set: map[string]string{"x-split-leg": "big"}, - }, - }, - { - Weight: 100.0, - Service: "goldilocks-side", - RequestHeaders: &structs.HTTPHeaderModifiers{ - Set: map[string]string{"x-split-leg": "goldilocks"}, - }, - ResponseHeaders: &structs.HTTPHeaderModifiers{ - Set: map[string]string{"x-split-leg": "goldilocks"}, - }, - }, - { - Weight: 100.0, - Service: "lil-bit-side", - RequestHeaders: &structs.HTTPHeaderModifiers{ - Set: map[string]string{"x-split-leg": "small"}, - }, - ResponseHeaders: &structs.HTTPHeaderModifiers{ - Set: map[string]string{"x-split-leg": "small"}, - }, - }, - }, - }, - ) case "grpc-router": entries = append(entries, &structs.ServiceResolverConfigEntry{ @@ -975,74 +917,12 @@ func setupTestVariationDiscoveryChain( Field: "header", FieldValue: "x-user-id", }, - { - Field: "query_parameter", - FieldValue: "my-pretty-param", - }, { SourceIP: true, Terminal: true, }, }, }, - }) - case "redirect-to-lb-node": - entries = append(entries, - &structs.ProxyConfigEntry{ - Kind: structs.ProxyDefaults, - Name: structs.ProxyConfigGlobal, - EnterpriseMeta: entMeta, - Config: map[string]interface{}{ - "protocol": "http", - }, - }, - &structs.ServiceRouterConfigEntry{ - Kind: structs.ServiceRouter, - Name: "db", - EnterpriseMeta: entMeta, - Routes: []structs.ServiceRoute{ - { - Match: httpMatch(&structs.ServiceRouteHTTPMatch{ - PathPrefix: "/web", - }), - Destination: toService("web"), - }, - }, - }, - &structs.ServiceResolverConfigEntry{ - Kind: structs.ServiceResolver, - Name: "web", - EnterpriseMeta: entMeta, - LoadBalancer: &structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 30, - }, - }, - }, - ) - case "resolver-with-lb": - entries = append(entries, - &structs.ProxyConfigEntry{ - Kind: structs.ProxyDefaults, - Name: structs.ProxyConfigGlobal, - EnterpriseMeta: entMeta, - Config: map[string]interface{}{ - "protocol": "http", - }, - }, - &structs.ServiceResolverConfigEntry{ - Kind: structs.ServiceResolver, - Name: "db", - EnterpriseMeta: entMeta, - LoadBalancer: &structs.LoadBalancer{ - Policy: "ring_hash", - RingHashConfig: &structs.RingHashConfig{ - MinimumRingSize: 20, - MaximumRingSize: 30, - }, - }, }, ) default: diff --git a/agent/proxycfg/testing_upstreams_ce.go b/agent/proxycfg/testing_upstreams_ce.go index bac9bb5ce6d72..3b8e22d0bda8b 100644 --- a/agent/proxycfg/testing_upstreams_ce.go +++ b/agent/proxycfg/testing_upstreams_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package proxycfg diff --git a/agent/proxycfg/upstreams.go b/agent/proxycfg/upstreams.go index fe2d502339c4e..3364b0cfe1038 100644 --- a/agent/proxycfg/upstreams.go +++ b/agent/proxycfg/upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxycfg diff --git a/agent/proxycfg_test.go b/agent/proxycfg_test.go index c8141e407fafa..334af2cca0acc 100644 --- a/agent/proxycfg_test.go +++ b/agent/proxycfg_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -13,11 +13,9 @@ import ( "github.com/stretchr/testify/require" "github.com/hashicorp/consul/agent/grpc-external/limiter" + "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" "github.com/hashicorp/consul/testrpc" ) @@ -54,7 +52,7 @@ func TestAgent_local_proxycfg(t *testing.T) { // This is a little gross, but this gives us the layered pair of // local/catalog sources for now. - cfg := a.xdsServer.ProxyWatcher + cfg := a.xdsServer.CfgSrc var ( timer = time.After(100 * time.Millisecond) @@ -64,9 +62,9 @@ func TestAgent_local_proxycfg(t *testing.T) { var ( firstTime = true - ch <-chan proxysnapshot.ProxySnapshot + ch <-chan *proxycfg.ConfigSnapshot stc limiter.SessionTerminatedChan - cancel proxysnapshot.CancelFunc + cancel proxycfg.CancelFunc ) defer func() { if cancel != nil { @@ -87,7 +85,7 @@ func TestAgent_local_proxycfg(t *testing.T) { // Prior to fixes in https://github.com/hashicorp/consul/pull/16497 // this call to Watch() would deadlock. var err error - ch, stc, cancel, err = cfg.Watch(rtest.Resource(pbmesh.ProxyConfigurationType, sid.ID).ID(), a.config.NodeName, token) + ch, stc, cancel, err = cfg.Watch(sid, a.config.NodeName, token) require.NoError(t, err) } select { diff --git a/agent/reload.go b/agent/reload.go index cf68481621bc5..ce31fd1a76c1c 100644 --- a/agent/reload.go +++ b/agent/reload.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/remote_exec.go b/agent/remote_exec.go index 876c1898620cd..770221ed2622f 100644 --- a/agent/remote_exec.go +++ b/agent/remote_exec.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/remote_exec_test.go b/agent/remote_exec_test.go index f077de895a396..9994095078d16 100644 --- a/agent/remote_exec_test.go +++ b/agent/remote_exec_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/retry_join.go b/agent/retry_join.go index eb010c0c22c47..a629aa04706e8 100644 --- a/agent/retry_join.go +++ b/agent/retry_join.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/retry_join_test.go b/agent/retry_join_test.go index 4184ab0a9f3df..af90205965b21 100644 --- a/agent/retry_join_test.go +++ b/agent/retry_join_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/router/grpc.go b/agent/router/grpc.go index ce3f079e86b97..9fe6355d4dcf1 100644 --- a/agent/router/grpc.go +++ b/agent/router/grpc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package router diff --git a/agent/router/manager.go b/agent/router/manager.go index 07d55127f3c8b..cccbc27d081a5 100644 --- a/agent/router/manager.go +++ b/agent/router/manager.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package servers provides a Manager interface for Manager managed // metadata.Server objects. The servers package manages servers from a Consul diff --git a/agent/router/manager_internal_test.go b/agent/router/manager_internal_test.go index 120a5f012c630..0e1fa28189a6d 100644 --- a/agent/router/manager_internal_test.go +++ b/agent/router/manager_internal_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package router diff --git a/agent/router/manager_test.go b/agent/router/manager_test.go index 6490164fda10c..708bb620a0da0 100644 --- a/agent/router/manager_test.go +++ b/agent/router/manager_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package router_test diff --git a/agent/router/router.go b/agent/router/router.go index c261b6ed7cd52..bdba22f42d41b 100644 --- a/agent/router/router.go +++ b/agent/router/router.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package router diff --git a/agent/router/router_test.go b/agent/router/router_test.go index 206b0befe811c..1064dea342a32 100644 --- a/agent/router/router_test.go +++ b/agent/router/router_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package router diff --git a/agent/router/serf_adapter.go b/agent/router/serf_adapter.go index d3a228ca3d5d7..f30449dc05dff 100644 --- a/agent/router/serf_adapter.go +++ b/agent/router/serf_adapter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package router diff --git a/agent/router/serf_flooder.go b/agent/router/serf_flooder.go index 06d59d5c4a89d..34ef318377faa 100644 --- a/agent/router/serf_flooder.go +++ b/agent/router/serf_flooder.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package router diff --git a/agent/routine-leak-checker/leak_test.go b/agent/routine-leak-checker/leak_test.go index f6b3c2a74953c..91d84b071b3f3 100644 --- a/agent/routine-leak-checker/leak_test.go +++ b/agent/routine-leak-checker/leak_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package leakcheck diff --git a/agent/rpc/middleware/interceptors.go b/agent/rpc/middleware/interceptors.go index e783254a980d1..f614e06cea768 100644 --- a/agent/rpc/middleware/interceptors.go +++ b/agent/rpc/middleware/interceptors.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware @@ -12,10 +12,9 @@ import ( "github.com/armon/go-metrics" "github.com/armon/go-metrics/prometheus" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/consul-net-rpc/net/rpc" rpcRate "github.com/hashicorp/consul/agent/consul/rate" + "github.com/hashicorp/go-hclog" ) // RPCTypeInternal identifies the "RPC" request as coming from some internal @@ -26,11 +25,9 @@ import ( // Really what we are measuring here is a "cluster operation". The term we have // used for this historically is "RPC", so we continue to use that here. const RPCTypeInternal = "internal" - const RPCTypeNetRPC = "net/rpc" var metricRPCRequest = []string{"rpc", "server", "call"} - var requestLogName = strings.Join(metricRPCRequest, "_") var OneTwelveRPCSummary = []prometheus.SummaryDefinition{ @@ -189,20 +186,3 @@ func GetNetRPCRateLimitingInterceptor(requestLimitsHandler rpcRate.RequestLimits return requestLimitsHandler.Allow(op) } } - -func ChainedRPCPreBodyInterceptor(chain ...rpc.PreBodyInterceptor) rpc.PreBodyInterceptor { - if len(chain) == 0 { - panic("don't call this with zero interceptors") - } - if len(chain) == 1 { - return chain[0] - } - return func(reqServiceMethod string, sourceAddr net.Addr) error { - for _, interceptor := range chain { - if err := interceptor(reqServiceMethod, sourceAddr); err != nil { - return err - } - } - return nil - } -} diff --git a/agent/rpc/middleware/interceptors_test.go b/agent/rpc/middleware/interceptors_test.go index a8e07c8d4d2ba..a22837fc6d952 100644 --- a/agent/rpc/middleware/interceptors_test.go +++ b/agent/rpc/middleware/interceptors_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/rpc/middleware/rate_limit_mappings.go b/agent/rpc/middleware/rate_limit_mappings.go index f9ca6a3333018..0df249c932338 100644 --- a/agent/rpc/middleware/rate_limit_mappings.go +++ b/agent/rpc/middleware/rate_limit_mappings.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/rpc/middleware/recovery.go b/agent/rpc/middleware/recovery.go index 6c23eb3ed3fa6..df37f969d4120 100644 --- a/agent/rpc/middleware/recovery.go +++ b/agent/rpc/middleware/recovery.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package middleware diff --git a/agent/rpc/operator/service.go b/agent/rpc/operator/service.go index 697b0db254321..6b3302c9f2e46 100644 --- a/agent/rpc/operator/service.go +++ b/agent/rpc/operator/service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package operator diff --git a/agent/rpc/operator/service_test.go b/agent/rpc/operator/service_test.go index 3cc9e117d4425..465a6d6428d29 100644 --- a/agent/rpc/operator/service_test.go +++ b/agent/rpc/operator/service_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package operator diff --git a/agent/rpc/peering/service.go b/agent/rpc/peering/service.go index d57e0378f98c0..cae0319a62dd1 100644 --- a/agent/rpc/peering/service.go +++ b/agent/rpc/peering/service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peering diff --git a/agent/rpc/peering/service_ce_test.go b/agent/rpc/peering/service_ce_test.go index b30a0ff59f7b0..d4e5fab0ba40e 100644 --- a/agent/rpc/peering/service_ce_test.go +++ b/agent/rpc/peering/service_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package peering_test diff --git a/agent/rpc/peering/service_test.go b/agent/rpc/peering/service_test.go index b2b2075157204..99d945c5fff4e 100644 --- a/agent/rpc/peering/service_test.go +++ b/agent/rpc/peering/service_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peering_test @@ -15,8 +15,6 @@ import ( "testing" "time" - "github.com/hashicorp/consul/internal/resource" - "github.com/google/tcpproxy" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-uuid" @@ -1821,7 +1819,7 @@ func newTestServer(t *testing.T, cb func(conf *consul.Config)) testingServer { deps := newDefaultDeps(t, conf) externalGRPCServer := external.NewServer(deps.Logger, nil, deps.TLSConfigurator, rate.NullRequestLimitsHandler(), keepalive.ServerParameters{}) - server, err := consul.NewServer(conf, deps, externalGRPCServer, nil, deps.Logger, nil) + server, err := consul.NewServer(conf, deps, externalGRPCServer, nil, deps.Logger) require.NoError(t, err) t.Cleanup(func() { require.NoError(t, server.Shutdown()) @@ -1953,7 +1951,6 @@ func newDefaultDeps(t *testing.T, c *consul.Config) consul.Deps { NewRequestRecorderFunc: middleware.NewRequestRecorder, GetNetRPCInterceptorFunc: middleware.GetNetRPCInterceptor, XDSStreamLimiter: limiter.NewSessionLimiter(), - Registry: resource.NewRegistry(), } } diff --git a/agent/rpc/peering/testing.go b/agent/rpc/peering/testing.go index 8989950ee29be..ddd9d43a8ad27 100644 --- a/agent/rpc/peering/testing.go +++ b/agent/rpc/peering/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peering diff --git a/agent/rpc/peering/testutil_ce_test.go b/agent/rpc/peering/testutil_ce_test.go index 7d9a0c286d265..d15d62e9f1cb1 100644 --- a/agent/rpc/peering/testutil_ce_test.go +++ b/agent/rpc/peering/testutil_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package peering_test diff --git a/agent/rpc/peering/validate.go b/agent/rpc/peering/validate.go index 2de6684d85ff9..1bd3f393bd748 100644 --- a/agent/rpc/peering/validate.go +++ b/agent/rpc/peering/validate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peering diff --git a/agent/rpc/peering/validate_test.go b/agent/rpc/peering/validate_test.go index 669baf41702fc..c5b3c6c7bdb08 100644 --- a/agent/rpc/peering/validate_test.go +++ b/agent/rpc/peering/validate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peering diff --git a/agent/rpcclient/common.go b/agent/rpcclient/common.go index 316fb341a9356..8ff1573992362 100644 --- a/agent/rpcclient/common.go +++ b/agent/rpcclient/common.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rpcclient diff --git a/agent/rpcclient/configentry/configentry.go b/agent/rpcclient/configentry/configentry.go index 2b38455beb074..ada7928dc1af7 100644 --- a/agent/rpcclient/configentry/configentry.go +++ b/agent/rpcclient/configentry/configentry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry diff --git a/agent/rpcclient/configentry/configentry_test.go b/agent/rpcclient/configentry/configentry_test.go index 92e6f4b3c88ae..9f526892fd11a 100644 --- a/agent/rpcclient/configentry/configentry_test.go +++ b/agent/rpcclient/configentry/configentry_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry diff --git a/agent/rpcclient/configentry/view.go b/agent/rpcclient/configentry/view.go index 70271a9220e97..dae3208810bfa 100644 --- a/agent/rpcclient/configentry/view.go +++ b/agent/rpcclient/configentry/view.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry diff --git a/agent/rpcclient/configentry/view_test.go b/agent/rpcclient/configentry/view_test.go index 0209c898cafed..37e642e5c36c1 100644 --- a/agent/rpcclient/configentry/view_test.go +++ b/agent/rpcclient/configentry/view_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package configentry diff --git a/agent/rpcclient/health/health.go b/agent/rpcclient/health/health.go index f062d2aac284e..8a65a50578aad 100644 --- a/agent/rpcclient/health/health.go +++ b/agent/rpcclient/health/health.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package health diff --git a/agent/rpcclient/health/health_test.go b/agent/rpcclient/health/health_test.go index 30900bc04cc01..2d8c57a3beba5 100644 --- a/agent/rpcclient/health/health_test.go +++ b/agent/rpcclient/health/health_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package health diff --git a/agent/rpcclient/health/streaming_test.go b/agent/rpcclient/health/streaming_test.go index 180b61f0eec65..3a0ba734ba9ab 100644 --- a/agent/rpcclient/health/streaming_test.go +++ b/agent/rpcclient/health/streaming_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package health diff --git a/agent/rpcclient/health/view.go b/agent/rpcclient/health/view.go index 8e08ba801e5f1..e1fffd3e23de6 100644 --- a/agent/rpcclient/health/view.go +++ b/agent/rpcclient/health/view.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package health diff --git a/agent/rpcclient/health/view_test.go b/agent/rpcclient/health/view_test.go index 83eba5ab41a07..6b4b8ee85798d 100644 --- a/agent/rpcclient/health/view_test.go +++ b/agent/rpcclient/health/view_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package health diff --git a/agent/service_checks_test.go b/agent/service_checks_test.go index 41372cc47dbbe..c567776587e36 100644 --- a/agent/service_checks_test.go +++ b/agent/service_checks_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/service_manager.go b/agent/service_manager.go index 355c73eb2c412..b7e38b393ace2 100644 --- a/agent/service_manager.go +++ b/agent/service_manager.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -148,8 +148,7 @@ func (w *serviceConfigWatch) register(ctx context.Context) error { // Merge the local registration with the central defaults and update this service // in the local state. - ns := w.registration.Service.WithNormalizedUpstreams() - merged, err := configentry.MergeServiceConfig(serviceDefaults, ns) + merged, err := configentry.MergeServiceConfig(serviceDefaults, w.registration.Service) if err != nil { return err } @@ -279,8 +278,7 @@ func (w *serviceConfigWatch) handleUpdate(ctx context.Context, event cache.Updat // Merge the local registration with the central defaults and update this service // in the local state. - ns := w.registration.Service.WithNormalizedUpstreams() - merged, err := configentry.MergeServiceConfig(serviceDefaults, ns) + merged, err := configentry.MergeServiceConfig(serviceDefaults, w.registration.Service) if err != nil { return err } diff --git a/agent/service_manager_test.go b/agent/service_manager_test.go index 289503a51ede4..724022d42ad90 100644 --- a/agent/service_manager_test.go +++ b/agent/service_manager_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/session_endpoint.go b/agent/session_endpoint.go index 90c3fa32bae7e..a9b9a6dee6baa 100644 --- a/agent/session_endpoint.go +++ b/agent/session_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/session_endpoint_test.go b/agent/session_endpoint_test.go index ae5a492808d7c..5ce93db7a68fe 100644 --- a/agent/session_endpoint_test.go +++ b/agent/session_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/setup.go b/agent/setup.go index 70770cb7cdf3f..88c883f9bdb71 100644 --- a/agent/setup.go +++ b/agent/setup.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -185,8 +185,6 @@ func NewBaseDeps(configLoader ConfigLoader, logOut io.Writer, providedLogger hcl TestOverrideCAChangeInitialDelay: cfg.ConnectTestCALeafRootChangeSpread, }, }) - // Set the leaf cert manager in the embedded deps type so it can be used by consul servers. - d.Deps.LeafCertManager = d.LeafCertManager agentType := "client" if cfg.ServerMode { @@ -262,8 +260,6 @@ func NewBaseDeps(configLoader ConfigLoader, logOut io.Writer, providedLogger hcl d.XDSStreamLimiter = limiter.NewSessionLimiter() - d.Registry = consul.NewTypeRegistry() - return d, nil } @@ -381,9 +377,7 @@ func getPrometheusDefs(cfg *config.RuntimeConfig, isServer bool) ([]prometheus.G gauges = append(gauges, verifierGauges) } - if isServer && - (cfg.RaftLogStoreConfig.Backend == consul.LogStoreBackendWAL || - cfg.RaftLogStoreConfig.Backend == consul.LogStoreBackendDefault) { + if isServer && cfg.RaftLogStoreConfig.Backend == consul.LogStoreBackendWAL { walGauges := make([]prometheus.GaugeDefinition, 0) for _, d := range wal.MetricDefinitions.Gauges { @@ -454,9 +448,7 @@ func getPrometheusDefs(cfg *config.RuntimeConfig, isServer bool) ([]prometheus.G } counters = append(counters, verifierCounters) } - if isServer && - (cfg.RaftLogStoreConfig.Backend == consul.LogStoreBackendWAL || - cfg.RaftLogStoreConfig.Backend == consul.LogStoreBackendDefault) { + if isServer && cfg.RaftLogStoreConfig.Backend == consul.LogStoreBackendWAL { walCounters := make([]prometheus.CounterDefinition, 0) for _, d := range wal.MetricDefinitions.Counters { walCounters = append(walCounters, prometheus.CounterDefinition{ diff --git a/agent/setup_ce.go b/agent/setup_ce.go index 1269e5282c021..46c4b80eb4efb 100644 --- a/agent/setup_ce.go +++ b/agent/setup_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/sidecar_service.go b/agent/sidecar_service.go index 8e57d5930bc11..7dfb067b50ef0 100644 --- a/agent/sidecar_service.go +++ b/agent/sidecar_service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/sidecar_service_test.go b/agent/sidecar_service_test.go index fd39a5a284a10..4960dd73d0542 100644 --- a/agent/sidecar_service_test.go +++ b/agent/sidecar_service_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/signal_unix.go b/agent/signal_unix.go index 173a82b96bd09..bd0b3e7793cdd 100644 --- a/agent/signal_unix.go +++ b/agent/signal_unix.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !windows +// +build !windows package agent diff --git a/agent/signal_windows.go b/agent/signal_windows.go index dc6d3cc5461a9..c6ea0c980ffb6 100644 --- a/agent/signal_windows.go +++ b/agent/signal_windows.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build windows +// +build windows package agent diff --git a/agent/snapshot_endpoint.go b/agent/snapshot_endpoint.go index 06805ae5f8c19..60d986256433b 100644 --- a/agent/snapshot_endpoint.go +++ b/agent/snapshot_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/snapshot_endpoint_test.go b/agent/snapshot_endpoint_test.go index a534fe0251135..e68fb22f385fd 100644 --- a/agent/snapshot_endpoint_test.go +++ b/agent/snapshot_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/status_endpoint.go b/agent/status_endpoint.go index 4a40ec8910270..86f9f1a5d0193 100644 --- a/agent/status_endpoint.go +++ b/agent/status_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/status_endpoint_test.go b/agent/status_endpoint_test.go index db231fbc9b834..5be9d6be64a3e 100644 --- a/agent/status_endpoint_test.go +++ b/agent/status_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/streaming_test.go b/agent/streaming_test.go index fed1e8126d41d..9074f66e83441 100644 --- a/agent/streaming_test.go +++ b/agent/streaming_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/structs/acl.go b/agent/structs/acl.go index 4d76dffa4e8e0..e611d22b89545 100644 --- a/agent/structs/acl.go +++ b/agent/structs/acl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -9,11 +9,11 @@ import ( "errors" "fmt" "hash" + "hash/fnv" "sort" "strings" "time" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib/stringslice" "golang.org/x/crypto/blake2b" @@ -63,10 +63,6 @@ agent_prefix "" { event_prefix "" { policy = "%[1]s" } -identity_prefix "" { - policy = "%[1]s" - intentions = "%[1]s" -} key_prefix "" { policy = "%[1]s" } @@ -130,7 +126,6 @@ type ACLIdentity interface { RoleIDs() []string ServiceIdentityList() []*ACLServiceIdentity NodeIdentityList() []*ACLNodeIdentity - TemplatedPolicyList() []*ACLTemplatedPolicy IsExpired(asOf time.Time) bool IsLocal() bool EnterpriseMetadata() *acl.EnterpriseMeta @@ -182,20 +177,22 @@ func (s *ACLServiceIdentity) EstimateSize() int { } func (s *ACLServiceIdentity) SyntheticPolicy(entMeta *acl.EnterpriseMeta) *ACLPolicy { - // use templated policy to generate synthetic policy - templatedPolicy := ACLTemplatedPolicy{ - TemplateID: ACLTemplatedPolicyServiceID, - TemplateName: api.ACLTemplatedPolicyServiceName, - Datacenters: s.Datacenters, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: s.ServiceName, - }, - } - // Given that we validate this string name before persisting, we do not - // expect any errors from generating the synthetic policy - policy, _ := templatedPolicy.SyntheticPolicy(entMeta) - + // have to escape it before doing the following interpolation. + rules := aclServiceIdentityRules(s.ServiceName, entMeta) + + hasher := fnv.New128a() + hashID := fmt.Sprintf("%x", hasher.Sum([]byte(rules))) + + policy := &ACLPolicy{} + policy.ID = hashID + policy.Name = fmt.Sprintf("synthetic-policy-%s", hashID) + sn := NewServiceName(s.ServiceName, entMeta) + policy.Description = fmt.Sprintf("synthetic policy for service identity %q", sn.String()) + policy.Rules = rules + policy.Datacenters = s.Datacenters + policy.EnterpriseMeta.Merge(entMeta) + policy.SetHash(true) return policy } @@ -252,20 +249,21 @@ func (s *ACLNodeIdentity) EstimateSize() int { } func (s *ACLNodeIdentity) SyntheticPolicy(entMeta *acl.EnterpriseMeta) *ACLPolicy { - // use templated policy to generate synthetic policy - templatedPolicy := ACLTemplatedPolicy{ - TemplateID: ACLTemplatedPolicyNodeID, - TemplateName: api.ACLTemplatedPolicyNodeName, - Datacenters: []string{s.Datacenter}, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: s.NodeName, - }, - } - // Given that we validate this string name before persisting, we do not - // expect any errors from generating the synthetic policy - policy, _ := templatedPolicy.SyntheticPolicy(entMeta) - + // have to escape it before doing the following interpolation. + rules := aclNodeIdentityRules(s.NodeName, entMeta) + + hasher := fnv.New128a() + hashID := fmt.Sprintf("%x", hasher.Sum([]byte(rules))) + + policy := &ACLPolicy{} + policy.ID = hashID + policy.Name = fmt.Sprintf("synthetic-policy-%s", hashID) + policy.Description = fmt.Sprintf("synthetic policy for node identity %q", s.NodeName) + policy.Rules = rules + policy.Datacenters = []string{s.Datacenter} + policy.EnterpriseMeta.Merge(entMeta) + policy.SetHash(true) return policy } @@ -316,9 +314,6 @@ type ACLToken struct { // The node identities that this token should be allowed to manage. NodeIdentities ACLNodeIdentities `json:",omitempty"` - // The templated policies to generate synthetic policies for. - TemplatedPolicies ACLTemplatedPolicies `json:",omitempty"` - // Whether this token is DC local. This means that it will not be synced // to the ACL datacenter and replicated to others. Local bool @@ -399,7 +394,6 @@ func (t *ACLToken) Clone() *ACLToken { t2.Roles = nil t2.ServiceIdentities = nil t2.NodeIdentities = nil - t2.TemplatedPolicies = nil if len(t.Policies) > 0 { t2.Policies = make([]ACLTokenPolicyLink, len(t.Policies)) @@ -421,12 +415,6 @@ func (t *ACLToken) Clone() *ACLToken { t2.NodeIdentities[i] = n.Clone() } } - if len(t.TemplatedPolicies) > 0 { - t2.TemplatedPolicies = make([]*ACLTemplatedPolicy, len(t.TemplatedPolicies)) - for idx, tp := range t.TemplatedPolicies { - t2.TemplatedPolicies[idx] = tp.Clone() - } - } return &t2 } @@ -535,10 +523,6 @@ func (t *ACLToken) SetHash(force bool) []byte { nodeID.AddToHash(hash) } - for _, templatedPolicy := range t.TemplatedPolicies { - templatedPolicy.AddToHash(hash) - } - t.EnterpriseMeta.AddToHash(hash, false) // Finalize the hash @@ -565,9 +549,6 @@ func (t *ACLToken) EstimateSize() int { for _, nodeID := range t.NodeIdentities { size += nodeID.EstimateSize() } - for _, templatedPolicy := range t.TemplatedPolicies { - size += templatedPolicy.EstimateSize() - } return size + t.EnterpriseMeta.EstimateSize() } @@ -582,7 +563,6 @@ type ACLTokenListStub struct { Roles []ACLTokenRoleLink `json:",omitempty"` ServiceIdentities ACLServiceIdentities `json:",omitempty"` NodeIdentities ACLNodeIdentities `json:",omitempty"` - TemplatedPolicies ACLTemplatedPolicies `json:",omitempty"` Local bool AuthMethod string `json:",omitempty"` ExpirationTime *time.Time `json:",omitempty"` @@ -605,7 +585,6 @@ func (token *ACLToken) Stub() *ACLTokenListStub { Roles: token.Roles, ServiceIdentities: token.ServiceIdentities, NodeIdentities: token.NodeIdentities, - TemplatedPolicies: token.TemplatedPolicies, Local: token.Local, AuthMethod: token.AuthMethod, ExpirationTime: token.ExpirationTime, @@ -891,9 +870,6 @@ type ACLRole struct { // List of nodes to generate synthetic policies for. NodeIdentities ACLNodeIdentities `json:",omitempty"` - // List of templated policies to generate synthethic policies for. - TemplatedPolicies ACLTemplatedPolicies `json:",omitempty"` - // Hash of the contents of the role // This does not take into account the ID (which is immutable) // nor the raft metadata. @@ -933,7 +909,6 @@ func (r *ACLRole) Clone() *ACLRole { r2.Policies = nil r2.ServiceIdentities = nil r2.NodeIdentities = nil - r2.TemplatedPolicies = nil if len(r.Policies) > 0 { r2.Policies = make([]ACLRolePolicyLink, len(r.Policies)) @@ -951,12 +926,6 @@ func (r *ACLRole) Clone() *ACLRole { r2.NodeIdentities[i] = n.Clone() } } - if len(r.TemplatedPolicies) > 0 { - r2.TemplatedPolicies = make([]*ACLTemplatedPolicy, len(r.TemplatedPolicies)) - for i, n := range r.TemplatedPolicies { - r2.TemplatedPolicies[i] = n.Clone() - } - } return &r2 } @@ -988,9 +957,6 @@ func (r *ACLRole) SetHash(force bool) []byte { for _, nodeID := range r.NodeIdentities { nodeID.AddToHash(hash) } - for _, templatedPolicy := range r.TemplatedPolicies { - templatedPolicy.AddToHash(hash) - } r.EnterpriseMeta.AddToHash(hash, false) @@ -1018,9 +984,6 @@ func (r *ACLRole) EstimateSize() int { for _, nodeID := range r.NodeIdentities { size += nodeID.EstimateSize() } - for _, templatedPolicy := range r.TemplatedPolicies { - size += templatedPolicy.EstimateSize() - } return size + r.EnterpriseMeta.EstimateSize() } @@ -1069,21 +1032,6 @@ const ( // } // } BindingRuleBindTypeNode = "node" - - // BindingRuleBindTypeTemplatedPolicy is the binding rule bind type that - // assigns a TemplatedPolicy to the token that is created using the value - // of the computed BindVars as template variables and BindName as template name like: - // - // &ACLToken{ - // ...other fields... - // TemplatedPolicies: []*ACLTemplatedPolicy{ - // &ACLTemplatedPolicy{ - // TemplateName: "", - // TemplateVariables: &ACLTemplatedPolicyVariables{} - // }, - // }, - // } - BindingRuleBindTypeTemplatedPolicy = "templated-policy" ) type ACLBindingRule struct { @@ -1103,10 +1051,8 @@ type ACLBindingRule struct { // BindType adjusts how this binding rule is applied at login time. The // valid values are: // - // - BindingRuleBindTypeService = "service" - // - BindingRuleBindTypeNode = "node" - // - BindingRuleBindTypeRole = "role" - // - BindingRuleBindTypeTemplatedPolicy = "templated-policy" + // - BindingRuleBindTypeService = "service" + // - BindingRuleBindTypeRole = "role" BindType string // BindName is the target of the binding. Can be lightly templated using @@ -1114,10 +1060,6 @@ type ACLBindingRule struct { // upon the BindType. BindName string - // BindVars is a the variables used when binding rule type is `templated-policy`. Can be lightly - // templated using HIL ${foo} syntax from available field names. - BindVars *ACLTemplatedPolicyVariables `json:",omitempty"` - // Embedded Enterprise ACL metadata acl.EnterpriseMeta `mapstructure:",squash"` @@ -1382,7 +1324,7 @@ type ACLTokenListResponse struct { } // ACLTokenBatchGetRequest is used for reading multiple tokens, this is -// different from the token list request in that only tokens with the +// different from the the token list request in that only tokens with the // the requested ids are returned type ACLTokenBatchGetRequest struct { AccessorIDs []string // List of accessor ids to fetch @@ -1903,10 +1845,6 @@ func (id *AgentRecoveryTokenIdentity) NodeIdentityList() []*ACLNodeIdentity { return nil } -func (id *AgentRecoveryTokenIdentity) TemplatedPolicyList() []*ACLTemplatedPolicy { - return nil -} - func (id *AgentRecoveryTokenIdentity) IsExpired(asOf time.Time) bool { return false } @@ -1955,10 +1893,6 @@ func (i *ACLServerIdentity) NodeIdentityList() []*ACLNodeIdentity { return nil } -func (i *ACLServerIdentity) TemplatedPolicyList() []*ACLTemplatedPolicy { - return nil -} - func (i *ACLServerIdentity) IsExpired(asOf time.Time) bool { return false } diff --git a/agent/structs/acl_cache.go b/agent/structs/acl_cache.go index 15f3a2edc3c26..46d4fdd28117b 100644 --- a/agent/structs/acl_cache.go +++ b/agent/structs/acl_cache.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/acl_cache_test.go b/agent/structs/acl_cache_test.go index 57e218ff21e32..e390da960f4ed 100644 --- a/agent/structs/acl_cache_test.go +++ b/agent/structs/acl_cache_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/acl_ce.go b/agent/structs/acl_ce.go index 166558ae65af8..9cc4e7813ce85 100644 --- a/agent/structs/acl_ce.go +++ b/agent/structs/acl_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/acl_templated_policy.go b/agent/structs/acl_templated_policy.go deleted file mode 100644 index d0da96e4eb4aa..0000000000000 --- a/agent/structs/acl_templated_policy.go +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package structs - -import ( - "bytes" - _ "embed" - "fmt" - "hash" - "hash/fnv" - "html/template" - - "github.com/hashicorp/go-multierror" - "github.com/xeipuuv/gojsonschema" - "golang.org/x/exp/slices" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/lib/stringslice" -) - -//go:embed acltemplatedpolicy/schemas/node.json -var ACLTemplatedPolicyNodeSchema string - -//go:embed acltemplatedpolicy/schemas/service.json -var ACLTemplatedPolicyServiceSchema string - -//go:embed acltemplatedpolicy/schemas/workload-identity.json -var ACLTemplatedPolicyWorkloadIdentitySchema string - -type ACLTemplatedPolicies []*ACLTemplatedPolicy - -const ( - ACLTemplatedPolicyServiceID = "00000000-0000-0000-0000-000000000003" - ACLTemplatedPolicyNodeID = "00000000-0000-0000-0000-000000000004" - ACLTemplatedPolicyDNSID = "00000000-0000-0000-0000-000000000005" - ACLTemplatedPolicyNomadServerID = "00000000-0000-0000-0000-000000000006" - ACLTemplatedPolicyWorkloadIdentityID = "00000000-0000-0000-0000-000000000007" - - ACLTemplatedPolicyNoRequiredVariablesSchema = "" // catch-all schema for all templated policy that don't require a schema -) - -// ACLTemplatedPolicyBase contains basic information about builtin templated policies -// template name, id, template code and schema -type ACLTemplatedPolicyBase struct { - TemplateName string - TemplateID string - Schema string - Template string -} - -var ( - // Note: when adding a new builtin template, ensure you update `command/acl/templatedpolicy/formatter.go` - // to handle the new templates required variables and schema. - aclTemplatedPoliciesList = map[string]*ACLTemplatedPolicyBase{ - api.ACLTemplatedPolicyServiceName: { - TemplateID: ACLTemplatedPolicyServiceID, - TemplateName: api.ACLTemplatedPolicyServiceName, - Schema: ACLTemplatedPolicyServiceSchema, - Template: ACLTemplatedPolicyService, - }, - api.ACLTemplatedPolicyNodeName: { - TemplateID: ACLTemplatedPolicyNodeID, - TemplateName: api.ACLTemplatedPolicyNodeName, - Schema: ACLTemplatedPolicyNodeSchema, - Template: ACLTemplatedPolicyNode, - }, - api.ACLTemplatedPolicyDNSName: { - TemplateID: ACLTemplatedPolicyDNSID, - TemplateName: api.ACLTemplatedPolicyDNSName, - Schema: ACLTemplatedPolicyNoRequiredVariablesSchema, - Template: ACLTemplatedPolicyDNS, - }, - api.ACLTemplatedPolicyNomadServerName: { - TemplateID: ACLTemplatedPolicyNomadServerID, - TemplateName: api.ACLTemplatedPolicyNomadServerName, - Schema: ACLTemplatedPolicyNoRequiredVariablesSchema, - Template: ACLTemplatedPolicyNomadServer, - }, - api.ACLTemplatedPolicyWorkloadIdentityName: { - TemplateID: ACLTemplatedPolicyWorkloadIdentityID, - TemplateName: api.ACLTemplatedPolicyWorkloadIdentityName, - Schema: ACLTemplatedPolicyWorkloadIdentitySchema, - Template: ACLTemplatedPolicyWorkloadIdentity, - }, - } -) - -// ACLTemplatedPolicy represents a template used to generate a `synthetic` policy -// given some input variables. -type ACLTemplatedPolicy struct { - // TemplateID are hidden from all displays and should not be exposed to the users. - TemplateID string `json:",omitempty"` - - // TemplateName is used for display purposes mostly and should not be used for policy rendering. - TemplateName string `json:",omitempty"` - - // TemplateVariables are input variables required to render templated policies. - TemplateVariables *ACLTemplatedPolicyVariables `json:",omitempty"` - - // Datacenters that the synthetic policy will be valid within. - // - No wildcards allowed - // - If empty then the synthetic policy is valid within all datacenters - // - // This is kept for legacy reasons to enable us to replace Node/Service Identities by templated policies. - // - // Only valid for global tokens. It is an error to specify this for local tokens. - Datacenters []string `json:",omitempty"` -} - -// ACLTemplatedPolicyVariables are input variables required to render templated policies. -type ACLTemplatedPolicyVariables struct { - Name string `json:"name,omitempty"` -} - -func (tp *ACLTemplatedPolicy) Clone() *ACLTemplatedPolicy { - tp2 := *tp - - tp2.TemplateVariables = nil - if tp.TemplateVariables != nil { - tp2.TemplateVariables = tp.TemplateVariables.Clone() - } - tp2.Datacenters = stringslice.CloneStringSlice(tp.Datacenters) - - return &tp2 -} - -func (tp *ACLTemplatedPolicy) AddToHash(h hash.Hash) { - h.Write([]byte(tp.TemplateID)) - h.Write([]byte(tp.TemplateName)) - - if tp.TemplateVariables != nil { - tp.TemplateVariables.AddToHash(h) - } - for _, dc := range tp.Datacenters { - h.Write([]byte(dc)) - } -} - -func (tv *ACLTemplatedPolicyVariables) AddToHash(h hash.Hash) { - h.Write([]byte(tv.Name)) -} - -func (tv *ACLTemplatedPolicyVariables) Clone() *ACLTemplatedPolicyVariables { - tv2 := *tv - return &tv2 -} - -// validates templated policy variables against schema. -func (tp *ACLTemplatedPolicy) ValidateTemplatedPolicy(schema string) error { - if schema == "" { - return nil - } - - loader := gojsonschema.NewStringLoader(schema) - dataloader := gojsonschema.NewGoLoader(tp.TemplateVariables) - res, err := gojsonschema.Validate(loader, dataloader) - if err != nil { - return fmt.Errorf("failed to load json schema for validation %w", err) - } - - if res.Valid() { - return nil - } - - var merr *multierror.Error - - for _, resultError := range res.Errors() { - merr = multierror.Append(merr, fmt.Errorf(resultError.Description())) - } - return merr.ErrorOrNil() -} - -func (tp *ACLTemplatedPolicy) EstimateSize() int { - size := len(tp.TemplateName) + len(tp.TemplateID) + tp.TemplateVariables.EstimateSize() - for _, dc := range tp.Datacenters { - size += len(dc) - } - - return size -} - -func (tv *ACLTemplatedPolicyVariables) EstimateSize() int { - return len(tv.Name) -} - -// SyntheticPolicy generates a policy based on templated policies' ID and variables -// -// Given that we validate this string name before persisting, we do not -// have to escape it before doing the following interpolation. -func (tp *ACLTemplatedPolicy) SyntheticPolicy(entMeta *acl.EnterpriseMeta) (*ACLPolicy, error) { - rules, err := tp.aclTemplatedPolicyRules(entMeta) - if err != nil { - return nil, err - } - hasher := fnv.New128a() - hashID := fmt.Sprintf("%x", hasher.Sum([]byte(rules))) - - policy := &ACLPolicy{ - Rules: rules, - ID: hashID, - Name: fmt.Sprintf("synthetic-policy-%s", hashID), - Datacenters: tp.Datacenters, - Description: fmt.Sprintf("synthetic policy generated from templated policy: %s", tp.TemplateName), - } - policy.EnterpriseMeta.Merge(entMeta) - policy.SetHash(true) - - return policy, nil -} - -func (tp *ACLTemplatedPolicy) aclTemplatedPolicyRules(entMeta *acl.EnterpriseMeta) (string, error) { - if entMeta == nil { - entMeta = DefaultEnterpriseMetaInDefaultPartition() - } - entMeta.Normalize() - - tpl := template.New(tp.TemplateName) - tmplCode, ok := aclTemplatedPoliciesList[tp.TemplateName] - if !ok { - return "", fmt.Errorf("acl templated policy does not exist: %s", tp.TemplateName) - } - - parsedTpl, err := tpl.Parse(tmplCode.Template) - if err != nil { - return "", fmt.Errorf("an error occured when parsing template structs: %w", err) - } - var buf bytes.Buffer - err = parsedTpl.Execute(&buf, struct { - *ACLTemplatedPolicyVariables - Namespace string - Partition string - }{ - Namespace: entMeta.NamespaceOrDefault(), - Partition: entMeta.PartitionOrDefault(), - ACLTemplatedPolicyVariables: tp.TemplateVariables, - }) - if err != nil { - return "", fmt.Errorf("an error occured when executing on templated policy variables: %w", err) - } - - return buf.String(), nil -} - -// Deduplicate returns a new list of templated policies without duplicates. -// compares values of template variables to ensure no duplicates -func (tps ACLTemplatedPolicies) Deduplicate() ACLTemplatedPolicies { - list := make(map[string][]ACLTemplatedPolicyVariables) - var out ACLTemplatedPolicies - - for _, tp := range tps { - // checks if template name already in the unique list - _, found := list[tp.TemplateName] - if !found { - list[tp.TemplateName] = make([]ACLTemplatedPolicyVariables, 0) - } - templateSchema := aclTemplatedPoliciesList[tp.TemplateName].Schema - - // if schema is empty, template does not require variables - if templateSchema == "" { - if !found { - out = append(out, tp) - } - continue - } - - if !slices.Contains(list[tp.TemplateName], *tp.TemplateVariables) { - list[tp.TemplateName] = append(list[tp.TemplateName], *tp.TemplateVariables) - out = append(out, tp) - } - } - - return out -} - -func GetACLTemplatedPolicyBase(templateName string) (*ACLTemplatedPolicyBase, bool) { - if orig, found := aclTemplatedPoliciesList[templateName]; found { - copy := *orig - return ©, found - } - - return nil, false -} - -// GetACLTemplatedPolicyList returns a copy of the list of templated policies -func GetACLTemplatedPolicyList() map[string]*ACLTemplatedPolicyBase { - m := make(map[string]*ACLTemplatedPolicyBase, len(aclTemplatedPoliciesList)) - for k, v := range aclTemplatedPoliciesList { - m[k] = v - } - - return m -} diff --git a/agent/structs/acl_templated_policy_ce.go b/agent/structs/acl_templated_policy_ce.go deleted file mode 100644 index cd9a52248a987..0000000000000 --- a/agent/structs/acl_templated_policy_ce.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package structs - -import _ "embed" - -//go:embed acltemplatedpolicy/policies/ce/service.hcl -var ACLTemplatedPolicyService string - -//go:embed acltemplatedpolicy/policies/ce/node.hcl -var ACLTemplatedPolicyNode string - -//go:embed acltemplatedpolicy/policies/ce/dns.hcl -var ACLTemplatedPolicyDNS string - -//go:embed acltemplatedpolicy/policies/ce/nomad-server.hcl -var ACLTemplatedPolicyNomadServer string - -//go:embed acltemplatedpolicy/policies/ce/workload-identity.hcl -var ACLTemplatedPolicyWorkloadIdentity string - -func (t *ACLToken) TemplatedPolicyList() []*ACLTemplatedPolicy { - if len(t.TemplatedPolicies) == 0 { - return nil - } - - out := make([]*ACLTemplatedPolicy, 0, len(t.TemplatedPolicies)) - for _, n := range t.TemplatedPolicies { - out = append(out, n.Clone()) - } - return out -} - -func (t *ACLRole) TemplatedPolicyList() []*ACLTemplatedPolicy { - if len(t.TemplatedPolicies) == 0 { - return nil - } - - out := make([]*ACLTemplatedPolicy, 0, len(t.TemplatedPolicies)) - for _, n := range t.TemplatedPolicies { - out = append(out, n.Clone()) - } - return out -} diff --git a/agent/structs/acl_templated_policy_ce_test.go b/agent/structs/acl_templated_policy_ce_test.go deleted file mode 100644 index e160a911cb89a..0000000000000 --- a/agent/structs/acl_templated_policy_ce_test.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package structs - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" -) - -func TestStructs_ACLTemplatedPolicy_SyntheticPolicy(t *testing.T) { - type testCase struct { - templatedPolicy *ACLTemplatedPolicy - expectedPolicy *ACLPolicy - } - - testCases := map[string]testCase{ - "service-identity-template": { - templatedPolicy: &ACLTemplatedPolicy{ - TemplateID: ACLTemplatedPolicyServiceID, - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - expectedPolicy: &ACLPolicy{ - Description: "synthetic policy generated from templated policy: builtin/service", - Rules: ` -service "api" { - policy = "write" -} -service "api-sidecar-proxy" { - policy = "write" -} -service_prefix "" { - policy = "read" -} -node_prefix "" { - policy = "read" -}`, - }, - }, - "node-identity-template": { - templatedPolicy: &ACLTemplatedPolicy{ - TemplateID: ACLTemplatedPolicyNodeID, - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "web", - }, - }, - expectedPolicy: &ACLPolicy{ - Description: "synthetic policy generated from templated policy: builtin/node", - Rules: ` -node "web" { - policy = "write" -} -service_prefix "" { - policy = "read" -}`, - }, - }, - "dns-template": { - templatedPolicy: &ACLTemplatedPolicy{ - TemplateID: ACLTemplatedPolicyDNSID, - TemplateName: api.ACLTemplatedPolicyDNSName, - }, - expectedPolicy: &ACLPolicy{ - Description: "synthetic policy generated from templated policy: builtin/dns", - Rules: ` -node_prefix "" { - policy = "read" -} -service_prefix "" { - policy = "read" -} -query_prefix "" { - policy = "read" -}`, - }, - }, - "workload-identity-template": { - templatedPolicy: &ACLTemplatedPolicy{ - TemplateID: ACLTemplatedPolicyWorkloadIdentityID, - TemplateName: api.ACLTemplatedPolicyWorkloadIdentityName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - expectedPolicy: &ACLPolicy{ - Description: "synthetic policy generated from templated policy: builtin/workload-identity", - Rules: `identity "api" { - policy = "write" -}`, - }, - }, - } - - for name, tcase := range testCases { - t.Run(name, func(t *testing.T) { - policy, err := tcase.templatedPolicy.SyntheticPolicy(nil) - - require.NoError(t, err) - require.Equal(t, tcase.expectedPolicy.Description, policy.Description) - require.Equal(t, tcase.expectedPolicy.Rules, policy.Rules) - require.Contains(t, policy.Name, "synthetic-policy-") - require.NotEmpty(t, policy.Hash) - require.NotEmpty(t, policy.ID) - }) - } -} diff --git a/agent/structs/acl_templated_policy_test.go b/agent/structs/acl_templated_policy_test.go deleted file mode 100644 index 5d907ca010bfd..0000000000000 --- a/agent/structs/acl_templated_policy_test.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package structs - -import ( - "testing" - - "github.com/hashicorp/consul/api" - "github.com/stretchr/testify/require" -) - -func TestDeduplicate(t *testing.T) { - type testCase struct { - templatedPolicies ACLTemplatedPolicies - expectedCount int - } - tcases := map[string]testCase{ - "multiple-of-the-same-template": { - templatedPolicies: ACLTemplatedPolicies{ - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - }, - expectedCount: 1, - }, - "separate-templates-with-matching-variables": { - templatedPolicies: ACLTemplatedPolicies{ - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - }, - expectedCount: 2, - }, - "separate-templates-with-multiple-matching-variables": { - templatedPolicies: ACLTemplatedPolicies{ - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "web", - }, - }, - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyDNSName, - }, - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &ACLTemplatedPolicyVariables{ - Name: "web", - }, - }, - &ACLTemplatedPolicy{ - TemplateName: api.ACLTemplatedPolicyDNSName, - }, - }, - expectedCount: 5, - }, - } - - for name, tcase := range tcases { - t.Run(name, func(t *testing.T) { - policies := tcase.templatedPolicies.Deduplicate() - - require.Equal(t, tcase.expectedCount, len(policies)) - }) - } -} diff --git a/agent/structs/acl_test.go b/agent/structs/acl_test.go index e1fb35263b95a..6658b8335021a 100644 --- a/agent/structs/acl_test.go +++ b/agent/structs/acl_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/aclfilter/filter.go b/agent/structs/aclfilter/filter.go index d59bf3c9c403b..ddd63db10e686 100644 --- a/agent/structs/aclfilter/filter.go +++ b/agent/structs/aclfilter/filter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package aclfilter diff --git a/agent/structs/aclfilter/filter_test.go b/agent/structs/aclfilter/filter_test.go index 98f3bb63f291b..2339b0acd223d 100644 --- a/agent/structs/aclfilter/filter_test.go +++ b/agent/structs/aclfilter/filter_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package aclfilter diff --git a/agent/structs/acltemplatedpolicy/policies/ce/dns.hcl b/agent/structs/acltemplatedpolicy/policies/ce/dns.hcl deleted file mode 100644 index 6627f1c96a5ff..0000000000000 --- a/agent/structs/acltemplatedpolicy/policies/ce/dns.hcl +++ /dev/null @@ -1,10 +0,0 @@ - -node_prefix "" { - policy = "read" -} -service_prefix "" { - policy = "read" -} -query_prefix "" { - policy = "read" -} \ No newline at end of file diff --git a/agent/structs/acltemplatedpolicy/policies/ce/node.hcl b/agent/structs/acltemplatedpolicy/policies/ce/node.hcl deleted file mode 100644 index b6b03a2250f02..0000000000000 --- a/agent/structs/acltemplatedpolicy/policies/ce/node.hcl +++ /dev/null @@ -1,7 +0,0 @@ - -node "{{.Name}}" { - policy = "write" -} -service_prefix "" { - policy = "read" -} \ No newline at end of file diff --git a/agent/structs/acltemplatedpolicy/policies/ce/nomad-server.hcl b/agent/structs/acltemplatedpolicy/policies/ce/nomad-server.hcl deleted file mode 100644 index 7030ff771a199..0000000000000 --- a/agent/structs/acltemplatedpolicy/policies/ce/nomad-server.hcl +++ /dev/null @@ -1,11 +0,0 @@ - -acl = "write" -agent_prefix "" { - policy = "read" -} -node_prefix "" { - policy = "read" -} -service_prefix "" { - policy = "write" -} \ No newline at end of file diff --git a/agent/structs/acltemplatedpolicy/policies/ce/service.hcl b/agent/structs/acltemplatedpolicy/policies/ce/service.hcl deleted file mode 100644 index a8d2faf2791d1..0000000000000 --- a/agent/structs/acltemplatedpolicy/policies/ce/service.hcl +++ /dev/null @@ -1,13 +0,0 @@ - -service "{{.Name}}" { - policy = "write" -} -service "{{.Name}}-sidecar-proxy" { - policy = "write" -} -service_prefix "" { - policy = "read" -} -node_prefix "" { - policy = "read" -} \ No newline at end of file diff --git a/agent/structs/acltemplatedpolicy/policies/ce/workload-identity.hcl b/agent/structs/acltemplatedpolicy/policies/ce/workload-identity.hcl deleted file mode 100644 index ccd1e0564633d..0000000000000 --- a/agent/structs/acltemplatedpolicy/policies/ce/workload-identity.hcl +++ /dev/null @@ -1,3 +0,0 @@ -identity "{{.Name}}" { - policy = "write" -} \ No newline at end of file diff --git a/agent/structs/acltemplatedpolicy/schemas/node.json b/agent/structs/acltemplatedpolicy/schemas/node.json deleted file mode 100644 index 8a3d193268217..0000000000000 --- a/agent/structs/acltemplatedpolicy/schemas/node.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "object", - "properties": { - "name": { "type": "string", "$ref": "#/definitions/min-length-one" } - }, - "required": ["name"], - "definitions": { - "min-length-one": { - "type": "string", - "minLength": 1 - } - } -} \ No newline at end of file diff --git a/agent/structs/acltemplatedpolicy/schemas/service.json b/agent/structs/acltemplatedpolicy/schemas/service.json deleted file mode 100644 index 8a3d193268217..0000000000000 --- a/agent/structs/acltemplatedpolicy/schemas/service.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "object", - "properties": { - "name": { "type": "string", "$ref": "#/definitions/min-length-one" } - }, - "required": ["name"], - "definitions": { - "min-length-one": { - "type": "string", - "minLength": 1 - } - } -} \ No newline at end of file diff --git a/agent/structs/acltemplatedpolicy/schemas/workload-identity.json b/agent/structs/acltemplatedpolicy/schemas/workload-identity.json deleted file mode 100644 index 31064f36af7f0..0000000000000 --- a/agent/structs/acltemplatedpolicy/schemas/workload-identity.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "object", - "properties": { - "name": { "type": "string", "$ref": "#/definitions/min-length-one" } - }, - "required": ["name"], - "definitions": { - "min-length-one": { - "type": "string", - "minLength": 1 - } - } -} \ No newline at end of file diff --git a/agent/structs/auto_encrypt.go b/agent/structs/auto_encrypt.go index cce7c4effa1e3..2e9053f9a5382 100644 --- a/agent/structs/auto_encrypt.go +++ b/agent/structs/auto_encrypt.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/autopilot.go b/agent/structs/autopilot.go index 431e2ad4d374f..a5a14684fa9e3 100644 --- a/agent/structs/autopilot.go +++ b/agent/structs/autopilot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/autopilot_ce.go b/agent/structs/autopilot_ce.go index f15e28f6a897e..3098c0cf3cae6 100644 --- a/agent/structs/autopilot_ce.go +++ b/agent/structs/autopilot_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/catalog.go b/agent/structs/catalog.go index 84795ce47898d..f11af9f87801b 100644 --- a/agent/structs/catalog.go +++ b/agent/structs/catalog.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/catalog_ce.go b/agent/structs/catalog_ce.go index 463f88fcbe2e4..91e08264b99d0 100644 --- a/agent/structs/catalog_ce.go +++ b/agent/structs/catalog_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/check_definition.go b/agent/structs/check_definition.go index 0b04290e707d5..f28201b4d17f5 100644 --- a/agent/structs/check_definition.go +++ b/agent/structs/check_definition.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/check_definition_test.go b/agent/structs/check_definition_test.go index 5a51f377c0e8f..676499ef042a1 100644 --- a/agent/structs/check_definition_test.go +++ b/agent/structs/check_definition_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/check_type.go b/agent/structs/check_type.go index 61a5a762f7c54..e6342e8231f93 100644 --- a/agent/structs/check_type.go +++ b/agent/structs/check_type.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry.go b/agent/structs/config_entry.go index 544820f4d607c..c18a8013b6d45 100644 --- a/agent/structs/config_entry.go +++ b/agent/structs/config_entry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -165,7 +165,6 @@ 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 EnvoyExtensions `json:",omitempty" alias:"envoy_extensions"` Meta map[string]string `json:",omitempty"` @@ -287,10 +286,6 @@ func (e *ServiceConfigEntry) Validate() error { } } - if err := validateRatelimit(e.RateLimits); err != nil { - validationErr = multierror.Append(validationErr, err) - } - if err := envoyextensions.ValidateExtensions(e.EnvoyExtensions.ToAPI()); err != nil { validationErr = multierror.Append(validationErr, err) } @@ -387,51 +382,14 @@ type DestinationConfig struct { Port int `json:",omitempty"` } -func IsIP(address string) bool { +func IsHostname(address string) bool { ip := net.ParseIP(address) - return ip != nil + return ip == nil } -// RateLimits is rate limiting configuration that is applied to -// inbound traffic for a service. -// Rate limiting is a Consul enterprise feature. -type RateLimits struct { - InstanceLevel InstanceLevelRateLimits `alias:"instance_level"` -} - -// InstanceLevelRateLimits represents rate limit configuration -// that are applied per service instance. -type InstanceLevelRateLimits struct { - // RequestsPerSecond is the average number of requests per second that can be - // made without being throttled. This field is required if RequestsMaxBurst - // is set. The allowed number of requests may exceed RequestsPerSecond up to - // the value specified in RequestsMaxBurst. - // - // Internally, this is the refill rate of the token bucket used for rate limiting. - RequestsPerSecond int `alias:"requests_per_second"` - - // RequestsMaxBurst is the maximum number of requests that can be sent - // in a burst. Should be equal to or greater than RequestsPerSecond. - // If unset, defaults to RequestsPerSecond. - // - // Internally, this is the maximum size of the token bucket used for rate limiting. - RequestsMaxBurst int `alias:"requests_max_burst"` - - // Routes is a list of rate limits applied to specific routes. - // For a given request, the first matching route will be applied, if any. - // Overrides any top-level configuration. - Routes []InstanceLevelRouteRateLimits -} - -// InstanceLevelRouteRateLimits represents rate limit configuration -// applied to a route matching one of PathExact/PathPrefix/PathRegex. -type InstanceLevelRouteRateLimits struct { - PathExact string `alias:"path_exact"` - PathPrefix string `alias:"path_prefix"` - PathRegex string `alias:"path_regex"` - - RequestsPerSecond int `alias:"requests_per_second"` - RequestsMaxBurst int `alias:"requests_max_burst"` +func IsIP(address string) bool { + ip := net.ParseIP(address) + return ip != nil } // ProxyConfigEntry is the top-level struct for global proxy configuration defaults. @@ -616,7 +574,7 @@ func (e *ProxyConfigEntry) UnmarshalBinary(data []byte) error { // into a concrete type. // // There is an 'api' variation of this in -// command/helpers/helpers.go:newDecodeConfigEntry +// command/config/write/config_write.go:newDecodeConfigEntry func DecodeConfigEntry(raw map[string]interface{}) (ConfigEntry, error) { var entry ConfigEntry @@ -868,6 +826,19 @@ func (s *ServiceConfigRequest) RequestDatacenter() string { return s.Datacenter } +// GetLocalUpstreamIDs returns the list of non-peer service ids for upstreams defined on this request. +// This is often used for fetching service-defaults config entries. +func (s *ServiceConfigRequest) GetLocalUpstreamIDs() []ServiceID { + var upstreams []ServiceID + for i := range s.UpstreamServiceNames { + u := &s.UpstreamServiceNames[i] + if u.Peer == "" { + upstreams = append(upstreams, u.ServiceName.ToServiceID()) + } + } + return upstreams +} + func (r *ServiceConfigRequest) CacheInfo() cache.RequestInfo { info := cache.RequestInfo{ Token: r.Token, @@ -1247,7 +1218,6 @@ type ServiceConfigResponse struct { Mode ProxyMode `json:",omitempty"` Destination DestinationConfig `json:",omitempty"` AccessLogs AccessLogsConfig `json:",omitempty"` - RateLimits RateLimits `json:",omitempty"` Meta map[string]string `json:",omitempty"` EnvoyExtensions []EnvoyExtension `json:",omitempty"` QueryMeta diff --git a/agent/structs/config_entry_apigw_jwt_ce.go b/agent/structs/config_entry_apigw_jwt_ce.go deleted file mode 100644 index 61b9db5b16ab9..0000000000000 --- a/agent/structs/config_entry_apigw_jwt_ce.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package structs - -// APIGatewayJWTRequirement holds the list of JWT providers to be verified against -type APIGatewayJWTRequirement struct{} - -// JWTFilter holds the JWT Filter configuration for an HTTPRoute -type JWTFilter struct{} diff --git a/agent/structs/config_entry_ce.go b/agent/structs/config_entry_ce.go index d8ca4968ad53f..2977075bff1b7 100644 --- a/agent/structs/config_entry_ce.go +++ b/agent/structs/config_entry_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs @@ -29,8 +30,6 @@ func validateUnusedKeys(unused []string) error { // to exist on the target. case strings.HasSuffix(strings.ToLower(k), "namespace"): err = multierror.Append(err, fmt.Errorf("invalid config key %q, namespaces are a consul enterprise feature", k)) - case strings.Contains(strings.ToLower(k), "jwt"): - err = multierror.Append(err, fmt.Errorf("invalid config key %q, api-gateway jwt validation is a consul enterprise feature", k)) default: err = multierror.Append(err, fmt.Errorf("invalid config key %q", k)) } @@ -52,25 +51,3 @@ func validateExportedServicesName(name string) error { func makeEnterpriseConfigEntry(kind, name string) ConfigEntry { return nil } - -func validateRatelimit(rl *RateLimits) error { - if rl != nil { - return fmt.Errorf("invalid rate_limits config. Rate limiting is a consul enterprise feature") - } - return nil -} - -func (rl RateLimits) ToEnvoyExtension() *EnvoyExtension { return nil } - -// GetLocalUpstreamIDs returns the list of non-peer service ids for upstreams defined on this request. -// This is often used for fetching service-defaults config entries. -func (s *ServiceConfigRequest) GetLocalUpstreamIDs() []ServiceID { - var upstreams []ServiceID - for _, u := range s.UpstreamServiceNames { - if u.Peer != "" { - continue - } - upstreams = append(upstreams, u.ServiceName.ToServiceID()) - } - return upstreams -} diff --git a/agent/structs/config_entry_ce_test.go b/agent/structs/config_entry_ce_test.go index 52ee3240afafe..4561f4aae3587 100644 --- a/agent/structs/config_entry_ce_test.go +++ b/agent/structs/config_entry_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs @@ -101,60 +102,3 @@ func TestDecodeConfigEntry_CE(t *testing.T) { }) } } - -func Test_GetLocalUpstreamIDs(t *testing.T) { - cases := map[string]struct { - input *ServiceConfigRequest - expect []ServiceID - }{ - "no_upstreams": { - input: &ServiceConfigRequest{ - Name: "svc", - }, - expect: nil, - }, - "upstreams": { - input: &ServiceConfigRequest{ - Name: "svc", - UpstreamServiceNames: []PeeredServiceName{ - {ServiceName: NewServiceName("a", nil)}, - {ServiceName: NewServiceName("b", nil)}, - {ServiceName: NewServiceName("c", nil)}, - }, - }, - expect: []ServiceID{ - {ID: "a"}, - {ID: "b"}, - {ID: "c"}, - }, - }, - "peer_upstream": { - input: &ServiceConfigRequest{ - Name: "svc", - UpstreamServiceNames: []PeeredServiceName{ - {Peer: "p", ServiceName: NewServiceName("a", nil)}, - }, - }, - expect: nil, - }, - "mixed_upstreams": { - input: &ServiceConfigRequest{ - Name: "svc", - UpstreamServiceNames: []PeeredServiceName{ - {ServiceName: NewServiceName("a", nil)}, - {Peer: "p", ServiceName: NewServiceName("b", nil)}, - {ServiceName: NewServiceName("c", nil)}, - }, - }, - expect: []ServiceID{ - {ID: "a"}, - {ID: "c"}, - }, - }, - } - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - require.Equal(t, tc.expect, tc.input.GetLocalUpstreamIDs()) - }) - } -} diff --git a/agent/structs/config_entry_discoverychain.go b/agent/structs/config_entry_discoverychain.go index ed81726830ed1..6eeeb741ab7f2 100644 --- a/agent/structs/config_entry_discoverychain.go +++ b/agent/structs/config_entry_discoverychain.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_discoverychain_ce.go b/agent/structs/config_entry_discoverychain_ce.go index d7333616d36e1..87c22263794e8 100644 --- a/agent/structs/config_entry_discoverychain_ce.go +++ b/agent/structs/config_entry_discoverychain_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_discoverychain_ce_test.go b/agent/structs/config_entry_discoverychain_ce_test.go index b5053774a2ba2..2edcce2bedd8f 100644 --- a/agent/structs/config_entry_discoverychain_ce_test.go +++ b/agent/structs/config_entry_discoverychain_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_discoverychain_test.go b/agent/structs/config_entry_discoverychain_test.go index b2547a7ace202..57607dbd4c8a8 100644 --- a/agent/structs/config_entry_discoverychain_test.go +++ b/agent/structs/config_entry_discoverychain_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_exports.go b/agent/structs/config_entry_exports.go index 97e33dd6e7059..631773072d0be 100644 --- a/agent/structs/config_entry_exports.go +++ b/agent/structs/config_entry_exports.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_exports_ce.go b/agent/structs/config_entry_exports_ce.go index bf69a2d8d78ba..9f9bb1cc0825e 100644 --- a/agent/structs/config_entry_exports_ce.go +++ b/agent/structs/config_entry_exports_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_exports_ce_test.go b/agent/structs/config_entry_exports_ce_test.go index fa66dd7ead329..671654b3b2a4a 100644 --- a/agent/structs/config_entry_exports_ce_test.go +++ b/agent/structs/config_entry_exports_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_exports_test.go b/agent/structs/config_entry_exports_test.go index 62e5586a0dac2..7905b46009b79 100644 --- a/agent/structs/config_entry_exports_test.go +++ b/agent/structs/config_entry_exports_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_gateways.go b/agent/structs/config_entry_gateways.go index 00c2687d1ec96..0be410d198708 100644 --- a/agent/structs/config_entry_gateways.go +++ b/agent/structs/config_entry_gateways.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -887,17 +887,6 @@ type APIGatewayListener struct { Protocol APIGatewayListenerProtocol // 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"` -} - -// 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"` } func (l APIGatewayListener) GetHostname() string { diff --git a/agent/structs/config_entry_gateways_test.go b/agent/structs/config_entry_gateways_test.go index f05638ec4d2e2..d624b39acd403 100644 --- a/agent/structs/config_entry_gateways_test.go +++ b/agent/structs/config_entry_gateways_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_inline_certificate.go b/agent/structs/config_entry_inline_certificate.go index f397ee2ba16ec..17ffa9082b6fd 100644 --- a/agent/structs/config_entry_inline_certificate.go +++ b/agent/structs/config_entry_inline_certificate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -58,7 +58,6 @@ func (e *InlineCertificateConfigEntry) Validate() error { if privateKeyBlock == nil { return errors.New("failed to parse private key PEM") } - err = validateKeyLength(privateKeyBlock) if err != nil { return err diff --git a/agent/structs/config_entry_inline_certificate_test.go b/agent/structs/config_entry_inline_certificate_test.go index 3c537c059161b..b95f3b0e9694d 100644 --- a/agent/structs/config_entry_inline_certificate_test.go +++ b/agent/structs/config_entry_inline_certificate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_intentions.go b/agent/structs/config_entry_intentions.go index f32aafa9a87d2..bc4d36863b567 100644 --- a/agent/structs/config_entry_intentions.go +++ b/agent/structs/config_entry_intentions.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_intentions_ce.go b/agent/structs/config_entry_intentions_ce.go index 83a09765def37..3c97b55aac56a 100644 --- a/agent/structs/config_entry_intentions_ce.go +++ b/agent/structs/config_entry_intentions_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_intentions_ce_test.go b/agent/structs/config_entry_intentions_ce_test.go index 2a5f093be70d6..23d4ded4d2617 100644 --- a/agent/structs/config_entry_intentions_ce_test.go +++ b/agent/structs/config_entry_intentions_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_intentions_test.go b/agent/structs/config_entry_intentions_test.go index ea8703de05d86..56c04bb21e3cf 100644 --- a/agent/structs/config_entry_intentions_test.go +++ b/agent/structs/config_entry_intentions_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_jwt_provider.go b/agent/structs/config_entry_jwt_provider.go index 12bc7c89d9ede..7336027d70954 100644 --- a/agent/structs/config_entry_jwt_provider.go +++ b/agent/structs/config_entry_jwt_provider.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_jwt_provider_ce.go b/agent/structs/config_entry_jwt_provider_ce.go index 4ec86f8ce04c3..533f349c01e52 100644 --- a/agent/structs/config_entry_jwt_provider_ce.go +++ b/agent/structs/config_entry_jwt_provider_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_jwt_provider_test.go b/agent/structs/config_entry_jwt_provider_test.go index 6a117fe5084f4..a63507663ce45 100644 --- a/agent/structs/config_entry_jwt_provider_test.go +++ b/agent/structs/config_entry_jwt_provider_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_mesh.go b/agent/structs/config_entry_mesh.go index a531821650d83..249973c00b08e 100644 --- a/agent/structs/config_entry_mesh.go +++ b/agent/structs/config_entry_mesh.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_mesh_ce.go b/agent/structs/config_entry_mesh_ce.go index 74c646361a465..1612d65682730 100644 --- a/agent/structs/config_entry_mesh_ce.go +++ b/agent/structs/config_entry_mesh_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_mesh_test.go b/agent/structs/config_entry_mesh_test.go index f6eaea9e9c546..6bdfaa15cae80 100644 --- a/agent/structs/config_entry_mesh_test.go +++ b/agent/structs/config_entry_mesh_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_routes.go b/agent/structs/config_entry_routes.go index 741404769e5d9..4d908331511d4 100644 --- a/agent/structs/config_entry_routes.go +++ b/agent/structs/config_entry_routes.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -7,7 +7,6 @@ import ( "errors" "fmt" "strings" - "time" "github.com/miekg/dns" @@ -343,38 +342,6 @@ type HTTPMatch struct { Query []HTTPQueryMatch } -func (m HTTPMatch) DeepEqual(other HTTPMatch) bool { - if m.Method != other.Method { - return false - } - - if m.Path != other.Path { - return false - } - - if len(m.Headers) != len(other.Headers) { - return false - } - - if len(m.Query) != len(other.Query) { - return false - } - - for i := 0; i < len(m.Headers); i++ { - if m.Headers[i] != other.Headers[i] { - return false - } - } - - for i := 0; i < len(m.Query); i++ { - if m.Query[i] != other.Query[i] { - return false - } - } - - return true -} - // HTTPMatchMethod specifies which type of HTTP verb should // be used for matching a given request. type HTTPMatchMethod string @@ -450,17 +417,8 @@ 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 - RetryFilter *RetryFilter - TimeoutFilter *TimeoutFilter - JWT *JWTFilter -} - -// HTTPResponseFilters specifies a list of filters used to modify the -// response returned by an upstream -type HTTPResponseFilters struct { - Headers []HTTPHeaderFilter + Headers []HTTPHeaderFilter + URLRewrite *URLRewrite } // HTTPHeaderFilter specifies how HTTP headers should be modified. @@ -474,27 +432,12 @@ 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 -} - // 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. @@ -514,10 +457,6 @@ type HTTPService struct { // 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 - acl.EnterpriseMeta `hcl:",squash" mapstructure:",squash"` } diff --git a/agent/structs/config_entry_routes_test.go b/agent/structs/config_entry_routes_test.go index 2aac0051a3263..476ce46eed05d 100644 --- a/agent/structs/config_entry_routes_test.go +++ b/agent/structs/config_entry_routes_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -437,476 +437,3 @@ func TestHTTPRoute(t *testing.T) { } testConfigEntryNormalizeAndValidate(t, cases) } - -func TestHTTPMatch_DeepEqual(t *testing.T) { - type fields struct { - Headers []HTTPHeaderMatch - Method HTTPMatchMethod - Path HTTPPathMatch - Query []HTTPQueryMatch - } - type args struct { - other HTTPMatch - } - tests := map[string]struct { - match HTTPMatch - other HTTPMatch - want bool - }{ - "all fields equal": { - match: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - other: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - want: true, - }, - "differing number of header matches": { - match: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - other: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - want: false, - }, - "differing header matches": { - match: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h4", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - other: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - want: false, - }, - "different path matching": { - match: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/zoidberg", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - other: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - want: false, - }, - "differing methods": { - match: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodConnect, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - other: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - want: false, - }, - "differing number of query matches": { - match: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - other: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - want: false, - }, - "different query matches": { - match: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "another", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - other: HTTPMatch{ - Headers: []HTTPHeaderMatch{ - { - Match: HTTPHeaderMatchExact, - Name: "h1", - Value: "a", - }, - { - Match: HTTPHeaderMatchPrefix, - Name: "h2", - Value: "b", - }, - }, - Method: HTTPMatchMethodGet, - Path: HTTPPathMatch{ - Match: HTTPPathMatchType(HTTPHeaderMatchPrefix), - Value: "/bender", - }, - Query: []HTTPQueryMatch{ - { - Match: HTTPQueryMatchExact, - Name: "q", - Value: "nibbler", - }, - { - Match: HTTPQueryMatchPresent, - Name: "ship", - Value: "planet express", - }, - }, - }, - want: false, - }, - } - for name, tt := range tests { - name := name - tt := tt - t.Run(name, func(t *testing.T) { - t.Parallel() - if got := tt.match.DeepEqual(tt.other); got != tt.want { - t.Errorf("HTTPMatch.DeepEqual() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/agent/structs/config_entry_sameness_group.go b/agent/structs/config_entry_sameness_group.go index dd1b84aa85ed3..a1d0dccb3c7c1 100644 --- a/agent/structs/config_entry_sameness_group.go +++ b/agent/structs/config_entry_sameness_group.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_sameness_group_ce.go b/agent/structs/config_entry_sameness_group_ce.go index c201ac8b429a3..282ab862fa3b3 100644 --- a/agent/structs/config_entry_sameness_group_ce.go +++ b/agent/structs/config_entry_sameness_group_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/config_entry_status.go b/agent/structs/config_entry_status.go index 749ba1596868d..fb91a0add3743 100644 --- a/agent/structs/config_entry_status.go +++ b/agent/structs/config_entry_status.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/config_entry_test.go b/agent/structs/config_entry_test.go index 9151ef815b158..cdaae4e23d4bf 100644 --- a/agent/structs/config_entry_test.go +++ b/agent/structs/config_entry_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/connect.go b/agent/structs/connect.go index 4a6033efab57c..227c2eb472702 100644 --- a/agent/structs/connect.go +++ b/agent/structs/connect.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/connect_ca.go b/agent/structs/connect_ca.go index 267aeba5e63d9..c8a7cea1df8ae 100644 --- a/agent/structs/connect_ca.go +++ b/agent/structs/connect_ca.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -217,11 +217,6 @@ type IssuedCert struct { // PrivateKeyPEM is the PEM encoded private key associated with CertPEM. PrivateKeyPEM string `json:",omitempty"` - // WorkloadIdentity is the name of the workload identity for which the cert was issued. - WorkloadIdentity string `json:",omitempty"` - // WorkloadIdentityURI is the cert URI value. - WorkloadIdentityURI string `json:",omitempty"` - // Service is the name of the service for which the cert was issued. Service string `json:",omitempty"` // ServiceURI is the cert URI value. @@ -252,12 +247,6 @@ type IssuedCert struct { RaftIndex } -func (i *IssuedCert) Key() string { - return fmt.Sprintf("%s", - i.SerialNumber, - ) -} - // CAOp is the operation for a request related to intentions. type CAOp string diff --git a/agent/structs/connect_ca_test.go b/agent/structs/connect_ca_test.go index 5f224e04f76a6..d64efef375bfd 100644 --- a/agent/structs/connect_ca_test.go +++ b/agent/structs/connect_ca_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/connect_ce.go b/agent/structs/connect_ce.go index 98d930939b3e3..9547c245148b0 100644 --- a/agent/structs/connect_ce.go +++ b/agent/structs/connect_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/connect_proxy_config.go b/agent/structs/connect_proxy_config.go index d84953e1b0e7e..acca2ad1cbcd4 100644 --- a/agent/structs/connect_proxy_config.go +++ b/agent/structs/connect_proxy_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -11,7 +11,6 @@ import ( "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" ) const ( @@ -181,39 +180,6 @@ type AccessLogsConfig struct { TextFormat string `json:",omitempty" alias:"text_format"` } -func (c *AccessLogsConfig) GetEnabled() bool { - return c.Enabled -} - -func (c *AccessLogsConfig) GetDisableListenerLogs() bool { - return c.DisableListenerLogs -} - -func (c *AccessLogsConfig) GetType() pbmesh.LogSinkType { - switch c.Type { - case FileLogSinkType: - return pbmesh.LogSinkType_LOG_SINK_TYPE_FILE - case StdErrLogSinkType: - return pbmesh.LogSinkType_LOG_SINK_TYPE_STDERR - case StdOutLogSinkType: - return pbmesh.LogSinkType_LOG_SINK_TYPE_STDOUT - } - - return pbmesh.LogSinkType_LOG_SINK_TYPE_DEFAULT -} - -func (c *AccessLogsConfig) GetPath() string { - return c.Path -} - -func (c *AccessLogsConfig) GetJsonFormat() string { - return c.JSONFormat -} - -func (c *AccessLogsConfig) GetTextFormat() string { - return c.TextFormat -} - func (c *AccessLogsConfig) IsZero() bool { if c == nil { return true @@ -839,12 +805,3 @@ func (e *ExposeConfig) Finalize() { } } } - -type AccessLogs interface { - GetEnabled() bool - GetDisableListenerLogs() bool - GetType() pbmesh.LogSinkType - GetPath() string - GetJsonFormat() string - GetTextFormat() string -} diff --git a/agent/structs/connect_proxy_config_ce.go b/agent/structs/connect_proxy_config_ce.go index 7b6bee851da9b..898ca163a5c2f 100644 --- a/agent/structs/connect_proxy_config_ce.go +++ b/agent/structs/connect_proxy_config_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/connect_proxy_config_test.go b/agent/structs/connect_proxy_config_test.go index be16d17be6a3c..bcf43b2119ca1 100644 --- a/agent/structs/connect_proxy_config_test.go +++ b/agent/structs/connect_proxy_config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/deep-copy.sh b/agent/structs/deep-copy.sh index cbc1bdc42ae5d..e4ab69273a473 100755 --- a/agent/structs/deep-copy.sh +++ b/agent/structs/deep-copy.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 readonly PACKAGE_DIR="$(dirname "${BASH_SOURCE[0]}")" diff --git a/agent/structs/discovery_chain.go b/agent/structs/discovery_chain.go index c81dd1ec0836e..029fc3b0a8be8 100644 --- a/agent/structs/discovery_chain.go +++ b/agent/structs/discovery_chain.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/discovery_chain_ce.go b/agent/structs/discovery_chain_ce.go index b769bf8c2e084..febff8c7762a7 100644 --- a/agent/structs/discovery_chain_ce.go +++ b/agent/structs/discovery_chain_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/envoy_extension.go b/agent/structs/envoy_extension.go index ab9988bf21bc8..c788aedf37e85 100644 --- a/agent/structs/envoy_extension.go +++ b/agent/structs/envoy_extension.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/errors.go b/agent/structs/errors.go index 31a818bd62f23..82e2b0b5f0132 100644 --- a/agent/structs/errors.go +++ b/agent/structs/errors.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -19,11 +19,6 @@ const ( errServiceNotFound = "Service not found: " errQueryNotFound = "Query not found" errLeaderNotTracked = "Raft leader not found in server lookup mapping" - errConnectNotEnabled = "Connect must be enabled in order to use this endpoint" - errRateLimited = "Rate limit reached, try again later" // Note: we depend on this error message in the gRPC ConnectCA.Sign endpoint (see: isRateLimitError). - errNotPrimaryDatacenter = "not the primary datacenter" - errStateReadOnly = "CA Provider State is read-only" - errUsingV2CatalogExperiment = "V1 catalog is disabled when V2 is enabled" ) var ( @@ -36,11 +31,6 @@ var ( ErrDCNotAvailable = errors.New(errDCNotAvailable) ErrQueryNotFound = errors.New(errQueryNotFound) ErrLeaderNotTracked = errors.New(errLeaderNotTracked) - ErrConnectNotEnabled = errors.New(errConnectNotEnabled) - ErrRateLimited = errors.New(errRateLimited) // Note: we depend on this error message in the gRPC ConnectCA.Sign endpoint (see: isRateLimitError). - ErrNotPrimaryDatacenter = errors.New(errNotPrimaryDatacenter) - ErrStateReadOnly = errors.New(errStateReadOnly) - ErrUsingV2CatalogExperiment = errors.New(errUsingV2CatalogExperiment) ) func IsErrNoDCPath(err error) bool { @@ -62,7 +52,3 @@ func IsErrRPCRateExceeded(err error) bool { func IsErrServiceNotFound(err error) bool { return err != nil && strings.Contains(err.Error(), errServiceNotFound) } - -func IsErrUsingV2CatalogExperiment(err error) bool { - return err != nil && strings.Contains(err.Error(), errUsingV2CatalogExperiment) -} diff --git a/agent/structs/federation_state.go b/agent/structs/federation_state.go index 5a0e8eef6d04d..f123a0954be7e 100644 --- a/agent/structs/federation_state.go +++ b/agent/structs/federation_state.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/identity.go b/agent/structs/identity.go index b55f6bb7ae51d..286dd552a3469 100644 --- a/agent/structs/identity.go +++ b/agent/structs/identity.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/intention.go b/agent/structs/intention.go index 3bbc2584f70fc..21d5432b41123 100644 --- a/agent/structs/intention.go +++ b/agent/structs/intention.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/intention_ce.go b/agent/structs/intention_ce.go index d417a63f5964e..af62df50bca44 100644 --- a/agent/structs/intention_ce.go +++ b/agent/structs/intention_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/intention_test.go b/agent/structs/intention_test.go index 077bef0f200d2..600f600729d13 100644 --- a/agent/structs/intention_test.go +++ b/agent/structs/intention_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/operator.go b/agent/structs/operator.go index 9d78cb92143f8..05862861e3f85 100644 --- a/agent/structs/operator.go +++ b/agent/structs/operator.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/peering.go b/agent/structs/peering.go index 927efabb34c25..3ee7acb224025 100644 --- a/agent/structs/peering.go +++ b/agent/structs/peering.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/prepared_query.go b/agent/structs/prepared_query.go index 1c851c476ef00..71b0eba81bc3e 100644 --- a/agent/structs/prepared_query.go +++ b/agent/structs/prepared_query.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -341,7 +341,7 @@ type PreparedQueryExecuteRemoteRequest struct { Connect bool // QueryOptions (unfortunately named here) controls the consistency - // settings for the service lookups. + // settings for the the service lookups. QueryOptions } diff --git a/agent/structs/prepared_query_test.go b/agent/structs/prepared_query_test.go index 537c6b043818a..a6d6e64849af0 100644 --- a/agent/structs/prepared_query_test.go +++ b/agent/structs/prepared_query_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/protobuf_compat.go b/agent/structs/protobuf_compat.go index c52d85a32c29f..65ebf2eaf4acd 100644 --- a/agent/structs/protobuf_compat.go +++ b/agent/structs/protobuf_compat.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/service_definition.go b/agent/structs/service_definition.go index 9b9fec89e9540..6ee81af0590c9 100644 --- a/agent/structs/service_definition.go +++ b/agent/structs/service_definition.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/service_definition_test.go b/agent/structs/service_definition_test.go index ec6d4fc5374e9..023972092ff44 100644 --- a/agent/structs/service_definition_test.go +++ b/agent/structs/service_definition_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/snapshot.go b/agent/structs/snapshot.go index 3d71fb093d3c6..4f622216751f0 100644 --- a/agent/structs/snapshot.go +++ b/agent/structs/snapshot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/structs.deepcopy.go b/agent/structs/structs.deepcopy.go index 017b0c943ca6e..cdd007c26cdb5 100644 --- a/agent/structs/structs.deepcopy.go +++ b/agent/structs/structs.deepcopy.go @@ -18,20 +18,6 @@ func (o *APIGatewayListener) DeepCopy() *APIGatewayListener { cp.TLS.CipherSuites = make([]types.TLSCipherSuite, len(o.TLS.CipherSuites)) copy(cp.TLS.CipherSuites, o.TLS.CipherSuites) } - if o.Override != nil { - cp.Override = new(APIGatewayPolicy) - *cp.Override = *o.Override - if o.Override.JWT != nil { - cp.Override.JWT = o.Override.JWT.DeepCopy() - } - } - if o.Default != nil { - cp.Default = new(APIGatewayPolicy) - *cp.Default = *o.Default - if o.Default.JWT != nil { - cp.Default.JWT = o.Default.JWT.DeepCopy() - } - } return &cp } @@ -397,47 +383,6 @@ func (o *HTTPRouteConfigEntry) DeepCopy() *HTTPRouteConfigEntry { cp.Rules[i2].Filters.URLRewrite = new(URLRewrite) *cp.Rules[i2].Filters.URLRewrite = *o.Rules[i2].Filters.URLRewrite } - if o.Rules[i2].Filters.RetryFilter != nil { - cp.Rules[i2].Filters.RetryFilter = new(RetryFilter) - *cp.Rules[i2].Filters.RetryFilter = *o.Rules[i2].Filters.RetryFilter - if o.Rules[i2].Filters.RetryFilter.RetryOn != nil { - cp.Rules[i2].Filters.RetryFilter.RetryOn = make([]string, len(o.Rules[i2].Filters.RetryFilter.RetryOn)) - copy(cp.Rules[i2].Filters.RetryFilter.RetryOn, o.Rules[i2].Filters.RetryFilter.RetryOn) - } - if o.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes != nil { - cp.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes = make([]uint32, len(o.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes)) - copy(cp.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes, o.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes) - } - } - if o.Rules[i2].Filters.TimeoutFilter != nil { - cp.Rules[i2].Filters.TimeoutFilter = new(TimeoutFilter) - *cp.Rules[i2].Filters.TimeoutFilter = *o.Rules[i2].Filters.TimeoutFilter - } - if o.Rules[i2].Filters.JWT != nil { - cp.Rules[i2].Filters.JWT = o.Rules[i2].Filters.JWT.DeepCopy() - } - if o.Rules[i2].ResponseFilters.Headers != nil { - cp.Rules[i2].ResponseFilters.Headers = make([]HTTPHeaderFilter, len(o.Rules[i2].ResponseFilters.Headers)) - copy(cp.Rules[i2].ResponseFilters.Headers, o.Rules[i2].ResponseFilters.Headers) - for i5 := range o.Rules[i2].ResponseFilters.Headers { - if o.Rules[i2].ResponseFilters.Headers[i5].Add != nil { - cp.Rules[i2].ResponseFilters.Headers[i5].Add = make(map[string]string, len(o.Rules[i2].ResponseFilters.Headers[i5].Add)) - for k7, v7 := range o.Rules[i2].ResponseFilters.Headers[i5].Add { - cp.Rules[i2].ResponseFilters.Headers[i5].Add[k7] = v7 - } - } - if o.Rules[i2].ResponseFilters.Headers[i5].Remove != nil { - cp.Rules[i2].ResponseFilters.Headers[i5].Remove = make([]string, len(o.Rules[i2].ResponseFilters.Headers[i5].Remove)) - copy(cp.Rules[i2].ResponseFilters.Headers[i5].Remove, o.Rules[i2].ResponseFilters.Headers[i5].Remove) - } - if o.Rules[i2].ResponseFilters.Headers[i5].Set != nil { - cp.Rules[i2].ResponseFilters.Headers[i5].Set = make(map[string]string, len(o.Rules[i2].ResponseFilters.Headers[i5].Set)) - for k7, v7 := range o.Rules[i2].ResponseFilters.Headers[i5].Set { - cp.Rules[i2].ResponseFilters.Headers[i5].Set[k7] = v7 - } - } - } - } if o.Rules[i2].Matches != nil { cp.Rules[i2].Matches = make([]HTTPMatch, len(o.Rules[i2].Matches)) copy(cp.Rules[i2].Matches, o.Rules[i2].Matches) @@ -482,47 +427,6 @@ func (o *HTTPRouteConfigEntry) DeepCopy() *HTTPRouteConfigEntry { cp.Rules[i2].Services[i4].Filters.URLRewrite = new(URLRewrite) *cp.Rules[i2].Services[i4].Filters.URLRewrite = *o.Rules[i2].Services[i4].Filters.URLRewrite } - if o.Rules[i2].Services[i4].Filters.RetryFilter != nil { - cp.Rules[i2].Services[i4].Filters.RetryFilter = new(RetryFilter) - *cp.Rules[i2].Services[i4].Filters.RetryFilter = *o.Rules[i2].Services[i4].Filters.RetryFilter - if o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn != nil { - cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn = make([]string, len(o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn)) - copy(cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn, o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn) - } - if o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes != nil { - cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes = make([]uint32, len(o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes)) - copy(cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes, o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes) - } - } - if o.Rules[i2].Services[i4].Filters.TimeoutFilter != nil { - cp.Rules[i2].Services[i4].Filters.TimeoutFilter = new(TimeoutFilter) - *cp.Rules[i2].Services[i4].Filters.TimeoutFilter = *o.Rules[i2].Services[i4].Filters.TimeoutFilter - } - if o.Rules[i2].Services[i4].Filters.JWT != nil { - cp.Rules[i2].Services[i4].Filters.JWT = o.Rules[i2].Services[i4].Filters.JWT.DeepCopy() - } - if o.Rules[i2].Services[i4].ResponseFilters.Headers != nil { - cp.Rules[i2].Services[i4].ResponseFilters.Headers = make([]HTTPHeaderFilter, len(o.Rules[i2].Services[i4].ResponseFilters.Headers)) - copy(cp.Rules[i2].Services[i4].ResponseFilters.Headers, o.Rules[i2].Services[i4].ResponseFilters.Headers) - for i7 := range o.Rules[i2].Services[i4].ResponseFilters.Headers { - if o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Add != nil { - cp.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Add = make(map[string]string, len(o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Add)) - for k9, v9 := range o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Add { - cp.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Add[k9] = v9 - } - } - if o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Remove != nil { - cp.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Remove = make([]string, len(o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Remove)) - copy(cp.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Remove, o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Remove) - } - if o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Set != nil { - cp.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Set = make(map[string]string, len(o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Set)) - for k9, v9 := range o.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Set { - cp.Rules[i2].Services[i4].ResponseFilters.Headers[i7].Set[k9] = v9 - } - } - } - } } } } @@ -925,14 +829,6 @@ func (o *ServiceConfigEntry) DeepCopy() *ServiceConfigEntry { copy(cp.Destination.Addresses, o.Destination.Addresses) } } - if o.RateLimits != nil { - cp.RateLimits = new(RateLimits) - *cp.RateLimits = *o.RateLimits - if o.RateLimits.InstanceLevel.Routes != nil { - cp.RateLimits.InstanceLevel.Routes = make([]InstanceLevelRouteRateLimits, len(o.RateLimits.InstanceLevel.Routes)) - copy(cp.RateLimits.InstanceLevel.Routes, o.RateLimits.InstanceLevel.Routes) - } - } if o.EnvoyExtensions != nil { cp.EnvoyExtensions = make([]EnvoyExtension, len(o.EnvoyExtensions)) copy(cp.EnvoyExtensions, o.EnvoyExtensions) @@ -983,10 +879,6 @@ func (o *ServiceConfigResponse) DeepCopy() *ServiceConfigResponse { cp.Destination.Addresses = make([]string, len(o.Destination.Addresses)) copy(cp.Destination.Addresses, o.Destination.Addresses) } - if o.RateLimits.InstanceLevel.Routes != nil { - cp.RateLimits.InstanceLevel.Routes = make([]InstanceLevelRouteRateLimits, len(o.RateLimits.InstanceLevel.Routes)) - copy(cp.RateLimits.InstanceLevel.Routes, o.RateLimits.InstanceLevel.Routes) - } if o.Meta != nil { cp.Meta = make(map[string]string, len(o.Meta)) for k2, v2 := range o.Meta { diff --git a/agent/structs/structs.deepcopy_ce.go b/agent/structs/structs.deepcopy_ce.go deleted file mode 100644 index 71f20d7632d55..0000000000000 --- a/agent/structs/structs.deepcopy_ce.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package structs - -// DeepCopy generates a deep copy of *APIGatewayJWTRequirement -func (o *APIGatewayJWTRequirement) DeepCopy() *APIGatewayJWTRequirement { - return new(APIGatewayJWTRequirement) -} - -// DeepCopy generates a deep copy of *JWTFilter -func (o *JWTFilter) DeepCopy() *JWTFilter { - return new(JWTFilter) -} diff --git a/agent/structs/structs.go b/agent/structs/structs.go index 9b2685946cbeb..b4548a734be99 100644 --- a/agent/structs/structs.go +++ b/agent/structs/structs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -10,7 +10,6 @@ import ( "encoding/json" "fmt" "math/rand" - "os" "reflect" "regexp" "sort" @@ -228,9 +227,6 @@ const ( var allowedConsulMetaKeysForMeshGateway = map[string]struct{}{MetaWANFederationKey: {}} -// CEDowngrade indicates if we are in downgrading from ent to ce -var CEDowngrade = os.Getenv("CONSUL_ENTERPRISE_DOWNGRADE_TO_CE") == "true" - var ( NodeMaintCheckID = NewCheckID(NodeMaint, nil) ) @@ -1487,10 +1483,6 @@ func (s *NodeService) IsGateway() bool { func (s *NodeService) Validate() error { var result error - if err := s.Locality.Validate(); err != nil { - result = multierror.Append(result, err) - } - if s.Kind == ServiceKindConnectProxy { if s.Port == 0 && s.SocketPath == "" { result = multierror.Append(result, fmt.Errorf("Port or SocketPath must be set for a %s", s.Kind)) @@ -2104,18 +2096,6 @@ func (csn *CheckServiceNode) CanRead(authz acl.Authorizer) acl.EnforcementDecisi return acl.Allow } -func (csn *CheckServiceNode) Locality() *Locality { - if csn.Service != nil && csn.Service.Locality != nil { - return csn.Service.Locality - } - - if csn.Node != nil && csn.Node.Locality != nil { - return csn.Node.Locality - } - - return nil -} - type CheckServiceNodes []CheckServiceNode func (csns CheckServiceNodes) DeepCopy() CheckServiceNodes { @@ -3137,15 +3117,3 @@ func (l *Locality) GetRegion() string { } return l.Region } - -func (l *Locality) Validate() error { - if l == nil { - return nil - } - - if l.Region == "" && l.Zone != "" { - return fmt.Errorf("zone cannot be set without region") - } - - return nil -} diff --git a/agent/structs/structs_ce.go b/agent/structs/structs_ce.go index 2fa039032c23b..6b004460e5fb7 100644 --- a/agent/structs/structs_ce.go +++ b/agent/structs/structs_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs @@ -173,13 +174,3 @@ func (s *ServiceNode) NodeIdentity() Identity { } type EnterpriseServiceUsage struct{} - -// WithNormalizedUpstreams returns a deep copy of the NodeService with no modifications to -// data for CE versions. -func (ns *NodeService) WithNormalizedUpstreams() *NodeService { - // Simply return a copy for CE, since it doesn't have partitions or namespaces. - if ns == nil { - return nil - } - return ns.DeepCopy() -} diff --git a/agent/structs/structs_ce_test.go b/agent/structs/structs_ce_test.go index 67e3825f24f9c..55e51a70088c3 100644 --- a/agent/structs/structs_ce_test.go +++ b/agent/structs/structs_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package structs diff --git a/agent/structs/structs_ext_test.go b/agent/structs/structs_ext_test.go index 3b1cd6b6df1cf..9bbc4ca0cb915 100644 --- a/agent/structs/structs_ext_test.go +++ b/agent/structs/structs_ext_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs_test diff --git a/agent/structs/structs_filtering_test.go b/agent/structs/structs_filtering_test.go index 3750adb16ce1f..9739923e0e5a9 100644 --- a/agent/structs/structs_filtering_test.go +++ b/agent/structs/structs_filtering_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/structs_test.go b/agent/structs/structs_test.go index bf909aa41903e..6d887da9ac776 100644 --- a/agent/structs/structs_test.go +++ b/agent/structs/structs_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs @@ -592,43 +592,6 @@ func TestStructs_ServiceNode_Conversions(t *testing.T) { } } -func TestStructs_Locality_Validate(t *testing.T) { - type testCase struct { - locality *Locality - err string - } - cases := map[string]testCase{ - "nil": { - nil, - "", - }, - "region only": { - &Locality{Region: "us-west-1"}, - "", - }, - "region and zone": { - &Locality{Region: "us-west-1", Zone: "us-west-1a"}, - "", - }, - "zone only": { - &Locality{Zone: "us-west-1a"}, - "zone cannot be set without region", - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - err := tc.locality.Validate() - if tc.err == "" { - require.NoError(t, err) - } else { - require.Error(t, err) - require.Contains(t, err.Error(), tc.err) - } - }) - } -} - func TestStructs_NodeService_ValidateMeshGateway(t *testing.T) { type testCase struct { Modify func(*NodeService) @@ -1189,13 +1152,6 @@ func TestStructs_NodeService_ValidateConnectProxy(t *testing.T) { }, "", }, - { - "connect-proxy: invalid locality", - func(x *NodeService) { - x.Locality = &Locality{Zone: "bad"} - }, - "zone cannot be set without region", - }, } for _, tc := range cases { @@ -1358,7 +1314,7 @@ func TestStructs_NodeService_ValidateSidecarService(t *testing.T) { } func TestStructs_NodeService_ConnectNativeEmptyPortError(t *testing.T) { - ns := TestNodeService() + ns := TestNodeService(t) ns.Connect.Native = true ns.Port = 0 err := ns.Validate() diff --git a/agent/structs/system_metadata.go b/agent/structs/system_metadata.go index 555756201a5d2..fa6f6cd0ae58c 100644 --- a/agent/structs/system_metadata.go +++ b/agent/structs/system_metadata.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/testing.go b/agent/structs/testing.go index 527da21c4e890..ad8382b0ce3b1 100644 --- a/agent/structs/testing.go +++ b/agent/structs/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/testing_catalog.go b/agent/structs/testing_catalog.go index 8047695bba564..9e72aebc77458 100644 --- a/agent/structs/testing_catalog.go +++ b/agent/structs/testing_catalog.go @@ -1,14 +1,13 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs import ( "fmt" - "github.com/mitchellh/go-testing-interface" - "github.com/hashicorp/consul/acl" + "github.com/mitchellh/go-testing-interface" ) // TestRegisterRequest returns a RegisterRequest for registering a typical service. @@ -48,11 +47,11 @@ func TestRegisterIngressGateway(t testing.T) *RegisterRequest { } // TestNodeService returns a *NodeService representing a valid regular service: "web". -func TestNodeService() *NodeService { - return TestNodeServiceWithName("web") +func TestNodeService(t testing.T) *NodeService { + return TestNodeServiceWithName(t, "web") } -func TestNodeServiceWithName(name string) *NodeService { +func TestNodeServiceWithName(t testing.T, name string) *NodeService { return &NodeService{ Kind: ServiceKindTypical, Service: name, diff --git a/agent/structs/testing_connect_proxy_config.go b/agent/structs/testing_connect_proxy_config.go index 971e355fba2da..c41cc99651113 100644 --- a/agent/structs/testing_connect_proxy_config.go +++ b/agent/structs/testing_connect_proxy_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/testing_intention.go b/agent/structs/testing_intention.go index 974a103de1bd4..57c6f9d50154e 100644 --- a/agent/structs/testing_intention.go +++ b/agent/structs/testing_intention.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/testing_service_definition.go b/agent/structs/testing_service_definition.go index da51014f43115..2707067262f5e 100644 --- a/agent/structs/testing_service_definition.go +++ b/agent/structs/testing_service_definition.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/structs/txn.go b/agent/structs/txn.go index efb11aa891eae..a97b4733f5edb 100644 --- a/agent/structs/txn.go +++ b/agent/structs/txn.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/agent/submatview/handler.go b/agent/submatview/handler.go index f33746a7f324c..b3c900e695286 100644 --- a/agent/submatview/handler.go +++ b/agent/submatview/handler.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview diff --git a/agent/submatview/local_materializer.go b/agent/submatview/local_materializer.go index 4ee06a3640298..5eeaefaa665a9 100644 --- a/agent/submatview/local_materializer.go +++ b/agent/submatview/local_materializer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview diff --git a/agent/submatview/local_materializer_test.go b/agent/submatview/local_materializer_test.go index fa7a01845034b..e6600a0516207 100644 --- a/agent/submatview/local_materializer_test.go +++ b/agent/submatview/local_materializer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview diff --git a/agent/submatview/materializer.go b/agent/submatview/materializer.go index 42754c914da08..240f6cfafbb4e 100644 --- a/agent/submatview/materializer.go +++ b/agent/submatview/materializer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview diff --git a/agent/submatview/rpc_materializer.go b/agent/submatview/rpc_materializer.go index dfeb90172a695..855576b1b339a 100644 --- a/agent/submatview/rpc_materializer.go +++ b/agent/submatview/rpc_materializer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview diff --git a/agent/submatview/store.go b/agent/submatview/store.go index ccfc319e2f4cc..1f189121264c4 100644 --- a/agent/submatview/store.go +++ b/agent/submatview/store.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview diff --git a/agent/submatview/store_integration_test.go b/agent/submatview/store_integration_test.go index 45ba11d3cc3cf..3b6d9fbc2b57d 100644 --- a/agent/submatview/store_integration_test.go +++ b/agent/submatview/store_integration_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview_test diff --git a/agent/submatview/store_test.go b/agent/submatview/store_test.go index c878654d89be9..36a92e7ec02b7 100644 --- a/agent/submatview/store_test.go +++ b/agent/submatview/store_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview diff --git a/agent/submatview/streaming_test.go b/agent/submatview/streaming_test.go index 54b28d1abe6bc..223babf530b13 100644 --- a/agent/submatview/streaming_test.go +++ b/agent/submatview/streaming_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package submatview diff --git a/agent/systemd/notify.go b/agent/systemd/notify.go index 60c71947dc8a4..88ce2c2ece95a 100644 --- a/agent/systemd/notify.go +++ b/agent/systemd/notify.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package systemd diff --git a/agent/testagent.go b/agent/testagent.go index 037bdc76da688..57b9c1b111833 100644 --- a/agent/testagent.go +++ b/agent/testagent.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -17,9 +17,9 @@ import ( "text/template" "time" - "github.com/armon/go-metrics" + metrics "github.com/armon/go-metrics" "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-uuid" + uuid "github.com/hashicorp/go-uuid" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/config" @@ -286,22 +286,6 @@ func (a *TestAgent) waitForUp() error { continue // fail, try again } if a.Config.Bootstrap && a.Config.ServerMode { - if a.baseDeps.UseV2Resources() { - args := structs.DCSpecificRequest{ - Datacenter: "dc1", - } - var leader string - if err := a.RPC(context.Background(), "Status.Leader", args, &leader); err != nil { - retErr = fmt.Errorf("Status.Leader failed: %v", err) - continue // fail, try again - } - if leader == "" { - retErr = fmt.Errorf("No leader") - continue // fail, try again - } - return nil // success - } - // Ensure we have a leader and a node registration. args := &structs.DCSpecificRequest{ Datacenter: a.Config.Datacenter, @@ -421,19 +405,6 @@ func (a *TestAgent) consulConfig() *consul.Config { return c } -// Using sdk/freeport with *retry.R is not possible without changing -// function signatures. We use this shim instead to save the headache -// of syncing sdk submodule updates. -type retryShim struct { - *retry.R - - name string -} - -func (r *retryShim) Name() string { - return r.name -} - // pickRandomPorts selects random ports from fixed size random blocks of // ports. This does not eliminate the chance for port conflict but // reduces it significantly with little overhead. Furthermore, asking @@ -443,15 +414,12 @@ func (r *retryShim) Name() string { // Instead of relying on one set of ports to be sufficient we retry // starting the agent with different ports on port conflict. func randomPortsSource(t *testing.T, useHTTPS bool) string { - var ports []int - retry.RunWith(retry.TwoSeconds(), t, func(r *retry.R) { - ports = freeport.GetN(&retryShim{r, t.Name()}, 7) - }) + ports := freeport.GetN(t, 8) var http, https int if useHTTPS { http = -1 - https = ports[1] + https = ports[2] } else { http = ports[1] https = -1 @@ -462,11 +430,11 @@ func randomPortsSource(t *testing.T, useHTTPS bool) string { dns = ` + strconv.Itoa(ports[0]) + ` http = ` + strconv.Itoa(http) + ` https = ` + strconv.Itoa(https) + ` - serf_lan = ` + strconv.Itoa(ports[2]) + ` - serf_wan = ` + strconv.Itoa(ports[3]) + ` - server = ` + strconv.Itoa(ports[4]) + ` - grpc = ` + strconv.Itoa(ports[5]) + ` - grpc_tls = ` + strconv.Itoa(ports[6]) + ` + serf_lan = ` + strconv.Itoa(ports[3]) + ` + serf_wan = ` + strconv.Itoa(ports[4]) + ` + server = ` + strconv.Itoa(ports[5]) + ` + grpc = ` + strconv.Itoa(ports[6]) + ` + grpc_tls = ` + strconv.Itoa(ports[7]) + ` } ` } @@ -561,7 +529,6 @@ type TestACLConfigParams struct { DefaultToken string AgentRecoveryToken string ReplicationToken string - DNSToken string EnableTokenReplication bool } @@ -580,8 +547,7 @@ func (p *TestACLConfigParams) HasConfiguredTokens() bool { p.AgentToken != "" || p.DefaultToken != "" || p.AgentRecoveryToken != "" || - p.ReplicationToken != "" || - p.DNSToken != "" + p.ReplicationToken != "" } func TestACLConfigNew() string { @@ -591,7 +557,6 @@ func TestACLConfigNew() string { InitialManagementToken: "root", AgentToken: "root", AgentRecoveryToken: "towel", - DNSToken: "dns", }) } diff --git a/agent/testagent_test.go b/agent/testagent_test.go index 266b6e864cc36..66d1d61f01e53 100644 --- a/agent/testagent_test.go +++ b/agent/testagent_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/token/persistence.go b/agent/token/persistence.go index 1a3898e12e8d4..9d543b30edf9d 100644 --- a/agent/token/persistence.go +++ b/agent/token/persistence.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package token @@ -26,7 +26,6 @@ type Config struct { ACLAgentRecoveryToken string ACLReplicationToken string ACLConfigFileRegistrationToken string - ACLDNSToken string EnterpriseConfig } @@ -78,7 +77,6 @@ type persistedTokens struct { Default string `json:"default,omitempty"` Agent string `json:"agent,omitempty"` ConfigFileRegistration string `json:"config_file_service_registration,omitempty"` - DNS string `json:"dns,omitempty"` } type fileStore struct { @@ -146,16 +144,6 @@ func loadTokens(s *Store, cfg Config, tokens persistedTokens, logger Logger) { s.UpdateConfigFileRegistrationToken(cfg.ACLConfigFileRegistrationToken, TokenSourceConfig) } - if tokens.DNS != "" { - s.UpdateDNSToken(tokens.DNS, TokenSourceAPI) - - if cfg.ACLDNSToken != "" { - logger.Warn("\"dns\" token present in both the configuration and persisted token store, using the persisted token") - } - } else { - s.UpdateDNSToken(cfg.ACLDNSToken, TokenSourceConfig) - } - loadEnterpriseTokens(s, cfg) } @@ -218,10 +206,6 @@ func (p *fileStore) saveToFile(s *Store) error { tokens.ConfigFileRegistration = tok } - if tok, source := s.DNSTokenAndSource(); tok != "" && source == TokenSourceAPI { - tokens.DNS = tok - } - data, err := json.Marshal(tokens) if err != nil { p.logger.Warn("failed to persist tokens", "error", err) diff --git a/agent/token/persistence_test.go b/agent/token/persistence_test.go index 4351efd1358e3..093515f70e434 100644 --- a/agent/token/persistence_test.go +++ b/agent/token/persistence_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package token @@ -8,10 +8,9 @@ import ( "path/filepath" "testing" + "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/sdk/testutil" ) func TestStore_Load(t *testing.T) { @@ -28,7 +27,6 @@ func TestStore_Load(t *testing.T) { ACLDefaultToken: "charlie", ACLReplicationToken: "delta", ACLConfigFileRegistrationToken: "echo", - ACLDNSToken: "foxtrot", } require.NoError(t, store.Load(cfg, logger)) require.Equal(t, "alfa", store.AgentToken()) @@ -36,69 +34,62 @@ func TestStore_Load(t *testing.T) { require.Equal(t, "charlie", store.UserToken()) require.Equal(t, "delta", store.ReplicationToken()) require.Equal(t, "echo", store.ConfigFileRegistrationToken()) - require.Equal(t, "foxtrot", store.DNSToken()) }) t.Run("updated from Config", func(t *testing.T) { cfg := Config{ DataDir: dataDir, - ACLDefaultToken: "sierra", - ACLAgentToken: "tango", - ACLAgentRecoveryToken: "uniform", - ACLReplicationToken: "victor", - ACLConfigFileRegistrationToken: "xray", - ACLDNSToken: "zulu", + ACLDefaultToken: "echo", + ACLAgentToken: "foxtrot", + ACLAgentRecoveryToken: "golf", + ACLReplicationToken: "hotel", + ACLConfigFileRegistrationToken: "india", } // ensures no error for missing persisted tokens file require.NoError(t, store.Load(cfg, logger)) - require.Equal(t, "sierra", store.UserToken()) - require.Equal(t, "tango", store.AgentToken()) - require.Equal(t, "uniform", store.AgentRecoveryToken()) - require.Equal(t, "victor", store.ReplicationToken()) - require.Equal(t, "xray", store.ConfigFileRegistrationToken()) - require.Equal(t, "zulu", store.DNSToken()) + require.Equal(t, "echo", store.UserToken()) + require.Equal(t, "foxtrot", store.AgentToken()) + require.Equal(t, "golf", store.AgentRecoveryToken()) + require.Equal(t, "hotel", store.ReplicationToken()) + require.Equal(t, "india", store.ConfigFileRegistrationToken()) }) t.Run("with persisted tokens", func(t *testing.T) { cfg := Config{ DataDir: dataDir, - ACLDefaultToken: "alpha", - ACLAgentToken: "bravo", - ACLAgentRecoveryToken: "charlie", - ACLReplicationToken: "delta", - ACLConfigFileRegistrationToken: "echo", - ACLDNSToken: "foxtrot", + ACLDefaultToken: "echo", + ACLAgentToken: "foxtrot", + ACLAgentRecoveryToken: "golf", + ACLReplicationToken: "hotel", + ACLConfigFileRegistrationToken: "delta", } tokens := `{ - "agent" : "golf", - "agent_recovery" : "hotel", - "default": "india", - "replication": "juliet", - "config_file_service_registration": "kilo", - "dns": "lima" + "agent" : "india", + "agent_recovery" : "juliett", + "default": "kilo", + "replication": "lima", + "config_file_service_registration": "mike" }` require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600)) require.NoError(t, store.Load(cfg, logger)) // no updates since token persistence is not enabled - require.Equal(t, "alpha", store.UserToken()) - require.Equal(t, "bravo", store.AgentToken()) - require.Equal(t, "charlie", store.AgentRecoveryToken()) - require.Equal(t, "delta", store.ReplicationToken()) - require.Equal(t, "echo", store.ConfigFileRegistrationToken()) - require.Equal(t, "foxtrot", store.DNSToken()) + require.Equal(t, "echo", store.UserToken()) + require.Equal(t, "foxtrot", store.AgentToken()) + require.Equal(t, "golf", store.AgentRecoveryToken()) + require.Equal(t, "hotel", store.ReplicationToken()) + require.Equal(t, "delta", store.ConfigFileRegistrationToken()) cfg.EnablePersistence = true require.NoError(t, store.Load(cfg, logger)) - require.Equal(t, "golf", store.AgentToken()) - require.Equal(t, "hotel", store.AgentRecoveryToken()) - require.Equal(t, "india", store.UserToken()) - require.Equal(t, "juliet", store.ReplicationToken()) - require.Equal(t, "kilo", store.ConfigFileRegistrationToken()) - require.Equal(t, "lima", store.DNSToken()) + require.Equal(t, "india", store.AgentToken()) + require.Equal(t, "juliett", store.AgentRecoveryToken()) + require.Equal(t, "kilo", store.UserToken()) + require.Equal(t, "lima", store.ReplicationToken()) + require.Equal(t, "mike", store.ConfigFileRegistrationToken()) // check store persistence was enabled require.NotNil(t, store.persistence) @@ -124,8 +115,7 @@ func TestStore_Load(t *testing.T) { "agent_recovery" : "november", "default": "oscar", "replication" : "papa", - "config_file_service_registration" : "lima", - "dns": "kilo" + "config_file_service_registration" : "lima" }` cfg := Config{ @@ -136,7 +126,6 @@ func TestStore_Load(t *testing.T) { ACLAgentRecoveryToken: "sierra", ACLReplicationToken: "tango", ACLConfigFileRegistrationToken: "uniform", - ACLDNSToken: "victor", } require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600)) @@ -147,48 +136,43 @@ func TestStore_Load(t *testing.T) { require.Equal(t, "oscar", store.UserToken()) require.Equal(t, "papa", store.ReplicationToken()) require.Equal(t, "lima", store.ConfigFileRegistrationToken()) - require.Equal(t, "kilo", store.DNSToken()) }) t.Run("with some persisted tokens", func(t *testing.T) { tokens := `{ - "agent" : "xray", - "agent_recovery" : "zulu" + "agent" : "uniform", + "agent_recovery" : "victor" }` cfg := Config{ EnablePersistence: true, DataDir: dataDir, - ACLDefaultToken: "alpha", - ACLAgentToken: "bravo", - ACLAgentRecoveryToken: "charlie", - ACLReplicationToken: "delta", - ACLConfigFileRegistrationToken: "echo", - ACLDNSToken: "foxtrot", + ACLDefaultToken: "whiskey", + ACLAgentToken: "xray", + ACLAgentRecoveryToken: "yankee", + ACLReplicationToken: "zulu", + ACLConfigFileRegistrationToken: "victor", } require.NoError(t, os.WriteFile(tokenFile, []byte(tokens), 0600)) require.NoError(t, store.Load(cfg, logger)) - require.Equal(t, "xray", store.AgentToken()) - require.Equal(t, "zulu", store.AgentRecoveryToken()) - - require.Equal(t, "alpha", store.UserToken()) - require.Equal(t, "delta", store.ReplicationToken()) - require.Equal(t, "echo", store.ConfigFileRegistrationToken()) - require.Equal(t, "foxtrot", store.DNSToken()) + require.Equal(t, "uniform", store.AgentToken()) + require.Equal(t, "victor", store.AgentRecoveryToken()) + require.Equal(t, "whiskey", store.UserToken()) + require.Equal(t, "zulu", store.ReplicationToken()) + require.Equal(t, "victor", store.ConfigFileRegistrationToken()) }) t.Run("persisted file contains invalid data", func(t *testing.T) { cfg := Config{ EnablePersistence: true, DataDir: dataDir, - ACLDefaultToken: "alpha", - ACLAgentToken: "bravo", - ACLAgentRecoveryToken: "charlie", - ACLReplicationToken: "delta", - ACLConfigFileRegistrationToken: "echo", - ACLDNSToken: "foxtrot", + ACLDefaultToken: "one", + ACLAgentToken: "two", + ACLAgentRecoveryToken: "three", + ACLReplicationToken: "four", + ACLConfigFileRegistrationToken: "five", } require.NoError(t, os.WriteFile(tokenFile, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, 0600)) @@ -196,12 +180,11 @@ func TestStore_Load(t *testing.T) { require.Error(t, err) require.Contains(t, err.Error(), "failed to decode tokens file") - require.Equal(t, "alpha", store.UserToken()) - require.Equal(t, "bravo", store.AgentToken()) - require.Equal(t, "charlie", store.AgentRecoveryToken()) - require.Equal(t, "delta", store.ReplicationToken()) - require.Equal(t, "echo", store.ConfigFileRegistrationToken()) - require.Equal(t, "foxtrot", store.DNSToken()) + require.Equal(t, "one", store.UserToken()) + require.Equal(t, "two", store.AgentToken()) + require.Equal(t, "three", store.AgentRecoveryToken()) + require.Equal(t, "four", store.ReplicationToken()) + require.Equal(t, "five", store.ConfigFileRegistrationToken()) }) t.Run("persisted file contains invalid json", func(t *testing.T) { @@ -211,9 +194,8 @@ func TestStore_Load(t *testing.T) { ACLDefaultToken: "alfa", ACLAgentToken: "bravo", ACLAgentRecoveryToken: "charlie", - ACLReplicationToken: "delta", - ACLConfigFileRegistrationToken: "echo", - ACLDNSToken: "foxtrot", + ACLReplicationToken: "foxtrot", + ACLConfigFileRegistrationToken: "golf", } require.NoError(t, os.WriteFile(tokenFile, []byte("[1,2,3]"), 0600)) @@ -224,31 +206,23 @@ func TestStore_Load(t *testing.T) { require.Equal(t, "alfa", store.UserToken()) require.Equal(t, "bravo", store.AgentToken()) require.Equal(t, "charlie", store.AgentRecoveryToken()) - require.Equal(t, "delta", store.ReplicationToken()) - require.Equal(t, "echo", store.ConfigFileRegistrationToken()) - require.Equal(t, "foxtrot", store.DNSToken()) + require.Equal(t, "foxtrot", store.ReplicationToken()) + require.Equal(t, "golf", store.ConfigFileRegistrationToken()) }) } func TestStore_WithPersistenceLock(t *testing.T) { - // ACLDefaultToken: alpha --> sierra - // ACLAgentToken: bravo --> tango - // ACLAgentRecoveryToken: charlie --> uniform - // ACLReplicationToken: delta --> victor - // ACLConfigFileRegistrationToken: echo --> xray - // ACLDNSToken: foxtrot --> zulu setupStore := func() (string, *Store) { dataDir := testutil.TempDir(t, "datadir") store := new(Store) cfg := Config{ EnablePersistence: true, DataDir: dataDir, - ACLDefaultToken: "alpha", - ACLAgentToken: "bravo", - ACLAgentRecoveryToken: "charlie", - ACLReplicationToken: "delta", - ACLConfigFileRegistrationToken: "echo", - ACLDNSToken: "foxtrot", + ACLDefaultToken: "default-token", + ACLAgentToken: "agent-token", + ACLAgentRecoveryToken: "recovery-token", + ACLReplicationToken: "replication-token", + ACLConfigFileRegistrationToken: "registration-token", } err := store.Load(cfg, hclog.New(nil)) require.NoError(t, err) @@ -266,39 +240,37 @@ func TestStore_WithPersistenceLock(t *testing.T) { t.Run("persist some tokens", func(t *testing.T) { dataDir, store := setupStore() err := store.WithPersistenceLock(func() error { - require.True(t, store.UpdateUserToken("sierra", TokenSourceAPI)) - require.True(t, store.UpdateAgentRecoveryToken("tango", TokenSourceAPI)) + require.True(t, store.UpdateUserToken("the-new-default-token", TokenSourceAPI)) + require.True(t, store.UpdateAgentRecoveryToken("the-new-recovery-token", TokenSourceAPI)) return nil }) require.NoError(t, err) // Only API-sourced tokens are persisted. requirePersistedTokens(t, dataDir, persistedTokens{ - Default: "sierra", - AgentRecovery: "tango", + Default: "the-new-default-token", + AgentRecovery: "the-new-recovery-token", }) }) t.Run("persist all tokens", func(t *testing.T) { dataDir, store := setupStore() err := store.WithPersistenceLock(func() error { - require.True(t, store.UpdateUserToken("sierra", TokenSourceAPI)) - require.True(t, store.UpdateAgentToken("tango", TokenSourceAPI)) - require.True(t, store.UpdateAgentRecoveryToken("uniform", TokenSourceAPI)) - require.True(t, store.UpdateReplicationToken("victor", TokenSourceAPI)) - require.True(t, store.UpdateConfigFileRegistrationToken("xray", TokenSourceAPI)) - require.True(t, store.UpdateDNSToken("zulu", TokenSourceAPI)) + require.True(t, store.UpdateUserToken("the-new-default-token", TokenSourceAPI)) + require.True(t, store.UpdateAgentToken("the-new-agent-token", TokenSourceAPI)) + require.True(t, store.UpdateAgentRecoveryToken("the-new-recovery-token", TokenSourceAPI)) + require.True(t, store.UpdateReplicationToken("the-new-replication-token", TokenSourceAPI)) + require.True(t, store.UpdateConfigFileRegistrationToken("the-new-registration-token", TokenSourceAPI)) return nil }) require.NoError(t, err) requirePersistedTokens(t, dataDir, persistedTokens{ - Default: "sierra", - Agent: "tango", - AgentRecovery: "uniform", - Replication: "victor", - ConfigFileRegistration: "xray", - DNS: "zulu", + Default: "the-new-default-token", + Agent: "the-new-agent-token", + AgentRecovery: "the-new-recovery-token", + Replication: "the-new-replication-token", + ConfigFileRegistration: "the-new-registration-token", }) }) diff --git a/agent/token/store.go b/agent/token/store.go index 848d539a2a806..b0f9732a8cc6f 100644 --- a/agent/token/store.go +++ b/agent/token/store.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package token @@ -24,7 +24,6 @@ const ( TokenKindUser TokenKindReplication TokenKindConfigFileRegistration - TokenKindDNS ) type watcher struct { @@ -53,7 +52,7 @@ type Store struct { // also be used for agent operations if the agent token isn't set. userToken string - // userTokenSource indicates where this token originated from. + // userTokenSource indicates where this token originated from userTokenSource TokenSource // agentToken is used for internal agent operations like self-registering @@ -61,7 +60,7 @@ type Store struct { // user-initiated operations. agentToken string - // agentTokenSource indicates where this token originated from. + // agentTokenSource indicates where this token originated from agentTokenSource TokenSource // agentRecoveryToken is a special token that's only used locally for @@ -69,30 +68,23 @@ type Store struct { // available. agentRecoveryToken string - // agentRecoveryTokenSource indicates where this token originated from. + // agentRecoveryTokenSource indicates where this token originated from agentRecoveryTokenSource TokenSource // replicationToken is a special token that's used by servers to // replicate data from the primary datacenter. replicationToken string - // replicationTokenSource indicates where this token originated from. + // replicationTokenSource indicates where this token originated from replicationTokenSource TokenSource // configFileRegistrationToken is used to register services and checks // that are defined in configuration files. configFileRegistrationToken string - // configFileRegistrationTokenSource indicates where this token originated from. + // configFileRegistrationTokenSource indicates where this token originated from configFileRegistrationTokenSource TokenSource - // dnsToken is a special token that is used as the implicit token for DNS requests - // as well as for DNS-specific RPC requests. - dnsToken string - - // dnsTokenSource indicates where the dnsToken originated from. - dnsTokenSource TokenSource - watchers map[int]watcher watcherIndex int @@ -212,12 +204,6 @@ func (t *Store) UpdateConfigFileRegistrationToken(token string, source TokenSour &t.configFileRegistrationTokenSource, TokenKindConfigFileRegistration) } -// UpdateDNSToken replaces the current DNS token in the store. -// Returns true if it was changed. -func (t *Store) UpdateDNSToken(token string, source TokenSource) bool { - return t.updateToken(token, source, &t.dnsToken, &t.dnsTokenSource, TokenKindDNS) -} - func (t *Store) updateToken(token string, source TokenSource, dstToken *string, dstSource *TokenSource, kind TokenKind) bool { t.l.Lock() changed := *dstToken != token || *dstSource != source @@ -275,13 +261,6 @@ func (t *Store) ConfigFileRegistrationToken() string { return t.configFileRegistrationToken } -func (t *Store) DNSToken() string { - t.l.RLock() - defer t.l.RUnlock() - - return t.dnsToken -} - // UserToken returns the best token to use for user operations. func (t *Store) UserTokenAndSource() (string, TokenSource) { t.l.RLock() @@ -320,14 +299,6 @@ func (t *Store) ConfigFileRegistrationTokenAndSource() (string, TokenSource) { return t.configFileRegistrationToken, t.configFileRegistrationTokenSource } -// DNSTokenAndSource returns the best token to use for DNS-specific RPC requests and DNS requests -func (t *Store) DNSTokenAndSource() (string, TokenSource) { - t.l.RLock() - defer t.l.RUnlock() - - return t.dnsToken, t.dnsTokenSource -} - // IsAgentRecoveryToken checks to see if a given token is the agent recovery token. // This will never match an empty token for safety. func (t *Store) IsAgentRecoveryToken(token string) bool { diff --git a/agent/token/store_ce.go b/agent/token/store_ce.go index af7732a902088..87fefdbbe0480 100644 --- a/agent/token/store_ce.go +++ b/agent/token/store_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package token diff --git a/agent/token/store_test.go b/agent/token/store_test.go index 2f91614085c4f..8d0992f229ca2 100644 --- a/agent/token/store_test.go +++ b/agent/token/store_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package token @@ -21,8 +21,6 @@ func TestStore_RegularTokens(t *testing.T) { replSource TokenSource registration string registrationSource TokenSource - dns string - dnsSource TokenSource } tests := []struct { @@ -97,23 +95,11 @@ func TestStore_RegularTokens(t *testing.T) { raw: tokens{registration: "G", registrationSource: TokenSourceAPI}, effective: tokens{registration: "G"}, }, - { - name: "set dns - config", - set: tokens{dns: "D", dnsSource: TokenSourceConfig}, - raw: tokens{dns: "D", dnsSource: TokenSourceConfig}, - effective: tokens{dns: "D"}, - }, - { - name: "set dns - api", - set: tokens{dns: "D", dnsSource: TokenSourceAPI}, - raw: tokens{dns: "D", dnsSource: TokenSourceAPI}, - effective: tokens{dns: "D"}, - }, { name: "set all", - set: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G", dns: "D"}, - raw: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G", dns: "D"}, - effective: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G", dns: "D"}, + set: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G"}, + raw: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G"}, + effective: tokens{user: "U", agent: "A", repl: "R", recovery: "M", registration: "G"}, }, } for _, tt := range tests { @@ -139,24 +125,18 @@ func TestStore_RegularTokens(t *testing.T) { require.True(t, s.UpdateConfigFileRegistrationToken(tt.set.registration, tt.set.registrationSource)) } - if tt.set.dns != "" { - require.True(t, s.UpdateDNSToken(tt.set.dns, tt.set.dnsSource)) - } - // If they don't change then they return false. require.False(t, s.UpdateUserToken(tt.set.user, tt.set.userSource)) require.False(t, s.UpdateAgentToken(tt.set.agent, tt.set.agentSource)) require.False(t, s.UpdateReplicationToken(tt.set.repl, tt.set.replSource)) require.False(t, s.UpdateAgentRecoveryToken(tt.set.recovery, tt.set.recoverySource)) require.False(t, s.UpdateConfigFileRegistrationToken(tt.set.registration, tt.set.registrationSource)) - require.False(t, s.UpdateDNSToken(tt.set.dns, tt.set.dnsSource)) require.Equal(t, tt.effective.user, s.UserToken()) require.Equal(t, tt.effective.agent, s.AgentToken()) require.Equal(t, tt.effective.recovery, s.AgentRecoveryToken()) require.Equal(t, tt.effective.repl, s.ReplicationToken()) require.Equal(t, tt.effective.registration, s.ConfigFileRegistrationToken()) - require.Equal(t, tt.effective.dns, s.DNSToken()) tok, src := s.UserTokenAndSource() require.Equal(t, tt.raw.user, tok) @@ -177,10 +157,6 @@ func TestStore_RegularTokens(t *testing.T) { tok, src = s.ConfigFileRegistrationTokenAndSource() require.Equal(t, tt.raw.registration, tok) require.Equal(t, tt.raw.registrationSource, src) - - tok, src = s.DNSTokenAndSource() - require.Equal(t, tt.raw.dns, tok) - require.Equal(t, tt.raw.dnsSource, src) }) } } @@ -235,7 +211,6 @@ func TestStore_Notify(t *testing.T) { replicationNotifier := newNotification(t, s, TokenKindReplication) replicationNotifier2 := newNotification(t, s, TokenKindReplication) registrationNotifier := newNotification(t, s, TokenKindConfigFileRegistration) - dnsNotifier := newNotification(t, s, TokenKindDNS) // perform an update of the user token require.True(t, s.UpdateUserToken("edcae2a2-3b51-4864-b412-c7a568f49cb1", TokenSourceConfig)) @@ -249,7 +224,6 @@ func TestStore_Notify(t *testing.T) { requireNotNotified(t, agentRecoveryNotifier.Ch) requireNotNotified(t, replicationNotifier2.Ch) requireNotNotified(t, registrationNotifier.Ch) - requireNotNotified(t, dnsNotifier.Ch) // update the agent token which should send a notification to the agent notifier. require.True(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI)) @@ -260,7 +234,6 @@ func TestStore_Notify(t *testing.T) { requireNotNotified(t, agentRecoveryNotifier.Ch) requireNotNotified(t, replicationNotifier2.Ch) requireNotNotified(t, registrationNotifier.Ch) - requireNotNotified(t, dnsNotifier.Ch) // update the agent recovery token which should send a notification to the agent recovery notifier. require.True(t, s.UpdateAgentRecoveryToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI)) @@ -271,7 +244,6 @@ func TestStore_Notify(t *testing.T) { requireNotifiedOnce(t, agentRecoveryNotifier.Ch) requireNotNotified(t, replicationNotifier2.Ch) requireNotNotified(t, registrationNotifier.Ch) - requireNotNotified(t, dnsNotifier.Ch) // update the replication token which should send a notification to the replication notifier. require.True(t, s.UpdateReplicationToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI)) @@ -282,7 +254,6 @@ func TestStore_Notify(t *testing.T) { requireNotNotified(t, agentRecoveryNotifier.Ch) requireNotifiedOnce(t, replicationNotifier2.Ch) requireNotNotified(t, registrationNotifier.Ch) - requireNotNotified(t, dnsNotifier.Ch) s.StopNotify(replicationNotifier2) @@ -295,7 +266,6 @@ func TestStore_Notify(t *testing.T) { requireNotNotified(t, agentRecoveryNotifier.Ch) requireNotNotified(t, replicationNotifier2.Ch) requireNotNotified(t, registrationNotifier.Ch) - requireNotNotified(t, dnsNotifier.Ch) // update the config file registration token which should send a notification to the replication notifier. require.True(t, s.UpdateConfigFileRegistrationToken("82fe7362-7d83-4f43-bb27-c35f1f15083c", TokenSourceAPI)) @@ -306,18 +276,6 @@ func TestStore_Notify(t *testing.T) { requireNotNotified(t, agentRecoveryNotifier.Ch) requireNotNotified(t, replicationNotifier2.Ch) requireNotifiedOnce(t, registrationNotifier.Ch) - requireNotNotified(t, dnsNotifier.Ch) - - // update the dns token which should send a notification to the replication notifier. - require.True(t, s.UpdateDNSToken("ce8e829f-dc45-4ba7-9dd3-1dbbe070f573", TokenSourceAPI)) - - requireNotNotified(t, agentNotifier.Ch) - requireNotNotified(t, userNotifier.Ch) - requireNotNotified(t, replicationNotifier.Ch) - requireNotNotified(t, agentRecoveryNotifier.Ch) - requireNotNotified(t, replicationNotifier2.Ch) - requireNotNotified(t, registrationNotifier.Ch) - requireNotifiedOnce(t, dnsNotifier.Ch) // request updates that are not changes require.False(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI)) @@ -325,7 +283,6 @@ func TestStore_Notify(t *testing.T) { require.False(t, s.UpdateUserToken("47788919-f944-476a-bda5-446d64be1df8", TokenSourceAPI)) require.False(t, s.UpdateReplicationToken("eb0b56b9-fa65-4ae1-902a-c64457c62ac6", TokenSourceAPI)) require.False(t, s.UpdateConfigFileRegistrationToken("82fe7362-7d83-4f43-bb27-c35f1f15083c", TokenSourceAPI)) - require.False(t, s.UpdateDNSToken("ce8e829f-dc45-4ba7-9dd3-1dbbe070f573", TokenSourceAPI)) // ensure that notifications were not sent requireNotNotified(t, agentNotifier.Ch) @@ -333,5 +290,4 @@ func TestStore_Notify(t *testing.T) { requireNotNotified(t, replicationNotifier.Ch) requireNotNotified(t, agentRecoveryNotifier.Ch) requireNotNotified(t, registrationNotifier.Ch) - requireNotNotified(t, dnsNotifier.Ch) } diff --git a/agent/translate_addr.go b/agent/translate_addr.go index 1c0f8a4003058..9be80ebc0f8c8 100644 --- a/agent/translate_addr.go +++ b/agent/translate_addr.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/txn_endpoint.go b/agent/txn_endpoint.go index 04dcd7fa39022..7c2f64c1a9317 100644 --- a/agent/txn_endpoint.go +++ b/agent/txn_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/txn_endpoint_test.go b/agent/txn_endpoint_test.go index fe19ed825301c..19c5925ba7a9c 100644 --- a/agent/txn_endpoint_test.go +++ b/agent/txn_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/ui_endpoint.go b/agent/ui_endpoint.go index d0cc8a5be8329..fa4bb23f84647 100644 --- a/agent/ui_endpoint.go +++ b/agent/ui_endpoint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -190,6 +190,7 @@ func AgentMembersMapAddrVer(s *HTTPHandlers, req *http.Request) (map[string]stri filter := consul.LANMemberFilter{ Partition: entMeta.PartitionOrDefault(), } + if acl.IsDefaultPartition(filter.Partition) { filter.AllSegments = true } diff --git a/agent/ui_endpoint_ce_test.go b/agent/ui_endpoint_ce_test.go index 2cb3f905e28b0..3e57fca667e87 100644 --- a/agent/ui_endpoint_ce_test.go +++ b/agent/ui_endpoint_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package agent diff --git a/agent/ui_endpoint_test.go b/agent/ui_endpoint_test.go index dd1c6d8134b2f..b39a2f31dc931 100644 --- a/agent/ui_endpoint_test.go +++ b/agent/ui_endpoint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent @@ -32,28 +32,6 @@ import ( "github.com/hashicorp/consul/types" ) -func TestUIEndpointsFailInV2(t *testing.T) { - t.Parallel() - - a := NewTestAgent(t, `experiments = ["resource-apis"]`) - - checkRequest := func(method, url string) { - t.Run(method+" "+url, func(t *testing.T) { - assertV1CatalogEndpointDoesNotWorkWithV2(t, a, method, url, "{}") - }) - } - - checkRequest("GET", "/v1/internal/ui/nodes") - checkRequest("GET", "/v1/internal/ui/node/web") - checkRequest("GET", "/v1/internal/ui/services") - checkRequest("GET", "/v1/internal/ui/exported-services") - checkRequest("GET", "/v1/internal/ui/catalog-overview") - checkRequest("GET", "/v1/internal/ui/gateway-services-nodes/web") - checkRequest("GET", "/v1/internal/ui/gateway-intentions/web") - checkRequest("GET", "/v1/internal/ui/service-topology/web") - checkRequest("PUT", "/v1/internal/service-virtual-ip") -} - func TestUIIndex(t *testing.T) { if testing.Short() { t.Skip("too slow for testing.Short") diff --git a/agent/uiserver/buf_index_fs.go b/agent/uiserver/buf_index_fs.go index 283616c36eda6..9ea23316fb10a 100644 --- a/agent/uiserver/buf_index_fs.go +++ b/agent/uiserver/buf_index_fs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package uiserver diff --git a/agent/uiserver/buffered_file.go b/agent/uiserver/buffered_file.go index daa30c610d29f..5c794dac26908 100644 --- a/agent/uiserver/buffered_file.go +++ b/agent/uiserver/buffered_file.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package uiserver diff --git a/agent/uiserver/redirect_fs.go b/agent/uiserver/redirect_fs.go index 4a61ba7b2c14d..66b48e637fdc8 100644 --- a/agent/uiserver/redirect_fs.go +++ b/agent/uiserver/redirect_fs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package uiserver diff --git a/agent/uiserver/ui_template_data.go b/agent/uiserver/ui_template_data.go index 726207b148f0c..d8d5fc42ba4e3 100644 --- a/agent/uiserver/ui_template_data.go +++ b/agent/uiserver/ui_template_data.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package uiserver diff --git a/agent/uiserver/uiserver.go b/agent/uiserver/uiserver.go index 0cd20c5fda0b4..8cabb8e3e0cd9 100644 --- a/agent/uiserver/uiserver.go +++ b/agent/uiserver/uiserver.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package uiserver diff --git a/agent/uiserver/uiserver_test.go b/agent/uiserver/uiserver_test.go index ce649276546be..c42792fe320bf 100644 --- a/agent/uiserver/uiserver_test.go +++ b/agent/uiserver/uiserver_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package uiserver diff --git a/agent/user_event.go b/agent/user_event.go index 23cbc90c336d8..25be0dd88f42a 100644 --- a/agent/user_event.go +++ b/agent/user_event.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/user_event_test.go b/agent/user_event_test.go index 62ea5f4adca31..ac807def924cf 100644 --- a/agent/user_event_test.go +++ b/agent/user_event_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/util.go b/agent/util.go index 1bcdbca01f1aa..285ba91df948d 100644 --- a/agent/util.go +++ b/agent/util.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/util_test.go b/agent/util_test.go index 42aa745e70fae..4c3ae5602d39b 100644 --- a/agent/util_test.go +++ b/agent/util_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/watch_handler.go b/agent/watch_handler.go index b926b7167505d..518fd6c77c98a 100644 --- a/agent/watch_handler.go +++ b/agent/watch_handler.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/watch_handler_test.go b/agent/watch_handler_test.go index 151e05e9c0778..f97d4d3982d3f 100644 --- a/agent/watch_handler_test.go +++ b/agent/watch_handler_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/agent/xds/accesslogs/accesslogs.go b/agent/xds/accesslogs/accesslogs.go index a5aac415832fa..84cbf55e64d8c 100644 --- a/agent/xds/accesslogs/accesslogs.go +++ b/agent/xds/accesslogs/accesslogs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package accesslogs @@ -10,7 +10,6 @@ import ( envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_fileaccesslog_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/file/v3" envoy_streamaccesslog_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/stream/v3" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" @@ -53,12 +52,12 @@ const ( // on the proxy-defaults settings. Currently only one access logger is supported. // Listeners (as opposed to listener filters) can trigger an access log filter with the boolean. // Tests are located in agent/xds/listeners_test.go. -func MakeAccessLogs(logs structs.AccessLogs, isListener bool) ([]*envoy_accesslog_v3.AccessLog, error) { - if logs == nil || !logs.GetEnabled() { +func MakeAccessLogs(logs *structs.AccessLogsConfig, isListener bool) ([]*envoy_accesslog_v3.AccessLog, error) { + if logs == nil || !logs.Enabled { return nil, nil } - if isListener && logs.GetDisableListenerLogs() { + if isListener && logs.DisableListenerLogs { return nil, nil } @@ -86,37 +85,37 @@ func MakeAccessLogs(logs structs.AccessLogs, isListener bool) ([]*envoy_accesslo } // getLogger returns an individual instance of an Envoy logger based on proxy-defaults -func getLogger(logs structs.AccessLogs) (*anypb.Any, error) { +func getLogger(logs *structs.AccessLogsConfig) (*anypb.Any, error) { logFormat, err := getLogFormat(logs) if err != nil { return nil, fmt.Errorf("could not get envoy log format: %w", err) } - switch logs.GetType() { - case pbmesh.LogSinkType_LOG_SINK_TYPE_DEFAULT, pbmesh.LogSinkType_LOG_SINK_TYPE_STDOUT: + switch logs.Type { + case structs.DefaultLogSinkType, structs.StdOutLogSinkType: return getStdoutLogger(logFormat) - case pbmesh.LogSinkType_LOG_SINK_TYPE_STDERR: + case structs.StdErrLogSinkType: return getStderrLogger(logFormat) - case pbmesh.LogSinkType_LOG_SINK_TYPE_FILE: - return getFileLogger(logFormat, logs.GetPath()) + case structs.FileLogSinkType: + return getFileLogger(logFormat, logs.Path) default: - return nil, fmt.Errorf("unsupported log format: %s", logs.GetType()) + return nil, fmt.Errorf("unsupported log format: %s", logs.Type) } } // getLogFormat returns an Envoy log format object that is compatible with all log sinks. // If a format is not provided in the proxy-defaults, the default JSON format is used. -func getLogFormat(logs structs.AccessLogs) (*envoy_core_v3.SubstitutionFormatString, error) { +func getLogFormat(logs *structs.AccessLogsConfig) (*envoy_core_v3.SubstitutionFormatString, error) { var format, formatType string - if logs.GetTextFormat() == "" && logs.GetJsonFormat() == "" { + if logs.TextFormat == "" && logs.JSONFormat == "" { format = defaultJSONFormat formatType = "json" - } else if logs.GetJsonFormat() != "" { - format = logs.GetJsonFormat() + } else if logs.JSONFormat != "" { + format = logs.JSONFormat formatType = "json" } else { - format = logs.GetTextFormat() + format = logs.TextFormat formatType = "text" } diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index b74fe371b28d8..e9e5f57a14450 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -19,8 +19,6 @@ import ( envoy_upstreams_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3" envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" - "github.com/hashicorp/consul/agent/xds/config" - "github.com/hashicorp/consul/agent/xds/naming" "github.com/hashicorp/go-hclog" "google.golang.org/protobuf/encoding/protojson" @@ -32,7 +30,6 @@ import ( "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/response" "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/proto/private/pbpeering" ) @@ -369,7 +366,7 @@ func makePassthroughClusters(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, !meshConf.TransparentProxy.MeshDestinationsOnly { clusters = append(clusters, &envoy_cluster_v3.Cluster{ - Name: naming.OriginalDestinationClusterName, + Name: OriginalDestinationClusterName, ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{ Type: envoy_cluster_v3.Cluster_ORIGINAL_DST, }, @@ -814,6 +811,27 @@ func (s *ResourceGenerator) makeGatewayOutgoingClusterPeeringServiceClusters(cfg } cluster := s.makeGatewayCluster(cfgSnap, opts) + if serviceGroup.UseCDS { + configureClusterWithHostnames( + s.Logger, + cluster, + "", /*TODO:make configurable?*/ + serviceGroup.Nodes, + true, /*isRemote*/ + false, /*onlyPassing*/ + ) + } else { + cluster.ClusterDiscoveryType = &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_EDS} + cluster.EdsClusterConfig = &envoy_cluster_v3.Cluster_EdsClusterConfig{ + EdsConfig: &envoy_core_v3.ConfigSource{ + ResourceApiVersion: envoy_core_v3.ApiVersion_V3, + ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_Ads{ + Ads: &envoy_core_v3.AggregatedConfigSource{}, + }, + }, + } + } + clusters = append(clusters, cluster) } } @@ -977,10 +995,8 @@ func (s *ResourceGenerator) clustersFromSnapshotAPIGateway(cfgSnap *proxycfg.Con // Grab the discovery chain compiled in handlerAPIGateway.recompileDiscoveryChains chain, ok := cfgSnap.APIGateway.DiscoveryChain[uid] if !ok { - // this should not happen, but it can't error out because the equivalent - // listener generation will continue - s.Logger.Warn("could not find discovery chain for gateway upstream", "upstream", uid) - continue + // this should not happen + return nil, fmt.Errorf("no discovery chain for upstream %q", uid) } // Generate the list of upstream clusters for the discovery chain @@ -1012,11 +1028,11 @@ func (s *ResourceGenerator) configIngressUpstreamCluster(c *envoy_cluster_v3.Clu switch limitType { case "max_connections": - threshold.MaxConnections = response.MakeUint32Value(limit) + threshold.MaxConnections = makeUint32Value(limit) case "max_pending_requests": - threshold.MaxPendingRequests = response.MakeUint32Value(limit) + threshold.MaxPendingRequests = makeUint32Value(limit) case "max_requests": - threshold.MaxRequests = response.MakeUint32Value(limit) + threshold.MaxRequests = makeUint32Value(limit) } } @@ -1047,7 +1063,12 @@ func (s *ResourceGenerator) configIngressUpstreamCluster(c *envoy_cluster_v3.Clu if svc != nil { override = svc.PassiveHealthCheck } - outlierDetection := config.ToOutlierDetection(cfgSnap.IngressGateway.Defaults.PassiveHealthCheck, override, false) + outlierDetection := ToOutlierDetection(cfgSnap.IngressGateway.Defaults.PassiveHealthCheck, override, false) + + // Specail handling for failover peering service, which has set MaxEjectionPercent + if c.OutlierDetection != nil && c.OutlierDetection.MaxEjectionPercent != nil { + outlierDetection.MaxEjectionPercent = &wrapperspb.UInt32Value{Value: c.OutlierDetection.MaxEjectionPercent.Value} + } c.OutlierDetection = outlierDetection } @@ -1056,7 +1077,7 @@ func (s *ResourceGenerator) makeAppCluster(cfgSnap *proxycfg.ConfigSnapshot, nam var c *envoy_cluster_v3.Cluster var err error - cfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) + cfg, err := ParseProxyConfig(cfgSnap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -1099,21 +1120,15 @@ func (s *ResourceGenerator) makeAppCluster(cfgSnap *proxycfg.ConfigSnapshot, nam protocol = cfg.Protocol } if protocol == "http2" || protocol == "grpc" { - if name == xdscommon.LocalAppClusterName { - if err := s.setLocalAppHttpProtocolOptions(c); err != nil { - return c, err - } - } else { - if err := s.setHttp2ProtocolOptions(c); err != nil { - return c, err - } + if err := s.setHttp2ProtocolOptions(c); err != nil { + return c, err } } if cfg.MaxInboundConnections > 0 { c.CircuitBreakers = &envoy_cluster_v3.CircuitBreakers{ Thresholds: []*envoy_cluster_v3.CircuitBreakers_Thresholds{ { - MaxConnections: response.MakeUint32Value(cfg.MaxInboundConnections), + MaxConnections: makeUint32Value(cfg.MaxInboundConnections), }, }, } @@ -1156,7 +1171,7 @@ func (s *ResourceGenerator) makeUpstreamClusterForPeerService( clusterName := generatePeeredClusterName(uid, tbs) - outlierDetection := config.ToOutlierDetection(upstreamConfig.PassiveHealthCheck, nil, true) + outlierDetection := ToOutlierDetection(upstreamConfig.PassiveHealthCheck, nil, true) // We can't rely on health checks for services on cluster peers because they // don't take into account service resolvers, splitters and routers. Setting // MaxEjectionPercent too 100% gives outlier detection the power to eject the @@ -1291,7 +1306,7 @@ func (s *ResourceGenerator) makeUpstreamClusterForPreparedQuery(upstream structs CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ Thresholds: makeThresholdsIfNeeded(cfg.Limits), }, - OutlierDetection: config.ToOutlierDetection(cfg.PassiveHealthCheck, nil, true), + OutlierDetection: ToOutlierDetection(cfg.PassiveHealthCheck, nil, true), } if cfg.Protocol == "http2" || cfg.Protocol == "grpc" { if err := s.setHttp2ProtocolOptions(c); err != nil { @@ -1433,7 +1448,7 @@ func (s *ResourceGenerator) makeUpstreamClustersForDiscoveryChain( // These variables are prefixed with primary to avoid shaddowing bugs. primaryTargetID := node.Resolver.Target primaryTarget := chain.Targets[primaryTargetID] - primaryTargetClusterName := s.getTargetClusterName(upstreamsSnapshot, chain, primaryTargetID, forMeshGateway) + primaryTargetClusterName := s.getTargetClusterName(upstreamsSnapshot, chain, primaryTargetID, forMeshGateway, false) if primaryTargetClusterName == "" { continue } @@ -1511,7 +1526,7 @@ func (s *ResourceGenerator) makeUpstreamClustersForDiscoveryChain( CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ Thresholds: makeThresholdsIfNeeded(upstreamConfig.Limits), }, - OutlierDetection: config.ToOutlierDetection(upstreamConfig.PassiveHealthCheck, nil, true), + OutlierDetection: ToOutlierDetection(upstreamConfig.PassiveHealthCheck, nil, true), } var lb *structs.LoadBalancer @@ -1665,6 +1680,11 @@ func makeClusterFromUserConfig(configJSON string) (*envoy_cluster_v3.Cluster, er return &c, err } +type addressPair struct { + host string + port int +} + type clusterOpts struct { // name for the cluster name string @@ -1688,7 +1708,7 @@ type clusterOpts struct { // makeGatewayCluster creates an Envoy cluster for a mesh or terminating gateway func (s *ResourceGenerator) makeGatewayCluster(snap *proxycfg.ConfigSnapshot, opts clusterOpts) *envoy_cluster_v3.Cluster { - cfg, err := config.ParseGatewayConfig(snap.Proxy.Config) + cfg, err := ParseGatewayConfig(snap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -1718,13 +1738,13 @@ func (s *ResourceGenerator) makeGatewayCluster(snap *proxycfg.ConfigSnapshot, op TcpKeepalive: &envoy_core_v3.TcpKeepalive{}, } if cfg.TcpKeepaliveTime != 0 { - cluster.UpstreamConnectionOptions.TcpKeepalive.KeepaliveTime = response.MakeUint32Value(cfg.TcpKeepaliveTime) + cluster.UpstreamConnectionOptions.TcpKeepalive.KeepaliveTime = makeUint32Value(cfg.TcpKeepaliveTime) } if cfg.TcpKeepaliveInterval != 0 { - cluster.UpstreamConnectionOptions.TcpKeepalive.KeepaliveInterval = response.MakeUint32Value(cfg.TcpKeepaliveInterval) + cluster.UpstreamConnectionOptions.TcpKeepalive.KeepaliveInterval = makeUint32Value(cfg.TcpKeepaliveInterval) } if cfg.TcpKeepaliveProbes != 0 { - cluster.UpstreamConnectionOptions.TcpKeepalive.KeepaliveProbes = response.MakeUint32Value(cfg.TcpKeepaliveProbes) + cluster.UpstreamConnectionOptions.TcpKeepalive.KeepaliveProbes = makeUint32Value(cfg.TcpKeepaliveProbes) } } @@ -1831,7 +1851,7 @@ func configureClusterWithHostnames( // makeExternalIPCluster creates an Envoy cluster for routing to IP addresses outside of Consul // This is used by terminating gateways for Destinations func (s *ResourceGenerator) makeExternalIPCluster(snap *proxycfg.ConfigSnapshot, opts clusterOpts) *envoy_cluster_v3.Cluster { - cfg, err := config.ParseGatewayConfig(snap.Proxy.Config) + cfg, err := ParseGatewayConfig(snap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -1870,7 +1890,7 @@ func (s *ResourceGenerator) makeExternalIPCluster(snap *proxycfg.ConfigSnapshot, // makeExternalHostnameCluster creates an Envoy cluster for hostname endpoints that will be resolved with DNS // This is used by both terminating gateways for Destinations, and Mesh Gateways for peering control plane traffic func (s *ResourceGenerator) makeExternalHostnameCluster(snap *proxycfg.ConfigSnapshot, opts clusterOpts, discoveryType envoy_cluster_v3.Cluster_DiscoveryType) *envoy_cluster_v3.Cluster { - cfg, err := config.ParseGatewayConfig(snap.Proxy.Config) + cfg, err := ParseGatewayConfig(snap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -1894,7 +1914,7 @@ func (s *ResourceGenerator) makeExternalHostnameCluster(snap *proxycfg.ConfigSna endpoints := make([]*envoy_endpoint_v3.LbEndpoint, 0, len(opts.addresses)) for _, pair := range opts.addresses { - address := response.MakeAddress(pair.Address, pair.Port) + address := makeAddress(pair.Address, pair.Port) endpoint := &envoy_endpoint_v3.LbEndpoint{ HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ @@ -1927,13 +1947,13 @@ func makeThresholdsIfNeeded(limits *structs.UpstreamLimits) []*envoy_cluster_v3. // Likewise, make sure to not set any threshold values on the zero-value in // order to rely on Envoy defaults if limits.MaxConnections != nil { - threshold.MaxConnections = response.MakeUint32Value(*limits.MaxConnections) + threshold.MaxConnections = makeUint32Value(*limits.MaxConnections) } if limits.MaxPendingRequests != nil { - threshold.MaxPendingRequests = response.MakeUint32Value(*limits.MaxPendingRequests) + threshold.MaxPendingRequests = makeUint32Value(*limits.MaxPendingRequests) } if limits.MaxConcurrentRequests != nil { - threshold.MaxRequests = response.MakeUint32Value(*limits.MaxConcurrentRequests) + threshold.MaxRequests = makeUint32Value(*limits.MaxConcurrentRequests) } return []*envoy_cluster_v3.CircuitBreakers_Thresholds{threshold} @@ -1956,7 +1976,7 @@ func makeLbEndpoint(addr string, port int, health envoy_core_v3.HealthStatus, we }, }, HealthStatus: health, - LoadBalancingWeight: response.MakeUint32Value(weight), + LoadBalancingWeight: makeUint32Value(weight), } } @@ -2025,29 +2045,6 @@ func (s *ResourceGenerator) setHttp2ProtocolOptions(c *envoy_cluster_v3.Cluster) return nil } -// Allows forwarding either HTTP/1.1 or HTTP/2 traffic to the local application. -// The protocol used depends on the protocol received from the downstream service -// on the public listener. -func (s *ResourceGenerator) setLocalAppHttpProtocolOptions(c *envoy_cluster_v3.Cluster) error { - cfg := &envoy_upstreams_v3.HttpProtocolOptions{ - UpstreamProtocolOptions: &envoy_upstreams_v3.HttpProtocolOptions_UseDownstreamProtocolConfig{ - UseDownstreamProtocolConfig: &envoy_upstreams_v3.HttpProtocolOptions_UseDownstreamHttpConfig{ - HttpProtocolOptions: &envoy_core_v3.Http1ProtocolOptions{}, - Http2ProtocolOptions: &envoy_core_v3.Http2ProtocolOptions{}, - }, - }, - } - any, err := anypb.New(cfg) - if err != nil { - return err - } - c.TypedExtensionProtocolOptions = map[string]*anypb.Any{ - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": any, - } - - return nil -} - // generatePeeredClusterName returns an SNI-like cluster name which mimics PeeredServiceSNI // but excludes partition information which could be ambiguous (local vs remote partition). func generatePeeredClusterName(uid proxycfg.UpstreamID, tb *pbpeering.PeeringTrustBundle) string { @@ -2060,11 +2057,15 @@ func generatePeeredClusterName(uid proxycfg.UpstreamID, tb *pbpeering.PeeringTru }, ".") } -func (s *ResourceGenerator) getTargetClusterName(upstreamsSnapshot *proxycfg.ConfigSnapshotUpstreams, chain *structs.CompiledDiscoveryChain, tid string, forMeshGateway bool) string { +type targetClusterData struct { + targetID string + clusterName string +} + +func (s *ResourceGenerator) getTargetClusterName(upstreamsSnapshot *proxycfg.ConfigSnapshotUpstreams, chain *structs.CompiledDiscoveryChain, tid string, forMeshGateway bool, failover bool) string { target := chain.Targets[tid] clusterName := target.Name targetUID := proxycfg.NewUpstreamIDFromTargetID(tid) - if targetUID.Peer != "" { tbs, ok := upstreamsSnapshot.UpstreamPeerTrustBundles.Get(targetUID.Peer) // We can't generate cluster on peers without the trust bundle. The @@ -2079,7 +2080,10 @@ func (s *ResourceGenerator) getTargetClusterName(upstreamsSnapshot *proxycfg.Con clusterName = generatePeeredClusterName(targetUID, tbs) } - clusterName = naming.CustomizeClusterName(clusterName, chain) + clusterName = CustomizeClusterName(clusterName, chain) + if failover { + clusterName = xdscommon.FailoverClusterNamePrefix + clusterName + } if forMeshGateway { clusterName = meshGatewayExportedClusterNamePrefix + clusterName } diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index fb92ea5804b6f..954aad7756f06 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -11,8 +11,6 @@ import ( "text/template" "time" - "github.com/hashicorp/consul/types" - envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" @@ -22,35 +20,16 @@ import ( "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/proxystateconverter" - "github.com/hashicorp/consul/agent/xds/response" "github.com/hashicorp/consul/agent/xds/testcommon" - "github.com/hashicorp/consul/agent/xdsv2" "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/sdk/testutil" + "github.com/hashicorp/consul/types" ) -type mockCfgFetcher struct { - addressLan string -} - -func (s *mockCfgFetcher) AdvertiseAddrLAN() string { - return s.addressLan -} - type clusterTestCase struct { name string create func(t testinf.T) *proxycfg.ConfigSnapshot overrideGoldenName string - alsoRunTestForV2 bool -} - -func uint32ptr(i uint32) *uint32 { - return &i -} - -func durationPtr(d time.Duration) *time.Duration { - return &d } func makeClusterDiscoChainTests(enterprise bool) []clusterTestCase { @@ -65,125 +44,90 @@ func makeClusterDiscoChainTests(enterprise bool) []clusterTestCase { }) }, nil) }, - // TODO(proxystate): requires custom cluster work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-chain", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", enterprise, nil, nil) }, - alsoRunTestForV2: true, - }, - { - name: "connect-proxy-with-chain-http2", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", enterprise, func(ns *structs.NodeService) { - ns.Proxy.Upstreams[0].Config["protocol"] = "http2" - }, nil) - }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-external-sni", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) }, - //TODO(proxystate): this requires terminating gateway work - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-overrides", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple-with-overrides", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-failover", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-failover-through-remote-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-remote-gateway", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-remote-gateway-triggered", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-double-failover-through-remote-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-double-remote-gateway", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-double-remote-gateway-triggered", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-failover-through-local-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-local-gateway", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-local-gateway-triggered", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-double-failover-through-local-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-double-local-gateway", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-double-local-gateway-triggered", enterprise, nil, nil) }, - // TODO(proxystate): requires routes work - alsoRunTestForV2: false, }, { name: "splitter-with-resolver-redirect", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "splitter-with-resolver-redirect-multidc", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-lb-in-resolver", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "lb-resolver", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, } } @@ -215,7 +159,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tls-outgoing-min-version", @@ -235,7 +178,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tls-outgoing-max-version", @@ -255,7 +197,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tls-outgoing-cipher-suites", @@ -278,7 +219,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-jwt-config-entry-with-local", @@ -302,8 +242,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - // TODO(proxystate): jwt work will come at a later time - alsoRunTestForV2: false, }, { name: "connect-proxy-with-jwt-config-entry-with-remote-jwks", @@ -338,8 +276,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - // TODO(proxystate): jwt work will come at a later time - alsoRunTestForV2: false, }, { name: "custom-local-app", @@ -351,8 +287,6 @@ func TestClustersFromSnapshot(t *testing.T) { }) }, nil) }, - // TODO(proxystate): requires custom cluster work - alsoRunTestForV2: false, }, { name: "custom-upstream", @@ -364,8 +298,6 @@ func TestClustersFromSnapshot(t *testing.T) { }) }, nil) }, - // TODO(proxystate): requires custom cluster work - alsoRunTestForV2: false, }, { name: "custom-upstream-ignores-tls", @@ -380,46 +312,6 @@ func TestClustersFromSnapshot(t *testing.T) { }) }, nil) }, - // TODO(proxystate): requires custom cluster work - alsoRunTestForV2: false, - }, - { - name: "custom-upstream-with-prepared-query", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - for i := range ns.Proxy.Upstreams { - - switch ns.Proxy.Upstreams[i].DestinationName { - case "db": - if ns.Proxy.Upstreams[i].Config == nil { - ns.Proxy.Upstreams[i].Config = map[string]interface{}{} - } - - uid := proxycfg.NewUpstreamID(&ns.Proxy.Upstreams[i]) - - // Triggers an override with the presence of the escape hatch listener - ns.Proxy.Upstreams[i].DestinationType = structs.UpstreamDestTypePreparedQuery - - ns.Proxy.Upstreams[i].Config["envoy_cluster_json"] = - customClusterJSON(t, customClusterJSONOptions{ - Name: uid.EnvoyID() + ":custom-upstream", - }) - - // Also test that http2 options are triggered. - // A separate upstream without an override is required to test - case "geo-cache": - if ns.Proxy.Upstreams[i].Config == nil { - ns.Proxy.Upstreams[i].Config = map[string]interface{}{} - } - ns.Proxy.Upstreams[i].Config["protocol"] = "http2" - default: - continue - } - } - }, nil) - }, - // TODO(proxystate): requires custom cluster work - alsoRunTestForV2: false, }, { name: "custom-timeouts", @@ -429,7 +321,6 @@ func TestClustersFromSnapshot(t *testing.T) { ns.Proxy.Upstreams[0].Config["connect_timeout_ms"] = 2345 }, nil) }, - alsoRunTestForV2: true, }, { name: "custom-passive-healthcheck", @@ -444,22 +335,6 @@ func TestClustersFromSnapshot(t *testing.T) { } }, nil) }, - alsoRunTestForV2: true, - }, - { - name: "custom-passive-healthcheck-zero-consecutive_5xx", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - ns.Proxy.Upstreams[0].Config["passive_health_check"] = map[string]interface{}{ - "enforcing_consecutive_5xx": float64(0), - "max_failures": float64(5), - "interval": float64(10 * time.Second), - "max_ejection_percent": float64(100), - "base_ejection_time": float64(10 * time.Second), - } - }, nil) - }, - alsoRunTestForV2: true, }, { name: "custom-max-inbound-connections", @@ -468,7 +343,6 @@ func TestClustersFromSnapshot(t *testing.T) { ns.Proxy.Config["max_inbound_connections"] = 3456 }, nil) }, - alsoRunTestForV2: true, }, { name: "custom-limits-max-connections-only", @@ -489,7 +363,6 @@ func TestClustersFromSnapshot(t *testing.T) { } }, nil) }, - alsoRunTestForV2: true, }, { name: "custom-limits-set-to-zero", @@ -508,7 +381,6 @@ func TestClustersFromSnapshot(t *testing.T) { } }, nil) }, - alsoRunTestForV2: true, }, { name: "custom-limits", @@ -527,14 +399,12 @@ func TestClustersFromSnapshot(t *testing.T) { } }, nil) }, - alsoRunTestForV2: true, }, { name: "expose-paths-local-app-paths", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotExposeConfig(t, nil) }, - alsoRunTestForV2: true, }, { name: "downstream-service-with-unix-sockets", @@ -547,7 +417,6 @@ func TestClustersFromSnapshot(t *testing.T) { ns.Proxy.LocalServiceSocketPath = "/tmp/downstream_proxy.sock" }, nil) }, - alsoRunTestForV2: true, }, { name: "expose-paths-new-cluster-http2", @@ -561,89 +430,58 @@ func TestClustersFromSnapshot(t *testing.T) { } }) }, - alsoRunTestForV2: true, - }, - { - name: "expose-checks", - create: proxycfg.TestConfigSnapshotExposeChecks, - alsoRunTestForV2: true, }, { - name: "expose-paths-grpc-new-cluster-http1", - create: proxycfg.TestConfigSnapshotGRPCExposeHTTP1, - alsoRunTestForV2: true, + name: "expose-paths-grpc-new-cluster-http1", + create: proxycfg.TestConfigSnapshotGRPCExposeHTTP1, }, { name: "mesh-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "default", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-using-federation-states", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "federation-states", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, - }, - { - name: "mesh-gateway-using-federation-control-plane", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotMeshGateway(t, "mesh-gateway-federation", nil, nil) - }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-no-services", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "no-services", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-service-subsets", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "service-subsets", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-ignore-extra-resolvers", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "ignore-extra-resolvers", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-service-timeouts", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "service-timeouts", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-non-hash-lb-injected", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "non-hash-lb-injected", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-hash-lb-ignored", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "hash-lb-ignored", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-tcp-keepalives", @@ -655,8 +493,6 @@ func TestClustersFromSnapshot(t *testing.T) { ns.Proxy.Config["envoy_gateway_remote_tcp_keepalive_probes"] = 7 }, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway", @@ -664,16 +500,12 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "default", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway-nil-config-entry", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotIngressGateway_NilConfigEntry(t) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway-with-tls-outgoing-min-version", @@ -693,8 +525,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway-with-tls-outgoing-max-version", @@ -714,8 +544,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway-with-tls-outgoing-cipher-suites", @@ -738,8 +566,6 @@ func TestClustersFromSnapshot(t *testing.T) { }, }) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway-no-services", @@ -747,8 +573,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, false, "tcp", "default", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain", @@ -756,8 +580,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "simple", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-service-max-connections", @@ -768,8 +590,6 @@ func TestClustersFromSnapshot(t *testing.T) { entry.Listeners[0].Services[0].MaxConnections = 4096 }, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-defaults-service-max-connections", @@ -784,8 +604,6 @@ func TestClustersFromSnapshot(t *testing.T) { } }, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-overwrite-defaults-service-max-connections", @@ -801,8 +619,6 @@ func TestClustersFromSnapshot(t *testing.T) { entry.Listeners[0].Services[0].MaxPendingRequests = 2048 }, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-service-passive-health-check", @@ -812,14 +628,11 @@ func TestClustersFromSnapshot(t *testing.T) { func(entry *structs.IngressGatewayConfigEntry) { entry.Listeners[0].Services[0].MaxConnections = 4096 entry.Listeners[0].Services[0].PassiveHealthCheck = &structs.PassiveHealthCheck{ - Interval: 5000000000, - MaxFailures: 10, - MaxEjectionPercent: uint32ptr(90), + Interval: 5000000000, + MaxFailures: 10, } }, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-defaults-passive-health-check", @@ -836,13 +649,10 @@ func TestClustersFromSnapshot(t *testing.T) { Interval: 5000000000, MaxFailures: 10, EnforcingConsecutive5xx: &enforcingConsecutive5xx, - MaxEjectionPercent: uint32ptr(90), }, } }, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-overwrite-defaults-passive-health-check", @@ -857,7 +667,6 @@ func TestClustersFromSnapshot(t *testing.T) { PassiveHealthCheck: &structs.PassiveHealthCheck{ Interval: 5000000000, EnforcingConsecutive5xx: &defaultEnforcingConsecutive5xx, - MaxEjectionPercent: uint32ptr(80), }, } enforcingConsecutive5xx := uint32(50) @@ -866,13 +675,9 @@ func TestClustersFromSnapshot(t *testing.T) { entry.Listeners[0].Services[0].PassiveHealthCheck = &structs.PassiveHealthCheck{ Interval: 8000000000, EnforcingConsecutive5xx: &enforcingConsecutive5xx, - MaxEjectionPercent: uint32ptr(90), - BaseEjectionTime: durationPtr(12 * time.Second), } }, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-external-sni", @@ -880,8 +685,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "external-sni", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-and-failover", @@ -889,8 +692,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-and-failover-to-cluster-peer", @@ -898,8 +699,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-to-cluster-peer", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-failover-through-remote-gateway", @@ -907,8 +706,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-remote-gateway", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-failover-through-remote-gateway-triggered", @@ -916,8 +713,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-remote-gateway-triggered", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-double-failover-through-remote-gateway", @@ -925,8 +720,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-double-remote-gateway", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered", @@ -934,8 +727,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-double-remote-gateway-triggered", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-failover-through-local-gateway", @@ -943,8 +734,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-local-gateway", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-failover-through-local-gateway-triggered", @@ -952,8 +741,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-local-gateway-triggered", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-double-failover-through-local-gateway", @@ -961,8 +748,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-double-local-gateway", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-double-failover-through-local-gateway-triggered", @@ -970,8 +755,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-double-local-gateway-triggered", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-splitter-with-resolver-redirect", @@ -979,8 +762,6 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "http", "splitter-with-resolver-redirect-multidc", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-lb-in-resolver", @@ -988,66 +769,46 @@ func TestClustersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "http", "lb-resolver", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotTerminatingGateway(t, true, nil, nil) }, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-no-services", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotTerminatingGateway(t, false, nil, nil) }, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-service-subsets", create: proxycfg.TestConfigSnapshotTerminatingGatewayServiceSubsetsWebAndCache, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-hostname-service-subsets", create: proxycfg.TestConfigSnapshotTerminatingGatewayHostnameSubsets, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-sni", create: proxycfg.TestConfigSnapshotTerminatingGatewaySNI, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-http2-upstream", create: proxycfg.TestConfigSnapshotTerminatingGatewayHTTP2, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-http2-upstream-subsets", create: proxycfg.TestConfigSnapshotTerminatingGatewaySubsetsHTTP2, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-ignore-extra-resolvers", create: proxycfg.TestConfigSnapshotTerminatingGatewayIgnoreExtraResolvers, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-lb-config", create: proxycfg.TestConfigSnapshotTerminatingGatewayLBConfigNoHashPolicies, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-tcp-keepalives", @@ -1062,24 +823,18 @@ func TestClustersFromSnapshot(t *testing.T) { ns.Proxy.Config["envoy_gateway_remote_tcp_keepalive_probes"] = 5 }, nil) }, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-multiple-listeners-duplicate-service", create: proxycfg.TestConfigSnapshotIngress_MultipleListenersDuplicateService, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { - name: "transparent-proxy-catalog-destinations-only", - create: proxycfg.TestConfigSnapshotTransparentProxyCatalogDestinationsOnly, - alsoRunTestForV2: true, + name: "transparent-proxy-catalog-destinations-only", + create: proxycfg.TestConfigSnapshotTransparentProxyCatalogDestinationsOnly, }, { - name: "transparent-proxy-dial-instances-directly", - create: proxycfg.TestConfigSnapshotTransparentProxyDialDirectly, - alsoRunTestForV2: true, + name: "transparent-proxy-dial-instances-directly", + create: proxycfg.TestConfigSnapshotTransparentProxyDialDirectly, }, } @@ -1111,10 +866,10 @@ func TestClustersFromSnapshot(t *testing.T) { return clusters[i].(*envoy_cluster_v3.Cluster).Name < clusters[j].(*envoy_cluster_v3.Cluster).Name }) - r, err := response.CreateResponse(xdscommon.ClusterType, "00000001", "00000001", clusters) + r, err := createResponse(xdscommon.ClusterType, "00000001", "00000001", clusters) require.NoError(t, err) - t.Run("current-xdsv1", func(t *testing.T) { + t.Run("current", func(t *testing.T) { gotJSON := protoToJSON(t, r) gName := tt.name @@ -1124,40 +879,6 @@ func TestClustersFromSnapshot(t *testing.T) { require.JSONEq(t, goldenEnvoy(t, filepath.Join("clusters", gName), envoyVersion, latestEnvoyVersion, gotJSON), gotJSON) }) - - if tt.alsoRunTestForV2 { - generator := xdsv2.NewResourceGenerator(testutil.Logger(t)) - - converter := proxystateconverter.NewConverter(testutil.Logger(t), &mockCfgFetcher{addressLan: "10.10.10.10"}) - proxyState, err := converter.ProxyStateFromSnapshot(snap) - require.NoError(t, err) - - res, err := generator.AllResourcesFromIR(proxyState) - require.NoError(t, err) - - clusters = res[xdscommon.ClusterType] - - // The order of clusters returned via CDS isn't relevant, so it's safe - // to sort these for the purposes of test comparisons. - sort.Slice(clusters, func(i, j int) bool { - return clusters[i].(*envoy_cluster_v3.Cluster).Name < clusters[j].(*envoy_cluster_v3.Cluster).Name - }) - - r, err := response.CreateResponse(xdscommon.ClusterType, "00000001", "00000001", clusters) - require.NoError(t, err) - - t.Run("current-xdsv2", func(t *testing.T) { - gotJSON := protoToJSON(t, r) - - gName := tt.name - if tt.overrideGoldenName != "" { - gName = tt.overrideGoldenName - } - - expectedJSON := goldenEnvoy(t, filepath.Join("clusters", gName), envoyVersion, latestEnvoyVersion, gotJSON) - require.JSONEq(t, expectedJSON, gotJSON) - }) - } }) } }) @@ -1213,41 +934,6 @@ func customAppClusterJSON(t testinf.T, opts customClusterJSONOptions) string { return buf.String() } -var customClusterJSONTpl = `{ - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "{{ .Name }}", - "connectTimeout": "15s", - "loadAssignment": { - "clusterName": "{{ .Name }}", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8443 - } - } - } - } - ] - } - ] - } -}` - -var customClusterJSONTemplate = template.Must(template.New("").Parse(customClusterJSONTpl)) - -func customClusterJSON(t testinf.T, opts customClusterJSONOptions) string { - t.Helper() - var buf bytes.Buffer - err := customClusterJSONTemplate.Execute(&buf, opts) - require.NoError(t, err) - return buf.String() -} - func TestEnvoyLBConfig_InjectToCluster(t *testing.T) { var tests = []struct { name string diff --git a/agent/xds/config/config.go b/agent/xds/config.go similarity index 98% rename from agent/xds/config/config.go rename to agent/xds/config.go index 32c46d07d3ef6..967bcb213dec5 100644 --- a/agent/xds/config/config.go +++ b/agent/xds/config.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 -package config +package xds import ( "strings" @@ -229,9 +229,9 @@ func ToOutlierDetection(p *structs.PassiveHealthCheck, override *structs.Passive // NOTE: EnforcingConsecutive5xx must be great than 0 for ingress-gateway if *override.EnforcingConsecutive5xx != 0 { od.EnforcingConsecutive_5Xx = &wrapperspb.UInt32Value{Value: *override.EnforcingConsecutive5xx} + } else if allowZero { + od.EnforcingConsecutive_5Xx = &wrapperspb.UInt32Value{Value: *override.EnforcingConsecutive5xx} } - // Because only ingress gateways have overrides and they cannot have a value of 0, there is no allowZero - // override case to handle } if override.MaxEjectionPercent != nil { diff --git a/agent/xds/config/config_test.go b/agent/xds/config_test.go similarity index 99% rename from agent/xds/config/config_test.go rename to agent/xds/config_test.go index 72e9a0e614614..e544c30b393e2 100644 --- a/agent/xds/config/config_test.go +++ b/agent/xds/config_test.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 -package config +package xds import ( "testing" diff --git a/agent/xds/configfetcher/config_fetcher.go b/agent/xds/configfetcher/config_fetcher.go deleted file mode 100644 index db7d4f2035d23..0000000000000 --- a/agent/xds/configfetcher/config_fetcher.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package configfetcher - -// ConfigFetcher is the interface the agent needs to expose -// for the xDS server to fetch agent config, currently only one field is fetched -type ConfigFetcher interface { - AdvertiseAddrLAN() string -} diff --git a/agent/xds/delta.go b/agent/xds/delta.go index f5d07e2763ae8..15c59193e626c 100644 --- a/agent/xds/delta.go +++ b/agent/xds/delta.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -19,6 +19,7 @@ import ( envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" "github.com/hashicorp/go-hclog" goversion "github.com/hashicorp/go-version" + "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -28,16 +29,11 @@ import ( external "github.com/hashicorp/consul/agent/grpc-external" "github.com/hashicorp/consul/agent/grpc-external/limiter" "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/xds/configfetcher" + "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/xds/extensionruntime" - "github.com/hashicorp/consul/agent/xdsv2" "github.com/hashicorp/consul/envoyextensions/extensioncommon" "github.com/hashicorp/consul/envoyextensions/xdscommon" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" "github.com/hashicorp/consul/logging" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/version" ) @@ -88,39 +84,6 @@ func (s *Server) DeltaAggregatedResources(stream ADSDeltaStream) error { return err } -// getEnvoyConfiguration is a utility function that instantiates the proper -// Envoy resource generator based on whether it was passed a ConfigSource or -// ProxyState implementation of the ProxySnapshot interface and returns the -// generated Envoy configuration. -func getEnvoyConfiguration(proxySnapshot proxysnapshot.ProxySnapshot, logger hclog.Logger, cfgFetcher configfetcher.ConfigFetcher) (map[string][]proto.Message, error) { - switch proxySnapshot.(type) { - case *proxycfg.ConfigSnapshot: - logger.Trace("ProxySnapshot update channel received a ProxySnapshot of type ConfigSnapshot") - generator := NewResourceGenerator( - logger, - cfgFetcher, - true, - ) - - c := proxySnapshot.(*proxycfg.ConfigSnapshot) - return generator.AllResourcesFromSnapshot(c) - case *proxytracker.ProxyState: - logger.Trace("ProxySnapshot update channel received a ProxySnapshot of type ProxyState") - generator := xdsv2.NewResourceGenerator( - logger, - ) - c := proxySnapshot.(*proxytracker.ProxyState) - resources, err := generator.AllResourcesFromIR(c) - if err != nil { - logger.Error("error generating resources from proxy state template", "err", err) - return nil, err - } - return resources, nil - default: - return nil, errors.New("proxysnapshot must be of type ProxyState or ConfigSnapshot") - } -} - const ( stateDeltaInit int = iota stateDeltaPendingInitialConfig @@ -135,13 +98,14 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove // Loop state var ( - proxySnapshot proxysnapshot.ProxySnapshot - node *envoy_config_core_v3.Node - stateCh <-chan proxysnapshot.ProxySnapshot - drainCh limiter.SessionTerminatedChan - watchCancel func() - nonce uint64 // xDS requires a unique nonce to correlate response/request pairs - ready bool // set to true after the first snapshot arrives + cfgSnap *proxycfg.ConfigSnapshot + node *envoy_config_core_v3.Node + stateCh <-chan *proxycfg.ConfigSnapshot + drainCh limiter.SessionTerminatedChan + watchCancel func() + proxyID structs.ServiceID + nonce uint64 // xDS requires a unique nonce to correlate response/request pairs + ready bool // set to true after the first snapshot arrives streamStartTime = time.Now() streamStartOnce sync.Once @@ -153,30 +117,42 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove // type => name => proto resourceMap = xdscommon.EmptyIndexedResources() - // currentVersions is the xDS versioning represented by Resources. + // currentVersions is the the xDS versioning represented by Resources. // // type => name => version (as consul knows right now) currentVersions = make(map[string]map[string]string) ) - logger := s.Logger.Named(logging.XDS).With("xdsVersion", "v3") + generator := NewResourceGenerator( + s.Logger.Named(logging.XDS).With("xdsVersion", "v3"), + s.CfgFetcher, + true, + ) // need to run a small state machine to get through initial authentication. var state = stateDeltaInit // Configure handlers for each type of request we currently care about. handlers := map[string]*xDSDeltaType{ - xdscommon.ListenerType: newDeltaType(logger, stream, xdscommon.ListenerType, func() bool { - return proxySnapshot.AllowEmptyListeners() + xdscommon.ListenerType: newDeltaType(generator, stream, xdscommon.ListenerType, func(kind structs.ServiceKind) bool { + // Ingress and API gateways are allowed to inform LDS of no listeners. + return cfgSnap.Kind == structs.ServiceKindIngressGateway || + cfgSnap.Kind == structs.ServiceKindAPIGateway }), - xdscommon.RouteType: newDeltaType(logger, stream, xdscommon.RouteType, func() bool { - return proxySnapshot.AllowEmptyRoutes() + xdscommon.RouteType: newDeltaType(generator, stream, xdscommon.RouteType, func(kind structs.ServiceKind) bool { + // Ingress and API gateways are allowed to inform RDS of no routes. + return cfgSnap.Kind == structs.ServiceKindIngressGateway || + cfgSnap.Kind == structs.ServiceKindAPIGateway }), - xdscommon.ClusterType: newDeltaType(logger, stream, xdscommon.ClusterType, func() bool { - return proxySnapshot.AllowEmptyClusters() + xdscommon.ClusterType: newDeltaType(generator, stream, xdscommon.ClusterType, func(kind structs.ServiceKind) bool { + // Mesh, Ingress, API and Terminating gateways are allowed to inform CDS of no clusters. + return cfgSnap.Kind == structs.ServiceKindMeshGateway || + cfgSnap.Kind == structs.ServiceKindTerminatingGateway || + cfgSnap.Kind == structs.ServiceKindIngressGateway || + cfgSnap.Kind == structs.ServiceKindAPIGateway }), - xdscommon.EndpointType: newDeltaType(logger, stream, xdscommon.EndpointType, nil), - xdscommon.SecretType: newDeltaType(logger, stream, xdscommon.SecretType, nil), // TODO allowEmptyFn + xdscommon.EndpointType: newDeltaType(generator, stream, xdscommon.EndpointType, nil), + xdscommon.SecretType: newDeltaType(generator, stream, xdscommon.SecretType, nil), // TODO allowEmptyFn } // Endpoints are stored within a Cluster (and Routes @@ -202,19 +178,19 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove authTimer = time.After(s.AuthCheckFrequency) } - checkStreamACLs := func(proxySnap proxysnapshot.ProxySnapshot) error { - return s.authorize(stream.Context(), proxySnap) + checkStreamACLs := func(cfgSnap *proxycfg.ConfigSnapshot) error { + return s.authorize(stream.Context(), cfgSnap) } for { select { case <-drainCh: - logger.Debug("draining stream to rebalance load") + generator.Logger.Debug("draining stream to rebalance load") metrics.IncrCounter([]string{"xds", "server", "streamDrained"}, 1) return errOverwhelmed case <-authTimer: // It's been too long since a Discovery{Request,Response} so recheck ACLs. - if err := checkStreamACLs(proxySnapshot); err != nil { + if err := checkStreamACLs(cfgSnap); err != nil { return err } extendAuthTimer() @@ -228,29 +204,28 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove return nil } - logTraceRequest(logger, "Incremental xDS v3", req) + generator.logTraceRequest("Incremental xDS v3", req) if req.TypeUrl == "" { return status.Errorf(codes.InvalidArgument, "type URL is required for ADS") } - var proxyFeatures xdscommon.SupportedProxyFeatures if node == nil && req.Node != nil { node = req.Node var err error - proxyFeatures, err = xdscommon.DetermineSupportedProxyFeatures(req.Node) + generator.ProxyFeatures, err = xdscommon.DetermineSupportedProxyFeatures(req.Node) if err != nil { return status.Errorf(codes.InvalidArgument, err.Error()) } } if handler, ok := handlers[req.TypeUrl]; ok { - switch handler.Recv(req, proxyFeatures) { + switch handler.Recv(req, generator.ProxyFeatures) { case deltaRecvNewSubscription: - logger.Trace("subscribing to type", "typeUrl", req.TypeUrl) + generator.Logger.Trace("subscribing to type", "typeUrl", req.TypeUrl) case deltaRecvResponseNack: - logger.Trace("got nack response for type", "typeUrl", req.TypeUrl) + generator.Logger.Trace("got nack response for type", "typeUrl", req.TypeUrl) // There is no reason to believe that generating new xDS resources from the same snapshot // would lead to an ACK from Envoy. Instead we continue to the top of this for loop and wait @@ -269,21 +244,21 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove // would've already exited this loop. return status.Error(codes.Aborted, "xDS stream terminated due to an irrecoverable error, please try again") } - proxySnapshot = cs + cfgSnap = cs - newRes, err := getEnvoyConfiguration(proxySnapshot, logger, s.CfgFetcher) + newRes, err := generator.AllResourcesFromSnapshot(cfgSnap) if err != nil { return status.Errorf(codes.Unavailable, "failed to generate all xDS resources from the snapshot: %v", err) } // index and hash the xDS structures - newResourceMap := xdscommon.IndexResources(logger, newRes) + newResourceMap := xdscommon.IndexResources(generator.Logger, newRes) if s.ResourceMapMutateFn != nil { s.ResourceMapMutateFn(newResourceMap) } - if newResourceMap, err = s.applyEnvoyExtensions(newResourceMap, proxySnapshot, node); err != nil { + if newResourceMap, err = s.applyEnvoyExtensions(newResourceMap, cfgSnap, node); err != nil { // err is already the result of calling status.Errorf return err } @@ -317,7 +292,7 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove } // Start authentication process, we need the proxyID - proxyID := newResourceIDFromEnvoyNode(node) + proxyID = structs.NewServiceID(node.Id, parseEnterpriseMeta(node)) // Start watching config for that proxy var err error @@ -326,12 +301,12 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove return status.Errorf(codes.Internal, "failed to watch proxy service: %s", err) } - stateCh, drainCh, watchCancel, err = s.ProxyWatcher.Watch(proxyID, nodeName, options.Token) + stateCh, drainCh, watchCancel, err = s.CfgSrc.Watch(proxyID, nodeName, options.Token) switch { case errors.Is(err, limiter.ErrCapacityReached): return errOverwhelmed case err != nil: - return status.Errorf(codes.Internal, "failed to watch proxy: %s", err) + return status.Errorf(codes.Internal, "failed to watch proxy service: %s", err) } // Note that in this case we _intend_ the defer to only be triggered when // this whole process method ends (i.e. when streaming RPC aborts) not at @@ -340,14 +315,14 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove // state machine. defer watchCancel() - logger = logger.With("service_id", proxyID.Name) // enhance future logs + generator.Logger = generator.Logger.With("service_id", proxyID.String()) // enhance future logs - logger.Trace("watching proxy, pending initial proxycfg snapshot for xDS") + generator.Logger.Trace("watching proxy, pending initial proxycfg snapshot for xDS") // Now wait for the config so we can check ACL state = stateDeltaPendingInitialConfig case stateDeltaPendingInitialConfig: - if proxySnapshot == nil { + if cfgSnap == nil { // Nothing we can do until we get the initial config continue } @@ -356,18 +331,23 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove state = stateDeltaRunning // Upgrade the logger - loggerName := proxySnapshot.LoggerName() - if loggerName != "" { - logger = logger.Named(loggerName) + switch cfgSnap.Kind { + case structs.ServiceKindConnectProxy: + case structs.ServiceKindTerminatingGateway: + generator.Logger = generator.Logger.Named(logging.TerminatingGateway) + case structs.ServiceKindMeshGateway: + generator.Logger = generator.Logger.Named(logging.MeshGateway) + case structs.ServiceKindIngressGateway: + generator.Logger = generator.Logger.Named(logging.IngressGateway) } - logger.Trace("Got initial config snapshot") + generator.Logger.Trace("Got initial config snapshot") // Let's actually process the config we just got, or we'll miss responding fallthrough case stateDeltaRunning: // Check ACLs on every Discovery{Request,Response}. - if err := checkStreamACLs(proxySnapshot); err != nil { + if err := checkStreamACLs(cfgSnap); err != nil { return err } // For the first time through the state machine, this is when the @@ -375,11 +355,11 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove extendAuthTimer() if !ready { - logger.Trace("Skipping delta computation because we haven't gotten a snapshot yet") + generator.Logger.Trace("Skipping delta computation because we haven't gotten a snapshot yet") continue } - logger.Trace("Invoking all xDS resource handlers and sending changed data if there are any") + generator.Logger.Trace("Invoking all xDS resource handlers and sending changed data if there are any") streamStartOnce.Do(func() { metrics.MeasureSince([]string{"xds", "server", "streamStart"}, streamStartTime) @@ -388,7 +368,7 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove for _, op := range xDSUpdateOrder { if op.TypeUrl == xdscommon.ListenerType || op.TypeUrl == xdscommon.RouteType { if clusterHandler := handlers[xdscommon.ClusterType]; clusterHandler.registered && len(clusterHandler.pendingUpdates) > 0 { - logger.Trace("Skipping delta computation for resource because there are dependent updates pending", + generator.Logger.Trace("Skipping delta computation for resource because there are dependent updates pending", "typeUrl", op.TypeUrl, "dependent", xdscommon.ClusterType) // Receiving an ACK from Envoy will unblock the select statement above, @@ -396,7 +376,7 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove break } if endpointHandler := handlers[xdscommon.EndpointType]; endpointHandler.registered && len(endpointHandler.pendingUpdates) > 0 { - logger.Trace("Skipping delta computation for resource because there are dependent updates pending", + generator.Logger.Trace("Skipping delta computation for resource because there are dependent updates pending", "typeUrl", op.TypeUrl, "dependent", xdscommon.EndpointType) // Receiving an ACK from Envoy will unblock the select statement above, @@ -404,7 +384,14 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove break } } - err, _ := handlers[op.TypeUrl].SendIfNew(currentVersions[op.TypeUrl], resourceMap, &nonce, op.Upsert, op.Remove) + err, _ := handlers[op.TypeUrl].SendIfNew( + cfgSnap.Kind, + currentVersions[op.TypeUrl], + resourceMap, + &nonce, + op.Upsert, + op.Remove, + ) if err != nil { return status.Errorf(codes.Unavailable, "failed to send %sreply for type %q: %v", @@ -416,37 +403,7 @@ func (s *Server) processDelta(stream ADSDeltaStream, reqCh <-chan *envoy_discove } } -// newResourceIDFromEnvoyNode is a utility function that allows creating a -// Resource ID from an Envoy proxy node so that existing delta calls can easily -// use ProxyWatcher interface arguments for Watch(). -func newResourceIDFromEnvoyNode(node *envoy_config_core_v3.Node) *pbresource.ID { - entMeta := parseEnterpriseMeta(node) - - return &pbresource.ID{ - Name: node.Id, - Tenancy: &pbresource.Tenancy{ - Namespace: entMeta.NamespaceOrDefault(), - Partition: entMeta.PartitionOrDefault(), - }, - Type: pbmesh.ProxyStateTemplateType, - } -} - -func (s *Server) applyEnvoyExtensions(resources *xdscommon.IndexedResources, proxySnapshot proxysnapshot.ProxySnapshot, node *envoy_config_core_v3.Node) (*xdscommon.IndexedResources, error) { - // TODO(proxystate) - // This is a workaround for now as envoy extensions are not yet supported with ProxyState. - // For now, we cast to proxycfg.ConfigSnapshot and no-op if it's the pbmesh.ProxyState type. - var snapshot *proxycfg.ConfigSnapshot - switch proxySnapshot.(type) { - //TODO(proxystate): implement envoy extensions for ProxyState - case *proxytracker.ProxyState: - return resources, nil - case *proxycfg.ConfigSnapshot: - snapshot = proxySnapshot.(*proxycfg.ConfigSnapshot) - default: - return nil, status.Errorf(codes.InvalidArgument, - "unsupported config snapshot type to apply envoy extensions to %T", proxySnapshot) - } +func (s *Server) applyEnvoyExtensions(resources *xdscommon.IndexedResources, cfgSnap *proxycfg.ConfigSnapshot, node *envoy_config_core_v3.Node) (*xdscommon.IndexedResources, error) { var err error envoyVersion := xdscommon.DetermineEnvoyVersionFromNode(node) consulVersion, err := goversion.NewVersion(version.Version) @@ -455,10 +412,10 @@ func (s *Server) applyEnvoyExtensions(resources *xdscommon.IndexedResources, pro return nil, status.Errorf(codes.InvalidArgument, "failed to parse Consul version") } - serviceConfigs := extensionruntime.GetRuntimeConfigurations(snapshot) + serviceConfigs := extensionruntime.GetRuntimeConfigurations(cfgSnap) for _, cfgs := range serviceConfigs { for _, cfg := range cfgs { - resources, err = validateAndApplyEnvoyExtension(s.Logger, snapshot, resources, cfg, envoyVersion, consulVersion) + resources, err = validateAndApplyEnvoyExtension(s.Logger, cfgSnap, resources, cfg, envoyVersion, consulVersion) if err != nil { return nil, err @@ -668,10 +625,10 @@ type xDSDeltaChild struct { } type xDSDeltaType struct { - logger hclog.Logger + generator *ResourceGenerator stream ADSDeltaStream typeURL string - allowEmptyFn func() bool + allowEmptyFn func(kind structs.ServiceKind) bool // deltaChild contains data for an xDS child type if there is one. // For example, endpoints are a child type of clusters. @@ -720,13 +677,13 @@ type PendingUpdate struct { } func newDeltaType( - logger hclog.Logger, + generator *ResourceGenerator, stream ADSDeltaStream, typeUrl string, - allowEmptyFn func() bool, + allowEmptyFn func(kind structs.ServiceKind) bool, ) *xDSDeltaType { return &xDSDeltaType{ - logger: logger, + generator: generator, stream: stream, typeURL: typeUrl, allowEmptyFn: allowEmptyFn, @@ -743,6 +700,7 @@ func (t *xDSDeltaType) Recv(req *envoy_discovery_v3.DeltaDiscoveryRequest, sf xd if t == nil { return deltaRecvUnknownType // not something we care about } + logger := t.generator.Logger.With("typeUrl", t.typeURL) registeredThisTime := false if !t.registered { @@ -779,10 +737,10 @@ func (t *xDSDeltaType) Recv(req *envoy_discovery_v3.DeltaDiscoveryRequest, sf xd response_nonce, with presence of error_detail making it a NACK). */ if req.ErrorDetail == nil { - t.logger.Trace("got ok response from envoy proxy", "nonce", req.ResponseNonce) + logger.Trace("got ok response from envoy proxy", "nonce", req.ResponseNonce) t.ack(req.ResponseNonce) } else { - t.logger.Error("got error response from envoy proxy", "nonce", req.ResponseNonce, + logger.Error("got error response from envoy proxy", "nonce", req.ResponseNonce, "error", status.ErrorProto(req.ErrorDetail)) t.nack(req.ResponseNonce) return deltaRecvResponseNack @@ -798,7 +756,7 @@ func (t *xDSDeltaType) Recv(req *envoy_discovery_v3.DeltaDiscoveryRequest, sf xd the client already possesses, using the initial_resource_versions field. */ - t.logger.Trace("setting initial resource versions for stream", + logger.Trace("setting initial resource versions for stream", "resources", req.InitialResourceVersions) t.resourceVersions = req.InitialResourceVersions if !t.wildcard { @@ -849,9 +807,9 @@ func (t *xDSDeltaType) Recv(req *envoy_discovery_v3.DeltaDiscoveryRequest, sf xd } if alreadySubscribed { - t.logger.Trace("re-subscribing resource for stream", "resource", name) + logger.Trace("re-subscribing resource for stream", "resource", name) } else { - t.logger.Trace("subscribing resource for stream", "resource", name) + logger.Trace("subscribing resource for stream", "resource", name) } } @@ -860,7 +818,7 @@ func (t *xDSDeltaType) Recv(req *envoy_discovery_v3.DeltaDiscoveryRequest, sf xd continue } delete(t.subscriptions, name) - t.logger.Trace("unsubscribing resource for stream", "resource", name) + logger.Trace("unsubscribing resource for stream", "resource", name) // NOTE: we'll let the normal differential comparison handle cleaning up resourceVersions } } @@ -894,6 +852,7 @@ func (t *xDSDeltaType) nack(nonce string) { } func (t *xDSDeltaType) SendIfNew( + kind structs.ServiceKind, currentVersions map[string]string, // type => name => version (as consul knows right now) resourceMap *xdscommon.IndexedResources, nonce *uint64, @@ -908,9 +867,9 @@ func (t *xDSDeltaType) SendIfNew( return nil, false } - logger := t.logger.With("typeUrl", t.typeURL) + logger := t.generator.Logger.With("typeUrl", t.typeURL) - allowEmpty := t.allowEmptyFn != nil && t.allowEmptyFn() + allowEmpty := t.allowEmptyFn != nil && t.allowEmptyFn(kind) // Zero length resource responses should be ignored and are the result of no // data yet. Notice that this caused a bug originally where we had zero @@ -935,7 +894,7 @@ func (t *xDSDeltaType) SendIfNew( *nonce++ resp.Nonce = fmt.Sprintf("%08x", *nonce) - logTraceResponse(t.logger, "Incremental xDS v3", resp) + t.generator.logTraceResponse("Incremental xDS v3", resp) logger.Trace("sending response", "nonce", resp.Nonce) if err := t.stream.Send(resp); err != nil { @@ -1087,7 +1046,7 @@ func (t *xDSDeltaType) ensureChildResend(parentName, childName string) { return } - t.logger.Trace( + t.generator.Logger.Trace( "triggering implicit update of resource", "typeUrl", t.typeURL, "resource", parentName, diff --git a/agent/xds/delta_envoy_extender_ce_test.go b/agent/xds/delta_envoy_extender_ce_test.go index 30ebd9184b37c..10411e353cec5 100644 --- a/agent/xds/delta_envoy_extender_ce_test.go +++ b/agent/xds/delta_envoy_extender_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package xds @@ -9,7 +10,6 @@ import ( "path/filepath" "sort" "testing" - "time" envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" @@ -21,12 +21,12 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" + "github.com/hashicorp/consul/agent/xds/testcommon" + propertyoverride "github.com/hashicorp/consul/agent/envoyextensions/builtin/property-override" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/xds/extensionruntime" - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/agent/xds/testcommon" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/envoyextensions/extensioncommon" "github.com/hashicorp/consul/envoyextensions/xdscommon" @@ -720,52 +720,6 @@ end`, }, nil) }, }, - { - // Insert an OpenTelemetry access logging extension - name: "otel-access-logging-http", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - ns.Proxy.Config = map[string]any{"protocol": "http"} - ns.Proxy.EnvoyExtensions = []structs.EnvoyExtension{ - { - Name: "builtin/otel-access-logging", - Arguments: map[string]any{ - "Config": map[string]any{ - "LogName": "otel-logger", - "GrpcService": map[string]any{ - "Target": map[string]any{ - "Service": map[string]any{ - "Name": "db", - }, - }, - }, - "BufferFlushInterval": time.Millisecond, - "BufferSizeBytes": 4096, - "FilterStateObjectsToLog": []string{"obj-1", "obj-2"}, - "RetryPolicy": map[string]any{ - "RetryBackOff": map[string]any{ - "BaseInterval": time.Second, - "MaxInterval": 10 * time.Second, - }, - "NumRetries": 5, - }, - // Note: only test with one entry in Attributes and ResourceAttributes because - // they are maps and multiple entries results in the output order being - // non-deterministic. - "Attributes": map[string]any{ - "name": "Bugs Bunny", - }, - "ResourceAttributes": map[string]any{ - "type": "compute", - }, - }, - }, - Required: true, - }, - } - }, nil) - }, - }, } latestEnvoyVersion := xdscommon.EnvoyVersions[0] @@ -849,7 +803,7 @@ end`, } sort.Slice(msgs, entity.sorter(msgs)) - r, err := response.CreateResponse(entity.key, "00000001", "00000001", msgs) + r, err := createResponse(entity.key, "00000001", "00000001", msgs) require.NoError(t, err) t.Run(entity.name, func(t *testing.T) { diff --git a/agent/xds/delta_envoy_extender_test.go b/agent/xds/delta_envoy_extender_test.go index cfa762cb049ed..6cd57fa53a041 100644 --- a/agent/xds/delta_envoy_extender_test.go +++ b/agent/xds/delta_envoy_extender_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds diff --git a/agent/xds/delta_test.go b/agent/xds/delta_test.go index d93d06271bac2..052e72ad558d8 100644 --- a/agent/xds/delta_test.go +++ b/agent/xds/delta_test.go @@ -1,12 +1,11 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds import ( "errors" "fmt" - "github.com/hashicorp/consul/envoyextensions/xdscommon" "strconv" "strings" "sync" @@ -18,22 +17,24 @@ import ( envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" + "github.com/hashicorp/go-hclog" + goversion "github.com/hashicorp/go-version" + "github.com/stretchr/testify/require" + rpcstatus "google.golang.org/genproto/googleapis/rpc/status" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/grpc-external/limiter" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/envoyextensions/extensioncommon" + "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/version" - "github.com/hashicorp/go-hclog" - goversion "github.com/hashicorp/go-version" - "github.com/stretchr/testify/require" - rpcstatus "google.golang.org/genproto/googleapis/rpc/status" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" ) // NOTE: For these tests, prefer not using xDS protobuf "factory" methods if @@ -1695,12 +1696,6 @@ func Test_validateAndApplyEnvoyExtension_Validations(t *testing.T) { runtimeConfig: makeRuntimeConfig(false, ">= 1.15.0", ">= 1.25.0", map[string]interface{}{"bad": "args"}), err: false, }, - { - name: "valid everything - no resources and required", - runtimeConfig: makeRuntimeConfig(true, ">= 1.15.0", ">= 1.25.0", nil), - err: true, - errString: "failed to patch xDS resources in", - }, { name: "valid everything", runtimeConfig: makeRuntimeConfig(false, ">= 1.15.0", ">= 1.25.0", nil), diff --git a/agent/xds/endpoints.go b/agent/xds/endpoints.go index 2fb0a4a1df598..021f9ae23ef3d 100644 --- a/agent/xds/endpoints.go +++ b/agent/xds/endpoints.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -8,20 +8,17 @@ import ( "fmt" "strconv" - "github.com/hashicorp/go-hclog" - envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" + "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/go-bexpr" "google.golang.org/protobuf/proto" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/response" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/envoyextensions/xdscommon" ) const ( @@ -138,10 +135,7 @@ func (s *ResourceGenerator) endpointsFromSnapshotConnectProxy(cfgSnap *proxycfg. endpoints, ok := cfgSnap.ConnectProxy.PreparedQueryEndpoints[uid] if ok { la := makeLoadAssignment( - s.Logger, - cfgSnap, clusterName, - nil, []loadAssignmentEndpointGroup{ {Endpoints: endpoints}, }, @@ -164,10 +158,7 @@ func (s *ResourceGenerator) endpointsFromSnapshotConnectProxy(cfgSnap *proxycfg. endpoints, ok := cfgSnap.ConnectProxy.DestinationGateways.Get(uid) if ok { la := makeLoadAssignment( - s.Logger, - cfgSnap, name, - nil, []loadAssignmentEndpointGroup{ {Endpoints: endpoints}, }, @@ -233,10 +224,7 @@ func (s *ResourceGenerator) endpointsFromSnapshotMeshGateway(cfgSnap *proxycfg.C clusterName := connect.GatewaySNI(key.Datacenter, key.Partition, cfgSnap.Roots.TrustDomain) la := makeLoadAssignment( - s.Logger, - cfgSnap, clusterName, - nil, []loadAssignmentEndpointGroup{ {Endpoints: endpoints}, }, @@ -251,10 +239,7 @@ func (s *ResourceGenerator) endpointsFromSnapshotMeshGateway(cfgSnap *proxycfg.C clusterName := cfgSnap.ServerSNIFn(key.Datacenter, "") la := makeLoadAssignment( - s.Logger, - cfgSnap, clusterName, - nil, []loadAssignmentEndpointGroup{ {Endpoints: endpoints}, }, @@ -279,7 +264,7 @@ func (s *ResourceGenerator) endpointsFromSnapshotMeshGateway(cfgSnap *proxycfg.C lbEndpoint := &envoy_endpoint_v3.LbEndpoint{ HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress(addr, port), + Address: makeAddress(addr, port), }, }, HealthStatus: envoy_core_v3.HealthStatus_UNKNOWN, @@ -336,7 +321,7 @@ func (s *ResourceGenerator) endpointsFromSnapshotMeshGateway(cfgSnap *proxycfg.C serverEndpoints = append(serverEndpoints, &envoy_endpoint_v3.LbEndpoint{ HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress(addr, port), + Address: makeAddress(addr, port), }, }, }) @@ -424,10 +409,7 @@ func (s *ResourceGenerator) endpointsFromServicesAndResolvers( for subsetName, groups := range clusterEndpoints { clusterName := connect.ServiceSNI(svc.Name, subsetName, svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) la := makeLoadAssignment( - s.Logger, - cfgSnap, clusterName, - nil, groups, cfgSnap.Locality, ) @@ -462,10 +444,7 @@ func (s *ResourceGenerator) makeEndpointsForOutgoingPeeredServices( groups := []loadAssignmentEndpointGroup{{Endpoints: serviceGroup.Nodes, OnlyPassing: false}} la := makeLoadAssignment( - s.Logger, - cfgSnap, clusterName, - nil, groups, // Use an empty key here so that it never matches. This will force the mesh gateway to always // reference the remote mesh gateway's wan addr. @@ -585,7 +564,7 @@ func makeEndpoint(host string, port int) *envoy_endpoint_v3.LbEndpoint { return &envoy_endpoint_v3.LbEndpoint{ HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress(host, port), + Address: makeAddress(host, port), }, }, } @@ -595,7 +574,7 @@ func makePipeEndpoint(path string) *envoy_endpoint_v3.LbEndpoint { return &envoy_endpoint_v3.LbEndpoint{ HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakePipeAddress(path, 0), + Address: makePipeAddress(path, 0), }, }, } @@ -627,10 +606,7 @@ func (s *ResourceGenerator) makeUpstreamLoadAssignmentForPeerService( return la, nil } la = makeLoadAssignment( - s.Logger, - cfgSnap, clusterName, - nil, []loadAssignmentEndpointGroup{ {Endpoints: localGw}, }, @@ -650,10 +626,7 @@ func (s *ResourceGenerator) makeUpstreamLoadAssignmentForPeerService( return nil, nil } la = makeLoadAssignment( - s.Logger, - cfgSnap, clusterName, - nil, []loadAssignmentEndpointGroup{ {Endpoints: endpoints}, }, @@ -785,10 +758,7 @@ func (s *ResourceGenerator) endpointsFromDiscoveryChain( } la := makeLoadAssignment( - s.Logger, - cfgSnap, clusterName, - ti.PrioritizeByLocality, []loadAssignmentEndpointGroup{endpointGroup}, gatewayKey, ) @@ -874,66 +844,49 @@ type loadAssignmentEndpointGroup struct { OverrideHealth envoy_core_v3.HealthStatus } -func makeLoadAssignment(logger hclog.Logger, cfgSnap *proxycfg.ConfigSnapshot, clusterName string, policy *structs.DiscoveryPrioritizeByLocality, endpointGroups []loadAssignmentEndpointGroup, localKey proxycfg.GatewayKey) *envoy_endpoint_v3.ClusterLoadAssignment { +func makeLoadAssignment(clusterName string, endpointGroups []loadAssignmentEndpointGroup, localKey proxycfg.GatewayKey) *envoy_endpoint_v3.ClusterLoadAssignment { cla := &envoy_endpoint_v3.ClusterLoadAssignment{ ClusterName: clusterName, Endpoints: make([]*envoy_endpoint_v3.LocalityLbEndpoints, 0, len(endpointGroups)), } - setFullFailoverProvisioningFactor := len(endpointGroups) > 1 - - var priority uint32 - - for _, endpointGroup := range endpointGroups { - endpointsByLocality, err := groupedEndpoints(logger, cfgSnap.ServiceLocality, policy, endpointGroup.Endpoints) - - if err != nil { - continue - } - - if len(endpointsByLocality) > 1 { - setFullFailoverProvisioningFactor = true + if len(endpointGroups) > 1 { + cla.Policy = &envoy_endpoint_v3.ClusterLoadAssignment_Policy{ + // We choose such a large value here that the failover math should + // in effect not happen until zero instances are healthy. + OverprovisioningFactor: makeUint32Value(100000), } + } - for _, endpoints := range endpointsByLocality { - es := make([]*envoy_endpoint_v3.LbEndpoint, 0, len(endpointGroup.Endpoints)) + for priority, endpointGroup := range endpointGroups { + endpoints := endpointGroup.Endpoints + es := make([]*envoy_endpoint_v3.LbEndpoint, 0, len(endpoints)) - for _, ep := range endpoints { - // TODO (mesh-gateway) - should we respect the translate_wan_addrs configuration here or just always use the wan for cross-dc? - _, addr, port := ep.BestAddress(!localKey.Matches(ep.Node.Datacenter, ep.Node.PartitionOrDefault())) - healthStatus, weight := calculateEndpointHealthAndWeight(ep, endpointGroup.OnlyPassing) + for _, ep := range endpoints { + // TODO (mesh-gateway) - should we respect the translate_wan_addrs configuration here or just always use the wan for cross-dc? + _, addr, port := ep.BestAddress(!localKey.Matches(ep.Node.Datacenter, ep.Node.PartitionOrDefault())) + healthStatus, weight := calculateEndpointHealthAndWeight(ep, endpointGroup.OnlyPassing) - if endpointGroup.OverrideHealth != envoy_core_v3.HealthStatus_UNKNOWN { - healthStatus = endpointGroup.OverrideHealth - } - - endpoint := &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress(addr, port), - } - es = append(es, &envoy_endpoint_v3.LbEndpoint{ - HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ - Endpoint: endpoint, - }, - HealthStatus: healthStatus, - LoadBalancingWeight: response.MakeUint32Value(weight), - }) + if endpointGroup.OverrideHealth != envoy_core_v3.HealthStatus_UNKNOWN { + healthStatus = endpointGroup.OverrideHealth } - cla.Endpoints = append(cla.Endpoints, &envoy_endpoint_v3.LocalityLbEndpoints{ - Priority: priority, - LbEndpoints: es, + endpoint := &envoy_endpoint_v3.Endpoint{ + Address: makeAddress(addr, port), + } + es = append(es, &envoy_endpoint_v3.LbEndpoint{ + HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ + Endpoint: endpoint, + }, + HealthStatus: healthStatus, + LoadBalancingWeight: makeUint32Value(weight), }) - - priority++ } - } - if setFullFailoverProvisioningFactor { - cla.Policy = &envoy_endpoint_v3.ClusterLoadAssignment_Policy{ - // We choose such a large value here that the failover math should - // in effect not happen until zero instances are healthy. - OverprovisioningFactor: response.MakeUint32Value(100000), - } + cla.Endpoints = append(cla.Endpoints, &envoy_endpoint_v3.LocalityLbEndpoints{ + Priority: uint32(priority), + LbEndpoints: es, + }) } return cla diff --git a/agent/xds/endpoints_test.go b/agent/xds/endpoints_test.go index 9daf5b31f55b3..ebdd06aa41e23 100644 --- a/agent/xds/endpoints_test.go +++ b/agent/xds/endpoints_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -10,18 +10,16 @@ import ( envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" - "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/proxystateconverter" - "github.com/hashicorp/consul/agent/xds/response" "github.com/hashicorp/consul/agent/xds/testcommon" - "github.com/hashicorp/consul/agent/xdsv2" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/go-hclog" + "github.com/mitchellh/copystructure" testinf "github.com/mitchellh/go-testing-interface" "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/agent/proxycfg" + "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/envoyextensions/xdscommon" + "github.com/hashicorp/consul/sdk/testutil" ) func Test_makeLoadAssignment(t *testing.T) { @@ -103,7 +101,6 @@ func Test_makeLoadAssignment(t *testing.T) { tests := []struct { name string clusterName string - locality *structs.Locality endpoints []loadAssignmentEndpointGroup want *envoy_endpoint_v3.ClusterLoadAssignment }{ @@ -133,18 +130,18 @@ func Test_makeLoadAssignment(t *testing.T) { { HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress("10.10.10.10", 1234), + Address: makeAddress("10.10.10.10", 1234), }}, HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, - LoadBalancingWeight: response.MakeUint32Value(1), + LoadBalancingWeight: makeUint32Value(1), }, { HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress("10.10.10.20", 1234), + Address: makeAddress("10.10.10.20", 1234), }}, HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, - LoadBalancingWeight: response.MakeUint32Value(1), + LoadBalancingWeight: makeUint32Value(1), }, }, }}, @@ -163,18 +160,18 @@ func Test_makeLoadAssignment(t *testing.T) { { HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress("10.10.10.10", 1234), + Address: makeAddress("10.10.10.10", 1234), }}, HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, - LoadBalancingWeight: response.MakeUint32Value(10), + LoadBalancingWeight: makeUint32Value(10), }, { HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress("10.10.10.20", 1234), + Address: makeAddress("10.10.10.20", 1234), }}, HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, - LoadBalancingWeight: response.MakeUint32Value(5), + LoadBalancingWeight: makeUint32Value(5), }, }, }}, @@ -193,18 +190,18 @@ func Test_makeLoadAssignment(t *testing.T) { { HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress("10.10.10.10", 1234), + Address: makeAddress("10.10.10.10", 1234), }}, HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, - LoadBalancingWeight: response.MakeUint32Value(1), + LoadBalancingWeight: makeUint32Value(1), }, { HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress("10.10.10.20", 1234), + Address: makeAddress("10.10.10.20", 1234), }}, HealthStatus: envoy_core_v3.HealthStatus_UNHEALTHY, - LoadBalancingWeight: response.MakeUint32Value(1), + LoadBalancingWeight: makeUint32Value(1), }, }, }}, @@ -214,26 +211,11 @@ func Test_makeLoadAssignment(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := makeLoadAssignment( - hclog.NewNullLogger(), - &proxycfg.ConfigSnapshot{ServiceLocality: tt.locality}, tt.clusterName, - nil, tt.endpoints, proxycfg.GatewayKey{Datacenter: "dc1"}, ) require.Equal(t, tt.want, got) - - if tt.locality == nil { - got := makeLoadAssignment( - hclog.NewNullLogger(), - &proxycfg.ConfigSnapshot{ServiceLocality: &structs.Locality{Region: "us-west-1", Zone: "us-west-1a"}}, - tt.clusterName, - nil, - tt.endpoints, - proxycfg.GatewayKey{Datacenter: "dc1"}, - ) - require.Equal(t, tt.want, got) - } }) } } @@ -242,7 +224,6 @@ type endpointTestCase struct { name string create func(t testinf.T) *proxycfg.ConfigSnapshot overrideGoldenName string - alsoRunTestForV2 bool } func makeEndpointDiscoChainTests(enterprise bool) []endpointTestCase { @@ -252,84 +233,72 @@ func makeEndpointDiscoChainTests(enterprise bool) []endpointTestCase { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-external-sni", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-overrides", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple-with-overrides", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-failover", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-failover-through-remote-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-remote-gateway", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-remote-gateway-triggered", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-double-failover-through-remote-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-double-remote-gateway", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-double-remote-gateway-triggered", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-failover-through-local-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-local-gateway", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-local-gateway-triggered", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-double-failover-through-local-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-double-local-gateway", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-double-local-gateway-triggered", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-default-chain-and-custom-cluster", @@ -341,15 +310,12 @@ func makeEndpointDiscoChainTests(enterprise bool) []endpointTestCase { }) }, nil) }, - // TODO(proxystate): requires custom cluster work - alsoRunTestForV2: false, }, { name: "splitter-with-resolver-redirect", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "splitter-with-resolver-redirect-multidc", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, } } @@ -368,64 +334,42 @@ func TestEndpointsFromSnapshot(t *testing.T) { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "default", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-using-federation-states", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "federation-states", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-newer-information-in-federation-states", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "newer-info-in-federation-states", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, - }, - { - name: "mesh-gateway-using-federation-control-plane", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotMeshGateway(t, "mesh-gateway-federation", nil, nil) - }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-older-information-in-federation-states", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "older-info-in-federation-states", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-no-services", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "no-services", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-service-subsets", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "service-subsets2", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "mesh-gateway-default-service-subset", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotMeshGateway(t, "default-service-subsets2", nil, nil) }, - // TODO(proxystate): mesh gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway", @@ -433,16 +377,12 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "default", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway-nil-config-entry", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotIngressGateway_NilConfigEntry(t) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-gateway-no-services", @@ -450,8 +390,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, false, "tcp", "default", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain", @@ -459,8 +397,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "simple", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-external-sni", @@ -468,8 +404,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "external-sni", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-and-failover", @@ -477,8 +411,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-and-failover-to-cluster-peer", @@ -486,8 +418,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-to-cluster-peer", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-failover-through-remote-gateway", @@ -495,8 +425,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-remote-gateway", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-failover-through-remote-gateway-triggered", @@ -504,8 +432,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-remote-gateway-triggered", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-double-failover-through-remote-gateway", @@ -513,8 +439,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-double-remote-gateway", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered", @@ -522,8 +446,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-double-remote-gateway-triggered", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-failover-through-local-gateway", @@ -531,8 +453,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-local-gateway", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-failover-through-local-gateway-triggered", @@ -540,8 +460,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-local-gateway-triggered", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-double-failover-through-local-gateway", @@ -549,8 +467,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-double-local-gateway", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-tcp-chain-double-failover-through-local-gateway-triggered", @@ -558,8 +474,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "failover-through-double-local-gateway-triggered", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-splitter-with-resolver-redirect", @@ -567,42 +481,30 @@ func TestEndpointsFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "http", "splitter-with-resolver-redirect-multidc", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotTerminatingGateway(t, true, nil, nil) }, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-no-services", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotTerminatingGateway(t, false, nil, nil) }, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-service-subsets", create: proxycfg.TestConfigSnapshotTerminatingGatewayServiceSubsets, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-default-service-subset", create: proxycfg.TestConfigSnapshotTerminatingGatewayDefaultServiceSubset, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-multiple-listeners-duplicate-service", create: proxycfg.TestConfigSnapshotIngress_MultipleListenersDuplicateService, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, } @@ -633,10 +535,10 @@ func TestEndpointsFromSnapshot(t *testing.T) { sort.Slice(endpoints, func(i, j int) bool { return endpoints[i].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName < endpoints[j].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName }) - r, err := response.CreateResponse(xdscommon.EndpointType, "00000001", "00000001", endpoints) + r, err := createResponse(xdscommon.EndpointType, "00000001", "00000001", endpoints) require.NoError(t, err) - t.Run("current-xdsv1", func(t *testing.T) { + t.Run("current", func(t *testing.T) { gotJSON := protoToJSON(t, r) gName := tt.name @@ -646,39 +548,6 @@ func TestEndpointsFromSnapshot(t *testing.T) { require.JSONEq(t, goldenEnvoy(t, filepath.Join("endpoints", gName), envoyVersion, latestEnvoyVersion, gotJSON), gotJSON) }) - - if tt.alsoRunTestForV2 { - generator := xdsv2.NewResourceGenerator(testutil.Logger(t)) - - converter := proxystateconverter.NewConverter(testutil.Logger(t), &mockCfgFetcher{addressLan: "10.10.10.10"}) - proxyState, err := converter.ProxyStateFromSnapshot(snap) - require.NoError(t, err) - - res, err := generator.AllResourcesFromIR(proxyState) - require.NoError(t, err) - - endpoints = res[xdscommon.EndpointType] - // The order of listeners returned via LDS isn't relevant, so it's safe - // to sort these for the purposes of test comparisons. - sort.Slice(endpoints, func(i, j int) bool { - return endpoints[i].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName < endpoints[j].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName - }) - - r, err := response.CreateResponse(xdscommon.EndpointType, "00000001", "00000001", endpoints) - require.NoError(t, err) - - t.Run("current-xdsv2", func(t *testing.T) { - gotJSON := protoToJSON(t, r) - - gName := tt.name - if tt.overrideGoldenName != "" { - gName = tt.overrideGoldenName - } - - expectedJSON := goldenEnvoy(t, filepath.Join("endpoints", gName), envoyVersion, latestEnvoyVersion, gotJSON) - require.JSONEq(t, expectedJSON, gotJSON) - }) - } }) } }) diff --git a/agent/xds/extensionruntime/runtime_config.go b/agent/xds/extensionruntime/runtime_config.go index 924368ebdf2a6..110e3db1df8b4 100644 --- a/agent/xds/extensionruntime/runtime_config.go +++ b/agent/xds/extensionruntime/runtime_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensionruntime diff --git a/agent/xds/extensionruntime/runtime_config_ce_test.go b/agent/xds/extensionruntime/runtime_config_ce_test.go index 102940b0db651..c70a3f47f4f34 100644 --- a/agent/xds/extensionruntime/runtime_config_ce_test.go +++ b/agent/xds/extensionruntime/runtime_config_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package extensionruntime diff --git a/agent/xds/failover_policy.go b/agent/xds/failover_policy.go index ab3e86f25d1db..5edcae914d52c 100644 --- a/agent/xds/failover_policy.go +++ b/agent/xds/failover_policy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -27,8 +27,6 @@ type targetInfo struct { // Region is the region from the failover target's Locality. nil means the // target is in the local Consul cluster. Region *string - - PrioritizeByLocality *structs.DiscoveryPrioritizeByLocality } type discoChainTargetGroup struct { @@ -70,7 +68,7 @@ func (s *ResourceGenerator) mapDiscoChainTargets(cfgSnap *proxycfg.ConfigSnapsho return discoChainTargets{}, err } - failoverTargets.baseClusterName = s.getTargetClusterName(upstreamsSnapshot, chain, primaryTargetID, forMeshGateway) + failoverTargets.baseClusterName = s.getTargetClusterName(upstreamsSnapshot, chain, primaryTargetID, forMeshGateway, false) tids := []string{primaryTargetID} failover := node.Resolver.Failover @@ -89,7 +87,7 @@ func (s *ResourceGenerator) mapDiscoChainTargets(cfgSnap *proxycfg.ConfigSnapsho var sni, rootPEMs string var spiffeIDs []string targetUID := proxycfg.NewUpstreamIDFromTargetID(tid) - ti := targetInfo{TargetID: tid, PrioritizeByLocality: target.PrioritizeByLocality} + ti := targetInfo{TargetID: tid} configureTLS := true if forMeshGateway { diff --git a/agent/xds/failover_policy_ce.go b/agent/xds/failover_policy_ce.go index 30cd41deef0e8..e22d717e2a110 100644 --- a/agent/xds/failover_policy_ce.go +++ b/agent/xds/failover_policy_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package xds diff --git a/agent/xds/golden_test.go b/agent/xds/golden_test.go index d36eff255bd25..9209678bb52ea 100644 --- a/agent/xds/golden_test.go +++ b/agent/xds/golden_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -14,9 +14,8 @@ import ( "github.com/hashicorp/go-version" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/proto/private/prototest" ) // update allows golden files to be updated based on the current output. @@ -125,8 +124,12 @@ func golden(t *testing.T, name, subname, latestSubname, got string) string { return got } - require.NoError(t, os.WriteFile(golden, []byte(got), 0644)) - + // We use require.JSONEq to compare values and ObjectsAreEqualValues is used + // internally by that function to compare the string JSON values. This only + // writes updates the golden file when they actually change. + if !assert.ObjectsAreEqualValues(gotInterface, latestExpectedInterface) { + require.NoError(t, os.WriteFile(golden, []byte(got), 0644)) + } return got } @@ -141,5 +144,11 @@ func golden(t *testing.T, name, subname, latestSubname, got string) string { } func protoToJSON(t *testing.T, pb proto.Message) string { - return prototest.ProtoToJSON(t, pb) + t.Helper() + m := protojson.MarshalOptions{ + Indent: " ", + } + gotJSON, err := m.Marshal(pb) + require.NoError(t, err) + return string(gotJSON) } diff --git a/agent/xds/gw_per_route_filters_ce.go b/agent/xds/gw_per_route_filters_ce.go deleted file mode 100644 index 489db77befc64..0000000000000 --- a/agent/xds/gw_per_route_filters_ce.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package xds - -import ( - envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/agent/structs" -) - -type perRouteFilterBuilder struct { - providerMap map[string]*structs.JWTProviderConfigEntry - listener *structs.APIGatewayListener - route *structs.HTTPRouteConfigEntry -} - -func (p perRouteFilterBuilder) buildTypedPerFilterConfig(match *envoy_route_v3.RouteMatch, routeAction *envoy_route_v3.Route_Route) (map[string]*anypb.Any, error) { - return nil, nil -} diff --git a/agent/xds/jwt_authn.go b/agent/xds/jwt_authn.go index 36b8e05cb30c1..17b34e5cd6ce8 100644 --- a/agent/xds/jwt_authn.go +++ b/agent/xds/jwt_authn.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds diff --git a/agent/xds/jwt_authn_ce.go b/agent/xds/jwt_authn_ce.go deleted file mode 100644 index f8cf52957dc43..0000000000000 --- a/agent/xds/jwt_authn_ce.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package xds - -import ( - envoy_http_jwt_authn_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/jwt_authn/v3" - envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" - - "github.com/hashicorp/consul/agent/structs" -) - -type GatewayAuthFilterBuilder struct { - listener structs.APIGatewayListener - routes []*structs.HTTPRouteConfigEntry - providers map[string]*structs.JWTProviderConfigEntry - envoyProviders map[string]*envoy_http_jwt_authn_v3.JwtProvider -} - -func (g *GatewayAuthFilterBuilder) makeGatewayAuthFilters() ([]*envoy_http_v3.HttpFilter, error) { - return nil, nil -} diff --git a/agent/xds/jwt_authn_test.go b/agent/xds/jwt_authn_test.go index 834f62ad4c1a0..ab8665b1dc3aa 100644 --- a/agent/xds/jwt_authn_test.go +++ b/agent/xds/jwt_authn_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds diff --git a/agent/xds/listeners.go b/agent/xds/listeners.go index 7e679bb811be2..3826dedb97011 100644 --- a/agent/xds/listeners.go +++ b/agent/xds/listeners.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -29,9 +29,6 @@ import ( envoy_tcp_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3" envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" - "github.com/hashicorp/consul/agent/xds/config" - "github.com/hashicorp/consul/agent/xds/naming" - "github.com/hashicorp/consul/agent/xds/platform" "github.com/hashicorp/go-hclog" "google.golang.org/protobuf/encoding/protojson" @@ -45,7 +42,6 @@ import ( "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/xds/accesslogs" - "github.com/hashicorp/consul/agent/xds/response" "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/stringslice" @@ -54,6 +50,8 @@ import ( "github.com/hashicorp/consul/types" ) +const virtualIPTag = "virtual" + // listenersFromSnapshot returns the xDS API representation of the "listeners" in the snapshot. func (s *ResourceGenerator) listenersFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { if cfgSnap == nil { @@ -120,7 +118,7 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg. } } - proxyCfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) + proxyCfg, err := ParseProxyConfig(cfgSnap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -169,7 +167,7 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg. return nil, err } - clusterName = s.getTargetClusterName(upstreamsSnapshot, chain, target.ID, false) + clusterName = s.getTargetClusterName(upstreamsSnapshot, chain, target.ID, false, false) if clusterName == "" { continue } @@ -260,7 +258,7 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg. // We only match on this virtual IP if the upstream is in the proxy's partition. // This is because the IP is not guaranteed to be unique across k8s clusters. if acl.EqualPartitions(e.Node.PartitionOrDefault(), cfgSnap.ProxyID.PartitionOrDefault()) { - if vip := e.Service.TaggedAddresses[naming.VirtualIPTag]; vip.Address != "" { + if vip := e.Service.TaggedAddresses[virtualIPTag]; vip.Address != "" { uniqueAddrs[vip.Address] = struct{}{} } } @@ -464,7 +462,7 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg. // The virtualIPTag is used by consul-k8s to store the ClusterIP for a service. // For services imported from a peer,the partition will be equal in all cases. if acl.EqualPartitions(e.Node.PartitionOrDefault(), cfgSnap.ProxyID.PartitionOrDefault()) { - if vip := e.Service.TaggedAddresses[naming.VirtualIPTag]; vip.Address != "" { + if vip := e.Service.TaggedAddresses[virtualIPTag]; vip.Address != "" { uniqueAddrs[vip.Address] = struct{}{} } } @@ -554,8 +552,8 @@ func (s *ResourceGenerator) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg. filterChain, err := s.makeUpstreamFilterChain(filterChainOpts{ accessLogs: &cfgSnap.Proxy.AccessLogs, - clusterName: naming.OriginalDestinationClusterName, - filterName: naming.OriginalDestinationClusterName, + clusterName: OriginalDestinationClusterName, + filterName: OriginalDestinationClusterName, protocol: "tcp", }) if err != nil { @@ -789,7 +787,7 @@ func parseCheckPath(check structs.CheckType) (structs.ExposePath, error) { // listenersFromSnapshotGateway returns the "listener" for a terminating-gateway or mesh-gateway service func (s *ResourceGenerator) listenersFromSnapshotGateway(cfgSnap *proxycfg.ConfigSnapshot) ([]proto.Message, error) { - cfg, err := config.ParseGatewayConfig(cfgSnap.Proxy.Config) + cfg, err := ParseGatewayConfig(cfgSnap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -937,7 +935,7 @@ func makeListenerWithDefault(opts makeListenerOpts) *envoy_listener_v3.Listener return &envoy_listener_v3.Listener{ Name: fmt.Sprintf("%s:%s:%d", opts.name, opts.addr, opts.port), AccessLog: accessLog, - Address: response.MakeAddress(opts.addr, opts.port), + Address: makeAddress(opts.addr, opts.port), TrafficDirection: opts.direction, } } @@ -956,7 +954,7 @@ func makePipeListener(opts makeListenerOpts) *envoy_listener_v3.Listener { return &envoy_listener_v3.Listener{ Name: fmt.Sprintf("%s:%s", opts.name, opts.path), AccessLog: accessLog, - Address: response.MakePipeAddress(opts.path, uint32(modeInt)), + Address: makePipeAddress(opts.path, uint32(modeInt)), TrafficDirection: opts.direction, } } @@ -1173,7 +1171,7 @@ func createDownstreamTransportSocketForConnectTLS(cfgSnap *proxycfg.ConfigSnapsh // Determine listener protocol type from configured service protocol. Don't hard fail on a config typo, //The parse func returns default config if there is an error, so it's safe to continue. - cfg, _ := config.ParseProxyConfig(cfgSnap.Proxy.Config) + cfg, _ := ParseProxyConfig(cfgSnap.Proxy.Config) // Create TLS validation context for mTLS with leaf certificate and root certs. tlsContext := makeCommonTLSContext( @@ -1265,7 +1263,7 @@ func (s *ResourceGenerator) makeInboundListener(cfgSnap *proxycfg.ConfigSnapshot var l *envoy_listener_v3.Listener var err error - cfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) + cfg, err := ParseProxyConfig(cfgSnap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -1515,7 +1513,7 @@ func (s *ResourceGenerator) finalizePublicListenerFromConfig(l *envoy_listener_v } func (s *ResourceGenerator) makeExposedCheckListener(cfgSnap *proxycfg.ConfigSnapshot, cluster string, path structs.ExposePath) (proto.Message, error) { - cfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) + cfg, err := ParseProxyConfig(cfgSnap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -1590,7 +1588,7 @@ func (s *ResourceGenerator) makeExposedCheckListener(cfgSnap *proxycfg.ConfigSna &envoy_core_v3.CidrRange{AddressPrefix: advertise, PrefixLen: &wrapperspb.UInt32Value{Value: uint32(advertiseLen)}}, ) - if ok, err := platform.SupportsIPv6(); err != nil { + if ok, err := kernelSupportsIPv6(); err != nil { return nil, err } else if ok { ranges = append(ranges, @@ -1642,7 +1640,7 @@ func (s *ResourceGenerator) makeTerminatingGatewayListener( svcConfig := cfgSnap.TerminatingGateway.ServiceConfigs[svc] peerTrustBundles := cfgSnap.TerminatingGateway.InboundPeerTrustBundles[svc] - cfg, err := config.ParseProxyConfig(svcConfig.ProxyConfig) + cfg, err := ParseProxyConfig(svcConfig.ProxyConfig) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -1688,7 +1686,7 @@ func (s *ResourceGenerator) makeTerminatingGatewayListener( svcConfig := cfgSnap.TerminatingGateway.ServiceConfigs[svc] peerTrustBundles := cfgSnap.TerminatingGateway.InboundPeerTrustBundles[svc] - cfg, err := config.ParseProxyConfig(svcConfig.ProxyConfig) + cfg, err := ParseProxyConfig(svcConfig.ProxyConfig) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -1814,7 +1812,7 @@ func (s *ResourceGenerator) makeFilterChainTerminatingGateway(cfgSnap *proxycfg. filterChain.Filters = append(filterChain.Filters, authFilter) } - proxyCfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) + proxyCfg, err := ParseProxyConfig(cfgSnap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -2134,7 +2132,7 @@ func (s *ResourceGenerator) makeMeshGatewayPeerFilterChain( if err != nil { return nil, err } - clusterName = meshGatewayExportedClusterNamePrefix + naming.CustomizeClusterName(target.Name, chain) + clusterName = meshGatewayExportedClusterNamePrefix + CustomizeClusterName(target.Name, chain) } uid := proxycfg.NewUpstreamIDFromServiceName(svc) @@ -2597,7 +2595,7 @@ func makeHTTPFilter(opts listenerFilterOpts) (*envoy_listener_v3.Filter, error) "envoy.filters.http.grpc_stats", &envoy_grpc_stats_v3.FilterConfig{ PerMethodStatSpecifier: &envoy_grpc_stats_v3.FilterConfig_StatsForAllMethods{ - StatsForAllMethods: response.MakeBoolValue(true), + StatsForAllMethods: makeBoolValue(true), }, }, ) diff --git a/agent/xds/listeners_apigateway.go b/agent/xds/listeners_apigateway.go index 771a482972033..1f15145ce1dce 100644 --- a/agent/xds/listeners_apigateway.go +++ b/agent/xds/listeners_apigateway.go @@ -1,22 +1,15 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds import ( "fmt" - "golang.org/x/exp/maps" - envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" - envoy_http_jwt_authn_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/jwt_authn/v3" - envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" - "github.com/hashicorp/consul/agent/consul/discoverychain" - "github.com/hashicorp/consul/agent/xds/naming" - "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/wrapperspb" @@ -77,7 +70,7 @@ func (s *ResourceGenerator) makeAPIGatewayListeners(address string, cfgSnap *pro if err != nil { return nil, err } - clusterName = naming.CustomizeClusterName(target.Name, chain) + clusterName = CustomizeClusterName(target.Name, chain) } filterName := fmt.Sprintf("%s.%s.%s.%s", chain.ServiceName, chain.Namespace, chain.Partition, chain.Datacenter) @@ -110,21 +103,15 @@ func (s *ResourceGenerator) makeAPIGatewayListeners(address string, cfgSnap *pro if isAPIGatewayWithTLS { // construct SNI filter chains - l.FilterChains, err = makeInlineOverrideFilterChains( - cfgSnap, - cfgSnap.APIGateway.TLSConfig, - listenerKey.Protocol, - listenerFilterOpts{ - useRDS: useRDS, - protocol: listenerKey.Protocol, - routeName: listenerKey.RouteName(), - cluster: clusterName, - statPrefix: "ingress_upstream_", - accessLogs: &cfgSnap.Proxy.AccessLogs, - logger: s.Logger, - }, - certs, - ) + l.FilterChains, err = makeInlineOverrideFilterChains(cfgSnap, cfgSnap.APIGateway.TLSConfig, listenerKey.Protocol, listenerFilterOpts{ + useRDS: useRDS, + protocol: listenerKey.Protocol, + routeName: listenerKey.RouteName(), + cluster: clusterName, + statPrefix: "ingress_upstream_", + accessLogs: &cfgSnap.Proxy.AccessLogs, + logger: s.Logger, + }, certs) if err != nil { return nil, err } @@ -149,61 +136,6 @@ func (s *ResourceGenerator) makeAPIGatewayListeners(address string, cfgSnap *pro logger: s.Logger, } listener := makeListener(listenerOpts) - - routes := make([]*structs.HTTPRouteConfigEntry, 0, len(readyListener.routeReferences)) - for _, routeRef := range maps.Keys(readyListener.routeReferences) { - route, ok := cfgSnap.APIGateway.HTTPRoutes.Get(routeRef) - if !ok { - return nil, fmt.Errorf("missing route for routeRef %s:%s", routeRef.Kind, routeRef.Name) - } - - routes = append(routes, route) - } - consolidatedRoutes := discoverychain.ConsolidateHTTPRoutes(cfgSnap.APIGateway.GatewayConfig, &readyListener.listenerCfg, routes...) - routesWithJWT := []*structs.HTTPRouteConfigEntry{} - for _, routeCfgEntry := range consolidatedRoutes { - routeCfgEntry := routeCfgEntry - route := &routeCfgEntry - - if listenerCfg.Override != nil && listenerCfg.Override.JWT != nil { - routesWithJWT = append(routesWithJWT, route) - continue - } - - if listenerCfg.Default != nil && listenerCfg.Default.JWT != nil { - routesWithJWT = append(routesWithJWT, route) - continue - } - - for _, rule := range route.Rules { - if rule.Filters.JWT != nil { - routesWithJWT = append(routesWithJWT, route) - continue - } - for _, svc := range rule.Services { - if svc.Filters.JWT != nil { - routesWithJWT = append(routesWithJWT, route) - continue - } - } - } - - } - - var authFilters []*envoy_http_v3.HttpFilter - if len(routesWithJWT) > 0 { - builder := &GatewayAuthFilterBuilder{ - listener: listenerCfg, - routes: routesWithJWT, - providers: cfgSnap.JWTProviders, - envoyProviders: make(map[string]*envoy_http_jwt_authn_v3.JwtProvider, len(cfgSnap.JWTProviders)), - } - authFilters, err = builder.makeGatewayAuthFilters() - if err != nil { - return nil, err - } - } - filterOpts := listenerFilterOpts{ useRDS: true, protocol: listenerKey.Protocol, @@ -212,7 +144,7 @@ func (s *ResourceGenerator) makeAPIGatewayListeners(address string, cfgSnap *pro cluster: "", statPrefix: "ingress_upstream_", routePath: "", - httpAuthzFilters: authFilters, + httpAuthzFilters: nil, accessLogs: &cfgSnap.Proxy.AccessLogs, logger: s.Logger, } @@ -277,6 +209,7 @@ type readyListener struct { // getReadyListeners returns a map containing the list of upstreams for each listener that is ready func getReadyListeners(cfgSnap *proxycfg.ConfigSnapshot) map[string]readyListener { + ready := map[string]readyListener{} for _, l := range cfgSnap.APIGateway.Listeners { // Only include upstreams for listeners that are ready @@ -321,10 +254,7 @@ func getReadyListeners(cfgSnap *proxycfg.ConfigSnapshot) map[string]readyListene return ready } -func makeDownstreamTLSContextFromSnapshotAPIListenerConfig( - cfgSnap *proxycfg.ConfigSnapshot, - listenerCfg structs.APIGatewayListener, -) (*envoy_tls_v3.DownstreamTlsContext, error) { +func makeDownstreamTLSContextFromSnapshotAPIListenerConfig(cfgSnap *proxycfg.ConfigSnapshot, listenerCfg structs.APIGatewayListener) (*envoy_tls_v3.DownstreamTlsContext, error) { var downstreamContext *envoy_tls_v3.DownstreamTlsContext tlsContext, err := makeCommonTLSContextFromSnapshotAPIGatewayListenerConfig(cfgSnap, listenerCfg) @@ -345,13 +275,10 @@ func makeDownstreamTLSContextFromSnapshotAPIListenerConfig( return downstreamContext, nil } -func makeCommonTLSContextFromSnapshotAPIGatewayListenerConfig( - cfgSnap *proxycfg.ConfigSnapshot, - listenerCfg structs.APIGatewayListener, -) (*envoy_tls_v3.CommonTlsContext, error) { +func makeCommonTLSContextFromSnapshotAPIGatewayListenerConfig(cfgSnap *proxycfg.ConfigSnapshot, listenerCfg structs.APIGatewayListener) (*envoy_tls_v3.CommonTlsContext, error) { var tlsContext *envoy_tls_v3.CommonTlsContext - // API Gateway TLS config is per listener + //API Gateway TLS config is per listener tlsCfg, err := resolveAPIListenerTLSConfig(listenerCfg.TLS) if err != nil { return nil, err @@ -359,7 +286,10 @@ func makeCommonTLSContextFromSnapshotAPIGatewayListenerConfig( connectTLSEnabled := (!listenerCfg.TLS.IsEmpty()) - if connectTLSEnabled { + if tlsCfg.SDS != nil { + // Set up listener TLS from SDS + tlsContext = makeCommonTLSContextFromGatewayTLSConfig(*tlsCfg) + } else if connectTLSEnabled { tlsContext = makeCommonTLSContext(cfgSnap.Leaf(), cfgSnap.RootPEMs(), makeTLSParametersFromGatewayTLSConfig(*tlsCfg)) } @@ -388,14 +318,37 @@ func resolveAPIListenerTLSConfig(listenerTLSCfg structs.APIGatewayTLSConfigurati return &mergedCfg, nil } +func routeNameForAPIGatewayUpstream(l structs.IngressListener, s structs.IngressService) string { + key := proxycfg.IngressListenerKeyFromListener(l) + + // If the upstream service doesn't have any TLS overrides then it can just use + // the combined filterchain with all the merged routes. + if !ingressServiceHasSDSOverrides(s) { + return key.RouteName() + } + + // Return a specific route for this service as it needs a custom FilterChain + // to serve its custom cert so we should attach its routes to a separate Route + // too. We need this to be consistent between OSS and Enterprise to avoid xDS + // config golden files in tests conflicting so we can't use ServiceID.String() + // which normalizes to included all identifiers in Enterprise. + sn := s.ToServiceName() + svcIdentifier := sn.Name + if !sn.InDefaultPartition() || !sn.InDefaultNamespace() { + // Non-default partition/namespace, use a full identifier + svcIdentifier = sn.String() + } + return fmt.Sprintf("%s_%s", key.RouteName(), svcIdentifier) +} + // when we have multiple certificates on a single listener, we need // to duplicate the filter chains with multiple TLS contexts func makeInlineOverrideFilterChains(cfgSnap *proxycfg.ConfigSnapshot, tlsCfg structs.GatewayTLSConfig, protocol string, filterOpts listenerFilterOpts, - certs []structs.InlineCertificateConfigEntry, -) ([]*envoy_listener_v3.FilterChain, error) { + certs []structs.InlineCertificateConfigEntry) ([]*envoy_listener_v3.FilterChain, error) { + var chains []*envoy_listener_v3.FilterChain constructChain := func(name string, hosts []string, tlsContext *envoy_tls_v3.CommonTlsContext) error { diff --git a/agent/xds/listeners_ingress.go b/agent/xds/listeners_ingress.go index e5e5a4980c411..031709e2a818c 100644 --- a/agent/xds/listeners_ingress.go +++ b/agent/xds/listeners_ingress.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -9,7 +9,6 @@ import ( envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" - "github.com/hashicorp/consul/agent/xds/naming" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/durationpb" @@ -63,7 +62,7 @@ func (s *ResourceGenerator) makeIngressGatewayListeners(address string, cfgSnap if err != nil { return nil, err } - clusterName = naming.CustomizeClusterName(target.Name, chain) + clusterName = CustomizeClusterName(target.Name, chain) } filterName := fmt.Sprintf("%s.%s.%s.%s", chain.ServiceName, chain.Namespace, chain.Partition, chain.Datacenter) diff --git a/agent/xds/listeners_test.go b/agent/xds/listeners_test.go index ff538342f78fd..6ccb722f1c53d 100644 --- a/agent/xds/listeners_test.go +++ b/agent/xds/listeners_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -10,8 +10,8 @@ import ( "testing" "text/template" + "github.com/hashicorp/consul/agent/xds/testcommon" "github.com/stretchr/testify/assert" - "google.golang.org/protobuf/proto" envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" testinf "github.com/mitchellh/go-testing-interface" @@ -19,11 +19,6 @@ import ( "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/configfetcher" - "github.com/hashicorp/consul/agent/xds/proxystateconverter" - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/agent/xds/testcommon" - "github.com/hashicorp/consul/agent/xdsv2" "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/proto/private/pbpeering" "github.com/hashicorp/consul/sdk/testutil" @@ -38,7 +33,6 @@ type listenerTestCase struct { // test input. overrideGoldenName string generatorSetup func(*ResourceGenerator) - alsoRunTestForV2 bool } func makeListenerDiscoChainTests(enterprise bool) []listenerTestCase { @@ -70,14 +64,12 @@ func makeListenerDiscoChainTests(enterprise bool) []listenerTestCase { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "splitter-with-resolver-redirect-multidc", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-http-chain", @@ -92,7 +84,6 @@ func makeListenerDiscoChainTests(enterprise bool) []listenerTestCase { }, ) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-http2-chain", @@ -107,7 +98,6 @@ func makeListenerDiscoChainTests(enterprise bool) []listenerTestCase { }, ) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-grpc-chain", @@ -122,35 +112,30 @@ func makeListenerDiscoChainTests(enterprise bool) []listenerTestCase { }, ) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-external-sni", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-overrides", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple-with-overrides", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-failover-through-remote-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-remote-gateway", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tcp-chain-failover-through-local-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-through-local-gateway", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-jwt-config-entry-with-local", @@ -241,7 +226,6 @@ func TestListenersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tls-incoming-min-version", @@ -261,7 +245,6 @@ func TestListenersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tls-incoming-max-version", @@ -281,7 +264,6 @@ func TestListenersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-tls-incoming-cipher-suites", @@ -304,7 +286,6 @@ func TestListenersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "grpc-public-listener", @@ -313,7 +294,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["protocol"] = "grpc" }, nil) }, - alsoRunTestForV2: true, }, { name: "listener-bind-address", @@ -322,7 +302,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["bind_address"] = "127.0.0.2" }, nil) }, - alsoRunTestForV2: true, }, { name: "listener-bind-port", @@ -331,7 +310,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["bind_port"] = 8888 }, nil) }, - alsoRunTestForV2: true, }, { name: "listener-bind-address-port", @@ -341,7 +319,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["bind_port"] = 8888 }, nil) }, - alsoRunTestForV2: true, }, { name: "listener-unix-domain-socket", @@ -353,7 +330,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Upstreams[0].LocalBindSocketMode = "0640" }, nil) }, - alsoRunTestForV2: true, }, { name: "listener-max-inbound-connections", @@ -362,7 +338,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["max_inbound_connections"] = 222 }, nil) }, - alsoRunTestForV2: true, }, { name: "http2-public-listener", @@ -371,7 +346,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["protocol"] = "http2" }, nil) }, - alsoRunTestForV2: true, }, { name: "listener-balance-inbound-connections", @@ -380,7 +354,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["balance_inbound_connections"] = "exact_balance" }, nil) }, - alsoRunTestForV2: true, }, { name: "listener-balance-outbound-connections-bind-port", @@ -389,7 +362,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Upstreams[0].Config["balance_outbound_connections"] = "exact_balance" }, nil) }, - alsoRunTestForV2: true, }, { name: "http-public-listener", @@ -398,7 +370,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["protocol"] = "http" }, nil) }, - alsoRunTestForV2: true, }, { name: "http-public-listener-no-xfcc", @@ -420,7 +391,6 @@ func TestListenersFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "http-listener-with-timeouts", @@ -432,7 +402,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Config["local_idle_timeout_ms"] = 3456 }, nil) }, - alsoRunTestForV2: true, }, { name: "http-upstream", @@ -441,7 +410,6 @@ func TestListenersFromSnapshot(t *testing.T) { ns.Proxy.Upstreams[0].Config["protocol"] = "http" }, nil) }, - alsoRunTestForV2: true, }, { name: "custom-public-listener", @@ -527,31 +495,6 @@ func TestListenersFromSnapshot(t *testing.T) { }, nil) }, }, - { - name: "custom-upstream-with-prepared-query", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { - for i := range ns.Proxy.Upstreams { - if ns.Proxy.Upstreams[i].DestinationName != "db" { - continue // only tweak the db upstream - } - if ns.Proxy.Upstreams[i].Config == nil { - ns.Proxy.Upstreams[i].Config = map[string]interface{}{} - } - - uid := proxycfg.NewUpstreamID(&ns.Proxy.Upstreams[i]) - - // Triggers an override with the presence of the escape hatch listener - ns.Proxy.Upstreams[i].DestinationType = structs.UpstreamDestTypePreparedQuery - - ns.Proxy.Upstreams[i].Config["envoy_listener_json"] = - customListenerJSON(t, customListenerJSONOptions{ - Name: uid.EnvoyID() + ":custom-upstream", - }) - } - }, nil) - }, - }, { name: "connect-proxy-upstream-defaults", create: func(t testinf.T) *proxycfg.ConfigSnapshot { @@ -569,7 +512,6 @@ func TestListenersFromSnapshot(t *testing.T) { } }, nil) }, - alsoRunTestForV2: true, }, { name: "expose-paths-local-app-paths", @@ -592,9 +534,9 @@ func TestListenersFromSnapshot(t *testing.T) { }, { // NOTE: if IPv6 is not supported in the kernel per - // platform.SupportsIPv6() then this test will fail because the golden + // kernelSupportsIPv6() then this test will fail because the golden // files were generated assuming ipv6 support was present - name: "expose-checks-http", + name: "expose-checks", create: proxycfg.TestConfigSnapshotExposeChecks, generatorSetup: func(s *ResourceGenerator) { s.CfgFetcher = configFetcherFunc(func() string { @@ -602,30 +544,6 @@ func TestListenersFromSnapshot(t *testing.T) { }) }, }, - { - // NOTE: if IPv6 is not supported in the kernel per - // platform.SupportsIPv6() then this test will fail because the golden - // files were generated assuming ipv6 support was present - name: "expose-checks-http-with-bind-override", - create: proxycfg.TestConfigSnapshotExposeChecksWithBindOverride, - generatorSetup: func(s *ResourceGenerator) { - s.CfgFetcher = configFetcherFunc(func() string { - return "192.0.2.1" - }) - }, - }, - { - // NOTE: if IPv6 is not supported in the kernel per - // platform.SupportsIPv6() then this test will fail because the golden - // files were generated assuming ipv6 support was present - name: "expose-checks-grpc", - create: proxycfg.TestConfigSnapshotExposeChecksGRPC, - generatorSetup: func(s *ResourceGenerator) { - s.CfgFetcher = configFetcherFunc(func() string { - return "192.0.2.1" - }) - }, - }, { name: "mesh-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { @@ -638,12 +556,6 @@ func TestListenersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotMeshGateway(t, "federation-states", nil, nil) }, }, - { - name: "mesh-gateway-using-federation-control-plane", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotMeshGateway(t, "mesh-gateway-federation", nil, nil) - }, - }, { name: "mesh-gateway-no-services", create: func(t testinf.T) *proxycfg.ConfigSnapshot { @@ -960,16 +872,6 @@ func TestListenersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotTerminatingGateway(t, true, nil, nil) }, }, - { - name: "terminating-gateway-custom-trace-listener", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotTerminatingGateway(t, true, func(ns *structs.NodeService) { - ns.Proxy.Config = map[string]interface{}{} - ns.Proxy.Config["protocol"] = "http" - ns.Proxy.Config["envoy_listener_tracing_json"] = customTraceJSON(t) - }, nil) - }, - }, { name: "terminating-gateway-with-tls-incoming-min-version", create: func(t testinf.T) *proxycfg.ConfigSnapshot { @@ -1178,14 +1080,6 @@ func TestListenersFromSnapshot(t *testing.T) { name: "ingress-with-tls-mixed-min-version-listeners", create: proxycfg.TestConfigSnapshotIngressGateway_TLSMixedMinVersionListeners, }, - { - name: "ingress-with-tls-mixed-max-version-listeners", - create: proxycfg.TestConfigSnapshotIngressGateway_TLSMixedMaxVersionListeners, - }, - { - name: "ingress-with-tls-mixed-cipher-suites-listeners", - create: proxycfg.TestConfigSnapshotIngressGateway_TLSMixedCipherVersionListeners, - }, { name: "ingress-with-sds-listener-gw-level", create: proxycfg.TestConfigSnapshotIngressGatewaySDS_GatewayLevel, @@ -1235,27 +1129,22 @@ func TestListenersFromSnapshot(t *testing.T) { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotTransparentProxyHTTPUpstream(t) }, - alsoRunTestForV2: true, }, { - name: "transparent-proxy-with-resolver-redirect-upstream", - create: proxycfg.TestConfigSnapshotTransparentProxyResolverRedirectUpstream, - alsoRunTestForV2: true, + name: "transparent-proxy-with-resolver-redirect-upstream", + create: proxycfg.TestConfigSnapshotTransparentProxyResolverRedirectUpstream, }, { - name: "transparent-proxy-catalog-destinations-only", - create: proxycfg.TestConfigSnapshotTransparentProxyCatalogDestinationsOnly, - alsoRunTestForV2: true, + name: "transparent-proxy-catalog-destinations-only", + create: proxycfg.TestConfigSnapshotTransparentProxyCatalogDestinationsOnly, }, { - name: "transparent-proxy-dial-instances-directly", - create: proxycfg.TestConfigSnapshotTransparentProxyDialDirectly, - alsoRunTestForV2: true, + name: "transparent-proxy-dial-instances-directly", + create: proxycfg.TestConfigSnapshotTransparentProxyDialDirectly, }, { - name: "transparent-proxy-terminating-gateway", - create: proxycfg.TestConfigSnapshotTransparentProxyTerminatingGatewayCatalogDestinationsOnly, - alsoRunTestForV2: true, + name: "transparent-proxy-terminating-gateway", + create: proxycfg.TestConfigSnapshotTransparentProxyTerminatingGatewayCatalogDestinationsOnly, }, { name: "custom-trace-listener", @@ -1314,11 +1203,9 @@ func TestListenersFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshot(t, func(ns *structs.NodeService) { ns.Proxy.MutualTLSMode = structs.MutualTLSModePermissive ns.Proxy.Mode = structs.ProxyModeTransparent - ns.Proxy.TransparentProxy.OutboundListenerPort = 1234 }, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-without-tproxy-and-permissive-mtls", @@ -1328,7 +1215,6 @@ func TestListenersFromSnapshot(t *testing.T) { }, nil) }, - alsoRunTestForV2: true, }, } @@ -1341,7 +1227,6 @@ func TestListenersFromSnapshot(t *testing.T) { t.Run("envoy-"+envoyVersion, func(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Sanity check default with no overrides first snap := tt.create(t) @@ -1353,26 +1238,26 @@ func TestListenersFromSnapshot(t *testing.T) { // golder files for every test case and so not be any use! testcommon.SetupTLSRootsAndLeaf(t, snap) - var listeners []proto.Message - // Need server just for logger dependency g := NewResourceGenerator(testutil.Logger(t), nil, false) g.ProxyFeatures = sf if tt.generatorSetup != nil { tt.generatorSetup(g) } - listeners, err = g.listenersFromSnapshot(snap) + + listeners, err := g.listenersFromSnapshot(snap) require.NoError(t, err) + // The order of listeners returned via LDS isn't relevant, so it's safe // to sort these for the purposes of test comparisons. sort.Slice(listeners, func(i, j int) bool { return listeners[i].(*envoy_listener_v3.Listener).Name < listeners[j].(*envoy_listener_v3.Listener).Name }) - r, err := response.CreateResponse(xdscommon.ListenerType, "00000001", "00000001", listeners) + r, err := createResponse(xdscommon.ListenerType, "00000001", "00000001", listeners) require.NoError(t, err) - t.Run("current-xdsv1", func(t *testing.T) { + t.Run("current", func(t *testing.T) { gotJSON := protoToJSON(t, r) gName := tt.name @@ -1383,39 +1268,6 @@ func TestListenersFromSnapshot(t *testing.T) { expectedJSON := goldenEnvoy(t, filepath.Join("listeners", gName), envoyVersion, latestEnvoyVersion, gotJSON) require.JSONEq(t, expectedJSON, gotJSON) }) - - if tt.alsoRunTestForV2 { - generator := xdsv2.NewResourceGenerator(testutil.Logger(t)) - converter := proxystateconverter.NewConverter(testutil.Logger(t), nil) - proxyState, err := converter.ProxyStateFromSnapshot(snap) - require.NoError(t, err) - - res, err := generator.AllResourcesFromIR(proxyState) - require.NoError(t, err) - - listeners = res[xdscommon.ListenerType] - // The order of listeners returned via LDS isn't relevant, so it's safe - // to sort these for the purposes of test comparisons. - sort.Slice(listeners, func(i, j int) bool { - return listeners[i].(*envoy_listener_v3.Listener).Name < listeners[j].(*envoy_listener_v3.Listener).Name - }) - - r, err := response.CreateResponse(xdscommon.ListenerType, "00000001", "00000001", listeners) - require.NoError(t, err) - - t.Run("current-xdsv2", func(t *testing.T) { - gotJSON := protoToJSON(t, r) - - gName := tt.name - if tt.overrideGoldenName != "" { - gName = tt.overrideGoldenName - } - - expectedJSON := goldenEnvoy(t, filepath.Join("listeners", gName), envoyVersion, latestEnvoyVersion, gotJSON) - require.JSONEq(t, expectedJSON, gotJSON) - }) - } - }) } }) @@ -1573,7 +1425,7 @@ func customTraceJSON(t testinf.T) string { type configFetcherFunc func() string -var _ configfetcher.ConfigFetcher = (configFetcherFunc)(nil) +var _ ConfigFetcher = (configFetcherFunc)(nil) func (f configFetcherFunc) AdvertiseAddrLAN() string { return f() diff --git a/agent/xds/locality_policy.go b/agent/xds/locality_policy.go deleted file mode 100644 index c94ba95ea2865..0000000000000 --- a/agent/xds/locality_policy.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "fmt" - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/agent/structs" -) - -func groupedEndpoints(logger hclog.Logger, locality *structs.Locality, policy *structs.DiscoveryPrioritizeByLocality, csns structs.CheckServiceNodes) ([]structs.CheckServiceNodes, error) { - switch { - case policy == nil || policy.Mode == "" || policy.Mode == "none": - return []structs.CheckServiceNodes{csns}, nil - case policy.Mode == "failover": - log := logger.Named("locality") - return prioritizeByLocalityFailover(log, locality, csns), nil - default: - return nil, fmt.Errorf("unexpected priortize-by-locality mode %q", policy.Mode) - } -} diff --git a/agent/xds/locality_policy_ce.go b/agent/xds/locality_policy_ce.go deleted file mode 100644 index 7d9f41be5dee2..0000000000000 --- a/agent/xds/locality_policy_ce.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package xds - -import ( - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/go-hclog" -) - -func prioritizeByLocalityFailover(_ hclog.Logger, _ *structs.Locality, _ structs.CheckServiceNodes) []structs.CheckServiceNodes { - return nil -} diff --git a/agent/xds/naming.go b/agent/xds/naming.go new file mode 100644 index 0000000000000..ab9224f71ce8b --- /dev/null +++ b/agent/xds/naming.go @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package xds + +import ( + "fmt" + + "github.com/hashicorp/consul/agent/structs" +) + +func CustomizeClusterName(clusterName string, chain *structs.CompiledDiscoveryChain) string { + if chain == nil || chain.CustomizationHash == "" { + return clusterName + } + // Use a colon to delimit this prefix instead of a dot to avoid a + // theoretical collision problem with subsets. + return fmt.Sprintf("%s~%s", chain.CustomizationHash, clusterName) +} diff --git a/agent/xds/naming/naming.go b/agent/xds/naming/naming.go deleted file mode 100644 index 3e19d93270038..0000000000000 --- a/agent/xds/naming/naming.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package naming - -import ( - "fmt" - - "github.com/hashicorp/consul/agent/structs" -) - -const ( - // OriginalDestinationClusterName is the name we give to the passthrough - // cluster which redirects transparently-proxied requests to their original - // destination outside the mesh. This cluster prevents Consul from blocking - // connections to destinations outside of the catalog when in transparent - // proxy mode. - OriginalDestinationClusterName = "original-destination" - VirtualIPTag = "virtual" -) - -func CustomizeClusterName(clusterName string, chain *structs.CompiledDiscoveryChain) string { - if chain == nil || chain.CustomizationHash == "" { - return clusterName - } - // Use a colon to delimit this prefix instead of a dot to avoid a - // theoretical collision problem with subsets. - return fmt.Sprintf("%s~%s", chain.CustomizationHash, clusterName) -} diff --git a/agent/xds/net_fallback.go b/agent/xds/net_fallback.go new file mode 100644 index 0000000000000..7230c18ef2e85 --- /dev/null +++ b/agent/xds/net_fallback.go @@ -0,0 +1,11 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build !linux +// +build !linux + +package xds + +func kernelSupportsIPv6() (bool, error) { + return true, nil +} diff --git a/agent/xds/platform/net_linux.go b/agent/xds/net_linux.go similarity index 85% rename from agent/xds/platform/net_linux.go rename to agent/xds/net_linux.go index 13596f8a555af..96932ca307309 100644 --- a/agent/xds/platform/net_linux.go +++ b/agent/xds/net_linux.go @@ -1,9 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build linux +// +build linux -package platform +package xds import ( "fmt" @@ -19,7 +20,7 @@ var ( ipv6SupportedErr error ) -func SupportsIPv6() (bool, error) { +func kernelSupportsIPv6() (bool, error) { ipv6SupportOnce.Do(func() { ipv6Supported, ipv6SupportedErr = checkIfKernelSupportsIPv6() }) diff --git a/agent/xds/platform/net_fallback.go b/agent/xds/platform/net_fallback.go deleted file mode 100644 index 391d4cf4ba80a..0000000000000 --- a/agent/xds/platform/net_fallback.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !linux - -package platform - -func SupportsIPv6() (bool, error) { - return true, nil -} diff --git a/agent/xds/protocol_trace.go b/agent/xds/protocol_trace.go index cfe905d70bf99..42d82d76012bc 100644 --- a/agent/xds/protocol_trace.go +++ b/agent/xds/protocol_trace.go @@ -1,27 +1,26 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds import ( envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - "github.com/hashicorp/go-hclog" "github.com/mitchellh/copystructure" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" ) -func logTraceRequest(logger hclog.Logger, msg string, pb proto.Message) { - logTraceProto(logger, msg, pb, false) +func (s *ResourceGenerator) logTraceRequest(msg string, pb proto.Message) { + s.logTraceProto(msg, pb, false) } -func logTraceResponse(logger hclog.Logger, msg string, pb proto.Message) { - logTraceProto(logger, msg, pb, true) +func (s *ResourceGenerator) logTraceResponse(msg string, pb proto.Message) { + s.logTraceProto(msg, pb, true) } -func logTraceProto(logger hclog.Logger, msg string, pb proto.Message, response bool) { - if !logger.IsTrace() { +func (s *ResourceGenerator) logTraceProto(msg string, pb proto.Message, response bool) { + if !s.Logger.IsTrace() { return } @@ -56,5 +55,5 @@ func logTraceProto(logger hclog.Logger, msg string, pb proto.Message, response b out = string(outBytes) } - logger.Trace(msg, "direction", dir, "protobuf", out) + s.Logger.Trace(msg, "direction", dir, "protobuf", out) } diff --git a/agent/xds/proxystateconverter/clusters.go b/agent/xds/proxystateconverter/clusters.go deleted file mode 100644 index b8857bee29c59..0000000000000 --- a/agent/xds/proxystateconverter/clusters.go +++ /dev/null @@ -1,1263 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxystateconverter - -import ( - "errors" - "fmt" - "strings" - "time" - - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-uuid" - - envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/agent/connect" - "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/config" - "github.com/hashicorp/consul/agent/xds/naming" - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto/private/pbpeering" -) - -const ( - meshGatewayExportedClusterNamePrefix = "exported~" -) - -type namedCluster struct { - name string - cluster *pbproxystate.Cluster -} - -// clustersFromSnapshot returns the xDS API representation of the "clusters" in the snapshot. -func (s *Converter) clustersFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) error { - if cfgSnap == nil { - return errors.New("nil config given") - } - - switch cfgSnap.Kind { - case structs.ServiceKindConnectProxy: - return s.clustersFromSnapshotConnectProxy(cfgSnap) - // TODO(proxystate): Terminating Gateways will be added in the future. - //case structs.ServiceKindTerminatingGateway: - // err := s.clustersFromSnapshotTerminatingGateway(cfgSnap) - // if err != nil { - // return err - // } - // return nil - // TODO(proxystate): Mesh Gateways will be added in the future. - //case structs.ServiceKindMeshGateway: - // err := s.clustersFromSnapshotMeshGateway(cfgSnap) - // if err != nil { - // return err - // } - // return nil - // TODO(proxystate): Ingress Gateways will be added in the future. - //case structs.ServiceKindIngressGateway: - // err := s.clustersFromSnapshotIngressGateway(cfgSnap) - // if err != nil { - // return err - // } - // return nil - // TODO(proxystate): API Gateways will be added in the future. - //case structs.ServiceKindAPIGateway: - // res, err := s.clustersFromSnapshotAPIGateway(cfgSnap) - // if err != nil { - // return err - // } - // return nil - default: - return fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind) - } -} - -// clustersFromSnapshot returns the xDS API representation of the "clusters" -// (upstreams) in the snapshot. -func (s *Converter) clustersFromSnapshotConnectProxy(cfgSnap *proxycfg.ConfigSnapshot) error { - // This is the list of listeners we add to. It will be empty to start. - clusters := s.proxyState.Clusters - var err error - - // Include the "app" cluster for the public listener - appCluster, err := s.makeAppCluster(cfgSnap, xdscommon.LocalAppClusterName, "", cfgSnap.Proxy.LocalServicePort) - if err != nil { - return err - } - clusters[appCluster.name] = appCluster.cluster - - if cfgSnap.Proxy.Mode == structs.ProxyModeTransparent { - passthroughs, err := s.makePassthroughClusters(cfgSnap) - if err != nil { - return fmt.Errorf("failed to make passthrough clusters for transparent proxy: %v", err) - } - for clusterName, cluster := range passthroughs { - clusters[clusterName] = cluster - } - } - - // NOTE: Any time we skip a chain below we MUST also skip that discovery chain in endpoints.go - // so that the sets of endpoints generated matches the sets of clusters. - for uid, chain := range cfgSnap.ConnectProxy.DiscoveryChain { - upstream, skip := cfgSnap.ConnectProxy.GetUpstream(uid, &cfgSnap.ProxyID.EnterpriseMeta) - if skip { - continue - } - - upstreamClusters, err := s.makeUpstreamClustersForDiscoveryChain( - uid, - upstream, - chain, - cfgSnap, - false, - ) - if err != nil { - return err - } - - for name, cluster := range upstreamClusters { - clusters[name] = cluster - } - } - - // TODO(proxystate): peering will be added in the future. - //// NOTE: Any time we skip an upstream below we MUST also skip that same - //// upstream in endpoints.go so that the sets of endpoints generated matches - //// the sets of clusters. - //for _, uid := range cfgSnap.ConnectProxy.PeeredUpstreamIDs() { - // upstream, skip := cfgSnap.ConnectProxy.GetUpstream(uid, &cfgSnap.ProxyID.EnterpriseMeta) - // if skip { - // continue - // } - // - // peerMeta, found := cfgSnap.ConnectProxy.UpstreamPeerMeta(uid) - // if !found { - // s.Logger.Warn("failed to fetch upstream peering metadata for cluster", "uid", uid) - // } - // cfg := s.getAndModifyUpstreamConfigForPeeredListener(uid, upstream, peerMeta) - // - // upstreamCluster, err := s.makeUpstreamClusterForPeerService(uid, cfg, peerMeta, cfgSnap) - // if err != nil { - // return nil, err - // } - // clusters = append(clusters, upstreamCluster) - //} - - // TODO(proxystate): L7 Intentions and JWT Auth will be added in the future. - //// add clusters for jwt-providers - //for _, prov := range cfgSnap.JWTProviders { - // //skip cluster creation for local providers - // if prov.JSONWebKeySet == nil || prov.JSONWebKeySet.Remote == nil { - // continue - // } - // - // cluster, err := makeJWTProviderCluster(prov) - // if err != nil { - // s.Logger.Warn("failed to make jwt-provider cluster", "provider name", prov.Name, "error", err) - // continue - // } - // - // clusters[cluster.GetName()] = cluster - //} - - for _, u := range cfgSnap.Proxy.Upstreams { - if u.DestinationType != structs.UpstreamDestTypePreparedQuery { - continue - } - - upstreamCluster, err := s.makeUpstreamClusterForPreparedQuery(u, cfgSnap) - if err != nil { - return err - } - clusters[upstreamCluster.name] = upstreamCluster.cluster - } - - cfgSnap.Proxy.Expose.Finalize() - paths := cfgSnap.Proxy.Expose.Paths - - // Add service health checks to the list of paths to create clusters for if needed - if cfgSnap.Proxy.Expose.Checks { - psid := structs.NewServiceID(cfgSnap.Proxy.DestinationServiceID, &cfgSnap.ProxyID.EnterpriseMeta) - for _, check := range cfgSnap.ConnectProxy.WatchedServiceChecks[psid] { - p, err := parseCheckPath(check) - if err != nil { - s.Logger.Warn("failed to create cluster for", "check", check.CheckID, "error", err) - continue - } - paths = append(paths, p) - } - } - - // Create a new cluster if we need to expose a port that is different from the service port - for _, path := range paths { - if path.LocalPathPort == cfgSnap.Proxy.LocalServicePort { - continue - } - c, err := s.makeAppCluster(cfgSnap, makeExposeClusterName(path.LocalPathPort), path.Protocol, path.LocalPathPort) - if err != nil { - s.Logger.Warn("failed to make local cluster", "path", path.Path, "error", err) - continue - } - clusters[c.name] = c.cluster - } - - return nil -} - -// TODO(proxystate): L7 Intentions and JWT Auth will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makeJWTProviderCluster -// func makeJWKSDiscoveryClusterType -// func makeJWTCertValidationContext -// func parseJWTRemoteURL - -func makeExposeClusterName(destinationPort int) string { - return fmt.Sprintf("exposed_cluster_%d", destinationPort) -} - -// In transparent proxy mode there are potentially multiple passthrough clusters added. -// The first is for destinations outside of Consul's catalog. This is for a plain TCP proxy. -// All of these use Envoy's ORIGINAL_DST listener filter, which forwards to the original -// destination address (before the iptables redirection). -// The rest are for destinations inside the mesh, which require certificates for mTLS. -func (s *Converter) makePassthroughClusters(cfgSnap *proxycfg.ConfigSnapshot) (map[string]*pbproxystate.Cluster, error) { - // This size is an upper bound. - clusters := make(map[string]*pbproxystate.Cluster, 0) - if meshConf := cfgSnap.MeshConfig(); meshConf == nil || - !meshConf.TransparentProxy.MeshDestinationsOnly { - - clusters[naming.OriginalDestinationClusterName] = &pbproxystate.Cluster{ - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Passthrough{ - Passthrough: &pbproxystate.PassthroughEndpointGroup{ - Config: &pbproxystate.PassthroughEndpointGroupConfig{ - ConnectTimeout: durationpb.New(5 * time.Second), - }, - }, - }, - }, - }, - } - } - - for uid, chain := range cfgSnap.ConnectProxy.DiscoveryChain { - targetMap, ok := cfgSnap.ConnectProxy.PassthroughUpstreams[uid] - if !ok { - continue - } - - for targetID := range targetMap { - uid := proxycfg.NewUpstreamIDFromTargetID(targetID) - - sni := connect.ServiceSNI( - uid.Name, "", uid.NamespaceOrDefault(), - uid.PartitionOrDefault(), cfgSnap.Datacenter, - cfgSnap.Roots.TrustDomain) - - // Prefixed with passthrough to distinguish from non-passthrough clusters for the same upstream. - name := "passthrough~" + sni - - c := pbproxystate.Cluster{ - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Passthrough{ - Passthrough: &pbproxystate.PassthroughEndpointGroup{ - Config: &pbproxystate.PassthroughEndpointGroupConfig{ - ConnectTimeout: durationpb.New(5 * time.Second), - }, - }, - }, - }, - }, - } - - if discoTarget, ok := chain.Targets[targetID]; ok && discoTarget.ConnectTimeout > 0 { - c.GetEndpointGroup().GetPassthrough().GetConfig(). - ConnectTimeout = durationpb.New(discoTarget.ConnectTimeout) - } - - transportSocket, err := s.createOutboundMeshMTLS(cfgSnap, []string{getSpiffeID(cfgSnap, uid)}, sni) - if err != nil { - return nil, err - } - c.GetEndpointGroup().GetPassthrough().OutboundTls = transportSocket - - clusters[name] = &c - } - } - - err := cfgSnap.ConnectProxy.DestinationsUpstream.ForEachKeyE(func(uid proxycfg.UpstreamID) error { - svcConfig, ok := cfgSnap.ConnectProxy.DestinationsUpstream.Get(uid) - if !ok || svcConfig.Destination == nil { - return nil - } - - // One Cluster per Destination Address - for _, address := range svcConfig.Destination.Addresses { - name := clusterNameForDestination(cfgSnap, uid.Name, address, uid.NamespaceOrDefault(), uid.PartitionOrDefault()) - - c := &pbproxystate.Cluster{ - AltStatName: name, - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Dynamic{ - Dynamic: &pbproxystate.DynamicEndpointGroup{ - Config: &pbproxystate.DynamicEndpointGroupConfig{ - ConnectTimeout: durationpb.New(5 * time.Second), - // Endpoints are managed separately by EDS - // Having an empty config enables outlier detection with default config. - OutlierDetection: &pbproxystate.OutlierDetection{}, - DisablePanicThreshold: true, - }, - }, - }, - }, - }, - } - sni := connect.ServiceSNI( - uid.Name, "", uid.NamespaceOrDefault(), - uid.PartitionOrDefault(), cfgSnap.Datacenter, - cfgSnap.Roots.TrustDomain) - transportSocket, err := s.createOutboundMeshMTLS(cfgSnap, []string{getSpiffeID(cfgSnap, uid)}, sni) - if err != nil { - return err - } - c.GetEndpointGroup().GetDynamic().OutboundTls = transportSocket - clusters[name] = c - } - return nil - }) - if err != nil { - return nil, err - } - - return clusters, nil -} - -func getSpiffeID(cfgSnap *proxycfg.ConfigSnapshot, uid proxycfg.UpstreamID) string { - spiffeIDService := &connect.SpiffeIDService{ - Host: cfgSnap.Roots.TrustDomain, - Partition: uid.PartitionOrDefault(), - Namespace: uid.NamespaceOrDefault(), - Datacenter: cfgSnap.Datacenter, - Service: uid.Name, - } - return spiffeIDService.URI().String() -} -func clusterNameForDestination(cfgSnap *proxycfg.ConfigSnapshot, name string, - address string, namespace string, partition string) string { - name = destinationSpecificServiceName(name, address) - sni := connect.ServiceSNI(name, "", namespace, partition, - cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) - - // Prefixed with destination to distinguish from non-passthrough clusters - // for the same upstream. - return "destination." + sni -} - -func destinationSpecificServiceName(name string, address string) string { - address = strings.ReplaceAll(address, ":", "-") - address = strings.ReplaceAll(address, ".", "-") - return fmt.Sprintf("%s.%s", address, name) -} - -// TODO(proxystate): Mesh Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func clustersFromSnapshotMeshGateway -// func haveVoters - -// TODO(proxystate): Peering will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makePeerServerClusters - -// TODO(proxystate): Terminating Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func clustersFromSnapshotTerminatingGateway - -// TODO(proxystate): Mesh Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makeGatewayServiceClusters - -// TODO(proxystate): Cluster Peering will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makeGatewayOutgoingClusterPeeringServiceClusters - -// TODO(proxystate): Terminating Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makeDestinationClusters - -// TODO(proxystate): Mesh Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func injectGatewayServiceAddons - -// TODO(proxystate): Terminating Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func injectGatewayDestinationAddons - -// TODO(proxystate): Ingress Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func clustersFromSnapshotIngressGateway - -// TODO(proxystate): API Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func clustersFromSnapshotAPIGateway - -// TODO(proxystate): Ingress Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func configIngressUpstreamCluster - -func (s *Converter) makeAppCluster(cfgSnap *proxycfg.ConfigSnapshot, name, pathProtocol string, port int) (*namedCluster, error) { - var err error - namedCluster := &namedCluster{} - - cfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse Connect.Proxy.Config", "error", err) - } - - //// If we have overridden local cluster config try to parse it into an Envoy cluster - //if cfg.LocalClusterJSON != "" { - // return makeClusterFromUserConfig(cfg.LocalClusterJSON) - //} - - var endpoint *pbproxystate.Endpoint - if cfgSnap.Proxy.LocalServiceSocketPath != "" { - endpoint = makeUnixSocketEndpoint(cfgSnap.Proxy.LocalServiceSocketPath) - } else { - addr := cfgSnap.Proxy.LocalServiceAddress - if addr == "" { - addr = "127.0.0.1" - } - endpoint = makeHostPortEndpoint(addr, port) - } - s.proxyState.Endpoints[name] = &pbproxystate.Endpoints{ - Endpoints: []*pbproxystate.Endpoint{endpoint}, - } - - namedCluster.name = name - namedCluster.cluster = &pbproxystate.Cluster{ - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Static{ - Static: &pbproxystate.StaticEndpointGroup{ - Config: &pbproxystate.StaticEndpointGroupConfig{ - ConnectTimeout: durationpb.New(time.Duration(cfg.LocalConnectTimeoutMs) * time.Millisecond), - }, - }, - }, - }, - }, - } - - protocol := pathProtocol - if protocol == "" { - protocol = cfg.Protocol - } - namedCluster.cluster.Protocol = protocolMap[protocol] - if cfg.MaxInboundConnections > 0 { - namedCluster.cluster.GetEndpointGroup().GetStatic().GetConfig(). - CircuitBreakers = &pbproxystate.CircuitBreakers{ - UpstreamLimits: &pbproxystate.UpstreamLimits{ - MaxConnections: response.MakeUint32Value(cfg.MaxInboundConnections), - }, - } - } - - return namedCluster, err -} - -func (s *Converter) makeUpstreamClusterForPeerService( - uid proxycfg.UpstreamID, - upstreamConfig structs.UpstreamConfig, - peerMeta structs.PeeringServiceMeta, - cfgSnap *proxycfg.ConfigSnapshot, -) (string, *pbproxystate.Cluster, *pbproxystate.Endpoints, error) { - var ( - c *pbproxystate.Cluster - e *pbproxystate.Endpoints - err error - ) - - // TODO(proxystate): escapeHatches will be implemented in the future - //if upstreamConfig.EnvoyClusterJSON != "" { - // c, err = makeClusterFromUserConfig(upstreamConfig.EnvoyClusterJSON) - // if err != nil { - // return "", c, e, err - // } - // // In the happy path don't return yet as we need to inject TLS config still. - //} - - upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - - if err != nil { - return "", c, e, err - } - - tbs, ok := upstreamsSnapshot.UpstreamPeerTrustBundles.Get(uid.Peer) - if !ok { - // this should never happen since we loop through upstreams with - // set trust bundles - return "", c, e, fmt.Errorf("trust bundle not ready for peer %s", uid.Peer) - } - - clusterName := generatePeeredClusterName(uid, tbs) - - outlierDetection := makeOutlierDetection(upstreamConfig.PassiveHealthCheck, nil, true) - // We can't rely on health checks for services on cluster peers because they - // don't take into account service resolvers, splitters and routers. Setting - // MaxEjectionPercent too 100% gives outlier detection the power to eject the - // entire cluster. - outlierDetection.MaxEjectionPercent = &wrapperspb.UInt32Value{Value: 100} - - s.Logger.Trace("generating cluster for", "cluster", clusterName) - if c == nil { - c = &pbproxystate.Cluster{} - - useEDS := true - if _, ok := cfgSnap.ConnectProxy.PeerUpstreamEndpointsUseHostnames[uid]; ok { - // If we're using local mesh gw, the fact that upstreams use hostnames don't matter. - // If we're not using local mesh gw, then resort to CDS. - if upstreamConfig.MeshGateway.Mode != structs.MeshGatewayModeLocal { - useEDS = false - } - } - - // If none of the service instances are addressed by a hostname we - // provide the endpoint IP addresses via EDS - if useEDS { - d := &pbproxystate.DynamicEndpointGroup{ - Config: &pbproxystate.DynamicEndpointGroupConfig{ - UseAltStatName: false, - ConnectTimeout: durationpb.New(time.Duration(upstreamConfig.ConnectTimeoutMs) * time.Millisecond), - DisablePanicThreshold: true, - CircuitBreakers: &pbproxystate.CircuitBreakers{ - UpstreamLimits: makeUpstreamLimitsIfNeeded(upstreamConfig.Limits), - }, - OutlierDetection: outlierDetection, - }, - } - c.Group = &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Dynamic{ - Dynamic: d, - }, - }, - } - transportSocket := &pbproxystate.TransportSocket{ - ConnectionTls: &pbproxystate.TransportSocket_OutboundMesh{ - OutboundMesh: &pbproxystate.OutboundMeshMTLS{ - ValidationContext: &pbproxystate.MeshOutboundValidationContext{ - SpiffeIds: peerMeta.SpiffeID, - TrustBundlePeerNameKey: uid.Peer, - }, - Sni: peerMeta.PrimarySNI(), - }, - }, - } - d.OutboundTls = transportSocket - } else { - d := &pbproxystate.DNSEndpointGroup{ - Config: &pbproxystate.DNSEndpointGroupConfig{ - UseAltStatName: false, - ConnectTimeout: durationpb.New(time.Duration(upstreamConfig.ConnectTimeoutMs) * time.Millisecond), - DisablePanicThreshold: true, - CircuitBreakers: &pbproxystate.CircuitBreakers{ - UpstreamLimits: makeUpstreamLimitsIfNeeded(upstreamConfig.Limits), - }, - OutlierDetection: outlierDetection, - }, - } - c.Group = &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Dns{ - Dns: d, - }, - }, - } - e = &pbproxystate.Endpoints{ - Endpoints: make([]*pbproxystate.Endpoint, 0), - } - - ep, _ := cfgSnap.ConnectProxy.PeerUpstreamEndpoints.Get(uid) - configureClusterWithHostnames( - s.Logger, - d, - e, - "", /*TODO:make configurable?*/ - ep, - true, /*isRemote*/ - false, /*onlyPassing*/ - ) - transportSocket := &pbproxystate.TransportSocket{ - ConnectionTls: &pbproxystate.TransportSocket_OutboundMesh{ - OutboundMesh: &pbproxystate.OutboundMeshMTLS{ - ValidationContext: &pbproxystate.MeshOutboundValidationContext{ - SpiffeIds: peerMeta.SpiffeID, - TrustBundlePeerNameKey: uid.Peer, - }, - Sni: peerMeta.PrimarySNI(), - }, - }, - } - d.OutboundTls = transportSocket - } - } - - return clusterName, c, e, nil -} - -func (s *Converter) makeUpstreamClusterForPreparedQuery(upstream structs.Upstream, cfgSnap *proxycfg.ConfigSnapshot) (*namedCluster, error) { - var c *pbproxystate.Cluster - var err error - - uid := proxycfg.NewUpstreamID(&upstream) - - dc := upstream.Datacenter - if dc == "" { - dc = cfgSnap.Datacenter - } - sni := connect.UpstreamSNI(&upstream, "", dc, cfgSnap.Roots.TrustDomain) - - cfg, _ := structs.ParseUpstreamConfig(upstream.Config) - // TODO(proxystate): add logger and enable this - //if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - //s.Logger.Warn("failed to parse", "upstream", uid, "error", err) - //} - - // TODO(proxystate): escapeHatches will be implemented in the future - //if cfg.EnvoyClusterJSON != "" { - // c, err = makeClusterFromUserConfig(cfg.EnvoyClusterJSON) - // if err != nil { - // return c, err - // } - // // In the happy path don't return yet as we need to inject TLS config still. - //} - - if c == nil { - c = &pbproxystate.Cluster{ - Protocol: protocolMap[cfg.Protocol], - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Dynamic{ - Dynamic: &pbproxystate.DynamicEndpointGroup{ - Config: &pbproxystate.DynamicEndpointGroupConfig{ - ConnectTimeout: durationpb.New(time.Duration(cfg.ConnectTimeoutMs) * time.Millisecond), - // Endpoints are managed separately by EDS - // Having an empty config enables outlier detection with default config. - OutlierDetection: makeOutlierDetection(cfg.PassiveHealthCheck, nil, true), - CircuitBreakers: &pbproxystate.CircuitBreakers{ - UpstreamLimits: makeUpstreamLimitsIfNeeded(cfg.Limits), - }, - }, - }, - }, - }, - }, - } - } - - endpoints := cfgSnap.ConnectProxy.PreparedQueryEndpoints[uid] - var ( - spiffeIDs = make([]string, 0) - seen = make(map[string]struct{}) - ) - for _, e := range endpoints { - id := fmt.Sprintf("%s/%s", e.Node.Datacenter, e.Service.CompoundServiceName()) - if _, ok := seen[id]; ok { - continue - } - seen[id] = struct{}{} - - name := e.Service.Proxy.DestinationServiceName - if e.Service.Connect.Native { - name = e.Service.Service - } - - spiffeIDs = append(spiffeIDs, connect.SpiffeIDService{ - Host: cfgSnap.Roots.TrustDomain, - Namespace: e.Service.NamespaceOrDefault(), - Partition: e.Service.PartitionOrDefault(), - Datacenter: e.Node.Datacenter, - Service: name, - }.URI().String()) - } - - transportSocket, err := s.createOutboundMeshMTLS(cfgSnap, spiffeIDs, sni) - if err != nil { - return nil, err - } - c.GetEndpointGroup().GetDynamic().OutboundTls = transportSocket - - return &namedCluster{name: sni, cluster: c}, nil -} - -func finalizeUpstreamConfig(cfg structs.UpstreamConfig, chain *structs.CompiledDiscoveryChain, connectTimeout time.Duration) structs.UpstreamConfig { - if cfg.Protocol == "" { - cfg.Protocol = chain.Protocol - } - - if cfg.Protocol == "" { - cfg.Protocol = "tcp" - } - - if cfg.ConnectTimeoutMs == 0 { - cfg.ConnectTimeoutMs = int(connectTimeout / time.Millisecond) - } - return cfg -} - -func (s *Converter) createOutboundMeshMTLS(cfgSnap *proxycfg.ConfigSnapshot, spiffeIDs []string, sni string) (*pbproxystate.TransportSocket, error) { - switch cfgSnap.Kind { - case structs.ServiceKindConnectProxy: - case structs.ServiceKindMeshGateway: - default: - return nil, fmt.Errorf("cannot inject peering trust bundles for kind %q", cfgSnap.Kind) - } - - cfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse Connect.Proxy.Config", "error", err) - } - - // Add all trust bundle peer names, including local. - trustBundlePeerNames := []string{"local"} - for _, tb := range cfgSnap.PeeringTrustBundles() { - trustBundlePeerNames = append(trustBundlePeerNames, tb.PeerName) - } - // Arbitrary UUID to reference the identity by. - uuid, err := uuid.GenerateUUID() - if err != nil { - return nil, err - } - - // Create the transport socket - ts := &pbproxystate.TransportSocket{} - - ts.ConnectionTls = &pbproxystate.TransportSocket_OutboundMesh{ - OutboundMesh: &pbproxystate.OutboundMeshMTLS{ - IdentityKey: uuid, - ValidationContext: &pbproxystate.MeshOutboundValidationContext{ - TrustBundlePeerNameKey: trustBundlePeerNames[0], - SpiffeIds: spiffeIDs, - }, - Sni: sni, - }, - } - s.proxyState.LeafCertificates[uuid] = &pbproxystate.LeafCertificate{ - Cert: cfgSnap.Leaf().CertPEM, - Key: cfgSnap.Leaf().PrivateKeyPEM, - } - ts.TlsParameters = makeTLSParametersFromProxyTLSConfig(cfgSnap.MeshConfigTLSOutgoing()) - ts.AlpnProtocols = getAlpnProtocols(cfg.Protocol) - - return ts, nil -} -func (s *Converter) makeUpstreamClustersForDiscoveryChain( - uid proxycfg.UpstreamID, - upstream *structs.Upstream, - chain *structs.CompiledDiscoveryChain, - cfgSnap *proxycfg.ConfigSnapshot, - forMeshGateway bool, -) (map[string]*pbproxystate.Cluster, error) { - if chain == nil { - return nil, fmt.Errorf("cannot create upstream cluster without discovery chain for %s", uid) - } - - if uid.Peer != "" && forMeshGateway { - return nil, fmt.Errorf("impossible to get a peer discovery chain in a mesh gateway") - } - - upstreamConfigMap := make(map[string]interface{}) - if upstream != nil { - upstreamConfigMap = upstream.Config - } - - upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - - // Mesh gateways are exempt because upstreamsSnapshot is only used for - // cluster peering targets and transative failover/redirects are unsupported. - if err != nil && !forMeshGateway { - return nil, err - } - - rawUpstreamConfig, err := structs.ParseUpstreamConfigNoDefaults(upstreamConfigMap) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse", "upstream", uid, - "error", err) - } - - // TODO(proxystate): escapeHatches will be implemented in the future - //var escapeHatchCluster *pbproxystate.Cluster - //if !forMeshGateway { - // if rawUpstreamConfig.EnvoyClusterJSON != "" { - // if chain.Default { - // // If you haven't done anything to setup the discovery chain, then - // // you can use the envoy_cluster_json escape hatch. - // escapeHatchCluster = &pbproxystate.Cluster{ - // EscapeHatchClusterJson: rawUpstreamConfig.EnvoyClusterJSON, - // } - // } else { - // s.Logger.Warn("ignoring escape hatch setting, because a discovery chain is configured for", - // "discovery chain", chain.ServiceName, "upstream", uid, - // "envoy_cluster_json", chain.ServiceName) - // } - // } - //} - - out := make(map[string]*pbproxystate.Cluster) - for _, node := range chain.Nodes { - switch { - case node == nil: - return nil, fmt.Errorf("impossible to process a nil node") - case node.Type != structs.DiscoveryGraphNodeTypeResolver: - continue - case node.Resolver == nil: - return nil, fmt.Errorf("impossible to process a non-resolver node") - } - // These variables are prefixed with primary to avoid shaddowing bugs. - primaryTargetID := node.Resolver.Target - primaryTarget := chain.Targets[primaryTargetID] - primaryTargetClusterName := s.getTargetClusterName(upstreamsSnapshot, chain, primaryTargetID, forMeshGateway) - if primaryTargetClusterName == "" { - continue - } - if forMeshGateway && !cfgSnap.Locality.Matches(primaryTarget.Datacenter, primaryTarget.Partition) { - s.Logger.Warn("ignoring discovery chain target that crosses a datacenter or partition boundary in a mesh gateway", - "target", primaryTarget, - "gatewayLocality", cfgSnap.Locality, - ) - continue - } - - upstreamConfig := finalizeUpstreamConfig(rawUpstreamConfig, chain, node.Resolver.ConnectTimeout) - - mappedTargets, err := s.mapDiscoChainTargets(cfgSnap, chain, node, upstreamConfig, forMeshGateway) - if err != nil { - return nil, err - } - - targetGroups, err := mappedTargets.groupedTargets() - if err != nil { - return nil, err - } - - var failoverGroup *pbproxystate.FailoverGroup - endpointGroups := make([]*pbproxystate.EndpointGroup, 0) - if mappedTargets.failover { - // Create a failover group. The endpoint groups that are part of this failover group are created by the loop - // below. - failoverGroup = &pbproxystate.FailoverGroup{ - Config: &pbproxystate.FailoverGroupConfig{ - ConnectTimeout: durationpb.New(node.Resolver.ConnectTimeout), - }, - } - } - - // Construct the target dynamic endpoint groups. If these are not part of a failover group, they will get added - // directly to the map of pbproxystate.Cluster, if they are a part of a failover group, they will be added to - // the failover group. - for _, groupedTarget := range targetGroups { - s.Logger.Debug("generating cluster for", "cluster", groupedTarget.ClusterName) - dynamic := &pbproxystate.DynamicEndpointGroup{ - Config: &pbproxystate.DynamicEndpointGroupConfig{ - UseAltStatName: true, - ConnectTimeout: durationpb.New(node.Resolver.ConnectTimeout), - // TODO(peering): make circuit breakers or outlier detection work? - CircuitBreakers: &pbproxystate.CircuitBreakers{ - UpstreamLimits: makeUpstreamLimitsIfNeeded(upstreamConfig.Limits), - }, - DisablePanicThreshold: true, - OutlierDetection: makeOutlierDetection(upstreamConfig.PassiveHealthCheck, nil, true), - }, - } - ti := groupedTarget.Targets[0] - transportSocket, err := s.createOutboundMeshMTLS(cfgSnap, ti.SpiffeIDs, ti.SNI) - if err != nil { - return nil, err - } - dynamic.OutboundTls = transportSocket - - var lb *structs.LoadBalancer - if node.LoadBalancer != nil { - lb = node.LoadBalancer - } - if err := injectLBToCluster(lb, dynamic.Config); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to cluster %q: %v", groupedTarget.ClusterName, err) - } - - // TODO: IR: http2 options not currently supported - //if upstreamConfig.Protocol == "http2" || upstreamConfig.Protocol == "grpc" { - // if err := s.setHttp2ProtocolOptions(c); err != nil { - // return nil, err - // } - //} - - switch len(groupedTarget.Targets) { - case 0: - continue - case 1: - // We expect one target so this passes through to continue setting the cluster up. - default: - return nil, fmt.Errorf("cannot have more than one target") - } - - if targetInfo := groupedTarget.Targets[0]; targetInfo.TransportSocket != nil { - dynamic.OutboundTls = targetInfo.TransportSocket - } - - // If the endpoint group is part of a failover group, add it to the failover group. Otherwise add it - // directly to the clusters. - if failoverGroup != nil { - eg := &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Dynamic{ - Dynamic: dynamic, - }, - } - endpointGroups = append(endpointGroups, eg) - } else { - cluster := &pbproxystate.Cluster{ - AltStatName: mappedTargets.baseClusterName, - Protocol: protocolMap[upstreamConfig.Protocol], - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Dynamic{ - Dynamic: dynamic, - }, - }, - }, - } - - out[mappedTargets.baseClusterName] = cluster - } - } - - // If there's a failover group, we only add the failover group to the top level list of clusters. Its endpoint - // groups are inlined. - if failoverGroup != nil { - failoverGroup.EndpointGroups = endpointGroups - cluster := &pbproxystate.Cluster{ - AltStatName: mappedTargets.baseClusterName, - Protocol: protocolMap[upstreamConfig.Protocol], - Group: &pbproxystate.Cluster_FailoverGroup{ - FailoverGroup: failoverGroup, - }, - } - out[mappedTargets.baseClusterName] = cluster - } - } - - //if escapeHatchCluster != nil { - // if len(out) != 1 { - // return nil, fmt.Errorf("cannot inject escape hatch cluster when discovery chain had no nodes") - // } - // var defaultCluster *pbproxystate.Cluster - // for _, k := range out { - // defaultCluster = k - // break - // } - // - // // Overlay what the user provided. - // escapeHatchCluster.GetEndpointGroup().GetDynamic().OutboundTls.ConnectionTls = - // defaultCluster.GetEndpointGroup().GetDynamic().OutboundTls.ConnectionTls - // - // out = append(out, escapeHatchCluster) - //} - - return out, nil -} - -// TODO(proxystate): Mesh Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makeExportedUpstreamClustersForMeshGateway - -// makeClusterFromUserConfig returns the listener config decoded from an -// arbitrary proto3 json format string or an error if it's invalid. -// -// For now we only support embedding in JSON strings because of the hcl parsing -// pain (see Background section in the comment for decode.HookWeakDecodeFromSlice). -// This may be fixed in decode.HookWeakDecodeFromSlice in the future. -// -// When we do that we can support just nesting the config directly into the -// JSON/hcl naturally but this is a stop-gap that gets us an escape hatch -// immediately. It's also probably not a bad thing to support long-term since -// any config generated by other systems will likely be in canonical protobuf -// from rather than our slight variant in JSON/hcl. - -// TODO(proxystate): Mesh and Terminating Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makeGatewayCluster - -func configureClusterWithHostnames( - logger hclog.Logger, - dnsEndpointGroup *pbproxystate.DNSEndpointGroup, - endpointList *pbproxystate.Endpoints, - dnsDiscoveryType string, - // hostnameEndpoints is a list of endpoints with a hostname as their address - hostnameEndpoints structs.CheckServiceNodes, - // isRemote determines whether the cluster is in a remote DC or partition and we should prefer a WAN address - isRemote bool, - // onlyPassing determines whether endpoints that do not have a passing status should be considered unhealthy - onlyPassing bool, -) { - // When a service instance is addressed by a hostname we have Envoy do the DNS resolution - // by setting a DNS cluster type and passing the hostname endpoints via CDS. - if dnsEndpointGroup.Config == nil { - dnsEndpointGroup.Config = &pbproxystate.DNSEndpointGroupConfig{} - } - dnsEndpointGroup.Config.DiscoveryType = pbproxystate.DiscoveryType_DISCOVERY_TYPE_LOGICAL - if dnsDiscoveryType == "strict_dns" { - dnsEndpointGroup.Config.DiscoveryType = pbproxystate.DiscoveryType_DISCOVERY_TYPE_STRICT - } - - endpoints := make([]*envoy_endpoint_v3.LbEndpoint, 0, 1) - uniqueHostnames := make(map[string]bool) - - var ( - hostname string - idx int - fallback *pbproxystate.Endpoint - ) - for i, e := range hostnameEndpoints { - _, addr, port := e.BestAddress(isRemote) - uniqueHostnames[addr] = true - - health, weight := calculateEndpointHealthAndWeight(e, onlyPassing) - if health == pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY { - fallback = makeLbEndpoint(addr, port, health, weight) - continue - } - - if len(endpoints) == 0 { - endpointList.Endpoints = append(endpointList.Endpoints, makeLbEndpoint(addr, port, health, weight)) - - hostname = addr - idx = i - break - } - } - - dc := hostnameEndpoints[idx].Node.Datacenter - service := hostnameEndpoints[idx].Service.CompoundServiceName() - - // Fall back to last unhealthy endpoint if none were healthy - if len(endpoints) == 0 { - logger.Warn("upstream service does not contain any healthy instances", - "dc", dc, "service", service.String()) - - //endpoints = append(endpoints, fallback) - endpointList.Endpoints = append(endpointList.Endpoints, fallback) - } - if len(uniqueHostnames) > 1 { - logger.Warn(fmt.Sprintf("service contains instances with more than one unique hostname; only %q be resolved by Envoy", hostname), - "dc", dc, "service", service.String()) - } - -} - -// TODO(proxystate): Terminating Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makeExternalIPCluster - -// TODO(proxystate): Terminating Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func makeExternalHostnameCluster - -func makeUpstreamLimitsIfNeeded(limits *structs.UpstreamLimits) *pbproxystate.UpstreamLimits { - if limits == nil { - return nil - } - - upstreamLimits := &pbproxystate.UpstreamLimits{} - - // Likewise, make sure to not set any threshold values on the zero-value in - // order to rely on Envoy defaults - if limits.MaxConnections != nil { - upstreamLimits.MaxConnections = response.MakeUint32Value(*limits.MaxConnections) - } - if limits.MaxPendingRequests != nil { - upstreamLimits.MaxPendingRequests = response.MakeUint32Value(*limits.MaxPendingRequests) - } - if limits.MaxConcurrentRequests != nil { - upstreamLimits.MaxConcurrentRequests = response.MakeUint32Value(*limits.MaxConcurrentRequests) - } - - return upstreamLimits -} - -func injectLBToCluster(ec *structs.LoadBalancer, dc *pbproxystate.DynamicEndpointGroupConfig) error { - if ec == nil { - return nil - } - - switch ec.Policy { - case "": - return nil - case structs.LBPolicyLeastRequest: - lr := &pbproxystate.DynamicEndpointGroupConfig_LeastRequest{ - LeastRequest: &pbproxystate.LBPolicyLeastRequest{}, - } - - dc.LbPolicy = lr - - if ec.LeastRequestConfig != nil { - lr.LeastRequest.ChoiceCount = &wrapperspb.UInt32Value{Value: ec.LeastRequestConfig.ChoiceCount} - } - case structs.LBPolicyRoundRobin: - dc.LbPolicy = &pbproxystate.DynamicEndpointGroupConfig_RoundRobin{ - RoundRobin: &pbproxystate.LBPolicyRoundRobin{}, - } - - case structs.LBPolicyRandom: - dc.LbPolicy = &pbproxystate.DynamicEndpointGroupConfig_Random{ - Random: &pbproxystate.LBPolicyRandom{}, - } - - case structs.LBPolicyRingHash: - rh := &pbproxystate.DynamicEndpointGroupConfig_RingHash{ - RingHash: &pbproxystate.LBPolicyRingHash{}, - } - - dc.LbPolicy = rh - - if ec.RingHashConfig != nil { - rh.RingHash.MinimumRingSize = &wrapperspb.UInt64Value{Value: ec.RingHashConfig.MinimumRingSize} - rh.RingHash.MaximumRingSize = &wrapperspb.UInt64Value{Value: ec.RingHashConfig.MaximumRingSize} - } - case structs.LBPolicyMaglev: - dc.LbPolicy = &pbproxystate.DynamicEndpointGroupConfig_Maglev{ - Maglev: &pbproxystate.LBPolicyMaglev{}, - } - - default: - return fmt.Errorf("unsupported load balancer policy %q", ec.Policy) - } - return nil -} - -// generatePeeredClusterName returns an SNI-like cluster name which mimics PeeredServiceSNI -// but excludes partition information which could be ambiguous (local vs remote partition). -func generatePeeredClusterName(uid proxycfg.UpstreamID, tb *pbpeering.PeeringTrustBundle) string { - return strings.Join([]string{ - uid.Name, - uid.NamespaceOrDefault(), - uid.Peer, - "external", - tb.TrustDomain, - }, ".") -} - -func (s *Converter) getTargetClusterName(upstreamsSnapshot *proxycfg.ConfigSnapshotUpstreams, chain *structs.CompiledDiscoveryChain, tid string, forMeshGateway bool) string { - target := chain.Targets[tid] - clusterName := target.Name - targetUID := proxycfg.NewUpstreamIDFromTargetID(tid) - if targetUID.Peer != "" { - tbs, ok := upstreamsSnapshot.UpstreamPeerTrustBundles.Get(targetUID.Peer) - // We can't generate cluster on peers without the trust bundle. The - // trust bundle should be ready soon. - if !ok { - s.Logger.Debug("peer trust bundle not ready for discovery chain target", - "peer", targetUID.Peer, - "target", tid, - ) - return "" - } - - clusterName = generatePeeredClusterName(targetUID, tbs) - } - clusterName = naming.CustomizeClusterName(clusterName, chain) - if forMeshGateway { - clusterName = meshGatewayExportedClusterNamePrefix + clusterName - } - return clusterName -} - -// Return an pbproxystate.OutlierDetection populated by the values from structs.PassiveHealthCheck. -// If all values are zero a default empty OutlierDetection will be returned to -// enable outlier detection with default values. -// - If override is not nil, it will overwrite the values from p, e.g., ingress gateway defaults -// - allowZero is added to handle the legacy case where connect-proxy and mesh gateway can set 0 -// for EnforcingConsecutive5xx. Due to the definition of proto of PassiveHealthCheck, ingress -// gateway's EnforcingConsecutive5xx must be > 0. -func makeOutlierDetection(p *structs.PassiveHealthCheck, override *structs.PassiveHealthCheck, allowZero bool) *pbproxystate.OutlierDetection { - od := &pbproxystate.OutlierDetection{} - if p != nil { - - if p.Interval != 0 { - od.Interval = durationpb.New(p.Interval) - } - if p.MaxFailures != 0 { - od.Consecutive_5Xx = &wrapperspb.UInt32Value{Value: p.MaxFailures} - } - - if p.EnforcingConsecutive5xx != nil { - // NOTE: EnforcingConsecutive5xx must be greater than 0 for ingress-gateway - if *p.EnforcingConsecutive5xx != 0 { - od.EnforcingConsecutive_5Xx = &wrapperspb.UInt32Value{Value: *p.EnforcingConsecutive5xx} - } else if allowZero { - od.EnforcingConsecutive_5Xx = &wrapperspb.UInt32Value{Value: *p.EnforcingConsecutive5xx} - } - } - - if p.MaxEjectionPercent != nil { - od.MaxEjectionPercent = &wrapperspb.UInt32Value{Value: *p.MaxEjectionPercent} - } - if p.BaseEjectionTime != nil { - od.BaseEjectionTime = durationpb.New(*p.BaseEjectionTime) - } - } - - if override == nil { - return od - } - - // override the default outlier detection value - if override.Interval != 0 { - od.Interval = durationpb.New(override.Interval) - } - if override.MaxFailures != 0 { - od.Consecutive_5Xx = &wrapperspb.UInt32Value{Value: override.MaxFailures} - } - - if override.EnforcingConsecutive5xx != nil { - // NOTE: EnforcingConsecutive5xx must be great than 0 for ingress-gateway - if *override.EnforcingConsecutive5xx != 0 { - od.EnforcingConsecutive_5Xx = &wrapperspb.UInt32Value{Value: *override.EnforcingConsecutive5xx} - } - // Because only ingress gateways have overrides and they cannot have a value of 0, there is no allowZero - // override case to handle - } - - if override.MaxEjectionPercent != nil { - od.MaxEjectionPercent = &wrapperspb.UInt32Value{Value: *override.MaxEjectionPercent} - } - if override.BaseEjectionTime != nil { - od.BaseEjectionTime = durationpb.New(*override.BaseEjectionTime) - } - - return od -} - -// protocolMap converts config entry protocols to proxystate protocol values. -// As documented on config entry protos, the valid values are "tcp", "http", -// "http2" and "grpc". Anything else is treated as tcp. -var protocolMap = map[string]pbproxystate.Protocol{ - "http": pbproxystate.Protocol_PROTOCOL_HTTP, - "http2": pbproxystate.Protocol_PROTOCOL_HTTP2, - "grpc": pbproxystate.Protocol_PROTOCOL_GRPC, - "tcp": pbproxystate.Protocol_PROTOCOL_TCP, -} diff --git a/agent/xds/proxystateconverter/converter.go b/agent/xds/proxystateconverter/converter.go deleted file mode 100644 index 4c31127400d2a..0000000000000 --- a/agent/xds/proxystateconverter/converter.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxystateconverter - -import ( - "fmt" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/configfetcher" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -// Converter converts a single snapshot into a ProxyState. -type Converter struct { - Logger hclog.Logger - CfgFetcher configfetcher.ConfigFetcher - proxyState *proxytracker.ProxyState -} - -func NewConverter( - logger hclog.Logger, - cfgFetcher configfetcher.ConfigFetcher, -) *Converter { - return &Converter{ - Logger: logger, - CfgFetcher: cfgFetcher, - proxyState: &proxytracker.ProxyState{ - ProxyState: &pbmesh.ProxyState{ - Listeners: make([]*pbproxystate.Listener, 0), - Clusters: make(map[string]*pbproxystate.Cluster), - Routes: make(map[string]*pbproxystate.Route), - Endpoints: make(map[string]*pbproxystate.Endpoints), - }, - }, - } -} - -func (g *Converter) ProxyStateFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) (*proxytracker.ProxyState, error) { - err := g.resourcesFromSnapshot(cfgSnap) - if err != nil { - return nil, fmt.Errorf("failed to generate FullProxyState: %v", err) - } - - return g.proxyState, nil -} - -func (g *Converter) resourcesFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) error { - err := g.tlsConfigFromSnapshot(cfgSnap) - if err != nil { - return err - } - - err = g.listenersFromSnapshot(cfgSnap) - if err != nil { - return err - } - - err = g.endpointsFromSnapshot(cfgSnap) - if err != nil { - return err - } - err = g.clustersFromSnapshot(cfgSnap) - if err != nil { - return err - } - err = g.routesFromSnapshot(cfgSnap) - if err != nil { - return err - } - - //g.secretsFromSnapshot(cfgSnap) - return nil -} - -const localPeerKey = "local" - -func (g *Converter) tlsConfigFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) error { - proxyStateTLS := &pbproxystate.TLS{} - g.proxyState.TrustBundles = make(map[string]*pbproxystate.TrustBundle) - g.proxyState.LeafCertificates = make(map[string]*pbproxystate.LeafCertificate) - - // Set the TLS in the top level proxyState - g.proxyState.Tls = proxyStateTLS - - // Add local trust bundle - g.proxyState.TrustBundles[localPeerKey] = &pbproxystate.TrustBundle{ - TrustDomain: cfgSnap.Roots.TrustDomain, - Roots: []string{cfgSnap.RootPEMs()}, - } - - // Add peered trust bundles for remote peers that will dial this proxy. - for _, peeringTrustBundle := range cfgSnap.PeeringTrustBundles() { - g.proxyState.TrustBundles[peeringTrustBundle.PeerName] = &pbproxystate.TrustBundle{ - TrustDomain: peeringTrustBundle.GetTrustDomain(), - Roots: peeringTrustBundle.RootPEMs, - } - } - - // Add upstream peer trust bundles for dialing upstreams in remote peers. - upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - if err != nil { - if !(cfgSnap.Kind == structs.ServiceKindMeshGateway || cfgSnap.Kind == structs.ServiceKindTerminatingGateway) { - return err - } - } - if upstreamsSnapshot != nil { - upstreamsSnapshot.UpstreamPeerTrustBundles.ForEachKeyE(func(k proxycfg.PeerName) error { - tbs, ok := upstreamsSnapshot.UpstreamPeerTrustBundles.Get(k) - if ok { - g.proxyState.TrustBundles[k] = &pbproxystate.TrustBundle{ - TrustDomain: tbs.TrustDomain, - Roots: tbs.RootPEMs, - } - } - return nil - }) - } - - if cfgSnap.MeshConfigTLSOutgoing() != nil { - proxyStateTLS.OutboundTlsParameters = makeTLSParametersFromTLSConfig(cfgSnap.MeshConfigTLSOutgoing().TLSMinVersion, - cfgSnap.MeshConfigTLSOutgoing().TLSMaxVersion, cfgSnap.MeshConfigTLSOutgoing().CipherSuites) - } - - if cfgSnap.MeshConfigTLSIncoming() != nil { - proxyStateTLS.InboundTlsParameters = makeTLSParametersFromTLSConfig(cfgSnap.MeshConfigTLSIncoming().TLSMinVersion, - cfgSnap.MeshConfigTLSIncoming().TLSMaxVersion, cfgSnap.MeshConfigTLSIncoming().CipherSuites) - } - - return nil -} diff --git a/agent/xds/proxystateconverter/endpoints.go b/agent/xds/proxystateconverter/endpoints.go deleted file mode 100644 index 2ed7164316c18..0000000000000 --- a/agent/xds/proxystateconverter/endpoints.go +++ /dev/null @@ -1,671 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxystateconverter - -import ( - "errors" - "fmt" - - "github.com/hashicorp/consul/agent/connect" - "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/go-bexpr" - - "google.golang.org/protobuf/types/known/wrapperspb" -) - -func makeLbEndpoint(addr string, port int, health pbproxystate.HealthStatus, weight int) *pbproxystate.Endpoint { - ep := &pbproxystate.Endpoint{ - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: addr, - Port: uint32(port), - }, - }, - } - ep.HealthStatus = health - ep.LoadBalancingWeight = &wrapperspb.UInt32Value{Value: uint32(weight)} - return ep -} - -// endpointsFromSnapshot returns the mesh API representation of the "routes" in the snapshot. -func (s *Converter) endpointsFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) error { - - if cfgSnap == nil { - return errors.New("nil config given") - } - - switch cfgSnap.Kind { - case structs.ServiceKindConnectProxy: - return s.endpointsFromSnapshotConnectProxy(cfgSnap) - //case structs.ServiceKindTerminatingGateway: - // return s.endpointsFromSnapshotTerminatingGateway(cfgSnap) - //case structs.ServiceKindMeshGateway: - // return s.endpointsFromSnapshotMeshGateway(cfgSnap) - //case structs.ServiceKindIngressGateway: - // return s.endpointsFromSnapshotIngressGateway(cfgSnap) - //case structs.ServiceKindAPIGateway: - // return s.endpointsFromSnapshotAPIGateway(cfgSnap) - default: - return fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind) - } -} - -// endpointsFromSnapshotConnectProxy returns the xDS API representation of the "endpoints" -// (upstream instances) in the snapshot. -func (s *Converter) endpointsFromSnapshotConnectProxy(cfgSnap *proxycfg.ConfigSnapshot) error { - eps := make(map[string]*pbproxystate.Endpoints) - - // NOTE: Any time we skip a chain below we MUST also skip that discovery chain in clusters.go - // so that the sets of endpoints generated matches the sets of clusters. - for uid, chain := range cfgSnap.ConnectProxy.DiscoveryChain { - upstream, skip := cfgSnap.ConnectProxy.GetUpstream(uid, &cfgSnap.ProxyID.EnterpriseMeta) - if skip { - // Discovery chain is not associated with a known explicit or implicit upstream so it is skipped. - continue - } - - var upstreamConfigMap map[string]interface{} - if upstream != nil { - upstreamConfigMap = upstream.Config - } - - es, err := s.endpointsFromDiscoveryChain( - uid, - chain, - cfgSnap, - cfgSnap.Locality, - upstreamConfigMap, - cfgSnap.ConnectProxy.WatchedUpstreamEndpoints[uid], - cfgSnap.ConnectProxy.WatchedGatewayEndpoints[uid], - false, - ) - if err != nil { - return err - } - - for clusterName, endpoints := range es { - eps[clusterName] = &pbproxystate.Endpoints{ - Endpoints: endpoints, - } - - } - } - - // NOTE: Any time we skip an upstream below we MUST also skip that same - // upstream in clusters.go so that the sets of endpoints generated matches - // the sets of clusters. - for _, uid := range cfgSnap.ConnectProxy.PeeredUpstreamIDs() { - upstream, skip := cfgSnap.ConnectProxy.GetUpstream(uid, &cfgSnap.ProxyID.EnterpriseMeta) - if skip { - // Discovery chain is not associated with a known explicit or implicit upstream so it is skipped. - continue - } - - tbs, ok := cfgSnap.ConnectProxy.UpstreamPeerTrustBundles.Get(uid.Peer) - if !ok { - // this should never happen since we loop through upstreams with - // set trust bundles - return fmt.Errorf("trust bundle not ready for peer %s", uid.Peer) - } - - clusterName := generatePeeredClusterName(uid, tbs) - - mgwMode := structs.MeshGatewayModeDefault - if upstream != nil { - mgwMode = upstream.MeshGateway.Mode - } - peerServiceEndpoints, err := s.makeEndpointsForPeerService(cfgSnap, uid, mgwMode) - if err != nil { - return err - } - - if peerServiceEndpoints != nil { - pbEndpoints := &pbproxystate.Endpoints{ - Endpoints: peerServiceEndpoints, - } - - eps[clusterName] = pbEndpoints - } - } - - // Looping over explicit upstreams is only needed for prepared queries because they do not have discovery chains - for _, u := range cfgSnap.Proxy.Upstreams { - if u.DestinationType != structs.UpstreamDestTypePreparedQuery { - continue - } - uid := proxycfg.NewUpstreamID(&u) - - dc := u.Datacenter - if dc == "" { - dc = cfgSnap.Datacenter - } - clusterName := connect.UpstreamSNI(&u, "", dc, cfgSnap.Roots.TrustDomain) - - endpoints, ok := cfgSnap.ConnectProxy.PreparedQueryEndpoints[uid] - if ok { - epts := makeEndpointsForLoadAssignment( - cfgSnap, - nil, - []loadAssignmentEndpointGroup{ - {Endpoints: endpoints}, - }, - cfgSnap.Locality, - ) - pbEndpoints := &pbproxystate.Endpoints{ - Endpoints: epts, - } - - eps[clusterName] = pbEndpoints - } - } - - // Loop over potential destinations in the mesh, then grab the gateway nodes associated with each - cfgSnap.ConnectProxy.DestinationsUpstream.ForEachKey(func(uid proxycfg.UpstreamID) bool { - svcConfig, ok := cfgSnap.ConnectProxy.DestinationsUpstream.Get(uid) - if !ok || svcConfig.Destination == nil { - return true - } - - for _, address := range svcConfig.Destination.Addresses { - clusterName := clusterNameForDestination(cfgSnap, uid.Name, address, uid.NamespaceOrDefault(), uid.PartitionOrDefault()) - - endpoints, ok := cfgSnap.ConnectProxy.DestinationGateways.Get(uid) - if ok { - epts := makeEndpointsForLoadAssignment( - cfgSnap, - nil, - []loadAssignmentEndpointGroup{ - {Endpoints: endpoints}, - }, - proxycfg.GatewayKey{ /*empty so it never matches*/ }, - ) - pbEndpoints := &pbproxystate.Endpoints{ - Endpoints: epts, - } - eps[clusterName] = pbEndpoints - } - } - - return true - }) - - s.proxyState.Endpoints = eps - return nil -} - -func (s *Converter) makeEndpointsForPeerService( - cfgSnap *proxycfg.ConfigSnapshot, - uid proxycfg.UpstreamID, - upstreamGatewayMode structs.MeshGatewayMode, -) ([]*pbproxystate.Endpoint, error) { - var eps []*pbproxystate.Endpoint - - upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - if err != nil { - return eps, err - } - - if upstreamGatewayMode == structs.MeshGatewayModeNone { - s.Logger.Warn(fmt.Sprintf("invalid mesh gateway mode 'none', defaulting to 'remote' for %q", uid)) - } - - // If an upstream is configured with local mesh gw mode, we make a load assignment - // from the gateway endpoints instead of those of the upstreams. - if upstreamGatewayMode == structs.MeshGatewayModeLocal { - localGw, ok := cfgSnap.ConnectProxy.WatchedLocalGWEndpoints.Get(cfgSnap.Locality.String()) - if !ok { - // local GW is not ready; return early - return eps, nil - } - eps = makeEndpointsForLoadAssignment( - cfgSnap, - nil, - []loadAssignmentEndpointGroup{ - {Endpoints: localGw}, - }, - cfgSnap.Locality, - ) - return eps, nil - } - - // Also skip peer instances with a hostname as their address. EDS - // cannot resolve hostnames, so we provide them through CDS instead. - if _, ok := upstreamsSnapshot.PeerUpstreamEndpointsUseHostnames[uid]; ok { - return eps, nil - } - - endpoints, ok := upstreamsSnapshot.PeerUpstreamEndpoints.Get(uid) - if !ok { - return nil, nil - } - eps = makeEndpointsForLoadAssignment( - cfgSnap, - nil, - []loadAssignmentEndpointGroup{ - {Endpoints: endpoints}, - }, - proxycfg.GatewayKey{ /*empty so it never matches*/ }, - ) - return eps, nil -} - -func (s *Converter) filterSubsetEndpoints(subset *structs.ServiceResolverSubset, endpoints structs.CheckServiceNodes) (structs.CheckServiceNodes, error) { - // locally execute the subsets filter - if subset.Filter != "" { - filter, err := bexpr.CreateFilter(subset.Filter, nil, endpoints) - if err != nil { - return nil, err - } - - raw, err := filter.Execute(endpoints) - if err != nil { - return nil, err - } - return raw.(structs.CheckServiceNodes), nil - } - return endpoints, nil -} - -// TODO(proxystate): Terminating Gateway will be added in the future. -// Functions to add from agent/xds/endpoints.go: -// func endpointsFromSnapshotTerminatingGateway - -// TODO(proxystate): Mesh Gateway will be added in the future. -// Functions to add from agent/xds/endpoints.go: -// func endpointsFromSnapshotMeshGateway - -// TODO(proxystate): Cluster Peering will be added in the future. -// Functions to add from agent/xds/endpoints.go: -// func makeEndpointsForOutgoingPeeredServices - -// TODO(proxystate): Mesh Gateway will be added in the future. -// Functions to add from agent/xds/endpoints.go: -// func endpointsFromServicesAndResolvers - -// TODO(proxystate): Mesh Gateway will be added in the future. -// Functions to add from agent/xds/endpoints.go: -// func makePeerServerEndpointsForMeshGateway - -// TODO(proxystate): Ingress Gateway will be added in the future. -// Functions to add from agent/xds/endpoints.go: -// func endpointsFromSnapshotIngressGateway - -// TODO(proxystate): API Gateway will be added in the future. -// Functions to add from agent/xds/endpoints.go: -// func endpointsFromSnapshotAPIGateway - -// used in clusters.go -func makeHostPortEndpoint(host string, port int) *pbproxystate.Endpoint { - return &pbproxystate.Endpoint{ - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: host, - Port: uint32(port), - }, - }, - } -} - -func makeUnixSocketEndpoint(path string) *pbproxystate.Endpoint { - return &pbproxystate.Endpoint{ - Address: &pbproxystate.Endpoint_UnixSocket{ - UnixSocket: &pbproxystate.UnixSocketAddress{ - Path: path, - // envoy's mode is particular to a pipe address and is uint32. - // it also says "The mode for the Pipe. Not applicable for abstract sockets." - // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/address.proto#config-core-v3-pipe - Mode: "0", - }, - }, - } -} - -func (s *Converter) makeUpstreamLoadAssignmentEndpointForPeerService( - cfgSnap *proxycfg.ConfigSnapshot, - uid proxycfg.UpstreamID, - upstreamGatewayMode structs.MeshGatewayMode, -) ([]*pbproxystate.Endpoint, error) { - var eps []*pbproxystate.Endpoint - - upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - if err != nil { - return eps, err - } - - if upstreamGatewayMode == structs.MeshGatewayModeNone { - s.Logger.Warn(fmt.Sprintf("invalid mesh gateway mode 'none', defaulting to 'remote' for %q", uid)) - } - - // If an upstream is configured with local mesh gw mode, we make a load assignment - // from the gateway endpoints instead of those of the upstreams. - if upstreamGatewayMode == structs.MeshGatewayModeLocal { - localGw, ok := cfgSnap.ConnectProxy.WatchedLocalGWEndpoints.Get(cfgSnap.Locality.String()) - if !ok { - // local GW is not ready; return early - return eps, nil - } - eps = makeEndpointsForLoadAssignment( - cfgSnap, - nil, - []loadAssignmentEndpointGroup{ - {Endpoints: localGw}, - }, - cfgSnap.Locality, - ) - return eps, nil - } - - // Also skip peer instances with a hostname as their address. EDS - // cannot resolve hostnames, so we provide them through CDS instead. - if _, ok := upstreamsSnapshot.PeerUpstreamEndpointsUseHostnames[uid]; ok { - return eps, nil - } - - endpoints, ok := upstreamsSnapshot.PeerUpstreamEndpoints.Get(uid) - if !ok { - return nil, nil - } - eps = makeEndpointsForLoadAssignment( - cfgSnap, - nil, - []loadAssignmentEndpointGroup{ - {Endpoints: endpoints}, - }, - proxycfg.GatewayKey{ /*empty so it never matches*/ }, - ) - return eps, nil -} - -func (s *Converter) endpointsFromDiscoveryChain( - uid proxycfg.UpstreamID, - chain *structs.CompiledDiscoveryChain, - cfgSnap *proxycfg.ConfigSnapshot, - gatewayKey proxycfg.GatewayKey, - upstreamConfigMap map[string]interface{}, - upstreamEndpoints map[string]structs.CheckServiceNodes, - gatewayEndpoints map[string]structs.CheckServiceNodes, - forMeshGateway bool, -) (map[string][]*pbproxystate.Endpoint, error) { - if chain == nil { - if forMeshGateway { - return nil, fmt.Errorf("missing discovery chain for %s", uid) - } - return nil, nil - } - - if upstreamConfigMap == nil { - upstreamConfigMap = make(map[string]interface{}) // TODO:needed? - } - - clusterEndpoints := make(map[string][]*pbproxystate.Endpoint) - - // TODO(proxystate): escape hatches will be implemented in the future - //var escapeHatchCluster *pbproxystate.Cluster - //if !forMeshGateway { - - //cfg, err := structs.ParseUpstreamConfigNoDefaults(upstreamConfigMap) - //if err != nil { - // // Don't hard fail on a config typo, just warn. The parse func returns - // // default config if there is an error so it's safe to continue. - // s.Logger.Warn("failed to parse", "upstream", uid, - // "error", err) - //} - - //if cfg.EnvoyClusterJSON != "" { - // if chain.Default { - // // If you haven't done anything to setup the discovery chain, then - // // you can use the envoy_cluster_json escape hatch. - // escapeHatchCluster, err = makeClusterFromUserConfig(cfg.EnvoyClusterJSON) - // if err != nil { - // return ce, nil - // } - // } else { - // s.Logger.Warn("ignoring escape hatch setting, because a discovery chain is configued for", - // "discovery chain", chain.ServiceName, "upstream", uid, - // "envoy_cluster_json", chain.ServiceName) - // } - //} - //} - - mgwMode := structs.MeshGatewayModeDefault - if upstream, _ := cfgSnap.ConnectProxy.GetUpstream(uid, &cfgSnap.ProxyID.EnterpriseMeta); upstream != nil { - mgwMode = upstream.MeshGateway.Mode - } - - // Find all resolver nodes. - for _, node := range chain.Nodes { - switch { - case node == nil: - return nil, fmt.Errorf("impossible to process a nil node") - case node.Type != structs.DiscoveryGraphNodeTypeResolver: - continue - case node.Resolver == nil: - return nil, fmt.Errorf("impossible to process a non-resolver node") - } - rawUpstreamConfig, err := structs.ParseUpstreamConfigNoDefaults(upstreamConfigMap) - if err != nil { - return nil, err - } - upstreamConfig := finalizeUpstreamConfig(rawUpstreamConfig, chain, node.Resolver.ConnectTimeout) - - mappedTargets, err := s.mapDiscoChainTargets(cfgSnap, chain, node, upstreamConfig, forMeshGateway) - if err != nil { - return nil, err - } - - targetGroups, err := mappedTargets.groupedTargets() - if err != nil { - return nil, err - } - - for _, groupedTarget := range targetGroups { - clusterName := groupedTarget.ClusterName - // TODO(proxystate): escape hatches will be implemented in the future - //if escapeHatchCluster != nil { - // clusterName = escapeHatchCluster.Name - //} - switch len(groupedTarget.Targets) { - case 0: - continue - case 1: - // We expect one target so this passes through to continue setting the load assignment up. - default: - return nil, fmt.Errorf("cannot have more than one target") - } - ti := groupedTarget.Targets[0] - s.Logger.Debug("generating endpoints for", "cluster", clusterName, "targetID", ti.TargetID) - targetUID := proxycfg.NewUpstreamIDFromTargetID(ti.TargetID) - if targetUID.Peer != "" { - peerServiceEndpoints, err := s.makeEndpointsForPeerService(cfgSnap, targetUID, mgwMode) - if err != nil { - return nil, err - } - if peerServiceEndpoints != nil { - clusterEndpoints[clusterName] = peerServiceEndpoints - } - continue - } - - endpointGroup, valid := makeLoadAssignmentEndpointGroup( - chain.Targets, - upstreamEndpoints, - gatewayEndpoints, - ti.TargetID, - gatewayKey, - forMeshGateway, - ) - if !valid { - continue // skip the cluster if we're still populating the snapshot - } - - epts := makeEndpointsForLoadAssignment( - cfgSnap, - ti.PrioritizeByLocality, - []loadAssignmentEndpointGroup{endpointGroup}, - gatewayKey, - ) - clusterEndpoints[clusterName] = epts - } - } - - return clusterEndpoints, nil -} - -// TODO(proxystate): Mesh Gateway will be added in the future. -// Functions to add from agent/xds/endpoints.go: -// func makeExportedUpstreamEndpointsForMeshGateway - -type loadAssignmentEndpointGroup struct { - Endpoints structs.CheckServiceNodes - OnlyPassing bool - OverrideHealth pbproxystate.HealthStatus -} - -func makeEndpointsForLoadAssignment(cfgSnap *proxycfg.ConfigSnapshot, - policy *structs.DiscoveryPrioritizeByLocality, - endpointGroups []loadAssignmentEndpointGroup, - localKey proxycfg.GatewayKey) []*pbproxystate.Endpoint { - pbEndpoints := make([]*pbproxystate.Endpoint, 0, len(endpointGroups)) - - // TODO(proxystate): this will be added with property overrides having golden files with this - //if len(endpointGroups) > 1 { - // cla.Policy = &envoy_endpoint_v3.ClusterLoadAssignment_Policy{ - // // We choose such a large value here that the failover math should - // // in effect not happen until zero instances are healthy. - // OverprovisioningFactor: response.MakeUint32Value(100000), - // } - //} - - var priority uint32 - - for _, endpointGroup := range endpointGroups { - endpointsByLocality, err := groupedEndpoints(cfgSnap.ServiceLocality, policy, endpointGroup.Endpoints) - - if err != nil { - continue - } - - for _, endpoints := range endpointsByLocality { - for _, ep := range endpoints { - // TODO (mesh-gateway) - should we respect the translate_wan_addrs configuration here or just always use the wan for cross-dc? - _, addr, port := ep.BestAddress(!localKey.Matches(ep.Node.Datacenter, ep.Node.PartitionOrDefault())) - healthStatus, weight := calculateEndpointHealthAndWeight(ep, endpointGroup.OnlyPassing) - - if endpointGroup.OverrideHealth != pbproxystate.HealthStatus_HEALTH_STATUS_UNKNOWN { - healthStatus = endpointGroup.OverrideHealth - } - - endpoint := makeHostPortEndpoint(addr, port) - endpoint.HealthStatus = healthStatus - endpoint.LoadBalancingWeight = response.MakeUint32Value(weight) - - pbEndpoints = append(pbEndpoints, endpoint) - } - - // TODO(proxystate): what do we do about priority downstream? - //cla.Endpoints = append(cla.Endpoints, &envoy_endpoint_v3.LocalityLbEndpoints{ - // Priority: priority, - // LbEndpoints: es, - //}) - - priority++ - } - } - - return pbEndpoints -} - -func makeLoadAssignmentEndpointGroup( - targets map[string]*structs.DiscoveryTarget, - targetHealth map[string]structs.CheckServiceNodes, - gatewayHealth map[string]structs.CheckServiceNodes, - targetID string, - localKey proxycfg.GatewayKey, - forMeshGateway bool, -) (loadAssignmentEndpointGroup, bool) { - realEndpoints, ok := targetHealth[targetID] - if !ok { - // skip the cluster if we're still populating the snapshot - return loadAssignmentEndpointGroup{}, false - } - target := targets[targetID] - - var gatewayKey proxycfg.GatewayKey - - switch target.MeshGateway.Mode { - case structs.MeshGatewayModeRemote: - gatewayKey.Datacenter = target.Datacenter - gatewayKey.Partition = target.Partition - case structs.MeshGatewayModeLocal: - gatewayKey = localKey - } - - if forMeshGateway || gatewayKey.IsEmpty() || localKey.Matches(target.Datacenter, target.Partition) { - // Gateways are not needed if the request isn't for a remote DC or partition. - return loadAssignmentEndpointGroup{ - Endpoints: realEndpoints, - OnlyPassing: target.Subset.OnlyPassing, - }, true - } - - // If using a mesh gateway we need to pull those endpoints instead. - gatewayEndpoints, ok := gatewayHealth[gatewayKey.String()] - if !ok { - // skip the cluster if we're still populating the snapshot - return loadAssignmentEndpointGroup{}, false - } - - // But we will use the health from the actual backend service. - overallHealth := pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY - for _, ep := range realEndpoints { - health, _ := calculateEndpointHealthAndWeight(ep, target.Subset.OnlyPassing) - if health == pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY { - overallHealth = pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY - break - } - } - - return loadAssignmentEndpointGroup{ - Endpoints: gatewayEndpoints, - OverrideHealth: overallHealth, - }, true -} - -func calculateEndpointHealthAndWeight( - ep structs.CheckServiceNode, - onlyPassing bool, -) (pbproxystate.HealthStatus, int) { - healthStatus := pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY - weight := 1 - if ep.Service.Weights != nil { - weight = ep.Service.Weights.Passing - } - - for _, chk := range ep.Checks { - if chk.Status == api.HealthCritical { - healthStatus = pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY - } - if onlyPassing && chk.Status != api.HealthPassing { - healthStatus = pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY - } - if chk.Status == api.HealthWarning && ep.Service.Weights != nil { - weight = ep.Service.Weights.Warning - } - } - // Make weights fit Envoy's limits. A zero weight means that either Warning - // (likely) or Passing (weirdly) weight has been set to 0 effectively making - // this instance unhealthy and should not be sent traffic. - if weight < 1 { - healthStatus = pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY - weight = 1 - } - if weight > 128 { - weight = 128 - } - return healthStatus, weight -} diff --git a/agent/xds/proxystateconverter/failover_policy.go b/agent/xds/proxystateconverter/failover_policy.go deleted file mode 100644 index ae1565458fa82..0000000000000 --- a/agent/xds/proxystateconverter/failover_policy.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxystateconverter - -import ( - "fmt" - - "github.com/hashicorp/consul/agent/connect" - "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -type discoChainTargets struct { - baseClusterName string - targets []targetInfo - failover bool - failoverPolicy structs.ServiceResolverFailoverPolicy -} - -type targetInfo struct { - TargetID string - TransportSocket *pbproxystate.TransportSocket - SNI string - RootPEMs string - SpiffeIDs []string - Region *string - - PrioritizeByLocality *structs.DiscoveryPrioritizeByLocality -} - -type discoChainTargetGroup struct { - Targets []targetInfo - ClusterName string -} - -func (ft discoChainTargets) groupedTargets() ([]discoChainTargetGroup, error) { - var targetGroups []discoChainTargetGroup - - if !ft.failover { - targetGroups = append(targetGroups, discoChainTargetGroup{ - ClusterName: ft.baseClusterName, - Targets: ft.targets, - }) - return targetGroups, nil - } - - switch ft.failoverPolicy.Mode { - case "sequential", "": - return ft.sequential() - case "order-by-locality": - return ft.orderByLocality() - default: - return targetGroups, fmt.Errorf("unexpected failover policy") - } -} - -func (s *Converter) mapDiscoChainTargets(cfgSnap *proxycfg.ConfigSnapshot, chain *structs.CompiledDiscoveryChain, node *structs.DiscoveryGraphNode, upstreamConfig structs.UpstreamConfig, forMeshGateway bool) (discoChainTargets, error) { - failoverTargets := discoChainTargets{} - - if node.Resolver == nil { - return discoChainTargets{}, fmt.Errorf("impossible to process a non-resolver node") - } - - primaryTargetID := node.Resolver.Target - upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - if err != nil && !forMeshGateway { - return discoChainTargets{}, err - } - - failoverTargets.baseClusterName = s.getTargetClusterName(upstreamsSnapshot, chain, primaryTargetID, forMeshGateway) - - tids := []string{primaryTargetID} - failover := node.Resolver.Failover - if failover != nil && !forMeshGateway { - tids = append(tids, failover.Targets...) - failoverTargets.failover = true - if failover.Policy == nil { - failoverTargets.failoverPolicy = structs.ServiceResolverFailoverPolicy{} - } else { - failoverTargets.failoverPolicy = *failover.Policy - } - } - - for _, tid := range tids { - target := chain.Targets[tid] - targetUID := proxycfg.NewUpstreamIDFromTargetID(tid) - ti := targetInfo{TargetID: tid, PrioritizeByLocality: target.PrioritizeByLocality} - - configureTLS := true - if forMeshGateway { - // We only initiate TLS if we're doing an L7 proxy. - configureTLS = structs.IsProtocolHTTPLike(upstreamConfig.Protocol) - } - - if !configureTLS { - failoverTargets.targets = append(failoverTargets.targets, ti) - continue - } - - if targetUID.Peer != "" { - tbs, _ := upstreamsSnapshot.UpstreamPeerTrustBundles.Get(targetUID.Peer) - - peerMeta, found := upstreamsSnapshot.UpstreamPeerMeta(targetUID) - if !found { - s.Logger.Warn("failed to fetch upstream peering metadata", "target", targetUID) - continue - } - ti.SNI = peerMeta.PrimarySNI() - ti.SpiffeIDs = peerMeta.SpiffeID - region := target.Locality.GetRegion() - ti.Region = ®ion - ti.RootPEMs = tbs.ConcatenatedRootPEMs() - } else { - ti.SNI = target.SNI - ti.RootPEMs = cfgSnap.RootPEMs() - ti.SpiffeIDs = []string{connect.SpiffeIDService{ - Host: cfgSnap.Roots.TrustDomain, - Namespace: target.Namespace, - Partition: target.Partition, - Datacenter: target.Datacenter, - Service: target.Service, - }.URI().String()} - } - //commonTLSContext := makeCommonTLSContext( - // cfgSnap.Leaf(), - // rootPEMs, - // makeTLSParametersFromProxyTLSConfig(cfgSnap.MeshConfigTLSOutgoing()), - //) - // - //err := injectSANMatcher(commonTLSContext, spiffeIDs...) - //if err != nil { - // return failoverTargets, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", sni, err) - //} - - //tlsContext := &envoy_tls_v3.UpstreamTlsContext{ - // CommonTlsContext: commonTLSContext, - // Sni: sni, - //} - //ti.TLSContext = tlsContext - failoverTargets.targets = append(failoverTargets.targets, ti) - } - - return failoverTargets, nil -} - -func (ft discoChainTargets) sequential() ([]discoChainTargetGroup, error) { - var targetGroups []discoChainTargetGroup - for i, t := range ft.targets { - targetGroups = append(targetGroups, discoChainTargetGroup{ - ClusterName: fmt.Sprintf("%s%d~%s", xdscommon.FailoverClusterNamePrefix, i, ft.baseClusterName), - Targets: []targetInfo{t}, - }) - } - return targetGroups, nil -} diff --git a/agent/xds/proxystateconverter/failover_policy_ce.go b/agent/xds/proxystateconverter/failover_policy_ce.go deleted file mode 100644 index b68d9b2e738bc..0000000000000 --- a/agent/xds/proxystateconverter/failover_policy_ce.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package proxystateconverter - -import ( - "fmt" -) - -func (ft discoChainTargets) orderByLocality() ([]discoChainTargetGroup, error) { - return nil, fmt.Errorf("order-by-locality is a Consul Enterprise feature") -} diff --git a/agent/xds/proxystateconverter/listeners.go b/agent/xds/proxystateconverter/listeners.go deleted file mode 100644 index 266e96383c7a6..0000000000000 --- a/agent/xds/proxystateconverter/listeners.go +++ /dev/null @@ -1,1695 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxystateconverter - -import ( - "errors" - "fmt" - "net" - "net/url" - "regexp" - "strconv" - "strings" - "time" - - envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-uuid" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/connect" - "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/config" - "github.com/hashicorp/consul/agent/xds/naming" - "github.com/hashicorp/consul/agent/xds/platform" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/sdk/iptables" - "github.com/hashicorp/consul/types" -) - -// listenersFromSnapshot adds listeners to pbmesh.ProxyState using the config snapshot. -func (s *Converter) listenersFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) error { - if cfgSnap == nil { - return errors.New("nil config given") - } - - switch cfgSnap.Kind { - case structs.ServiceKindConnectProxy: - return s.listenersFromSnapshotConnectProxy(cfgSnap) - case structs.ServiceKindTerminatingGateway, - structs.ServiceKindMeshGateway, - structs.ServiceKindIngressGateway, - structs.ServiceKindAPIGateway: - // TODO(proxystate): gateway support will be added in the future - //return s.listenersFromSnapshotGateway(cfgSnap) - default: - return fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind) - } - return nil -} - -// listenersFromSnapshotConnectProxy returns the "listeners" for a connect proxy service -func (s *Converter) listenersFromSnapshotConnectProxy(cfgSnap *proxycfg.ConfigSnapshot) error { - // This is the list of listeners we add to. It will be empty to start. - listeners := s.proxyState.Listeners - var err error - - // Configure inbound listener. - inboundListener, err := s.makeInboundListener(cfgSnap, xdscommon.PublicListenerName) - if err != nil { - return err - } - listeners = append(listeners, inboundListener) - - // This outboundListener is exclusively used when transparent proxy mode is active. - // In that situation there is a single listener where we are redirecting outbound traffic, - // and each upstream gets a filter chain attached to that listener. - var outboundListener *pbproxystate.Listener - - if cfgSnap.Proxy.Mode == structs.ProxyModeTransparent { - port := iptables.DefaultTProxyOutboundPort - if cfgSnap.Proxy.TransparentProxy.OutboundListenerPort != 0 { - port = cfgSnap.Proxy.TransparentProxy.OutboundListenerPort - } - - opts := makeListenerOpts{ - name: xdscommon.OutboundListenerName, - //accessLogs: cfgSnap.Proxy.AccessLogs, - addr: "127.0.0.1", - port: port, - direction: pbproxystate.Direction_DIRECTION_OUTBOUND, - logger: s.Logger, - } - outboundListener = makeListener(opts) - if outboundListener.Capabilities == nil { - outboundListener.Capabilities = []pbproxystate.Capability{} - } - outboundListener.Capabilities = append(outboundListener.Capabilities, pbproxystate.Capability_CAPABILITY_TRANSPARENT) - } - - // TODO(proxystate): tracing escape hatch will be added in the future. It will be added to the top level in proxystate, and used in xds generation. - //proxyCfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) - //if err != nil { - // // Don't hard fail on a config typo, just warn. The parse func returns - // // default config if there is an error so it's safe to continue. - // s.Logger.Warn("failed to parse Connect.Proxy.Config", "error", err) - //} - //var tracing *envoy_http_v3.HttpConnectionManager_Tracing - //if proxyCfg.ListenerTracingJSON != "" { - // if tracing, err = makeTracingFromUserConfig(proxyCfg.ListenerTracingJSON); err != nil { - // s.Logger.Warn("failed to parse ListenerTracingJSON config", "error", err) - // } - //} - - upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - if err != nil { - return err - } - - for uid, chain := range cfgSnap.ConnectProxy.DiscoveryChain { - upstreamCfg, skip := cfgSnap.ConnectProxy.GetUpstream(uid, &cfgSnap.ProxyID.EnterpriseMeta) - if skip { - // Discovery chain is not associated with a known explicit or implicit upstream so it is skipped. - continue - } - - cfg := s.getAndModifyUpstreamConfigForListener(uid, upstreamCfg, chain) - - // If escape hatch is present, create a listener from it and move on to the next - if cfg.EnvoyListenerJSON != "" { - upstreamListener := &pbproxystate.Listener{ - EscapeHatchListener: cfg.EnvoyListenerJSON, - } - listeners = append(listeners, upstreamListener) - continue - } - - // RDS, Envoy's Route Discovery Service, is only used for HTTP services with a customized discovery chain. - useRDS := chain.Protocol != "tcp" && !chain.Default - - var clusterName string - if !useRDS { - // When not using RDS we must generate a cluster name to attach to the filter chain. - // With RDS, cluster names get attached to the dynamic routes instead. - target, err := simpleChainTarget(chain) - if err != nil { - return err - } - - clusterName = s.getTargetClusterName(upstreamsSnapshot, chain, target.ID, false) - if clusterName == "" { - continue - } - } - - filterName := fmt.Sprintf("%s.%s.%s.%s", chain.ServiceName, chain.Namespace, chain.Partition, chain.Datacenter) - - // Generate the upstream listeners for when they are explicitly set with a local bind port or socket path - if upstreamCfg != nil && upstreamCfg.HasLocalPortOrSocket() { - router, err := s.makeUpstreamRouter(routerOpts{ - // TODO(proxystate): access logs and tracing will be added in the future. - //accessLogs: &cfgSnap.Proxy.AccessLogs, - routeName: uid.EnvoyID(), - clusterName: clusterName, - filterName: filterName, - protocol: cfg.Protocol, - useRDS: useRDS, - //tracing: tracing, - }) - if err != nil { - return err - } - - opts := makeListenerOpts{ - name: uid.EnvoyID(), - //accessLogs: cfgSnap.Proxy.AccessLogs, - direction: pbproxystate.Direction_DIRECTION_OUTBOUND, - logger: s.Logger, - upstream: upstreamCfg, - } - upstreamListener := makeListener(opts) - upstreamListener.BalanceConnections = balanceConnections[cfg.BalanceOutboundConnections] - - upstreamListener.Routers = append(upstreamListener.Routers, router) - listeners = append(listeners, upstreamListener) - - // Avoid creating filter chains below for upstreams that have dedicated listeners - continue - } - - // The rest of this loop is used exclusively for transparent proxies. - // Below we create a filter chain per upstream, rather than a listener per upstream - // as we do for explicit upstreams above. - - upstreamRouter, err := s.makeUpstreamRouter(routerOpts{ - //accessLogs: &cfgSnap.Proxy.AccessLogs, - routeName: uid.EnvoyID(), - clusterName: clusterName, - filterName: filterName, - protocol: cfg.Protocol, - useRDS: useRDS, - //tracing: tracing, - }) - if err != nil { - return err - } - - endpoints := cfgSnap.ConnectProxy.WatchedUpstreamEndpoints[uid][chain.ID()] - uniqueAddrs := make(map[string]struct{}) - - if chain.Partition == cfgSnap.ProxyID.PartitionOrDefault() { - for _, ip := range chain.AutoVirtualIPs { - uniqueAddrs[ip] = struct{}{} - } - for _, ip := range chain.ManualVirtualIPs { - uniqueAddrs[ip] = struct{}{} - } - } - - // Match on the virtual IP for the upstream service (identified by the chain's ID). - // We do not match on all endpoints here since it would lead to load balancing across - // all instances when any instance address is dialed. - for _, e := range endpoints { - if e.Service.Kind == structs.ServiceKind(structs.TerminatingGateway) { - key := structs.ServiceGatewayVirtualIPTag(chain.CompoundServiceName()) - - if vip := e.Service.TaggedAddresses[key]; vip.Address != "" { - uniqueAddrs[vip.Address] = struct{}{} - } - - continue - } - if vip := e.Service.TaggedAddresses[structs.TaggedAddressVirtualIP]; vip.Address != "" { - uniqueAddrs[vip.Address] = struct{}{} - } - - // The virtualIPTag is used by consul-k8s to store the ClusterIP for a service. - // We only match on this virtual IP if the upstream is in the proxy's partition. - // This is because the IP is not guaranteed to be unique across k8s clusters. - if acl.EqualPartitions(e.Node.PartitionOrDefault(), cfgSnap.ProxyID.PartitionOrDefault()) { - if vip := e.Service.TaggedAddresses[naming.VirtualIPTag]; vip.Address != "" { - uniqueAddrs[vip.Address] = struct{}{} - } - } - } - if len(uniqueAddrs) > 2 { - s.Logger.Debug("detected multiple virtual IPs for an upstream, all will be used to match traffic", - "upstream", uid, "ip_count", len(uniqueAddrs)) - } - - // For every potential address we collected, create the appropriate address prefix to match on. - // In this case we are matching on exact addresses, so the prefix is the address itself, - // and the prefix length is based on whether it's IPv4 or IPv6. - upstreamRouter.Match = makeRouterMatchFromAddrs(uniqueAddrs) - - // Only attach the filter chain if there are addresses to match on - if upstreamRouter.Match != nil && len(upstreamRouter.Match.PrefixRanges) > 0 { - outboundListener.Routers = append(outboundListener.Routers, upstreamRouter) - } - } - requiresTLSInspector := false - requiresHTTPInspector := false - - configuredPorts := make(map[int]interface{}) - err = cfgSnap.ConnectProxy.DestinationsUpstream.ForEachKeyE(func(uid proxycfg.UpstreamID) error { - svcConfig, ok := cfgSnap.ConnectProxy.DestinationsUpstream.Get(uid) - if !ok || svcConfig == nil { - return nil - } - - if structs.IsProtocolHTTPLike(svcConfig.Protocol) { - if _, ok := configuredPorts[svcConfig.Destination.Port]; ok { - return nil - } - configuredPorts[svcConfig.Destination.Port] = struct{}{} - const name = "~http" // name used for the shared route name - routeName := clusterNameForDestination(cfgSnap, name, fmt.Sprintf("%d", svcConfig.Destination.Port), svcConfig.NamespaceOrDefault(), svcConfig.PartitionOrDefault()) - upstreamRouter, err := s.makeUpstreamRouter(routerOpts{ - //accessLogs: &cfgSnap.Proxy.AccessLogs, - routeName: routeName, - filterName: routeName, - protocol: svcConfig.Protocol, - useRDS: true, - //tracing: tracing, - }) - if err != nil { - return err - } - upstreamRouter.Match = makeRouterMatchFromAddressWithPort("", svcConfig.Destination.Port) - outboundListener.Routers = append(outboundListener.Routers, upstreamRouter) - requiresHTTPInspector = true - } else { - for _, address := range svcConfig.Destination.Addresses { - clusterName := clusterNameForDestination(cfgSnap, uid.Name, address, uid.NamespaceOrDefault(), uid.PartitionOrDefault()) - - upstreamRouter, err := s.makeUpstreamRouter(routerOpts{ - //accessLogs: &cfgSnap.Proxy.AccessLogs, - routeName: uid.EnvoyID(), - clusterName: clusterName, - filterName: clusterName, - protocol: svcConfig.Protocol, - //tracing: tracing, - }) - if err != nil { - return err - } - - upstreamRouter.Match = makeRouterMatchFromAddressWithPort(address, svcConfig.Destination.Port) - outboundListener.Routers = append(outboundListener.Routers, upstreamRouter) - - requiresTLSInspector = len(upstreamRouter.Match.ServerNames) != 0 || requiresTLSInspector - } - } - return nil - }) - if err != nil { - return err - } - - if requiresTLSInspector { - outboundListener.Capabilities = append(outboundListener.Capabilities, pbproxystate.Capability_CAPABILITY_L4_TLS_INSPECTION) - } - - if requiresHTTPInspector { - outboundListener.Capabilities = append(outboundListener.Capabilities, pbproxystate.Capability_CAPABILITY_L7_PROTOCOL_INSPECTION) - } - - // Looping over explicit and implicit upstreams is only needed for cross-peer - // because they do not have discovery chains. - for _, uid := range cfgSnap.ConnectProxy.PeeredUpstreamIDs() { - upstreamCfg, skip := cfgSnap.ConnectProxy.GetUpstream(uid, &cfgSnap.ProxyID.EnterpriseMeta) - if skip { - // Not associated with a known explicit or implicit upstream so it is skipped. - continue - } - - peerMeta, found := cfgSnap.ConnectProxy.UpstreamPeerMeta(uid) - if !found { - s.Logger.Warn("failed to fetch upstream peering metadata for listener", "uid", uid) - } - cfg := s.getAndModifyUpstreamConfigForPeeredListener(uid, upstreamCfg, peerMeta) - - // If escape hatch is present, create a listener from it and move on to the next - if cfg.EnvoyListenerJSON != "" { - upstreamListener := &pbproxystate.Listener{ - EscapeHatchListener: cfg.EnvoyListenerJSON, - } - listeners = append(listeners, upstreamListener) - continue - } - - tbs, ok := cfgSnap.ConnectProxy.UpstreamPeerTrustBundles.Get(uid.Peer) - if !ok { - // this should never happen since we loop through upstreams with - // set trust bundles - return fmt.Errorf("trust bundle not ready for peer %s", uid.Peer) - } - - clusterName := generatePeeredClusterName(uid, tbs) - - // Generate the upstream listeners for when they are explicitly set with a local bind port or socket path - if upstreamCfg != nil && upstreamCfg.HasLocalPortOrSocket() { - upstreamRouter, err := s.makeUpstreamRouter(routerOpts{ - //accessLogs: &cfgSnap.Proxy.AccessLogs, - clusterName: clusterName, - filterName: fmt.Sprintf("%s.%s.%s", - upstreamCfg.DestinationName, - upstreamCfg.DestinationNamespace, - upstreamCfg.DestinationPeer), - routeName: uid.EnvoyID(), - protocol: cfg.Protocol, - useRDS: false, - statPrefix: "upstream_peered.", - }) - if err != nil { - return err - } - - opts := makeListenerOpts{ - name: uid.EnvoyID(), - //accessLogs: cfgSnap.Proxy.AccessLogs, - direction: pbproxystate.Direction_DIRECTION_OUTBOUND, - logger: s.Logger, - upstream: upstreamCfg, - } - upstreamListener := makeListener(opts) - upstreamListener.BalanceConnections = balanceConnections[cfg.BalanceOutboundConnections] - - upstreamListener.Routers = []*pbproxystate.Router{ - upstreamRouter, - } - listeners = append(listeners, upstreamListener) - - // Avoid creating filter chains below for upstreams that have dedicated listeners - continue - } - - // The rest of this loop is used exclusively for transparent proxies. - // Below we create a filter chain per upstream, rather than a listener per upstream - // as we do for explicit upstreams above. - - upstreamRouter, err := s.makeUpstreamRouter(routerOpts{ - //accessLogs: &cfgSnap.Proxy.AccessLogs, - routeName: uid.EnvoyID(), - clusterName: clusterName, - filterName: fmt.Sprintf("%s.%s.%s", - uid.Name, - uid.NamespaceOrDefault(), - uid.Peer), - protocol: cfg.Protocol, - useRDS: false, - statPrefix: "upstream_peered.", - //tracing: tracing, - }) - if err != nil { - return err - } - - endpoints, _ := cfgSnap.ConnectProxy.PeerUpstreamEndpoints.Get(uid) - uniqueAddrs := make(map[string]struct{}) - - // Match on the virtual IP for the upstream service (identified by the chain's ID). - // We do not match on all endpoints here since it would lead to load balancing across - // all instances when any instance address is dialed. - for _, e := range endpoints { - if vip := e.Service.TaggedAddresses[structs.TaggedAddressVirtualIP]; vip.Address != "" { - uniqueAddrs[vip.Address] = struct{}{} - } - - // The virtualIPTag is used by consul-k8s to store the ClusterIP for a service. - // For services imported from a peer,the partition will be equal in all cases. - if acl.EqualPartitions(e.Node.PartitionOrDefault(), cfgSnap.ProxyID.PartitionOrDefault()) { - if vip := e.Service.TaggedAddresses[naming.VirtualIPTag]; vip.Address != "" { - uniqueAddrs[vip.Address] = struct{}{} - } - } - } - if len(uniqueAddrs) > 2 { - s.Logger.Debug("detected multiple virtual IPs for an upstream, all will be used to match traffic", - "upstream", uid, "ip_count", len(uniqueAddrs)) - } - - // For every potential address we collected, create the appropriate address prefix to match on. - // In this case we are matching on exact addresses, so the prefix is the address itself, - // and the prefix length is based on whether it's IPv4 or IPv6. - upstreamRouter.Match = makeRouterMatchFromAddrs(uniqueAddrs) - - // Only attach the filter chain if there are addresses to match on - if upstreamRouter.Match != nil && len(upstreamRouter.Match.PrefixRanges) > 0 { - outboundListener.Routers = append(outboundListener.Routers, upstreamRouter) - } - - } - - if outboundListener != nil { - // Add a passthrough for every mesh endpoint that can be dialed directly, - // as opposed to via a virtual IP. - var passthroughRouters []*pbproxystate.Router - - for _, targets := range cfgSnap.ConnectProxy.PassthroughUpstreams { - for tid, addrs := range targets { - uid := proxycfg.NewUpstreamIDFromTargetID(tid) - - sni := connect.ServiceSNI( - uid.Name, "", uid.NamespaceOrDefault(), uid.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) - - routerName := fmt.Sprintf("%s.%s.%s.%s", uid.Name, uid.NamespaceOrDefault(), uid.PartitionOrDefault(), cfgSnap.Datacenter) - - upstreamRouter, err := s.makeUpstreamRouter(routerOpts{ - //accessLogs: &cfgSnap.Proxy.AccessLogs, - clusterName: "passthrough~" + sni, - filterName: routerName, - protocol: "tcp", - }) - if err != nil { - return err - } - upstreamRouter.Match = makeRouterMatchFromAddrs(addrs) - - passthroughRouters = append(passthroughRouters, upstreamRouter) - } - } - - outboundListener.Routers = append(outboundListener.Routers, passthroughRouters...) - - // Add a catch-all filter chain that acts as a TCP proxy to destinations outside the mesh - if meshConf := cfgSnap.MeshConfig(); meshConf == nil || - !meshConf.TransparentProxy.MeshDestinationsOnly { - - upstreamRouter, err := s.makeUpstreamRouter(routerOpts{ - //accessLogs: &cfgSnap.Proxy.AccessLogs, - clusterName: naming.OriginalDestinationClusterName, - filterName: naming.OriginalDestinationClusterName, - protocol: "tcp", - }) - if err != nil { - return err - } - outboundListener.DefaultRouter = upstreamRouter - } - - // Only add the outbound listener if configured. - if len(outboundListener.Routers) > 0 || outboundListener.DefaultRouter != nil { - listeners = append(listeners, outboundListener) - - } - } - - // Looping over explicit upstreams is only needed for prepared queries because they do not have discovery chains - for uid, u := range cfgSnap.ConnectProxy.UpstreamConfig { - if u.DestinationType != structs.UpstreamDestTypePreparedQuery { - continue - } - - cfg, err := structs.ParseUpstreamConfig(u.Config) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse", "upstream", uid, "error", err) - } - - // If escape hatch is present, create a listener from it and move on to the next - if cfg.EnvoyListenerJSON != "" { - upstreamListener := &pbproxystate.Listener{ - EscapeHatchListener: cfg.EnvoyListenerJSON, - } - listeners = append(listeners, upstreamListener) - continue - } - - opts := makeListenerOpts{ - name: uid.EnvoyID(), - //accessLogs: cfgSnap.Proxy.AccessLogs, - direction: pbproxystate.Direction_DIRECTION_OUTBOUND, - logger: s.Logger, - upstream: u, - } - upstreamListener := makeListener(opts) - upstreamListener.BalanceConnections = balanceConnections[cfg.BalanceOutboundConnections] - - upstreamRouter, err := s.makeUpstreamRouter(routerOpts{ - // TODO (SNI partition) add partition for upstream SNI - //accessLogs: &cfgSnap.Proxy.AccessLogs, - clusterName: connect.UpstreamSNI(u, "", cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain), - filterName: uid.EnvoyID(), - routeName: uid.EnvoyID(), - protocol: cfg.Protocol, - //tracing: tracing, - }) - if err != nil { - return err - } - upstreamListener.Routers = []*pbproxystate.Router{ - upstreamRouter, - } - listeners = append(listeners, upstreamListener) - } - - cfgSnap.Proxy.Expose.Finalize() - paths := cfgSnap.Proxy.Expose.Paths - - // Add service health checks to the list of paths to create listeners for if needed - if cfgSnap.Proxy.Expose.Checks { - psid := structs.NewServiceID(cfgSnap.Proxy.DestinationServiceID, &cfgSnap.ProxyID.EnterpriseMeta) - for _, check := range cfgSnap.ConnectProxy.WatchedServiceChecks[psid] { - p, err := parseCheckPath(check) - if err != nil { - s.Logger.Warn("failed to create listener for", "check", check.CheckID, "error", err) - continue - } - paths = append(paths, p) - } - } - - // Configure additional listener for exposed check paths - for _, path := range paths { - clusterName := xdscommon.LocalAppClusterName - if path.LocalPathPort != cfgSnap.Proxy.LocalServicePort { - clusterName = makeExposeClusterName(path.LocalPathPort) - } - - l, err := s.makeExposedCheckListener(cfgSnap, clusterName, path) - if err != nil { - return err - } - listeners = append(listeners, l) - } - - // Set listeners on the proxy state. - s.proxyState.Listeners = listeners - - return nil -} - -func makeRouterMatchFromAddrs(addrs map[string]struct{}) *pbproxystate.Match { - ranges := make([]*pbproxystate.CidrRange, 0) - - for addr := range addrs { - ip := net.ParseIP(addr) - if ip == nil { - continue - } - - pfxLen := uint32(32) - if ip.To4() == nil { - pfxLen = 128 - } - ranges = append(ranges, &pbproxystate.CidrRange{ - AddressPrefix: addr, - PrefixLen: &wrapperspb.UInt32Value{Value: pfxLen}, - }) - } - - return &pbproxystate.Match{ - PrefixRanges: ranges, - } -} - -func makeRouterMatchFromAddressWithPort(address string, port int) *pbproxystate.Match { - ranges := make([]*pbproxystate.CidrRange, 0) - - ip := net.ParseIP(address) - if ip == nil { - if address != "" { - return &pbproxystate.Match{ - ServerNames: []string{address}, - DestinationPort: &wrapperspb.UInt32Value{Value: uint32(port)}, - } - } - return &pbproxystate.Match{ - DestinationPort: &wrapperspb.UInt32Value{Value: uint32(port)}, - } - } - - pfxLen := uint32(32) - if ip.To4() == nil { - pfxLen = 128 - } - ranges = append(ranges, &pbproxystate.CidrRange{ - AddressPrefix: address, - PrefixLen: &wrapperspb.UInt32Value{Value: pfxLen}, - }) - - return &pbproxystate.Match{ - PrefixRanges: ranges, - DestinationPort: &wrapperspb.UInt32Value{Value: uint32(port)}, - } -} - -func parseCheckPath(check structs.CheckType) (structs.ExposePath, error) { - var path structs.ExposePath - - if check.HTTP != "" { - path.Protocol = "http" - - // Get path and local port from original HTTP target - u, err := url.Parse(check.HTTP) - if err != nil { - return path, fmt.Errorf("failed to parse url '%s': %v", check.HTTP, err) - } - path.Path = u.Path - - _, portStr, err := net.SplitHostPort(u.Host) - if err != nil { - return path, fmt.Errorf("failed to parse port from '%s': %v", check.HTTP, err) - } - path.LocalPathPort, err = strconv.Atoi(portStr) - if err != nil { - return path, fmt.Errorf("failed to parse port from '%s': %v", check.HTTP, err) - } - - // Get listener port from proxied HTTP target - u, err = url.Parse(check.ProxyHTTP) - if err != nil { - return path, fmt.Errorf("failed to parse url '%s': %v", check.ProxyHTTP, err) - } - - _, portStr, err = net.SplitHostPort(u.Host) - if err != nil { - return path, fmt.Errorf("failed to parse port from '%s': %v", check.ProxyHTTP, err) - } - path.ListenerPort, err = strconv.Atoi(portStr) - if err != nil { - return path, fmt.Errorf("failed to parse port from '%s': %v", check.ProxyHTTP, err) - } - } - - if check.GRPC != "" { - path.Path = "/grpc.health.v1.Health/Check" - path.Protocol = "http2" - - // Get local port from original GRPC target of the form: host/service - proxyServerAndService := strings.SplitN(check.GRPC, "/", 2) - _, portStr, err := net.SplitHostPort(proxyServerAndService[0]) - if err != nil { - return path, fmt.Errorf("failed to split host/port from '%s': %v", check.GRPC, err) - } - path.LocalPathPort, err = strconv.Atoi(portStr) - if err != nil { - return path, fmt.Errorf("failed to parse port from '%s': %v", check.GRPC, err) - } - - // Get listener port from proxied GRPC target of the form: host/service - proxyServerAndService = strings.SplitN(check.ProxyGRPC, "/", 2) - _, portStr, err = net.SplitHostPort(proxyServerAndService[0]) - if err != nil { - return path, fmt.Errorf("failed to split host/port from '%s': %v", check.ProxyGRPC, err) - } - path.ListenerPort, err = strconv.Atoi(portStr) - if err != nil { - return path, fmt.Errorf("failed to parse port from '%s': %v", check.ProxyGRPC, err) - } - } - - path.ParsedFromCheck = true - - return path, nil -} - -// TODO(proxystate): Gateway support will be added in the future. -// Functions to add from agent/xds/listeners.go: -// func listenersFromSnapshotGateway - -// makeListener returns a listener with name and bind details set. Routers and destinations -// must be added before it's useful. -// -// Note on names: Envoy listeners attempt graceful transitions of connections -// when their config changes but that means they can't have their bind address -// or port changed in a running instance. Since our users might choose to change -// a bind address or port for the public or upstream listeners, we need to -// encode those into the unique name for the listener such that if the user -// changes them, we actually create a whole new listener on the new address and -// port. Envoy should take care of closing the old one once it sees it's no -// longer in the config. -type makeListenerOpts struct { - addr string - //accessLogs structs.AccessLogsConfig - logger hclog.Logger - mode string - name string - path string - port int - direction pbproxystate.Direction - upstream *structs.Upstream -} - -func makeListener(opts makeListenerOpts) *pbproxystate.Listener { - if opts.upstream != nil && opts.upstream.LocalBindPort == 0 && opts.upstream.LocalBindSocketPath != "" { - opts.path = opts.upstream.LocalBindSocketPath - opts.mode = opts.upstream.LocalBindSocketMode - return makePipeListener(opts) - } - if opts.upstream != nil { - opts.port = opts.upstream.LocalBindPort - opts.addr = opts.upstream.LocalBindAddress - return makeListenerWithDefault(opts) - } - - return makeListenerWithDefault(opts) -} - -func makeListenerWithDefault(opts makeListenerOpts) *pbproxystate.Listener { - if opts.addr == "" { - opts.addr = "127.0.0.1" - } - // TODO(proxystate): Access logs will be added in the future. It will be added to top level IR, and used by xds code generation. - //accessLog, err := accesslogs.MakeAccessLogs(&opts.accessLogs, true) - //if err != nil && opts.logger != nil { - // // Since access logging is non-essential for routing, warn and move on - // opts.logger.Warn("error generating access log xds", err) - //} - return &pbproxystate.Listener{ - Name: fmt.Sprintf("%s:%s:%d", opts.name, opts.addr, opts.port), - //AccessLog: accessLog, - BindAddress: &pbproxystate.Listener_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: opts.addr, - Port: uint32(opts.port), - }, - }, - Direction: opts.direction, - } -} - -func makePipeListener(opts makeListenerOpts) *pbproxystate.Listener { - // TODO(proxystate): Access logs will be added in the future. It will be added to top level IR, and used by xds code generation. - //accessLog, err := accesslogs.MakeAccessLogs(&opts.accessLogs, true) - //if err != nil && opts.logger != nil { - // // Since access logging is non-essential for routing, warn and move on - // opts.logger.Warn("error generating access log xds", err) - //} - return &pbproxystate.Listener{ - Name: fmt.Sprintf("%s:%s", opts.name, opts.path), - //AccessLog: accessLog, - BindAddress: &pbproxystate.Listener_UnixSocket{ - UnixSocket: &pbproxystate.UnixSocketAddress{Path: opts.path, Mode: opts.mode}, - }, - Direction: opts.direction, - } -} - -// TODO(proxystate): Escape hatches will be added in the future. -// Functions to add from agent/xds/listeners.go: -// func makeListenerFromUserConfig - -// TODO(proxystate): Intentions will be added in the future -// Functions to add from agent/xds/listeners.go: -// func injectConnectFilters - -// TODO(proxystate): httpConnectionManager constants will need to be added when used for listeners L7 in the future. -// Constants to add from agent/xds/listeners.go: -// const httpConnectionManagerOldName -// const httpConnectionManagerNewName - -// TODO(proxystate): Extracting RDS resource names will be used when wiring up xds v2 server in the future. -// Functions to add from agent/xds/listeners.go: -// func extractRdsResourceNames - -// TODO(proxystate): Intentions will be added in the future. -// Functions to add from agent/xds/listeners.go: -// func injectHTTPFilterOnFilterChains - -// NOTE: This method MUST only be used for connect proxy public listeners, -// since TLS validation will be done against root certs for all peers -// that might dial this proxy. -func (s *Converter) injectConnectTLSForPublicListener(cfgSnap *proxycfg.ConfigSnapshot, listener *pbproxystate.Listener) error { - transportSocket, err := s.createInboundMeshMTLS(cfgSnap) - if err != nil { - return err - } - - for idx := range listener.Routers { - listener.Routers[idx].InboundTls = transportSocket - } - return nil -} - -func getAlpnProtocols(protocol string) []string { - var alpnProtocols []string - - switch protocol { - case "grpc", "http2": - alpnProtocols = append(alpnProtocols, "h2", "http/1.1") - case "http": - alpnProtocols = append(alpnProtocols, "http/1.1") - } - - return alpnProtocols -} - -func (s *Converter) createInboundMeshMTLS(cfgSnap *proxycfg.ConfigSnapshot) (*pbproxystate.TransportSocket, error) { - switch cfgSnap.Kind { - case structs.ServiceKindConnectProxy: - case structs.ServiceKindMeshGateway: - default: - return nil, fmt.Errorf("cannot inject peering trust bundles for kind %q", cfgSnap.Kind) - } - - cfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse Connect.Proxy.Config", "error", err) - } - - // Add all trust bundle peer names, including local. - trustBundlePeerNames := []string{"local"} - for _, tb := range cfgSnap.PeeringTrustBundles() { - trustBundlePeerNames = append(trustBundlePeerNames, tb.PeerName) - } - // Arbitrary UUID to reference the identity by. - uuid, err := uuid.GenerateUUID() - if err != nil { - return nil, err - } - // Create the transport socket - ts := &pbproxystate.TransportSocket{} - ts.ConnectionTls = &pbproxystate.TransportSocket_InboundMesh{ - InboundMesh: &pbproxystate.InboundMeshMTLS{ - IdentityKey: uuid, - ValidationContext: &pbproxystate.MeshInboundValidationContext{ - TrustBundlePeerNameKeys: trustBundlePeerNames, - }, - }, - } - s.proxyState.LeafCertificates[uuid] = &pbproxystate.LeafCertificate{ - Cert: cfgSnap.Leaf().CertPEM, - Key: cfgSnap.Leaf().PrivateKeyPEM, - } - ts.TlsParameters = makeTLSParametersFromProxyTLSConfig(cfgSnap.MeshConfigTLSIncoming()) - ts.AlpnProtocols = getAlpnProtocols(cfg.Protocol) - - return ts, nil -} - -func (s *Converter) makeInboundListener(cfgSnap *proxycfg.ConfigSnapshot, name string) (*pbproxystate.Listener, error) { - l := &pbproxystate.Listener{} - l.Routers = make([]*pbproxystate.Router, 0) - var err error - - cfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse Connect.Proxy.Config", "error", err) - } - - // This controls if we do L4 or L7 intention checks. - useHTTPFilter := structs.IsProtocolHTTPLike(cfg.Protocol) - - // TODO(proxystate): Escape hatches will be added in the future. This one is a top level escape hatch. - // Generate and return custom public listener from config if one was provided. - //if cfg.PublicListenerJSON != "" { - // l, err = makeListenerFromUserConfig(cfg.PublicListenerJSON) - // if err != nil { - // return nil, err - // } - // - // // For HTTP-like services attach an RBAC http filter and do a best-effort insert - // if useHTTPFilter { - // httpAuthzFilter, err := makeRBACHTTPFilter( - // cfgSnap.ConnectProxy.Intentions, - // cfgSnap.IntentionDefaultAllow, - // rbacLocalInfo{ - // trustDomain: cfgSnap.Roots.TrustDomain, - // datacenter: cfgSnap.Datacenter, - // partition: cfgSnap.ProxyID.PartitionOrDefault(), - // }, - // cfgSnap.ConnectProxy.InboundPeerTrustBundles, - // ) - // if err != nil { - // return nil, err - // } - // - // // Try our best to inject the HTTP RBAC filter. - // if err := injectHTTPFilterOnFilterChains(l, httpAuthzFilter); err != nil { - // s.Logger.Warn( - // "could not inject the HTTP RBAC filter to enforce intentions on user-provided "+ - // "'envoy_public_listener_json' config; falling back on the RBAC network filter instead", - // "proxy", cfgSnap.ProxyID, - // "error", err, - // ) - // - // // If we get an error inject the RBAC network filter instead. - // useHTTPFilter = false - // } - // } - // - // err := s.finalizePublicListenerFromConfig(l, cfgSnap, useHTTPFilter) - // if err != nil { - // return nil, fmt.Errorf("failed to attach Consul filters and TLS context to custom public listener: %v", err) - // } - // return l, nil - //} - - // No JSON user config, use default listener address - // Default to listening on all addresses, but override with bind address if one is set. - addr := cfgSnap.Address - if addr == "" { - addr = "0.0.0.0" - } - if cfg.BindAddress != "" { - addr = cfg.BindAddress - } - - // Override with bind port if one is set, otherwise default to - // proxy service's address - port := cfgSnap.Port - if cfg.BindPort != 0 { - port = cfg.BindPort - } - - opts := makeListenerOpts{ - name: name, - //accessLogs: cfgSnap.Proxy.AccessLogs, - addr: addr, - port: port, - direction: pbproxystate.Direction_DIRECTION_INBOUND, - logger: s.Logger, - } - l = makeListener(opts) - l.BalanceConnections = balanceConnections[cfg.BalanceInboundConnections] - - // TODO(proxystate): Escape hatches will be added in the future. This one is a top level escape hatch. - //var tracing *envoy_http_v3.HttpConnectionManager_Tracing - //if cfg.ListenerTracingJSON != "" { - // if tracing, err = makeTracingFromUserConfig(cfg.ListenerTracingJSON); err != nil { - // s.Logger.Warn("failed to parse ListenerTracingJSON config", "error", err) - // } - //} - - // make local app cluster router - localAppRouter := &pbproxystate.Router{} - - destOpts := destinationOpts{ - protocol: cfg.Protocol, - filterName: name, - routeName: name, - cluster: xdscommon.LocalAppClusterName, - requestTimeoutMs: cfg.LocalRequestTimeoutMs, - idleTimeoutMs: cfg.LocalIdleTimeoutMs, - //tracing: tracing, - //accessLogs: &cfgSnap.Proxy.AccessLogs, - logger: s.Logger, - } - - err = s.addRouterDestination(destOpts, localAppRouter) - if err != nil { - return nil, err - } - - if useHTTPFilter { - l7Dest := localAppRouter.GetL7() - if l7Dest == nil { - return nil, fmt.Errorf("l7 destination on inbound listener should not be empty") - } - - // TODO(proxystate): L7 traffic permissions and JWT Auth will be added in the future. For now, just add an empty traffic permission. - l7Dest.TrafficPermissions = &pbproxystate.TrafficPermissions{} - //jwtFilter, jwtFilterErr := makeJWTAuthFilter(cfgSnap.JWTProviders, cfgSnap.ConnectProxy.Intentions) - //if jwtFilterErr != nil { - // return nil, jwtFilterErr - //} - //rbacFilter, err := makeRBACHTTPFilter( - // cfgSnap.ConnectProxy.Intentions, - // cfgSnap.IntentionDefaultAllow, - // rbacLocalInfo{ - // trustDomain: cfgSnap.Roots.TrustDomain, - // datacenter: cfgSnap.Datacenter, - // partition: cfgSnap.ProxyID.PartitionOrDefault(), - // }, - // cfgSnap.ConnectProxy.InboundPeerTrustBundles, - //) - //if err != nil { - // return nil, err - //} - // - //filterOpts.httpAuthzFilters = []*envoy_http_v3.HttpFilter{rbacFilter} - // - //if jwtFilter != nil { - // filterOpts.httpAuthzFilters = append(filterOpts.httpAuthzFilters, jwtFilter) - //} - - meshConfig := cfgSnap.MeshConfig() - includeXFCC := meshConfig == nil || meshConfig.HTTP == nil || !meshConfig.HTTP.SanitizeXForwardedClientCert - notGRPC := cfg.Protocol != "grpc" - if includeXFCC && notGRPC { - l7Dest.IncludeXfccPolicy = includeXFCC - l7Dest.XfccPolicy = pbproxystate.XFCCPolicy_XFCC_POLICY_APPEND_FORWARD - l7Dest.ParseXfccHeaders = true - } - l7Dest.Protocol = l7Protocols[cfg.Protocol] - if cfg.MaxInboundConnections > 0 { - l7Dest.MaxInboundConnections = uint64(cfg.MaxInboundConnections) - } - } else { - l4Dest := localAppRouter.GetL4() - if l4Dest == nil { - return nil, fmt.Errorf("l4 destination on inbound listener should not be empty") - } - - if cfg.MaxInboundConnections > 0 { - l4Dest.MaxInboundConnections = uint64(cfg.MaxInboundConnections) - } - - l4Dest.TrafficPermissions = &pbproxystate.TrafficPermissions{} - } - l.Routers = append(l.Routers, localAppRouter) - - err = s.finalizePublicListenerFromConfig(l, cfgSnap) - if err != nil { - return nil, fmt.Errorf("failed to attach Consul filters and TLS context to custom public listener: %v", err) - } - - // When permissive mTLS mode is enabled, include an additional router - // that matches on the `destination_port == `. Traffic sent - // directly to the service port is passed through to the application - // unmodified. - if cfgSnap.Proxy.Mode == structs.ProxyModeTransparent && - cfgSnap.Proxy.MutualTLSMode == structs.MutualTLSModePermissive { - router, err := makePermissiveRouter(cfgSnap, destOpts) - if err != nil { - return nil, fmt.Errorf("unable to add permissive mtls router: %w", err) - } - if router == nil { - s.Logger.Debug("no service port defined for service in permissive mTLS mode; not adding filter chain for non-mTLS traffic") - } else { - l.Routers = append(l.Routers, router) - - // With tproxy, the REDIRECT iptables target rewrites the destination ip/port - // to the proxy ip/port (e.g. 127.0.0.1:20000) for incoming packets. - // We need the original_dst filter to recover the original destination address. - l.Capabilities = append(l.Capabilities, pbproxystate.Capability_CAPABILITY_TRANSPARENT) - } - } - return l, err -} - -func makePermissiveRouter(cfgSnap *proxycfg.ConfigSnapshot, opts destinationOpts) (*pbproxystate.Router, error) { - servicePort := cfgSnap.Proxy.LocalServicePort - if servicePort <= 0 { - // No service port means the service does not accept incoming traffic, so - // the connect proxy does not need to listen for incoming non-mTLS traffic. - return nil, nil - } - - opts.statPrefix += "permissive_" - dest, err := makeL4Destination(opts) - if err != nil { - return nil, err - } - - router := &pbproxystate.Router{ - Match: &pbproxystate.Match{ - DestinationPort: &wrapperspb.UInt32Value{Value: uint32(servicePort)}, - }, - Destination: &pbproxystate.Router_L4{L4: dest}, - } - return router, nil -} - -// finalizePublicListenerFromConfig is used for best-effort injection of L4 intentions and TLS onto listeners. -func (s *Converter) finalizePublicListenerFromConfig(l *pbproxystate.Listener, cfgSnap *proxycfg.ConfigSnapshot) error { - // TODO(proxystate): L4 intentions will be added in the future. - //if !useHTTPFilter { - // // Best-effort injection of L4 intentions - // if err := s.injectConnectFilters(cfgSnap, l); err != nil { - // return nil - // } - //} - - // Always apply TLS certificates - if err := s.injectConnectTLSForPublicListener(cfgSnap, l); err != nil { - return nil - } - - return nil -} - -func (s *Converter) makeExposedCheckListener(cfgSnap *proxycfg.ConfigSnapshot, cluster string, path structs.ExposePath) (*pbproxystate.Listener, error) { - cfg, err := config.ParseProxyConfig(cfgSnap.Proxy.Config) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse Connect.Proxy.Config", "error", err) - } - - // No user config, use default listener - addr := cfgSnap.Address - - // Override with bind address if one is set, otherwise default to 0.0.0.0 - if cfg.BindAddress != "" { - addr = cfg.BindAddress - } else if addr == "" { - addr = "0.0.0.0" - } - - // Strip any special characters from path to make a valid and hopefully unique name - r := regexp.MustCompile(`[^a-zA-Z0-9]+`) - strippedPath := r.ReplaceAllString(path.Path, "") - listenerName := fmt.Sprintf("exposed_path_%s", strippedPath) - - listenerOpts := makeListenerOpts{ - name: listenerName, - //accessLogs: cfgSnap.Proxy.AccessLogs, - addr: addr, - port: path.ListenerPort, - direction: pbproxystate.Direction_DIRECTION_INBOUND, - logger: s.Logger, - } - l := makeListener(listenerOpts) - - filterName := fmt.Sprintf("exposed_path_filter_%s_%d", strippedPath, path.ListenerPort) - - destOpts := destinationOpts{ - useRDS: false, - protocol: path.Protocol, - filterName: filterName, - routeName: filterName, - cluster: cluster, - statPrefix: "", - routePath: path.Path, - httpAuthzFilters: nil, - //accessLogs: &cfgSnap.Proxy.AccessLogs, - logger: s.Logger, - // in the exposed check listener we don't set the tracing configuration - } - - router := &pbproxystate.Router{} - err = s.addRouterDestination(destOpts, router) - if err != nil { - return nil, err - } - - // For registered checks restrict traffic sources to localhost and Consul's advertise addr - if path.ParsedFromCheck { - - // For the advertise addr we use a CidrRange that only matches one address - advertise := s.CfgFetcher.AdvertiseAddrLAN() - - // Get prefix length based on whether address is ipv4 (32 bits) or ipv6 (128 bits) - advertiseLen := 32 - ip := net.ParseIP(advertise) - if ip != nil && strings.Contains(advertise, ":") { - advertiseLen = 128 - } - - ranges := make([]*pbproxystate.CidrRange, 0, 3) - ranges = append(ranges, - &pbproxystate.CidrRange{AddressPrefix: "127.0.0.1", PrefixLen: &wrapperspb.UInt32Value{Value: 8}}, - &pbproxystate.CidrRange{AddressPrefix: advertise, PrefixLen: &wrapperspb.UInt32Value{Value: uint32(advertiseLen)}}, - ) - - if ok, err := platform.SupportsIPv6(); err != nil { - return nil, err - } else if ok { - ranges = append(ranges, - &pbproxystate.CidrRange{AddressPrefix: "::1", PrefixLen: &wrapperspb.UInt32Value{Value: 128}}, - ) - } - - router.Match = &pbproxystate.Match{ - SourcePrefixRanges: ranges, - } - } - - l.Routers = []*pbproxystate.Router{router} - - return l, err -} - -// TODO(proxystate): Gateway support will be added in the future. -// Functions and types to convert from agent/xds/listeners.go: -// func makeTerminatingGatewayListener -// type terminatingGatewayFilterChainOpts -// func makeFilterChainTerminatingGateway -// func makeMeshGatewayListener -// func makeMeshGatewayPeerFilterChain - -type routerOpts struct { - //accessLogs *structs.AccessLogsConfig - routeName string - clusterName string - filterName string - protocol string - useRDS bool - statPrefix string - forwardClientDetails bool - forwardClientPolicy pbproxystate.XFCCPolicy - //tracing *envoy_http_v3.HttpConnectionManager_Tracing -} - -func (g *Converter) makeUpstreamRouter(opts routerOpts) (*pbproxystate.Router, error) { - if opts.statPrefix == "" { - opts.statPrefix = "upstream." - } - - router := &pbproxystate.Router{} - - err := g.addRouterDestination(destinationOpts{ - useRDS: opts.useRDS, - protocol: opts.protocol, - filterName: opts.filterName, - routeName: opts.routeName, - cluster: opts.clusterName, - statPrefix: opts.statPrefix, - forwardClientDetails: opts.forwardClientDetails, - forwardClientPolicy: opts.forwardClientPolicy, - //tracing: opts.tracing, - //accessLogs: opts.accessLogs, - logger: g.Logger, - }, router) - if err != nil { - return nil, err - } - - return router, nil -} - -// simpleChainTarget returns the discovery target for a chain with a single node. -// A chain can have a single target if it is for a TCP service or an HTTP service without -// multiple splits/routes/failovers. -func simpleChainTarget(chain *structs.CompiledDiscoveryChain) (*structs.DiscoveryTarget, error) { - startNode := chain.Nodes[chain.StartNode] - if startNode == nil { - return nil, fmt.Errorf("missing first node in compiled discovery chain for: %s", chain.ServiceName) - } - if startNode.Type != structs.DiscoveryGraphNodeTypeResolver { - return nil, fmt.Errorf("expected discovery chain with single node, found unexpected start node: %s", startNode.Type) - } - targetID := startNode.Resolver.Target - return chain.Targets[targetID], nil -} - -func (s *Converter) getAndModifyUpstreamConfigForListener( - uid proxycfg.UpstreamID, - u *structs.Upstream, - chain *structs.CompiledDiscoveryChain, -) structs.UpstreamConfig { - var ( - cfg structs.UpstreamConfig - err error - ) - - configMap := make(map[string]interface{}) - if u != nil { - configMap = u.Config - } - if chain == nil || chain.Default { - cfg, err = structs.ParseUpstreamConfigNoDefaults(configMap) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse", "upstream", uid, "error", err) - } - } else { - // Use NoDefaults here so that we can set the protocol to the chain - // protocol if necessary - cfg, err = structs.ParseUpstreamConfigNoDefaults(configMap) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse", "upstream", uid, "error", err) - } - - if cfg.EnvoyListenerJSON != "" { - s.Logger.Warn("ignoring escape hatch setting because already configured for", - "discovery chain", chain.ServiceName, "upstream", uid, "config", "envoy_listener_json") - - // Remove from config struct so we don't use it later on - cfg.EnvoyListenerJSON = "" - } - } - protocol := cfg.Protocol - if chain != nil { - if protocol == "" { - protocol = chain.Protocol - } - if protocol == "" { - protocol = "tcp" - } - } else { - protocol = "tcp" - } - - // set back on the config so that we can use it from return value - cfg.Protocol = protocol - - return cfg -} - -func (s *Converter) getAndModifyUpstreamConfigForPeeredListener( - uid proxycfg.UpstreamID, - u *structs.Upstream, - peerMeta structs.PeeringServiceMeta, -) structs.UpstreamConfig { - var ( - cfg structs.UpstreamConfig - err error - ) - - configMap := make(map[string]interface{}) - if u != nil { - configMap = u.Config - } - - cfg, err = structs.ParseUpstreamConfigNoDefaults(configMap) - if err != nil { - // Don't hard fail on a config typo, just warn. The parse func returns - // default config if there is an error so it's safe to continue. - s.Logger.Warn("failed to parse", "upstream", uid, "error", err) - } - - // Ignore the configured protocol for peer upstreams, since it is defined by the remote - // cluster, which we cannot control. - protocol := peerMeta.Protocol - if protocol == "" { - protocol = "tcp" - } - - // set back on the config so that we can use it from return value - cfg.Protocol = protocol - - if cfg.ConnectTimeoutMs == 0 { - cfg.ConnectTimeoutMs = 5000 - } - - if cfg.MeshGateway.Mode == "" && u != nil { - cfg.MeshGateway = u.MeshGateway - } - - return cfg -} - -type destinationOpts struct { - // All listener filters - // TODO(proxystate): access logs support will be added later - //accessLogs *structs.AccessLogsConfig - cluster string - filterName string - logger hclog.Logger - protocol string - statPrefix string - - // HTTP listener filter options - forwardClientDetails bool - forwardClientPolicy pbproxystate.XFCCPolicy - httpAuthzFilters []*envoy_http_v3.HttpFilter - idleTimeoutMs *int - requestTimeoutMs *int - routeName string - routePath string - // TODO(proxystate): tracing support will be added later - //tracing *envoy_http_v3.HttpConnectionManager_Tracing - useRDS bool -} - -func (g *Converter) addRouterDestination(opts destinationOpts, router *pbproxystate.Router) error { - switch opts.protocol { - case "grpc", "http2", "http": - dest, err := g.makeL7Destination(opts) - if err != nil { - return err - } - router.Destination = &pbproxystate.Router_L7{ - L7: dest, - } - return nil - case "tcp": - fallthrough - default: - if opts.useRDS { - return fmt.Errorf("RDS is not compatible with the tcp proxy filter") - } else if opts.cluster == "" { - return fmt.Errorf("cluster name is required for a tcp proxy filter") - } - dest, err := makeL4Destination(opts) - if err != nil { - return err - } - router.Destination = &pbproxystate.Router_L4{ - L4: dest, - } - return nil - } -} - -func makeL4Destination(opts destinationOpts) (*pbproxystate.L4Destination, error) { - // TODO(proxystate): implement access logs at top level - //accessLogs, err := accesslogs.MakeAccessLogs(opts.accessLogs, false) - //if err != nil && opts.logger != nil { - // opts.logger.Warn("could not make access log xds for tcp proxy", err) - //} - - l4Dest := &pbproxystate.L4Destination{ - //AccessLog: accessLogs, - Destination: &pbproxystate.L4Destination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: opts.cluster, - }, - }, - StatPrefix: makeStatPrefix(opts.statPrefix, opts.filterName), - } - return l4Dest, nil -} - -func makeStatPrefix(prefix, filterName string) string { - // Replace colons here because Envoy does that in the metrics for the actual - // clusters but doesn't in the stat prefix here while dashboards assume they - // will match. - return fmt.Sprintf("%s%s", prefix, strings.Replace(filterName, ":", "_", -1)) -} - -func (g *Converter) makeL7Destination(opts destinationOpts) (*pbproxystate.L7Destination, error) { - dest := &pbproxystate.L7Destination{} - - // TODO(proxystate) access logs will be added to proxystate top level and in xds generation - //accessLogs, err := accesslogs.MakeAccessLogs(opts.accessLogs, false) - //if err != nil && opts.logger != nil { - // opts.logger.Warn("could not make access log xds for http connection manager", err) - //} - - // An L7 Destination's name will be the route name, so during xds generation the route can be looked up. - dest.Route = &pbproxystate.L7DestinationRoute{ - Name: opts.routeName, - } - dest.StatPrefix = makeStatPrefix(opts.statPrefix, opts.filterName) - - // TODO(proxystate) tracing will be added at the top level proxystate and xds generation - //if opts.tracing != nil { - // cfg.Tracing = opts.tracing - //} - - if opts.useRDS { - if opts.cluster != "" { - return nil, fmt.Errorf("cannot specify cluster name when using RDS") - } - } else { - dest.StaticRoute = true - - if opts.cluster == "" { - return nil, fmt.Errorf("must specify cluster name when not using RDS") - } - - routeRule := &pbproxystate.RouteRule{ - Match: &pbproxystate.RouteMatch{ - PathMatch: &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: "/", - }, - }, - // TODO(banks) Envoy supports matching only valid GRPC - // requests which might be nice to add here for gRPC services - // but it's not supported in our current envoy SDK version - // although docs say it was supported by 1.8.0. Going to defer - // that until we've updated the deps. - }, - Destination: &pbproxystate.RouteDestination{ - Destination: &pbproxystate.RouteDestination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: opts.cluster, - }, - }, - }, - } - - var timeoutCfg *pbproxystate.TimeoutConfig - r := routeRule.GetDestination() - - if opts.requestTimeoutMs != nil { - if timeoutCfg == nil { - timeoutCfg = &pbproxystate.TimeoutConfig{} - } - timeoutCfg.Timeout = durationpb.New(time.Duration(*opts.requestTimeoutMs) * time.Millisecond) - } - - if opts.idleTimeoutMs != nil { - if timeoutCfg == nil { - timeoutCfg = &pbproxystate.TimeoutConfig{} - } - timeoutCfg.IdleTimeout = durationpb.New(time.Duration(*opts.idleTimeoutMs) * time.Millisecond) - } - r.DestinationConfiguration = &pbproxystate.DestinationConfiguration{ - TimeoutConfig: timeoutCfg, - } - - // If a path is provided, do not match on a catch-all prefix - if opts.routePath != "" { - routeRule.Match.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Exact{ - Exact: opts.routePath, - }, - } - } - - // Create static route object - route := &pbproxystate.Route{ - VirtualHosts: []*pbproxystate.VirtualHost{ - { - Name: opts.filterName, - Domains: []string{"*"}, - RouteRules: []*pbproxystate.RouteRule{ - routeRule, - }, - }, - }, - } - // Save the route to proxy state. - g.proxyState.Routes[opts.routeName] = route - } - - dest.Protocol = l7Protocols[opts.protocol] - - // Note the default leads to setting HttpConnectionManager_SANITIZE - if opts.forwardClientDetails { - dest.IncludeXfccPolicy = true - dest.XfccPolicy = opts.forwardClientPolicy - } - - // Like injectConnectFilters for L4, here we ensure that the first filter - // (other than the "envoy.grpc_http1_bridge" filter) in the http filter - // chain of a public listener is the authz filter to prevent unauthorized - // access and that every filter chain uses our TLS certs. - if len(opts.httpAuthzFilters) > 0 { - // TODO(proxystate) support intentions in the future - dest.TrafficPermissions = &pbproxystate.TrafficPermissions{} - //cfg.HttpFilters = append(opts.httpAuthzFilters, cfg.HttpFilters...) - } - - // TODO(proxystate) add grpc http filters in xds in future L7 task - //if opts.protocol == "grpc" { - // grpcHttp1Bridge, err := makeEnvoyHTTPFilter( - // "envoy.filters.http.grpc_http1_bridge", - // &envoy_grpc_http1_bridge_v3.Config{}, - // ) - // if err != nil { - // return nil, err - // } - // - // // In envoy 1.14.x the default value "stats_for_all_methods=true" was - // // deprecated, and was changed to "false" in 1.18.x. Avoid using the - // // default. TODO: we may want to expose this to users somehow easily. - // grpcStatsFilter, err := makeEnvoyHTTPFilter( - // "envoy.filters.http.grpc_stats", - // &envoy_grpc_stats_v3.FilterConfig{ - // PerMethodStatSpecifier: &envoy_grpc_stats_v3.FilterConfig_StatsForAllMethods{ - // StatsForAllMethods: makeBoolValue(true), - // }, - // }, - // ) - // if err != nil { - // return nil, err - // } - // - // // Add grpc bridge before router and authz, and the stats in front of that. - // cfg.HttpFilters = append([]*envoy_http_v3.HttpFilter{ - // grpcStatsFilter, - // grpcHttp1Bridge, - // }, cfg.HttpFilters...) - //} - - return dest, nil -} - -var tlsVersionsWithConfigurableCipherSuites = map[types.TLSVersion]struct{}{ - // Remove these two if Envoy ever sets TLS 1.3 as default minimum - types.TLSVersionUnspecified: {}, - types.TLSVersionAuto: {}, - - types.TLSv1_0: {}, - types.TLSv1_1: {}, - types.TLSv1_2: {}, -} - -func makeTLSParametersFromProxyTLSConfig(tlsConf *structs.MeshDirectionalTLSConfig) *pbproxystate.TLSParameters { - if tlsConf == nil { - return &pbproxystate.TLSParameters{} - } - - return makeTLSParametersFromTLSConfig(tlsConf.TLSMinVersion, tlsConf.TLSMaxVersion, tlsConf.CipherSuites) -} - -func makeTLSParametersFromTLSConfig( - tlsMinVersion types.TLSVersion, - tlsMaxVersion types.TLSVersion, - cipherSuites []types.TLSCipherSuite, -) *pbproxystate.TLSParameters { - tlsParams := pbproxystate.TLSParameters{} - - if tlsMinVersion != types.TLSVersionUnspecified { - tlsParams.MinVersion = tlsVersions[tlsMinVersion] - } - if tlsMaxVersion != types.TLSVersionUnspecified { - tlsParams.MaxVersion = tlsVersions[tlsMaxVersion] - } - if len(cipherSuites) != 0 { - var suites []pbproxystate.TLSCipherSuite - for _, cs := range cipherSuites { - suites = append(suites, tlsCipherSuites[cs]) - } - tlsParams.CipherSuites = suites - } - - return &tlsParams -} - -var tlsVersions = map[types.TLSVersion]pbproxystate.TLSVersion{ - types.TLSVersionAuto: pbproxystate.TLSVersion_TLS_VERSION_AUTO, - types.TLSv1_0: pbproxystate.TLSVersion_TLS_VERSION_1_0, - types.TLSv1_1: pbproxystate.TLSVersion_TLS_VERSION_1_1, - types.TLSv1_2: pbproxystate.TLSVersion_TLS_VERSION_1_2, - types.TLSv1_3: pbproxystate.TLSVersion_TLS_VERSION_1_3, -} - -var tlsCipherSuites = map[types.TLSCipherSuite]pbproxystate.TLSCipherSuite{ - types.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256, - types.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305, - types.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256, - types.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305, - types.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA, - types.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA, - types.TLS_RSA_WITH_AES_128_GCM_SHA256: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_AES128_GCM_SHA256, - types.TLS_RSA_WITH_AES_128_CBC_SHA: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_AES128_SHA, - types.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384, - types.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384, - types.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA, - types.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA, - types.TLS_RSA_WITH_AES_256_GCM_SHA384: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_AES256_GCM_SHA384, - types.TLS_RSA_WITH_AES_256_CBC_SHA: pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_AES256_SHA, -} - -var l7Protocols = map[string]pbproxystate.L7Protocol{ - "http": pbproxystate.L7Protocol_L7_PROTOCOL_HTTP, - "http2": pbproxystate.L7Protocol_L7_PROTOCOL_HTTP2, - "grpc": pbproxystate.L7Protocol_L7_PROTOCOL_GRPC, -} - -var balanceConnections = map[string]pbproxystate.BalanceConnections{ - "": pbproxystate.BalanceConnections_BALANCE_CONNECTIONS_DEFAULT, - structs.ConnectionExactBalance: pbproxystate.BalanceConnections_BALANCE_CONNECTIONS_EXACT, -} diff --git a/agent/xds/proxystateconverter/locality_policy.go b/agent/xds/proxystateconverter/locality_policy.go deleted file mode 100644 index c33f428fc2e27..0000000000000 --- a/agent/xds/proxystateconverter/locality_policy.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxystateconverter - -import ( - "fmt" - - "github.com/hashicorp/consul/agent/structs" -) - -func groupedEndpoints(locality *structs.Locality, policy *structs.DiscoveryPrioritizeByLocality, csns structs.CheckServiceNodes) ([]structs.CheckServiceNodes, error) { - switch { - case policy == nil || policy.Mode == "" || policy.Mode == "none": - return []structs.CheckServiceNodes{csns}, nil - case policy.Mode == "failover": - return prioritizeByLocalityFailover(locality, csns), nil - default: - return nil, fmt.Errorf("unexpected priortize-by-locality mode %q", policy.Mode) - } -} diff --git a/agent/xds/proxystateconverter/locality_policy_ce.go b/agent/xds/proxystateconverter/locality_policy_ce.go deleted file mode 100644 index cd7a3e7912e1f..0000000000000 --- a/agent/xds/proxystateconverter/locality_policy_ce.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package proxystateconverter - -import ( - "github.com/hashicorp/consul/agent/structs" -) - -func prioritizeByLocalityFailover(locality *structs.Locality, csns structs.CheckServiceNodes) []structs.CheckServiceNodes { - return nil -} diff --git a/agent/xds/proxystateconverter/routes.go b/agent/xds/proxystateconverter/routes.go deleted file mode 100644 index 9cdd24fe12b05..0000000000000 --- a/agent/xds/proxystateconverter/routes.go +++ /dev/null @@ -1,777 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxystateconverter - -import ( - "errors" - "fmt" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "sort" - "strings" - "time" - - "github.com/hashicorp/consul/agent/xds/response" - - "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/structs" - "google.golang.org/protobuf/types/known/durationpb" -) - -// routesFromSnapshot returns the xDS API representation of the "routes" in the -// snapshot. -func (s *Converter) routesFromSnapshot(cfgSnap *proxycfg.ConfigSnapshot) error { - if cfgSnap == nil { - return errors.New("nil config given") - } - - switch cfgSnap.Kind { - case structs.ServiceKindConnectProxy: - return s.routesForConnectProxy(cfgSnap) - // TODO(proxystate): Ingress Gateways will be added in the future. - //case structs.ServiceKindIngressGateway: - // return s.routesForIngressGateway(cfgSnap) - // TODO(proxystate): API Gateways will be added in the future. - //case structs.ServiceKindAPIGateway: - // return s.routesForAPIGateway(cfgSnap) - // TODO(proxystate): Terminating Gateways will be added in the future. - //case structs.ServiceKindTerminatingGateway: - // return s.routesForTerminatingGateway(cfgSnap) - // TODO(proxystate): Mesh Gateways will be added in the future. - //case structs.ServiceKindMeshGateway: - // return s.routesForMeshGateway(cfgSnap) - default: - return fmt.Errorf("Invalid service kind: %v", cfgSnap.Kind) - } -} - -// routesFromSnapshotConnectProxy returns the xDS API representation of the -// "routes" in the snapshot. -func (s *Converter) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapshot) error { - for uid, chain := range cfgSnap.ConnectProxy.DiscoveryChain { - if chain.Default { - continue - } - - virtualHost, err := s.makeUpstreamHostForDiscoveryChain(cfgSnap, uid, chain, []string{"*"}, false) - if err != nil { - return err - } - if virtualHost == nil { - continue - } - - route := &pbproxystate.Route{ - VirtualHosts: []*pbproxystate.VirtualHost{virtualHost}, - } - s.proxyState.Routes[uid.EnvoyID()] = route - } - addressesMap := make(map[string]map[string]string) - err := cfgSnap.ConnectProxy.DestinationsUpstream.ForEachKeyE(func(uid proxycfg.UpstreamID) error { - svcConfig, ok := cfgSnap.ConnectProxy.DestinationsUpstream.Get(uid) - if !ok || svcConfig == nil { - return nil - } - if !structs.IsProtocolHTTPLike(svcConfig.Protocol) { - // Routes can only be defined for HTTP services - return nil - } - - for _, address := range svcConfig.Destination.Addresses { - - routeName := clusterNameForDestination(cfgSnap, "~http", fmt.Sprintf("%d", svcConfig.Destination.Port), svcConfig.NamespaceOrDefault(), svcConfig.PartitionOrDefault()) - if _, ok := addressesMap[routeName]; !ok { - addressesMap[routeName] = make(map[string]string) - } - // cluster name is unique per address/port so we should not be doing any override here - clusterName := clusterNameForDestination(cfgSnap, svcConfig.Name, address, svcConfig.NamespaceOrDefault(), svcConfig.PartitionOrDefault()) - addressesMap[routeName][clusterName] = address - } - return nil - }) - - if err != nil { - return err - } - - for routeName, clusters := range addressesMap { - route, err := s.makeRouteForAddresses(clusters) - if err != nil { - return err - } - if route != nil { - s.proxyState.Routes[routeName] = route - } - } - - // TODO(rb): make sure we don't generate an empty result - return nil -} - -func (s *Converter) makeRouteForAddresses(addresses map[string]string) (*pbproxystate.Route, error) { - route, err := makeAddressesRoute(addresses) - if err != nil { - s.Logger.Error("failed to make route", "cluster", "error", err) - return nil, err - } - - return route, nil -} - -// TODO(proxystate): Terminating Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func routesForTerminatingGateway - -// TODO(proxystate): Mesh Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func routesForMeshGateway - -func makeAddressesRoute(addresses map[string]string) (*pbproxystate.Route, error) { - route := &pbproxystate.Route{} - for clusterName, address := range addresses { - destination := makeRouteDestinationFromName(clusterName) - virtualHost := &pbproxystate.VirtualHost{ - Name: clusterName, - Domains: []string{address}, - RouteRules: []*pbproxystate.RouteRule{ - { - Match: makeDefaultRouteMatch(), - Destination: destination, - }, - }, - } - route.VirtualHosts = append(route.VirtualHosts, virtualHost) - } - - // sort virtual hosts to have a stable order - sort.SliceStable(route.VirtualHosts, func(i, j int) bool { - return route.VirtualHosts[i].Name > route.VirtualHosts[j].Name - }) - return route, nil -} - -// makeRouteDestinationFromName (fka makeRouteActionFromName) -func makeRouteDestinationFromName(clusterName string) *pbproxystate.RouteDestination { - return &pbproxystate.RouteDestination{ - Destination: &pbproxystate.RouteDestination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: clusterName, - }, - }, - } -} - -// TODO(proxystate): Ingress Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func routesForIngressGateway - -// TODO(proxystate): API Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func routesForAPIGateway -// func buildHTTPRouteUpstream - -// TODO(proxystate): Ingress Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func findIngressServiceMatchingUpstream - -// TODO(proxystate): Ingress Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func generateUpstreamIngressDomains - -// TODO(proxystate): Ingress Gateways will be added in the future. -// Functions to add from agent/xds/clusters.go: -// func generateUpstreamAPIsDomains - -func (s *Converter) makeUpstreamHostForDiscoveryChain( - cfgSnap *proxycfg.ConfigSnapshot, - uid proxycfg.UpstreamID, - chain *structs.CompiledDiscoveryChain, - serviceDomains []string, - forMeshGateway bool, -) (*pbproxystate.VirtualHost, error) { - var routeRules []*pbproxystate.RouteRule - - startNode := chain.Nodes[chain.StartNode] - if startNode == nil { - return nil, fmt.Errorf("missing first node in compiled discovery chain for: %s", chain.ServiceName) - } - - upstreamsSnapshot, err := cfgSnap.ToConfigSnapshotUpstreams() - if err != nil && !forMeshGateway { - return nil, err - } - - switch startNode.Type { - case structs.DiscoveryGraphNodeTypeRouter: - routeRules = make([]*pbproxystate.RouteRule, 0, len(startNode.Routes)) - - for _, discoveryRoute := range startNode.Routes { - routeMatch := makeRouteMatchForDiscoveryRoute(discoveryRoute) - - var ( - routeDestination *pbproxystate.RouteDestination - err error - ) - - nextNode := chain.Nodes[discoveryRoute.NextNode] - - var lb *structs.LoadBalancer - if nextNode.LoadBalancer != nil { - lb = nextNode.LoadBalancer - } - - switch nextNode.Type { - case structs.DiscoveryGraphNodeTypeSplitter: - routeDestination, err = s.makeRouteDestinationForSplitter(upstreamsSnapshot, nextNode.Splits, chain, forMeshGateway) - if err != nil { - return nil, err - } - - case structs.DiscoveryGraphNodeTypeResolver: - rd, ok := s.makeRouteDestinationForChainCluster(upstreamsSnapshot, nextNode.Resolver.Target, chain, forMeshGateway) - if !ok { - continue - } - routeDestination = rd - - default: - return nil, fmt.Errorf("unexpected graph node after route %q", nextNode.Type) - } - - routeDestination.DestinationConfiguration = &pbproxystate.DestinationConfiguration{} - if err := injectLBToDestinationConfiguration(lb, routeDestination.DestinationConfiguration); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) - } - - // TODO(rb): Better help handle the envoy case where you need (prefix=/foo/,rewrite=/) and (exact=/foo,rewrite=/) to do a full rewrite - - destination := discoveryRoute.Definition.Destination - - routeRule := &pbproxystate.RouteRule{} - - if destination != nil { - configHandle := routeDestination.DestinationConfiguration - if destination.PrefixRewrite != "" { - configHandle.PrefixRewrite = destination.PrefixRewrite - } - - if destination.RequestTimeout > 0 || destination.IdleTimeout > 0 { - configHandle.TimeoutConfig = &pbproxystate.TimeoutConfig{} - } - if destination.RequestTimeout > 0 { - configHandle.TimeoutConfig.Timeout = durationpb.New(destination.RequestTimeout) - } - if destination.IdleTimeout > 0 { - configHandle.TimeoutConfig.IdleTimeout = durationpb.New(destination.IdleTimeout) - } - - if destination.HasRetryFeatures() { - configHandle.RetryPolicy = getRetryPolicyForDestination(destination) - } - - if err := injectHeaderManipToRoute(destination, routeRule); err != nil { - return nil, fmt.Errorf("failed to apply header manipulation configuration to route: %v", err) - } - } - - routeRule.Match = routeMatch - routeRule.Destination = routeDestination - - routeRules = append(routeRules, routeRule) - } - - case structs.DiscoveryGraphNodeTypeSplitter: - routeDestination, err := s.makeRouteDestinationForSplitter(upstreamsSnapshot, startNode.Splits, chain, forMeshGateway) - if err != nil { - return nil, err - } - var lb *structs.LoadBalancer - if startNode.LoadBalancer != nil { - lb = startNode.LoadBalancer - } - routeDestination.DestinationConfiguration = &pbproxystate.DestinationConfiguration{} - if err := injectLBToDestinationConfiguration(lb, routeDestination.DestinationConfiguration); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) - } - - defaultRoute := &pbproxystate.RouteRule{ - Match: makeDefaultRouteMatch(), - Destination: routeDestination, - } - - routeRules = []*pbproxystate.RouteRule{defaultRoute} - - case structs.DiscoveryGraphNodeTypeResolver: - routeDestination, ok := s.makeRouteDestinationForChainCluster(upstreamsSnapshot, startNode.Resolver.Target, chain, forMeshGateway) - if !ok { - break - } - var lb *structs.LoadBalancer - if startNode.LoadBalancer != nil { - lb = startNode.LoadBalancer - } - routeDestination.DestinationConfiguration = &pbproxystate.DestinationConfiguration{} - if err := injectLBToDestinationConfiguration(lb, routeDestination.DestinationConfiguration); err != nil { - return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) - } - - if startNode.Resolver.RequestTimeout > 0 { - to := &pbproxystate.TimeoutConfig{ - Timeout: durationpb.New(startNode.Resolver.RequestTimeout), - } - routeDestination.DestinationConfiguration.TimeoutConfig = to - } - defaultRoute := &pbproxystate.RouteRule{ - Match: makeDefaultRouteMatch(), - Destination: routeDestination, - } - - routeRules = []*pbproxystate.RouteRule{defaultRoute} - - default: - return nil, fmt.Errorf("unknown first node in discovery chain of type: %s", startNode.Type) - } - - host := &pbproxystate.VirtualHost{ - Name: uid.EnvoyID(), - Domains: serviceDomains, - RouteRules: routeRules, - } - - return host, nil -} - -func getRetryPolicyForDestination(destination *structs.ServiceRouteDestination) *pbproxystate.RetryPolicy { - retryPolicy := &pbproxystate.RetryPolicy{} - if destination.NumRetries > 0 { - retryPolicy.NumRetries = response.MakeUint32Value(int(destination.NumRetries)) - } - - // The RetryOn magic values come from: https://www.envoyproxy.io/docs/envoy/v1.10.0/configuration/http_filters/router_filter#config-http-filters-router-x-envoy-retry-on - var retryStrings []string - - if len(destination.RetryOn) > 0 { - retryStrings = append(retryStrings, destination.RetryOn...) - } - - if destination.RetryOnConnectFailure { - // connect-failure can be enabled by either adding connect-failure to the RetryOn list or by using the legacy RetryOnConnectFailure option - // Check that it's not already in the RetryOn list, so we don't set it twice - connectFailureExists := false - for _, r := range retryStrings { - if r == "connect-failure" { - connectFailureExists = true - } - } - if !connectFailureExists { - retryStrings = append(retryStrings, "connect-failure") - } - } - - if len(destination.RetryOnStatusCodes) > 0 { - retryStrings = append(retryStrings, "retriable-status-codes") - retryPolicy.RetriableStatusCodes = destination.RetryOnStatusCodes - } - - retryPolicy.RetryOn = strings.Join(retryStrings, ",") - - return retryPolicy -} - -func makeRouteMatchForDiscoveryRoute(discoveryRoute *structs.DiscoveryRoute) *pbproxystate.RouteMatch { - match := discoveryRoute.Definition.Match - if match == nil || match.IsEmpty() { - return makeDefaultRouteMatch() - } - - routeMatch := &pbproxystate.RouteMatch{} - - switch { - case match.HTTP.PathExact != "": - routeMatch.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Exact{ - Exact: match.HTTP.PathExact, - }, - } - case match.HTTP.PathPrefix != "": - routeMatch.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: match.HTTP.PathPrefix, - }, - } - case match.HTTP.PathRegex != "": - routeMatch.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Regex{ - Regex: match.HTTP.PathRegex, - }, - } - default: - routeMatch.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: "/", - }, - } - } - - if len(match.HTTP.Header) > 0 { - routeMatch.HeaderMatches = make([]*pbproxystate.HeaderMatch, 0, len(match.HTTP.Header)) - for _, hdr := range match.HTTP.Header { - headerMatch := &pbproxystate.HeaderMatch{ - Name: hdr.Name, - } - - switch { - case hdr.Exact != "": - headerMatch.Match = &pbproxystate.HeaderMatch_Exact{ - Exact: hdr.Exact, - } - case hdr.Regex != "": - headerMatch.Match = &pbproxystate.HeaderMatch_Regex{ - Regex: hdr.Regex, - } - case hdr.Prefix != "": - headerMatch.Match = &pbproxystate.HeaderMatch_Prefix{ - Prefix: hdr.Prefix, - } - case hdr.Suffix != "": - headerMatch.Match = &pbproxystate.HeaderMatch_Suffix{ - Suffix: hdr.Suffix, - } - case hdr.Present: - headerMatch.Match = &pbproxystate.HeaderMatch_Present{ - Present: true, - } - default: - continue // skip this impossible situation - } - - if hdr.Invert { - headerMatch.InvertMatch = true - } - - routeMatch.HeaderMatches = append(routeMatch.HeaderMatches, headerMatch) - } - } - - if len(match.HTTP.Methods) > 0 { - routeMatch.MethodMatches = append(routeMatch.MethodMatches, match.HTTP.Methods...) - } - - if len(match.HTTP.QueryParam) > 0 { - routeMatch.QueryParameterMatches = make([]*pbproxystate.QueryParameterMatch, 0, len(match.HTTP.QueryParam)) - for _, qm := range match.HTTP.QueryParam { - - queryMatcher := &pbproxystate.QueryParameterMatch{ - Name: qm.Name, - } - - switch { - case qm.Exact != "": - queryMatcher.Match = &pbproxystate.QueryParameterMatch_Exact{ - Exact: qm.Exact, - } - case qm.Regex != "": - queryMatcher.Match = &pbproxystate.QueryParameterMatch_Regex{ - Regex: qm.Regex, - } - case qm.Present: - queryMatcher.Match = &pbproxystate.QueryParameterMatch_Present{ - Present: true, - } - default: - continue // skip this impossible situation - } - - routeMatch.QueryParameterMatches = append(routeMatch.QueryParameterMatches, queryMatcher) - } - } - - return routeMatch -} - -func makeDefaultRouteMatch() *pbproxystate.RouteMatch { - return &pbproxystate.RouteMatch{ - PathMatch: &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: "/", - }, - }, - // TODO(banks) Envoy supports matching only valid GRPC - // requests which might be nice to add here for gRPC services - // but it's not supported in our current envoy SDK version - // although docs say it was supported by 1.8.0. Going to defer - // that until we've updated the deps. - } -} - -func (s *Converter) makeRouteDestinationForChainCluster( - upstreamsSnapshot *proxycfg.ConfigSnapshotUpstreams, - targetID string, - chain *structs.CompiledDiscoveryChain, - forMeshGateway bool, -) (*pbproxystate.RouteDestination, bool) { - clusterName := s.getTargetClusterName(upstreamsSnapshot, chain, targetID, forMeshGateway) - if clusterName == "" { - return nil, false - } - return makeRouteDestinationFromName(clusterName), true -} - -func (s *Converter) makeRouteDestinationForSplitter( - upstreamsSnapshot *proxycfg.ConfigSnapshotUpstreams, - splits []*structs.DiscoverySplit, - chain *structs.CompiledDiscoveryChain, - forMeshGateway bool, -) (*pbproxystate.RouteDestination, error) { - clusters := make([]*pbproxystate.L7WeightedDestinationCluster, 0, len(splits)) - for _, split := range splits { - nextNode := chain.Nodes[split.NextNode] - - if nextNode.Type != structs.DiscoveryGraphNodeTypeResolver { - return nil, fmt.Errorf("unexpected splitter destination node type: %s", nextNode.Type) - } - targetID := nextNode.Resolver.Target - - clusterName := s.getTargetClusterName(upstreamsSnapshot, chain, targetID, forMeshGateway) - if clusterName == "" { - continue - } - - // The smallest representable weight is 1/10000 or .01% but envoy - // deals with integers so scale everything up by 100x. - weight := int(split.Weight * 100) - - clusterWeight := &pbproxystate.L7WeightedDestinationCluster{ - Name: clusterName, - Weight: response.MakeUint32Value(weight), - } - if err := injectHeaderManipToWeightedCluster(split.Definition, clusterWeight); err != nil { - return nil, err - } - - clusters = append(clusters, clusterWeight) - } - - if len(clusters) <= 0 { - return nil, fmt.Errorf("number of clusters in splitter must be > 0; got %d", len(clusters)) - } - - return &pbproxystate.RouteDestination{ - Destination: &pbproxystate.RouteDestination_WeightedClusters{ - WeightedClusters: &pbproxystate.L7WeightedClusterGroup{ - Clusters: clusters, - }, - }, - }, nil -} - -func injectLBToDestinationConfiguration(lb *structs.LoadBalancer, destinationConfig *pbproxystate.DestinationConfiguration) error { - if lb == nil || !lb.IsHashBased() { - return nil - } - - result := make([]*pbproxystate.LoadBalancerHashPolicy, 0, len(lb.HashPolicies)) - for _, policy := range lb.HashPolicies { - if policy.SourceIP { - p := &pbproxystate.LoadBalancerHashPolicy{ - Policy: &pbproxystate.LoadBalancerHashPolicy_ConnectionProperties{ - ConnectionProperties: &pbproxystate.ConnectionPropertiesPolicy{ - SourceIp: true, - Terminal: policy.Terminal, - }, - }, - } - result = append(result, p) - continue - } - - switch policy.Field { - case structs.HashPolicyHeader: - p := &pbproxystate.LoadBalancerHashPolicy{ - Policy: &pbproxystate.LoadBalancerHashPolicy_Header{ - Header: &pbproxystate.HeaderPolicy{ - Name: policy.FieldValue, - Terminal: policy.Terminal, - }, - }, - } - result = append(result, p) - - case structs.HashPolicyCookie: - - cookie := &pbproxystate.CookiePolicy{ - Name: policy.FieldValue, - Terminal: policy.Terminal, - } - if policy.CookieConfig != nil { - cookie.Path = policy.CookieConfig.Path - - if policy.CookieConfig.TTL != 0*time.Second { - cookie.Ttl = durationpb.New(policy.CookieConfig.TTL) - } - - // Envoy will generate a session cookie if the ttl is present and zero. - if policy.CookieConfig.Session { - cookie.Ttl = durationpb.New(0 * time.Second) - } - } - p := &pbproxystate.LoadBalancerHashPolicy{ - Policy: &pbproxystate.LoadBalancerHashPolicy_Cookie{ - Cookie: cookie, - }, - } - result = append(result, p) - - case structs.HashPolicyQueryParam: - p := &pbproxystate.LoadBalancerHashPolicy{ - Policy: &pbproxystate.LoadBalancerHashPolicy_QueryParameter{ - QueryParameter: &pbproxystate.QueryParameterPolicy{ - Name: policy.FieldValue, - Terminal: policy.Terminal, - }, - }, - } - result = append(result, p) - - default: - return fmt.Errorf("unsupported load balancer hash policy field: %v", policy.Field) - } - } - - destinationConfig.HashPolicies = result - return nil -} - -func injectHeaderManipToRoute(dest *structs.ServiceRouteDestination, r *pbproxystate.RouteRule) error { - if !dest.RequestHeaders.IsZero() { - r.HeaderMutations = append( - r.HeaderMutations, - makeRequestHeaderAdd(dest.RequestHeaders.Add, true)..., - ) - r.HeaderMutations = append( - r.HeaderMutations, - makeRequestHeaderAdd(dest.RequestHeaders.Set, false)..., - ) - r.HeaderMutations = append( - r.HeaderMutations, - makeRequestHeaderRemove(dest.RequestHeaders.Remove), - ) - } - if !dest.ResponseHeaders.IsZero() { - r.HeaderMutations = append( - r.HeaderMutations, - makeResponseHeaderAdd(dest.ResponseHeaders.Add, true)..., - ) - r.HeaderMutations = append( - r.HeaderMutations, - makeResponseHeaderAdd(dest.ResponseHeaders.Set, false)..., - ) - r.HeaderMutations = append( - r.HeaderMutations, - makeResponseHeaderRemove(dest.ResponseHeaders.Remove), - ) - } - return nil -} - -func injectHeaderManipToWeightedCluster(split *structs.ServiceSplit, c *pbproxystate.L7WeightedDestinationCluster) error { - if !split.RequestHeaders.IsZero() { - c.HeaderMutations = append( - c.HeaderMutations, - makeRequestHeaderAdd(split.RequestHeaders.Add, true)..., - ) - c.HeaderMutations = append( - c.HeaderMutations, - makeRequestHeaderAdd(split.RequestHeaders.Set, false)..., - ) - c.HeaderMutations = append( - c.HeaderMutations, - makeRequestHeaderRemove(split.RequestHeaders.Remove), - ) - } - if !split.ResponseHeaders.IsZero() { - c.HeaderMutations = append( - c.HeaderMutations, - makeResponseHeaderAdd(split.ResponseHeaders.Add, true)..., - ) - c.HeaderMutations = append( - c.HeaderMutations, - makeResponseHeaderAdd(split.ResponseHeaders.Set, false)..., - ) - c.HeaderMutations = append( - c.HeaderMutations, - makeResponseHeaderRemove(split.ResponseHeaders.Remove), - ) - } - return nil -} - -func makeRequestHeaderAdd(vals map[string]string, add bool) []*pbproxystate.HeaderMutation { - mutations := make([]*pbproxystate.HeaderMutation, 0, len(vals)) - - appendAction := pbproxystate.AppendAction_APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD - if add { - appendAction = pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD - } - - for k, v := range vals { - m := &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_RequestHeaderAdd{ - RequestHeaderAdd: &pbproxystate.RequestHeaderAdd{ - Header: &pbproxystate.Header{ - Key: k, - Value: v, - }, - AppendAction: appendAction, - }, - }, - } - mutations = append(mutations, m) - } - return mutations -} - -func makeRequestHeaderRemove(values []string) *pbproxystate.HeaderMutation { - return &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_RequestHeaderRemove{ - RequestHeaderRemove: &pbproxystate.RequestHeaderRemove{ - HeaderKeys: values, - }, - }, - } -} - -func makeResponseHeaderAdd(vals map[string]string, add bool) []*pbproxystate.HeaderMutation { - mutations := make([]*pbproxystate.HeaderMutation, 0, len(vals)) - - appendAction := pbproxystate.AppendAction_APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD - if add { - appendAction = pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD - } - - for k, v := range vals { - m := &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_ResponseHeaderAdd{ - ResponseHeaderAdd: &pbproxystate.ResponseHeaderAdd{ - Header: &pbproxystate.Header{ - Key: k, - Value: v, - }, - AppendAction: appendAction, - }, - }, - } - mutations = append(mutations, m) - } - return mutations -} - -func makeResponseHeaderRemove(values []string) *pbproxystate.HeaderMutation { - return &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_ResponseHeaderRemove{ - ResponseHeaderRemove: &pbproxystate.ResponseHeaderRemove{ - HeaderKeys: values, - }, - }, - } -} diff --git a/agent/xds/rbac.go b/agent/xds/rbac.go index d8252d7cabc90..f38525abb78d9 100644 --- a/agent/xds/rbac.go +++ b/agent/xds/rbac.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -19,15 +19,9 @@ import ( "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/response" "github.com/hashicorp/consul/proto/private/pbpeering" ) -const ( - envoyHTTPRBACFilterKey = "envoy.filters.http.rbac" - envoyNetworkRBACFilterKey = "envoy.filters.network.rbac" -) - func makeRBACNetworkFilter( intentions structs.SimplifiedIntentions, intentionDefaultAllow bool, @@ -43,7 +37,7 @@ func makeRBACNetworkFilter( StatPrefix: "connect_authz", Rules: rules, } - return makeFilter(envoyNetworkRBACFilterKey, cfg) + return makeFilter("envoy.filters.network.rbac", cfg) } func makeRBACHTTPFilter( @@ -61,7 +55,7 @@ func makeRBACHTTPFilter( cfg := &envoy_http_rbac_v3.RBAC{ Rules: rules, } - return makeEnvoyHTTPFilter(envoyHTTPRBACFilterKey, cfg) + return makeEnvoyHTTPFilter("envoy.filters.http.rbac", cfg) } func intentionListToIntermediateRBACForm( @@ -331,7 +325,6 @@ func intentionActionFromBool(v bool) intentionAction { return intentionActionDeny } } - func intentionActionFromString(s structs.IntentionAction) intentionAction { if s == structs.IntentionActionAllow { return intentionActionAllow @@ -815,6 +808,7 @@ func segmentToPermission(segments []*envoy_matcher_v3.MetadataMatcher_PathSegmen // }, // }, func pathToSegments(paths []string, payloadKey string) []*envoy_matcher_v3.MetadataMatcher_PathSegment { + segments := make([]*envoy_matcher_v3.MetadataMatcher_PathSegment, 0, len(paths)) segments = append(segments, makeSegment(payloadKey)) @@ -839,9 +833,6 @@ func optimizePrincipals(orig []*envoy_rbac_v3.Principal) []*envoy_rbac_v3.Princi if !ok { return orig } - // In practice, you can't hit this - // Only JWTs (HTTP-only) generate orPrinciples, but optimizePrinciples is only called - // against the combined list of principles for L4 intentions. orIds = append(orIds, or.OrIds.Ids...) } @@ -993,7 +984,7 @@ func authenticatedPatternPrincipal(pattern string) *envoy_rbac_v3.Principal { Authenticated: &envoy_rbac_v3.Principal_Authenticated{ PrincipalName: &envoy_matcher_v3.StringMatcher{ MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(pattern), + SafeRegex: makeEnvoyRegexMatch(pattern), }, }, }, @@ -1025,7 +1016,7 @@ func xfccPrincipal(src rbacService) *envoy_rbac_v3.Principal { HeaderMatchSpecifier: &envoy_route_v3.HeaderMatcher_StringMatch{ StringMatch: &envoy_matcher_v3.StringMatcher{ MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(pattern), + SafeRegex: makeEnvoyRegexMatch(pattern), }, }, }, @@ -1034,10 +1025,8 @@ func xfccPrincipal(src rbacService) *envoy_rbac_v3.Principal { } } -const ( - anyPath = `[^/]+` - trustDomain = anyPath + "." + anyPath -) +const anyPath = `[^/]+` +const trustDomain = anyPath + "." + anyPath // downstreamServiceIdentityMatcher needs to match XFCC headers in two cases: // 1. Requests to cluster peered services through a mesh gateway. In this case, the XFCC header looks like the following (I added a new line after each ; for readability) @@ -1232,7 +1221,7 @@ func convertPermission(perm *structs.IntentionPermission) *envoy_rbac_v3.Permiss Rule: &envoy_matcher_v3.PathMatcher_Path{ Path: &envoy_matcher_v3.StringMatcher{ MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(perm.HTTP.PathRegex), + SafeRegex: makeEnvoyRegexMatch(perm.HTTP.PathRegex), }, }, }, @@ -1248,44 +1237,21 @@ func convertPermission(perm *structs.IntentionPermission) *envoy_rbac_v3.Permiss switch { case hdr.Exact != "": - eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ - Exact: hdr.Exact, - }, - IgnoreCase: false, - }, + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_ExactMatch{ + ExactMatch: hdr.Exact, } case hdr.Regex != "": - eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(hdr.Regex), - }, - IgnoreCase: false, - }, + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_SafeRegexMatch{ + SafeRegexMatch: makeEnvoyRegexMatch(hdr.Regex), } - case hdr.Prefix != "": - eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Prefix{ - Prefix: hdr.Prefix, - }, - IgnoreCase: false, - }, + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_PrefixMatch{ + PrefixMatch: hdr.Prefix, } - case hdr.Suffix != "": - eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Suffix{ - Suffix: hdr.Suffix, - }, - IgnoreCase: false, - }, + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_SuffixMatch{ + SuffixMatch: hdr.Suffix, } - case hdr.Present: eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_PresentMatch{ PresentMatch: true, @@ -1311,7 +1277,7 @@ func convertPermission(perm *structs.IntentionPermission) *envoy_rbac_v3.Permiss eh := &envoy_route_v3.HeaderMatcher{ Name: ":method", HeaderMatchSpecifier: &envoy_route_v3.HeaderMatcher_SafeRegexMatch{ - SafeRegexMatch: response.MakeEnvoyRegexMatch(methodHeaderRegex), + SafeRegexMatch: makeEnvoyRegexMatch(methodHeaderRegex), }, } diff --git a/agent/xds/rbac_test.go b/agent/xds/rbac_test.go index 71b2a69433264..6bc36028707a5 100644 --- a/agent/xds/rbac_test.go +++ b/agent/xds/rbac_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -10,17 +10,13 @@ import ( "sort" "testing" - envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" envoy_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xdsv2" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" "github.com/hashicorp/consul/proto/private/pbpeering" ) @@ -556,206 +552,62 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { } ) - makeSpiffe := func(name string, entMeta *acl.EnterpriseMeta) *pbproxystate.Spiffe { - em := *acl.DefaultEnterpriseMeta() - if entMeta != nil { - em = *entMeta - } - regex := makeSpiffePattern(rbacService{ - ServiceName: structs.ServiceName{ - Name: name, - EnterpriseMeta: em, - }, - TrustDomain: testTrustDomain, - }) - return &pbproxystate.Spiffe{Regex: regex} - } - tests := map[string]struct { - intentionDefaultAllow bool - v1Intentions structs.SimplifiedIntentions - v2L4TrafficPermissions *pbproxystate.TrafficPermissions + intentionDefaultAllow bool + intentions structs.SimplifiedIntentions }{ "default-deny-mixed-precedence": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testIntention(t, "web", "api", structs.IntentionActionAllow), testIntention(t, "*", "api", structs.IntentionActionDeny), testIntention(t, "web", "*", structs.IntentionActionDeny), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("web", nil), - }, - }, - }, - }, - }, }, "default-deny-service-wildcard-allow": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourceIntention("*", structs.IntentionActionAllow), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("*", nil), - }, - }, - }, - }, - }, }, "default-allow-service-wildcard-deny": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( testSourceIntention("*", structs.IntentionActionDeny), ), }, "default-deny-one-allow": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourceIntention("web", structs.IntentionActionAllow), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("web", nil), - }, - }, - }, - }, - }, }, "default-allow-one-deny": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( testSourceIntention("web", structs.IntentionActionDeny), ), }, "default-deny-allow-deny": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourceIntention("web", structs.IntentionActionDeny), testSourceIntention("*", structs.IntentionActionAllow), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("*", nil), - ExcludeSpiffes: []*pbproxystate.Spiffe{makeSpiffe("web", nil)}, - }, - }, - }, - }, - }, }, "default-deny-kitchen-sink": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( // (double exact) testSourceIntention("web", structs.IntentionActionAllow), testSourceIntention("unsafe", structs.IntentionActionDeny), testSourceIntention("cron", structs.IntentionActionAllow), testSourceIntention("*", structs.IntentionActionAllow), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("cron", nil), - }, - { - Spiffe: makeSpiffe("web", nil), - }, - { - Spiffe: makeSpiffe("*", nil), - ExcludeSpiffes: []*pbproxystate.Spiffe{ - makeSpiffe("web", nil), - makeSpiffe("unsafe", nil), - makeSpiffe("cron", nil), - }, - }, - }, - }, - }, - }, - }, - "v2-kitchen-sink": { - intentionDefaultAllow: false, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("api", nil), - }, - { - Spiffe: makeSpiffe("*", nil), - ExcludeSpiffes: []*pbproxystate.Spiffe{ - makeSpiffe("unsafe", nil), - }, - }, - }, - }, - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("web", nil), - }, - }, - }, - }, - DenyPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: makeSpiffe("db", nil), - }, - { - Spiffe: makeSpiffe("cron", nil), - }, - }, - }, - }, - }, - }, - "v2-default-deny": { - intentionDefaultAllow: false, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{}, - }, - "v2-default-allow": { - intentionDefaultAllow: true, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{}, - }, - // This validates that we don't send xDS messages to Envoy that will fail validation. - // Traffic permissions validations prevent this from being written to the IR, so the thing - // that matters is that the snapshot is valid to Envoy. - "v2-ignore-empty-permissions": { - intentionDefaultAllow: false, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ - DenyPermissions: []*pbproxystate.Permission{ - {}, - }, - AllowPermissions: []*pbproxystate.Permission{ - {}, - }, - }, }, "default-allow-kitchen-sink": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( // (double exact) testSourceIntention("web", structs.IntentionActionDeny), testSourceIntention("unsafe", structs.IntentionActionAllow), @@ -765,7 +617,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "default-deny-peered-kitchen-sink": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourceIntention("web", structs.IntentionActionAllow), testIntentionPeered("*", "peer1", structs.IntentionActionAllow), testIntentionPeered("web", "peer1", structs.IntentionActionDeny), @@ -774,32 +626,32 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { // ======================== "default-allow-path-allow": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", permSlashPrefix), ), }, "default-deny-path-allow": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", permSlashPrefix), ), }, "default-allow-path-deny": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", permDenySlashPrefix), ), }, "default-deny-path-deny": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", permDenySlashPrefix), ), }, // ======================== "default-allow-deny-all-and-path-allow": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", &structs.IntentionPermission{ Action: structs.IntentionActionAllow, @@ -813,7 +665,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "default-deny-deny-all-and-path-allow": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", &structs.IntentionPermission{ Action: structs.IntentionActionAllow, @@ -827,7 +679,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "default-allow-deny-all-and-path-deny": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", &structs.IntentionPermission{ Action: structs.IntentionActionDeny, @@ -841,7 +693,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "default-deny-deny-all-and-path-deny": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", &structs.IntentionPermission{ Action: structs.IntentionActionDeny, @@ -856,7 +708,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { // ======================== "default-deny-two-path-deny-and-path-allow": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", &structs.IntentionPermission{ Action: structs.IntentionActionDeny, @@ -881,7 +733,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "default-allow-two-path-deny-and-path-allow": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", &structs.IntentionPermission{ Action: structs.IntentionActionDeny, @@ -906,7 +758,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "default-deny-single-intention-with-kitchen-sink-perms": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", &structs.IntentionPermission{ Action: structs.IntentionActionDeny, @@ -949,7 +801,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "default-allow-single-intention-with-kitchen-sink-perms": { intentionDefaultAllow: true, - v1Intentions: sorted( + intentions: sorted( testSourcePermIntention("web", &structs.IntentionPermission{ Action: structs.IntentionActionAllow, @@ -993,13 +845,13 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { // ========= JWTAuthn Filter checks "top-level-jwt-no-permissions": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testIntentionWithJWT("web", structs.IntentionActionAllow, jwtRequirement), ), }, "empty-top-level-jwt-with-one-permission": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testIntentionWithJWT("web", structs.IntentionActionAllow, nil, &structs.IntentionPermission{ Action: structs.IntentionActionAllow, HTTP: &structs.IntentionHTTPPermission{ @@ -1011,7 +863,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "top-level-jwt-with-one-permission": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testIntentionWithJWT("web", structs.IntentionActionAllow, jwtRequirement, @@ -1033,7 +885,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "top-level-jwt-with-multiple-permissions": { intentionDefaultAllow: false, - v1Intentions: sorted( + intentions: sorted( testIntentionWithJWT("web", structs.IntentionActionAllow, jwtRequirement, @@ -1065,49 +917,17 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { tt := tt t.Run(name, func(t *testing.T) { t.Run("network filter", func(t *testing.T) { + filter, err := makeRBACNetworkFilter(tt.intentions, tt.intentionDefaultAllow, testLocalInfo, testPeerTrustBundle) + require.NoError(t, err) t.Run("current", func(t *testing.T) { - if len(tt.v1Intentions) == 0 { - return - } - - filter, err := makeRBACNetworkFilter(tt.v1Intentions, tt.intentionDefaultAllow, testLocalInfo, testPeerTrustBundle) - require.NoError(t, err) gotJSON := protoToJSON(t, filter) require.JSONEq(t, goldenSimple(t, filepath.Join("rbac", name), gotJSON), gotJSON) }) - - t.Run("v1 vs v2", func(t *testing.T) { - if tt.v2L4TrafficPermissions == nil { - return - } - - tt.v2L4TrafficPermissions.DefaultAllow = tt.intentionDefaultAllow - - filters, err := xdsv2.MakeRBACNetworkFilters(tt.v2L4TrafficPermissions) - require.NoError(t, err) - - var gotJSON string - if len(filters) == 1 { - gotJSON = protoToJSON(t, filters[0]) - } else { - // This is wrapped because protoToJSON won't encode an array of protobufs. - chain := &envoy_listener_v3.FilterChain{} - chain.Filters = filters - gotJSON = protoToJSON(t, chain) - } - - require.JSONEq(t, goldenSimple(t, filepath.Join("rbac", name), gotJSON), gotJSON) - }) }) - t.Run("http filter", func(t *testing.T) { - if len(tt.v1Intentions) == 0 { - return - } - - filter, err := makeRBACHTTPFilter(tt.v1Intentions, tt.intentionDefaultAllow, testLocalInfo, testPeerTrustBundle, testJWTProviderConfigEntry) + filter, err := makeRBACHTTPFilter(tt.intentions, tt.intentionDefaultAllow, testLocalInfo, testPeerTrustBundle, testJWTProviderConfigEntry) require.NoError(t, err) t.Run("current", func(t *testing.T) { diff --git a/agent/xds/resources.go b/agent/xds/resources.go index fc761040029c2..c7099e5cb50a0 100644 --- a/agent/xds/resources.go +++ b/agent/xds/resources.go @@ -1,12 +1,11 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds import ( "fmt" - "github.com/hashicorp/consul/agent/xds/configfetcher" "github.com/hashicorp/go-hclog" "google.golang.org/protobuf/proto" @@ -19,7 +18,7 @@ import ( // resources for a single client. type ResourceGenerator struct { Logger hclog.Logger - CfgFetcher configfetcher.ConfigFetcher + CfgFetcher ConfigFetcher IncrementalXDS bool ProxyFeatures xdscommon.SupportedProxyFeatures @@ -27,7 +26,7 @@ type ResourceGenerator struct { func NewResourceGenerator( logger hclog.Logger, - cfgFetcher configfetcher.ConfigFetcher, + cfgFetcher ConfigFetcher, incrementalXDS bool, ) *ResourceGenerator { return &ResourceGenerator{ diff --git a/agent/xds/resources_ce_test.go b/agent/xds/resources_ce_test.go index 08b922809fc74..5da963940ccba 100644 --- a/agent/xds/resources_ce_test.go +++ b/agent/xds/resources_ce_test.go @@ -1,12 +1,11 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package xds -import "testing" - -func getEnterpriseGoldenTestCases(t *testing.T) []goldenTestCase { +func getEnterpriseGoldenTestCases() []goldenTestCase { return nil } diff --git a/agent/xds/resources_test.go b/agent/xds/resources_test.go index b47edcbac3684..29743c060bfd4 100644 --- a/agent/xds/resources_test.go +++ b/agent/xds/resources_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -7,25 +7,23 @@ import ( "path/filepath" "sort" "testing" - "time" envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" + "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/discoverychain" "github.com/hashicorp/consul/agent/xds/testcommon" "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/types" testinf "github.com/mitchellh/go-testing-interface" "github.com/stretchr/testify/require" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/response" "github.com/hashicorp/consul/sdk/testutil" ) @@ -119,7 +117,7 @@ func TestAllResourcesFromSnapshot(t *testing.T) { } }) - r, err := response.CreateResponse(typeUrl, "00000001", "00000001", items) + r, err := createResponse(typeUrl, "00000001", "00000001", items) require.NoError(t, err) gotJSON := protoToJSON(t, r) @@ -158,23 +156,13 @@ func TestAllResourcesFromSnapshot(t *testing.T) { }, }, { - name: "transparent-proxy", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotTransparentProxy(t) - }, + name: "transparent-proxy", + create: proxycfg.TestConfigSnapshotTransparentProxy, }, { name: "connect-proxy-with-peered-upstreams", create: proxycfg.TestConfigSnapshotPeering, }, - { - name: "connect-proxy-with-peered-upstreams-escape-overrides", - create: proxycfg.TestConfigSnapshotPeeringWithEscapeOverrides, - }, - { - name: "connect-proxy-with-peered-upstreams-http2", - create: proxycfg.TestConfigSnapshotPeeringWithHTTP2, - }, { name: "transparent-proxy-with-peered-upstreams", create: proxycfg.TestConfigSnapshotPeeringTProxy, @@ -191,7 +179,7 @@ func TestAllResourcesFromSnapshot(t *testing.T) { tests = append(tests, getConnectProxyTransparentProxyGoldenTestCases()...) tests = append(tests, getMeshGatewayPeeringGoldenTestCases()...) tests = append(tests, getTrafficControlPeeringGoldenTestCases(false)...) - tests = append(tests, getEnterpriseGoldenTestCases(t)...) + tests = append(tests, getEnterpriseGoldenTestCases()...) tests = append(tests, getAPIGatewayGoldenTestCases(t)...) latestEnvoyVersion := xdscommon.EnvoyVersions[0] @@ -258,11 +246,7 @@ func getMeshGatewayPeeringGoldenTestCases() []goldenTestCase { { name: "mesh-gateway-with-imported-peered-services", create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotPeeredMeshGateway(t, "imported-services", func(ns *structs.NodeService) { - ns.Proxy.Config = map[string]interface{}{ - "envoy_dns_discovery_type": "STRICT_DNS", - } - }, nil) + return proxycfg.TestConfigSnapshotPeeredMeshGateway(t, "imported-services", nil, nil) }, }, { @@ -342,54 +326,6 @@ RahYIzNLRBTLrwadLAZkApUpZvB8qDK4knsTWFYujNsylCww2A6ajzIMFNU4GkUK NtyHRuD+KYRmjXtyX1yHNqfGN3vOQmwavHq2R8wHYuBSc6LAHHV9vG+j0VsgMELO qwxn8SmLkSKbf2+MsQVzLCXXN5u+D8Yv+4py+oKP4EQ5aFZuDEx+r/G/31rTthww AAJAMaoXmoYVdgXV+CPuBb2M4XCpuzLu3bcA2PXm5ipSyIgntMKwXV7r ------END CERTIFICATE-----` - // openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -sha256 -days 3650 \ - // -nodes -subj "/C=XX/CN=secondcert.com" -addext "subjectAltName = DNS:secondcert.com" - gatewayTestPrivateKeyTwo = `-----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCiPr2HCbVzbZ1M -IW89rfLLrciPTWWl48DF9CmYHS0C2gSD1W6bxzO7zdA+ced0ajI+YsQ9aBAXRhKl -EHgnhBJ6sGsz1XBQ9+lNDHrg9AjugIiHoscYOeCcxMeXhp97ti+vpVsc2/AvEf2K -GIUuOjcufXuRXkWQ2aB4RGyodkgRF6n8YrLJb7pWIjoCNwDAWtZX4wIVFgGq1ew0 -E/E9EyStMYTb5h1lvCpXYRN9AeSFKUQI/y0xsT3+nZ/gyzx3CrgzuSYRgptbuVwm -5F2Q16sLR/EtCBIhA8npKagx/4U7KOilF31I2locH4Aq5l9VJd/6pTA5F4KCAW/E -ybXz6DojAgMBAAECggEAPcOuuRqsFf4ztIjB5XQ0Cu/kexFW0flLKNDTiNIKkZxX -vaxhyDHkculeDnekSkAnUnKdDFdyULnfXTFQ3JI9yrEgjoIBmQFXsno+ySZ9w/Xw -g9om+wUFigirhva7/geUTcSgU/Myk2jA4XKGONv2p98jTGrcBtGickZyKwukUcTa -M18phLdjejg09d45QV5pEtU5m0HuydvtMNCxL2UeWMxyIVezAH2S48m7IAn7Xs4p -J9bwjboDWQYs+zLPfEZyosiJiKugpEKvApIKsJXf4JqRXHN+vvKKDeXkKrrGR+pg -3e5foPjFrLcDltZMkrfnlm8fa0yLnoxdiyd1pDcJaQKBgQDSnJbM6CDb0b3bUyiz -LpfJSBzEPqABM8mNeVHfEjHcBJ7YBOceBxDNasmAPvFbhoDrlHiEYW2QnDLRXKeF -XVdXjSsUV30SPMeg6yeSd8L+LKXLjrGMNGDcJfnjLavv7Glu1xDnYyFSmeVIhWoo -cOhfaFQ69vnHiU1idrOlz6zhPwKBgQDFNcY0S59f3tht7kgnItg8PSfJqJQrIdLt -x6MC2Nc7Eui7/LTuO2rMG6HRA/8zQa/TfnfG7CsUwLB1NiC2R1TtM9YBYPxhMl1o -JeGTfM+tD0lBwPhYpgnOCppuayRCfAsPYA6NcvXcGZbxOigxliOuvgVBH47EAApA -zJ+8b6nKHQKBgQCZ0GDV/4XX5KNq5Z3o1tNl3jOcIzyKBD9kAkGHz+r4C6vSiioc -pP5hd2b4MX/l3yKSapll3R2+qkT24Fs8LEJYn7Hhpk+inR8SaAs7jhmrtgHT2z/R -7IL85QNOJhHXJGqP16PxyVUR1XE9eKpiJKug2joB4lPjpWQN0DE9nKFe0wKBgEo3 -qpgTva7+1sTIYC8aVfaVrVufLePtnswNzbNMl/OLcjsNJ6pgghi+bW+T6X8IwXr+ -pWUfjDcLLV1vOXBf9/4s++UY8uJBahW/69zto9qlXhR44v25vwbjxqq3d7XtqNvo -cpGZKh3jI4M1N9sxfcxNhvyzO69XtIQefh8UhvmhAoGBAKzSA51l50ocOnWSNAXs -QQoU+dYQjLDMtzc5N68EUf1GSjtgkpa3PYjVo09OMeb7+W9LhwHQDNMqgeeEDCsm -B6NDnI4VyjVae7Hqz48WBERJBFMFWiLxEa1m2UwaV2jAubN8FKgH4KzDzOKtJEUy -Rz9IUct6HXsDSs+Q3/zdFmPo ------END PRIVATE KEY-----` - gatewayTestCertificateTwo = `-----BEGIN CERTIFICATE----- -MIIC7DCCAdSgAwIBAgIJAMHpuSA3ioNPMA0GCSqGSIb3DQEBCwUAMCYxCzAJBgNV -BAYTAlhYMRcwFQYDVQQDDA5zZWNvbmRjZXJ0LmNvbTAeFw0yMzA3MTExNTE1MjBa -Fw0zMzA3MDgxNTE1MjBaMCYxCzAJBgNVBAYTAlhYMRcwFQYDVQQDDA5zZWNvbmRj -ZXJ0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKI+vYcJtXNt -nUwhbz2t8sutyI9NZaXjwMX0KZgdLQLaBIPVbpvHM7vN0D5x53RqMj5ixD1oEBdG -EqUQeCeEEnqwazPVcFD36U0MeuD0CO6AiIeixxg54JzEx5eGn3u2L6+lWxzb8C8R -/YoYhS46Ny59e5FeRZDZoHhEbKh2SBEXqfxisslvulYiOgI3AMBa1lfjAhUWAarV -7DQT8T0TJK0xhNvmHWW8KldhE30B5IUpRAj/LTGxPf6dn+DLPHcKuDO5JhGCm1u5 -XCbkXZDXqwtH8S0IEiEDyekpqDH/hTso6KUXfUjaWhwfgCrmX1Ul3/qlMDkXgoIB -b8TJtfPoOiMCAwEAAaMdMBswGQYDVR0RBBIwEIIOc2Vjb25kY2VydC5jb20wDQYJ -KoZIhvcNAQELBQADggEBAJvP3deuEpJZktAny6/az09GLSUYddiNCE4sG/2ASj7C -mwRTh2HM4BDnkhW9PNjfHoaWa2TDIhOyHQ5hLYz2tnaeU1sOrADCuFSxGiQqgr8J -prahKh6AzNsXba4rumoO08QTTtJzoa8L6TV4PTQ6gi+OMdbyBe3CQ7DSRzLseHNH -KG5tqRRu+Jm7dUuOXDV4MDHoloyZlksOvIYSC+gaS+ke3XlR+GzOW7hpgn5SIDlv -aR/zlIKXUCvVux3/pNFgW6rduFE0f5Hbc1+J4ghTl8EQu1dwDTax7blXQwE+VDgJ -u4fZGRmoUvvO/bjVCbehBxfJn0rHsxpuD5b4Jg2OZNc= -----END CERTIFICATE-----` ) @@ -455,80 +391,7 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { }, }, { - name: "api-gateway-with-multiple-inline-certificates", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, func(entry *structs.APIGatewayConfigEntry, bound *structs.BoundAPIGatewayConfigEntry) { - entry.Listeners = []structs.APIGatewayListener{ - { - Name: "listener", - Protocol: structs.ListenerProtocolTCP, - Port: 8080, - TLS: structs.APIGatewayTLSConfiguration{ - Certificates: []structs.ResourceReference{{ - Kind: structs.InlineCertificate, - Name: "certificate", - }}, - MinVersion: types.TLSv1_2, - MaxVersion: types.TLSv1_3, - CipherSuites: []types.TLSCipherSuite{ - types.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - types.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - }, - }, - }, - } - bound.Listeners = []structs.BoundAPIGatewayListener{ - { - Name: "listener", - Certificates: []structs.ResourceReference{ - { - Kind: structs.InlineCertificate, - Name: "certificate", - }, - { - Kind: structs.InlineCertificate, - Name: "certificate-too", - }, - }, - Routes: []structs.ResourceReference{{ - Kind: structs.TCPRoute, - Name: "route", - }}, - }, - } - }, - []structs.BoundRoute{ - &structs.TCPRouteConfigEntry{ - Kind: structs.TCPRoute, - Name: "route", - Services: []structs.TCPService{{ - Name: "service", - }}, - Parents: []structs.ResourceReference{ - { - Kind: structs.APIGateway, - Name: "api-gateway", - }, - }, - }, - }, []structs.InlineCertificateConfigEntry{ - { - Kind: structs.InlineCertificate, - Name: "certificate", - PrivateKey: gatewayTestPrivateKey, - Certificate: gatewayTestCertificate, - }, - { - Kind: structs.InlineCertificate, - Name: "certificate-too", - PrivateKey: gatewayTestPrivateKeyTwo, - Certificate: gatewayTestCertificateTwo, - }, - }, nil) - }, - }, - { - name: "api-gateway-with-http-route", + name: "api-gateway-with-http-route-and-inline-certificate", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, func(entry *structs.APIGatewayConfigEntry, bound *structs.BoundAPIGatewayConfigEntry) { entry.Listeners = []structs.APIGatewayListener{ @@ -541,10 +404,6 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { bound.Listeners = []structs.BoundAPIGatewayListener{ { Name: "listener", - Certificates: []structs.ResourceReference{{ - Kind: structs.InlineCertificate, - Name: "certificate", - }}, Routes: []structs.ResourceReference{{ Kind: structs.HTTPRoute, Name: "route", @@ -568,90 +427,6 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { Remove: []string{"X-Header-Remove"}, }, }, - RetryFilter: &structs.RetryFilter{ - NumRetries: 3, - RetryOn: []string{"cancelled"}, - RetryOnStatusCodes: []uint32{500}, - RetryOnConnectFailure: true, - }, - TimeoutFilter: &structs.TimeoutFilter{ - IdleTimeout: time.Second * 30, - RequestTimeout: time.Second * 30, - }, - }, - Services: []structs.HTTPService{{ - Name: "service", - }}, - }}, - Parents: []structs.ResourceReference{ - { - Kind: structs.APIGateway, - Name: "api-gateway", - }, - }, - }, - }, []structs.InlineCertificateConfigEntry{{ - Kind: structs.InlineCertificate, - Name: "certificate", - PrivateKey: gatewayTestPrivateKey, - Certificate: gatewayTestCertificate, - }}, []proxycfg.UpdateEvent{{ - CorrelationID: "discovery-chain:" + serviceUID.String(), - Result: &structs.DiscoveryChainResponse{ - Chain: serviceChain, - }, - }, { - CorrelationID: "upstream-target:" + serviceChain.ID() + ":" + serviceUID.String(), - Result: &structs.IndexedCheckServiceNodes{ - Nodes: proxycfg.TestUpstreamNodes(t, "service"), - }, - }}) - }, - }, - { - name: "api-gateway-with-http-route-timeoutfilter-one-set", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotAPIGateway(t, "default", nil, func(entry *structs.APIGatewayConfigEntry, bound *structs.BoundAPIGatewayConfigEntry) { - entry.Listeners = []structs.APIGatewayListener{ - { - Name: "listener", - Protocol: structs.ListenerProtocolHTTP, - Port: 8080, - }, - } - bound.Listeners = []structs.BoundAPIGatewayListener{ - { - Name: "listener", - Certificates: []structs.ResourceReference{{ - Kind: structs.InlineCertificate, - Name: "certificate", - }}, - Routes: []structs.ResourceReference{{ - Kind: structs.HTTPRoute, - Name: "route", - }}, - }, - } - }, []structs.BoundRoute{ - &structs.HTTPRouteConfigEntry{ - Kind: structs.HTTPRoute, - Name: "route", - Rules: []structs.HTTPRouteRule{{ - Filters: structs.HTTPFilters{ - Headers: []structs.HTTPHeaderFilter{ - { - Add: map[string]string{ - "X-Header-Add": "added", - }, - Set: map[string]string{ - "X-Header-Set": "set", - }, - Remove: []string{"X-Header-Remove"}, - }, - }, - TimeoutFilter: &structs.TimeoutFilter{ - IdleTimeout: time.Second * 30, - }, }, Services: []structs.HTTPService{{ Name: "service", @@ -664,12 +439,7 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { }, }, }, - }, []structs.InlineCertificateConfigEntry{{ - Kind: structs.InlineCertificate, - Name: "certificate", - PrivateKey: gatewayTestPrivateKey, - Certificate: gatewayTestCertificate, - }}, []proxycfg.UpdateEvent{{ + }, nil, []proxycfg.UpdateEvent{{ CorrelationID: "discovery-chain:" + serviceUID.String(), Result: &structs.DiscoveryChainResponse{ Chain: serviceChain, diff --git a/agent/xds/response/response.go b/agent/xds/response.go similarity index 80% rename from agent/xds/response/response.go rename to agent/xds/response.go index 91ce6d7397386..e452e8a2f26e4 100644 --- a/agent/xds/response/response.go +++ b/agent/xds/response.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 -package response +package xds import ( envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" @@ -13,7 +13,7 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) -func CreateResponse(typeURL string, version, nonce string, resources []proto.Message) (*envoy_discovery_v3.DiscoveryResponse, error) { +func createResponse(typeURL string, version, nonce string, resources []proto.Message) (*envoy_discovery_v3.DiscoveryResponse, error) { anys := make([]*anypb.Any, 0, len(resources)) for _, r := range resources { if r == nil { @@ -41,7 +41,7 @@ func CreateResponse(typeURL string, version, nonce string, resources []proto.Mes return resp, nil } -func MakePipeAddress(path string, mode uint32) *envoy_core_v3.Address { +func makePipeAddress(path string, mode uint32) *envoy_core_v3.Address { return &envoy_core_v3.Address{ Address: &envoy_core_v3.Address_Pipe{ Pipe: &envoy_core_v3.Pipe{ @@ -52,7 +52,7 @@ func MakePipeAddress(path string, mode uint32) *envoy_core_v3.Address { } } -func MakeAddress(ip string, port int) *envoy_core_v3.Address { +func makeAddress(ip string, port int) *envoy_core_v3.Address { return &envoy_core_v3.Address{ Address: &envoy_core_v3.Address_SocketAddress{ SocketAddress: &envoy_core_v3.SocketAddress{ @@ -65,15 +65,15 @@ func MakeAddress(ip string, port int) *envoy_core_v3.Address { } } -func MakeUint32Value(n int) *wrapperspb.UInt32Value { +func makeUint32Value(n int) *wrapperspb.UInt32Value { return &wrapperspb.UInt32Value{Value: uint32(n)} } -func MakeBoolValue(n bool) *wrapperspb.BoolValue { +func makeBoolValue(n bool) *wrapperspb.BoolValue { return &wrapperspb.BoolValue{Value: n} } -func MakeEnvoyRegexMatch(patt string) *envoy_matcher_v3.RegexMatcher { +func makeEnvoyRegexMatch(patt string) *envoy_matcher_v3.RegexMatcher { return &envoy_matcher_v3.RegexMatcher{ EngineType: &envoy_matcher_v3.RegexMatcher_GoogleRe2{ GoogleRe2: &envoy_matcher_v3.RegexMatcher_GoogleRE2{}, diff --git a/agent/xds/routes.go b/agent/xds/routes.go index 99d72735b35d6..4484f6a6a0986 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -16,17 +16,13 @@ import ( envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" "golang.org/x/exp/maps" "golang.org/x/exp/slices" - "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/discoverychain" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/config" - "github.com/hashicorp/consul/agent/xds/response" ) // routesFromSnapshot returns the xDS API representation of the "routes" in the @@ -61,13 +57,17 @@ func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapsh continue } - virtualHost, err := s.makeUpstreamRouteForDiscoveryChain(cfgSnap, uid, chain, []string{"*"}, false, perRouteFilterBuilder{}) + explicit := cfgSnap.ConnectProxy.UpstreamConfig[uid].HasLocalPortOrSocket() + implicit := cfgSnap.ConnectProxy.IsImplicitUpstream(uid) + if !implicit && !explicit { + // Discovery chain is not associated with a known explicit or implicit upstream so it is skipped. + continue + } + + virtualHost, err := s.makeUpstreamRouteForDiscoveryChain(cfgSnap, uid, chain, []string{"*"}, false) if err != nil { return nil, err } - if virtualHost == nil { - continue - } route := &envoy_route_v3.RouteConfiguration{ Name: uid.EnvoyID(), @@ -75,7 +75,7 @@ func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapsh // ValidateClusters defaults to true when defined statically and false // when done via RDS. Re-set the reasonable value of true to prevent // null-routing traffic. - ValidateClusters: response.MakeBoolValue(true), + ValidateClusters: makeBoolValue(true), } resources = append(resources, route) } @@ -97,12 +97,12 @@ func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapsh addressesMap[routeName] = make(map[string]string) } // cluster name is unique per address/port so we should not be doing any override here - clusterName := clusterNameForDestination(cfgSnap, svcConfig.Name, address, svcConfig.NamespaceOrDefault(), svcConfig.PartitionOrDefault()) addressesMap[routeName][clusterName] = address } return nil }) + if err != nil { return nil, err } @@ -122,6 +122,7 @@ func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapsh } func (s *ResourceGenerator) makeRoutesForAddresses(routeName string, addresses map[string]string) ([]proto.Message, error) { + var resources []proto.Message route, err := makeNamedAddressesRoute(routeName, addresses) @@ -144,7 +145,7 @@ func (s *ResourceGenerator) routesForTerminatingGateway(cfgSnap *proxycfg.Config var resources []proto.Message for _, svc := range cfgSnap.TerminatingGateway.ValidServices() { clusterName := connect.ServiceSNI(svc.Name, "", svc.NamespaceOrDefault(), svc.PartitionOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) - cfg, err := config.ParseProxyConfig(cfgSnap.TerminatingGateway.ServiceConfigs[svc].ProxyConfig) + cfg, err := ParseProxyConfig(cfgSnap.TerminatingGateway.ServiceConfigs[svc].ProxyConfig) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -172,7 +173,7 @@ func (s *ResourceGenerator) routesForTerminatingGateway(cfgSnap *proxycfg.Config for _, address := range svcConfig.Destination.Addresses { clusterName := clusterNameForDestination(cfgSnap, svc.Name, address, svc.NamespaceOrDefault(), svc.PartitionOrDefault()) - cfg, err := config.ParseProxyConfig(cfgSnap.TerminatingGateway.ServiceConfigs[svc].ProxyConfig) + cfg, err := ParseProxyConfig(cfgSnap.TerminatingGateway.ServiceConfigs[svc].ProxyConfig) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns // default config if there is an error so it's safe to continue. @@ -203,8 +204,7 @@ func (s *ResourceGenerator) makeRoutes( cfgSnap *proxycfg.ConfigSnapshot, svc structs.ServiceName, clusterName string, - autoHostRewrite bool, -) ([]proto.Message, error) { + autoHostRewrite bool) ([]proto.Message, error) { resolver, hasResolver := cfgSnap.TerminatingGateway.ServiceResolvers[svc] if !hasResolver { @@ -250,6 +250,10 @@ func (s *ResourceGenerator) routesForMeshGateway(cfgSnap *proxycfg.ConfigSnapsho continue // ignore; not relevant } + if cfgSnap.MeshGateway.Leaf == nil { + continue // ignore; not ready + } + uid := proxycfg.NewUpstreamIDFromServiceName(svc) virtualHost, err := s.makeUpstreamRouteForDiscoveryChain( @@ -258,14 +262,10 @@ func (s *ResourceGenerator) routesForMeshGateway(cfgSnap *proxycfg.ConfigSnapsho chain, []string{"*"}, true, - perRouteFilterBuilder{}, ) if err != nil { return nil, err } - if virtualHost == nil { - continue - } route := &envoy_route_v3.RouteConfiguration{ Name: uid.EnvoyID(), @@ -273,7 +273,7 @@ func (s *ResourceGenerator) routesForMeshGateway(cfgSnap *proxycfg.ConfigSnapsho // ValidateClusters defaults to true when defined statically and false // when done via RDS. Re-set the reasonable value of true to prevent // null-routing traffic. - ValidateClusters: response.MakeBoolValue(true), + ValidateClusters: makeBoolValue(true), } resources = append(resources, route) } @@ -291,7 +291,7 @@ func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer, t // Configure Envoy to rewrite Host header if autoHostRewrite { action.Route.HostRewriteSpecifier = &envoy_route_v3.RouteAction_AutoHostRewrite{ - AutoHostRewrite: response.MakeBoolValue(true), + AutoHostRewrite: makeBoolValue(true), } } @@ -316,7 +316,7 @@ func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer, t // ValidateClusters defaults to true when defined statically and false // when done via RDS. Re-set the reasonable value of true to prevent // null-routing traffic. - ValidateClusters: response.MakeBoolValue(true), + ValidateClusters: makeBoolValue(true), }, nil } @@ -326,7 +326,7 @@ func makeNamedAddressesRoute(routeName string, addresses map[string]string) (*en // ValidateClusters defaults to true when defined statically and false // when done via RDS. Re-set the reasonable value of true to prevent // null-routing traffic. - ValidateClusters: response.MakeBoolValue(true), + ValidateClusters: makeBoolValue(true), } for clusterName, address := range addresses { action := makeRouteActionFromName(clusterName) @@ -368,27 +368,21 @@ func (s *ResourceGenerator) routesForIngressGateway(cfgSnap *proxycfg.ConfigSnap // ValidateClusters defaults to true when defined statically and false // when done via RDS. Re-set the reasonable value of true to prevent // null-routing traffic. - ValidateClusters: response.MakeBoolValue(true), + ValidateClusters: makeBoolValue(true), } for _, u := range upstreams { uid := proxycfg.NewUpstreamID(&u) chain := cfgSnap.IngressGateway.DiscoveryChain[uid] if chain == nil { - // Note that if we continue here we must also do this in the cluster generation - s.Logger.Warn("could not find discovery chain for ingress upstream", - "listener", listenerKey, "upstream", uid) continue } domains := generateUpstreamIngressDomains(listenerKey, u) - virtualHost, err := s.makeUpstreamRouteForDiscoveryChain(cfgSnap, uid, chain, domains, false, perRouteFilterBuilder{}) + virtualHost, err := s.makeUpstreamRouteForDiscoveryChain(cfgSnap, uid, chain, domains, false) if err != nil { return nil, err } - if virtualHost == nil { - continue - } // Lookup listener and service config details from ingress gateway // definition. @@ -417,7 +411,7 @@ func (s *ResourceGenerator) routesForIngressGateway(cfgSnap *proxycfg.ConfigSnap } else { svcRoute := &envoy_route_v3.RouteConfiguration{ Name: svcRouteName, - ValidateClusters: response.MakeBoolValue(true), + ValidateClusters: makeBoolValue(true), VirtualHosts: []*envoy_route_v3.VirtualHost{virtualHost}, } result = append(result, svcRoute) @@ -440,11 +434,13 @@ func (s *ResourceGenerator) routesForAPIGateway(cfgSnap *proxycfg.ConfigSnapshot readyListeners := getReadyListeners(cfgSnap) listenerNames := maps.Keys(readyListeners) sort.Strings(listenerNames) + for _, listenerName := range listenerNames { readyListener, ok := readyListeners[listenerName] if !ok { continue } + // Do not create any route configuration for TCP listeners if readyListener.listenerCfg.Protocol != structs.ListenerProtocolHTTP { continue @@ -455,7 +451,7 @@ func (s *ResourceGenerator) routesForAPIGateway(cfgSnap *proxycfg.ConfigSnapshot // ValidateClusters defaults to true when defined statically and false // when done via RDS. Re-set the reasonable value of true to prevent // null-routing traffic. - ValidateClusters: response.MakeBoolValue(true), + ValidateClusters: makeBoolValue(true), } // Consolidate all routes for this listener into the minimum possible set based on hostname matching. @@ -473,7 +469,6 @@ func (s *ResourceGenerator) routesForAPIGateway(cfgSnap *proxycfg.ConfigSnapshot // Gateway + HTTPRoutes, then the virtual host will be "*". for _, consolidatedRoute := range consolidatedRoutes { upstream := buildHTTPRouteUpstream(consolidatedRoute, readyListener.listenerCfg) - // Consolidate all routes for this listener into the minimum possible set based on hostname matching. uid := proxycfg.NewUpstreamID(&upstream) chain := cfgSnap.APIGateway.DiscoveryChain[uid] if chain == nil { @@ -482,9 +477,7 @@ func (s *ResourceGenerator) routesForAPIGateway(cfgSnap *proxycfg.ConfigSnapshot } domains := generateUpstreamAPIsDomains(readyListener.listenerKey, upstream, consolidatedRoute.Hostnames) - - filterBuilder := perRouteFilterBuilder{providerMap: cfgSnap.JWTProviders, listener: &readyListener.listenerCfg, route: &consolidatedRoute} - virtualHost, err := s.makeUpstreamRouteForDiscoveryChain(cfgSnap, uid, chain, domains, false, filterBuilder) + virtualHost, err := s.makeUpstreamRouteForDiscoveryChain(cfgSnap, uid, chain, domains, false) if err != nil { return nil, err } @@ -494,12 +487,7 @@ func (s *ResourceGenerator) routesForAPIGateway(cfgSnap *proxycfg.ConfigSnapshot if len(listenerRoute.VirtualHosts) > 0 { // Build up the virtual hosts in a deterministic way - slices.SortStableFunc(listenerRoute.VirtualHosts, func(a, b *envoy_route_v3.VirtualHost) int { - if a.Name < b.Name { - return -1 - } - return 1 - }) + slices.SortStableFunc(listenerRoute.VirtualHosts, func(a, b *envoy_route_v3.VirtualHost) bool { return a.Name < b.Name }) result = append(result, listenerRoute) } } @@ -528,7 +516,7 @@ func makeHeadersValueOptions(vals map[string]string, add bool) []*envoy_core_v3. Key: k, Value: v, }, - Append: response.MakeBoolValue(add), + Append: makeBoolValue(add), } opts = append(opts, o) } @@ -617,7 +605,6 @@ func (s *ResourceGenerator) makeUpstreamRouteForDiscoveryChain( chain *structs.CompiledDiscoveryChain, serviceDomains []string, forMeshGateway bool, - filterBuilder perRouteFilterBuilder, ) (*envoy_route_v3.VirtualHost, error) { routeName := uid.EnvoyID() var routes []*envoy_route_v3.Route @@ -637,7 +624,6 @@ func (s *ResourceGenerator) makeUpstreamRouteForDiscoveryChain( routes = make([]*envoy_route_v3.Route, 0, len(startNode.Routes)) for _, discoveryRoute := range startNode.Routes { - discoveryRoute := discoveryRoute routeMatch := makeRouteMatchForDiscoveryRoute(discoveryRoute) var ( @@ -702,13 +688,8 @@ func (s *ResourceGenerator) makeUpstreamRouteForDiscoveryChain( } } - filter, err := filterBuilder.buildTypedPerFilterConfig(routeMatch, routeAction) - if err != nil { - return nil, err - } route.Match = routeMatch route.Action = routeAction - route.TypedPerFilterConfig = filter routes = append(routes, route) } @@ -772,7 +753,7 @@ func (s *ResourceGenerator) makeUpstreamRouteForDiscoveryChain( func getRetryPolicyForDestination(destination *structs.ServiceRouteDestination) *envoy_route_v3.RetryPolicy { retryPolicy := &envoy_route_v3.RetryPolicy{} if destination.NumRetries > 0 { - retryPolicy.NumRetries = response.MakeUint32Value(int(destination.NumRetries)) + retryPolicy.NumRetries = makeUint32Value(int(destination.NumRetries)) } // The RetryOn magic values come from: https://www.envoyproxy.io/docs/envoy/v1.10.0/configuration/http_filters/router_filter#config-http-filters-router-x-envoy-retry-on @@ -825,7 +806,7 @@ func makeRouteMatchForDiscoveryRoute(discoveryRoute *structs.DiscoveryRoute) *en } case match.HTTP.PathRegex != "": em.PathSpecifier = &envoy_route_v3.RouteMatch_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(match.HTTP.PathRegex), + SafeRegex: makeEnvoyRegexMatch(match.HTTP.PathRegex), } default: em.PathSpecifier = &envoy_route_v3.RouteMatch_Prefix{ @@ -842,44 +823,21 @@ func makeRouteMatchForDiscoveryRoute(discoveryRoute *structs.DiscoveryRoute) *en switch { case hdr.Exact != "": - eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ - Exact: hdr.Exact, - }, - IgnoreCase: false, - }, + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_ExactMatch{ + ExactMatch: hdr.Exact, } case hdr.Regex != "": - eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(hdr.Regex), - }, - IgnoreCase: false, - }, + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_SafeRegexMatch{ + SafeRegexMatch: makeEnvoyRegexMatch(hdr.Regex), } - case hdr.Prefix != "": - eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Prefix{ - Prefix: hdr.Prefix, - }, - IgnoreCase: false, - }, + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_PrefixMatch{ + PrefixMatch: hdr.Prefix, } - case hdr.Suffix != "": - eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Suffix{ - Suffix: hdr.Suffix, - }, - IgnoreCase: false, - }, + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_SuffixMatch{ + SuffixMatch: hdr.Suffix, } - case hdr.Present: eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_PresentMatch{ PresentMatch: true, @@ -902,7 +860,7 @@ func makeRouteMatchForDiscoveryRoute(discoveryRoute *structs.DiscoveryRoute) *en eh := &envoy_route_v3.HeaderMatcher{ Name: ":method", HeaderMatchSpecifier: &envoy_route_v3.HeaderMatcher_SafeRegexMatch{ - SafeRegexMatch: response.MakeEnvoyRegexMatch(methodHeaderRegex), + SafeRegexMatch: makeEnvoyRegexMatch(methodHeaderRegex), }, } @@ -929,7 +887,7 @@ func makeRouteMatchForDiscoveryRoute(discoveryRoute *structs.DiscoveryRoute) *en eq.QueryParameterMatchSpecifier = &envoy_route_v3.QueryParameterMatcher_StringMatch{ StringMatch: &envoy_matcher_v3.StringMatcher{ MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(qm.Regex), + SafeRegex: makeEnvoyRegexMatch(qm.Regex), }, }, } @@ -967,7 +925,7 @@ func (s *ResourceGenerator) makeRouteActionForChainCluster( chain *structs.CompiledDiscoveryChain, forMeshGateway bool, ) (*envoy_route_v3.Route_Route, bool) { - clusterName := s.getTargetClusterName(upstreamsSnapshot, chain, targetID, forMeshGateway) + clusterName := s.getTargetClusterName(upstreamsSnapshot, chain, targetID, forMeshGateway, false) if clusterName == "" { return nil, false } @@ -1000,7 +958,7 @@ func (s *ResourceGenerator) makeRouteActionForSplitter( } targetID := nextNode.Resolver.Target - clusterName := s.getTargetClusterName(upstreamsSnapshot, chain, targetID, forMeshGateway) + clusterName := s.getTargetClusterName(upstreamsSnapshot, chain, targetID, forMeshGateway, false) if clusterName == "" { continue } @@ -1010,7 +968,7 @@ func (s *ResourceGenerator) makeRouteActionForSplitter( weight := int(split.Weight * 100) totalWeight += weight cw := &envoy_route_v3.WeightedCluster_ClusterWeight{ - Weight: response.MakeUint32Value(weight), + Weight: makeUint32Value(weight), Name: clusterName, } if err := injectHeaderManipToWeightedCluster(split.Definition, cw); err != nil { @@ -1024,18 +982,19 @@ func (s *ResourceGenerator) makeRouteActionForSplitter( return nil, fmt.Errorf("number of clusters in splitter must be > 0; got %d", len(clusters)) } - var envoyWeightScale *wrapperspb.UInt32Value - if totalWeight == 10000 { - envoyWeightScale = response.MakeUint32Value(10000) + envoyWeightScale := 10000 + if envoyWeightScale < totalWeight { + clusters[0].Weight.Value += uint32(totalWeight - envoyWeightScale) + } else { + clusters[0].Weight.Value += uint32(envoyWeightScale - totalWeight) } return &envoy_route_v3.Route_Route{ Route: &envoy_route_v3.RouteAction{ ClusterSpecifier: &envoy_route_v3.RouteAction_WeightedClusters{ WeightedClusters: &envoy_route_v3.WeightedCluster{ - Clusters: clusters, - // this field is deprecated, and we should get the desired behavior with the front-end validation - TotalWeight: envoyWeightScale, // scaled up 100% + Clusters: clusters, + TotalWeight: makeUint32Value(envoyWeightScale), // scaled up 100% }, }, }, diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index eda10f2234667..72082ba1c02ca 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -10,16 +10,14 @@ import ( "time" envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + testinf "github.com/mitchellh/go-testing-interface" "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/durationpb" "github.com/hashicorp/consul/agent/proxycfg" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/proxystateconverter" - "github.com/hashicorp/consul/agent/xds/response" "github.com/hashicorp/consul/agent/xds/testcommon" - "github.com/hashicorp/consul/agent/xdsv2" "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/sdk/testutil" ) @@ -28,7 +26,6 @@ type routeTestCase struct { name string create func(t testinf.T) *proxycfg.ConfigSnapshot overrideGoldenName string - alsoRunTestForV2 bool } func makeRouteDiscoChainTests(enterprise bool) []routeTestCase { @@ -38,77 +35,48 @@ func makeRouteDiscoChainTests(enterprise bool) []routeTestCase { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-external-sni", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) }, - alsoRunTestForV2: true, - }, - { - name: "connect-proxy-splitter-overweight", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "splitter-overweight", enterprise, nil, nil) - }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-overrides", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple-with-overrides", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "splitter-with-resolver-redirect", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "splitter-with-resolver-redirect-multidc", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-splitter", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "chain-and-splitter", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-grpc-router", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "grpc-router", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-chain-and-router", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "chain-and-router", enterprise, nil, nil) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-lb-in-resolver", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "lb-resolver", enterprise, nil, nil) }, - alsoRunTestForV2: true, - }, - { - name: "connect-proxy-route-to-lb-resolver", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "redirect-to-lb-node", enterprise, nil, nil) - }, - alsoRunTestForV2: true, - }, - { - name: "connect-proxy-resolver-with-lb", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "resolver-with-lb", enterprise, nil, nil) - }, - alsoRunTestForV2: true, }, } } @@ -129,8 +97,6 @@ func TestRoutesFromSnapshot(t *testing.T) { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotIngressGateway_NilConfigEntry(t) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-defaults-no-chain", @@ -138,8 +104,6 @@ func TestRoutesFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, false, "tcp", "default", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain", @@ -147,8 +111,6 @@ func TestRoutesFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "simple", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-external-sni", @@ -156,8 +118,6 @@ func TestRoutesFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "tcp", "external-sni", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-splitter-with-resolver-redirect", @@ -165,8 +125,6 @@ func TestRoutesFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "http", "splitter-with-resolver-redirect-multidc", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-and-splitter", @@ -174,8 +132,6 @@ func TestRoutesFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "http", "chain-and-splitter", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-grpc-router", @@ -183,8 +139,6 @@ func TestRoutesFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "http", "grpc-router", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-and-router", @@ -192,8 +146,6 @@ func TestRoutesFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "http", "chain-and-router", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-lb-in-resolver", @@ -201,66 +153,48 @@ func TestRoutesFromSnapshot(t *testing.T) { return proxycfg.TestConfigSnapshotIngressGateway(t, true, "http", "lb-resolver", nil, nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-http-multiple-services", create: proxycfg.TestConfigSnapshotIngress_HTTPMultipleServices, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-grpc-multiple-services", create: proxycfg.TestConfigSnapshotIngress_GRPCMultipleServices, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-chain-and-router-header-manip", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotIngressGatewayWithChain(t, "router-header-manip", nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-sds-listener-level", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotIngressGatewayWithChain(t, "sds-listener-level", nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-sds-listener-level-wildcard", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotIngressGatewayWithChain(t, "sds-listener-level-wildcard", nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-sds-service-level", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotIngressGatewayWithChain(t, "sds-service-level", nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "ingress-with-sds-service-level-mixed-tls", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotIngressGatewayWithChain(t, "sds-service-level-mixed-tls", nil, nil) }, - // TODO(proxystate): ingress gateway will come at a later time - alsoRunTestForV2: false, }, { name: "terminating-gateway-lb-config", create: proxycfg.TestConfigSnapshotTerminatingGatewayLBConfig, - // TODO(proxystate): terminating gateway will come at a later time - alsoRunTestForV2: false, }, { name: "api-gateway-with-multiple-hostnames", @@ -349,10 +283,10 @@ func TestRoutesFromSnapshot(t *testing.T) { sort.Slice(routes, func(i, j int) bool { return routes[i].(*envoy_route_v3.RouteConfiguration).Name < routes[j].(*envoy_route_v3.RouteConfiguration).Name }) - r, err := response.CreateResponse(xdscommon.RouteType, "00000001", "00000001", routes) + r, err := createResponse(xdscommon.RouteType, "00000001", "00000001", routes) require.NoError(t, err) - t.Run("current-xdsv1", func(t *testing.T) { + t.Run("current", func(t *testing.T) { gotJSON := protoToJSON(t, r) gName := tt.name @@ -362,39 +296,6 @@ func TestRoutesFromSnapshot(t *testing.T) { require.JSONEq(t, goldenEnvoy(t, filepath.Join("routes", gName), envoyVersion, latestEnvoyVersion, gotJSON), gotJSON) }) - - if tt.alsoRunTestForV2 { - generator := xdsv2.NewResourceGenerator(testutil.Logger(t)) - - converter := proxystateconverter.NewConverter(testutil.Logger(t), &mockCfgFetcher{addressLan: "10.10.10.10"}) - proxyState, err := converter.ProxyStateFromSnapshot(snap) - require.NoError(t, err) - - res, err := generator.AllResourcesFromIR(proxyState) - require.NoError(t, err) - - routes = res[xdscommon.RouteType] - // The order of routes returned via RDS isn't relevant, so it's safe - // to sort these for the purposes of test comparisons. - sort.Slice(routes, func(i, j int) bool { - return routes[i].(*envoy_route_v3.Route).Name < routes[j].(*envoy_route_v3.Route).Name - }) - - r, err := response.CreateResponse(xdscommon.RouteType, "00000001", "00000001", routes) - require.NoError(t, err) - - t.Run("current-xdsv2", func(t *testing.T) { - gotJSON := protoToJSON(t, r) - - gName := tt.name - if tt.overrideGoldenName != "" { - gName = tt.overrideGoldenName - } - - expectedJSON := goldenEnvoy(t, filepath.Join("routes", gName), envoyVersion, latestEnvoyVersion, gotJSON) - require.JSONEq(t, expectedJSON, gotJSON) - }) - } }) } }) @@ -601,11 +502,6 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { FieldValue: "special-header", Terminal: true, }, - { - Field: structs.HashPolicyQueryParam, - FieldValue: "my-pretty-param", - Terminal: true, - }, }, }, expected: &envoy_route_v3.RouteAction{ @@ -644,14 +540,6 @@ func TestEnvoyLBConfig_InjectToRouteAction(t *testing.T) { }, Terminal: true, }, - { - PolicySpecifier: &envoy_route_v3.RouteAction_HashPolicy_QueryParameter_{ - QueryParameter: &envoy_route_v3.RouteAction_HashPolicy_QueryParameter{ - Name: "my-pretty-param", - }, - }, - Terminal: true, - }, }, }, }, diff --git a/agent/xds/secrets.go b/agent/xds/secrets.go index 628cec7905ba1..d150a12dc1611 100644 --- a/agent/xds/secrets.go +++ b/agent/xds/secrets.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds diff --git a/agent/xds/server.go b/agent/xds/server.go index 45c11fa0b3a17..2e012a4cb6fd5 100644 --- a/agent/xds/server.go +++ b/agent/xds/server.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -9,9 +9,12 @@ import ( "sync/atomic" "time" + envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" + + "github.com/hashicorp/consul/envoyextensions/xdscommon" + "github.com/armon/go-metrics" "github.com/armon/go-metrics/prometheus" - envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" "github.com/hashicorp/go-hclog" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -20,10 +23,8 @@ import ( "github.com/hashicorp/consul/acl" external "github.com/hashicorp/consul/agent/grpc-external" "github.com/hashicorp/consul/agent/grpc-external/limiter" - "github.com/hashicorp/consul/agent/xds/configfetcher" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/consul/agent/proxycfg" + "github.com/hashicorp/consul/agent/structs" ) var ( @@ -69,6 +70,13 @@ const ( // services named "local_agent" in the future. LocalAgentClusterName = "local_agent" + // OriginalDestinationClusterName is the name we give to the passthrough + // cluster which redirects transparently-proxied requests to their original + // destination outside the mesh. This cluster prevents Consul from blocking + // connections to destinations outside of the catalog when in transparent + // proxy mode. + OriginalDestinationClusterName = "original-destination" + // DefaultAuthCheckFrequency is the default value for // Server.AuthCheckFrequency to use when the zero value is provided. DefaultAuthCheckFrequency = 5 * time.Minute @@ -80,10 +88,16 @@ const ( // coupling this to the agent. type ACLResolverFunc func(id string) (acl.Authorizer, error) +// ConfigFetcher is the interface the agent needs to expose +// for the xDS server to fetch agent config, currently only one field is fetched +type ConfigFetcher interface { + AdvertiseAddrLAN() string +} + // ProxyConfigSource is the interface xds.Server requires to consume proxy // config updates. -type ProxyWatcher interface { - Watch(proxyID *pbresource.ID, nodeName string, token string) (<-chan proxysnapshot.ProxySnapshot, limiter.SessionTerminatedChan, proxysnapshot.CancelFunc, error) +type ProxyConfigSource interface { + Watch(id structs.ServiceID, nodeName string, token string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.CancelFunc, error) } // Server represents a gRPC server that can handle xDS requests from Envoy. All @@ -94,9 +108,9 @@ type ProxyWatcher interface { type Server struct { NodeName string Logger hclog.Logger - ProxyWatcher ProxyWatcher + CfgSrc ProxyConfigSource ResolveToken ACLResolverFunc - CfgFetcher configfetcher.ConfigFetcher + CfgFetcher ConfigFetcher // AuthCheckFrequency is how often we should re-check the credentials used // during a long-lived gRPC Stream after it has been initially established. @@ -145,14 +159,14 @@ func (c *activeStreamCounters) Increment(ctx context.Context) func() { func NewServer( nodeName string, logger hclog.Logger, - proxyWatcher ProxyWatcher, + cfgMgr ProxyConfigSource, resolveTokenSecret ACLResolverFunc, - cfgFetcher configfetcher.ConfigFetcher, + cfgFetcher ConfigFetcher, ) *Server { return &Server{ NodeName: nodeName, Logger: logger, - ProxyWatcher: proxyWatcher, + CfgSrc: cfgMgr, ResolveToken: resolveTokenSecret, CfgFetcher: cfgFetcher, AuthCheckFrequency: DefaultAuthCheckFrequency, @@ -200,9 +214,9 @@ func (s *Server) authenticate(ctx context.Context) (acl.Authorizer, error) { // using a token with the same permissions, and that it stores the data by // proxy ID. We assume that any data in the snapshot was already filtered, // which allows this authorization to be a shallow authorization check -// for all the data in a ProxySnapshot. -func (s *Server) authorize(ctx context.Context, proxySnapshot proxysnapshot.ProxySnapshot) error { - if proxySnapshot == nil { +// for all the data in a ConfigSnapshot. +func (s *Server) authorize(ctx context.Context, cfgSnap *proxycfg.ConfigSnapshot) error { + if cfgSnap == nil { return status.Errorf(codes.Unauthenticated, "unauthenticated: no config snapshot") } @@ -211,5 +225,22 @@ func (s *Server) authorize(ctx context.Context, proxySnapshot proxysnapshot.Prox return err } - return proxySnapshot.Authorize(authz) + var authzContext acl.AuthorizerContext + switch cfgSnap.Kind { + case structs.ServiceKindConnectProxy: + cfgSnap.ProxyID.EnterpriseMeta.FillAuthzContext(&authzContext) + if err := authz.ToAllowAuthorizer().ServiceWriteAllowed(cfgSnap.Proxy.DestinationServiceName, &authzContext); err != nil { + return status.Errorf(codes.PermissionDenied, err.Error()) + } + case structs.ServiceKindMeshGateway, structs.ServiceKindTerminatingGateway, structs.ServiceKindIngressGateway, structs.ServiceKindAPIGateway: + cfgSnap.ProxyID.EnterpriseMeta.FillAuthzContext(&authzContext) + if err := authz.ToAllowAuthorizer().ServiceWriteAllowed(cfgSnap.Service, &authzContext); err != nil { + return status.Errorf(codes.PermissionDenied, err.Error()) + } + default: + return status.Errorf(codes.Internal, "Invalid service kind") + } + + // Authed OK! + return nil } diff --git a/agent/xds/server_ce.go b/agent/xds/server_ce.go index cce9b75d6ebc6..c1d651c0ad59a 100644 --- a/agent/xds/server_ce.go +++ b/agent/xds/server_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package xds diff --git a/agent/xds/testcommon/testcommon.go b/agent/xds/testcommon/testcommon.go index 44d2cc3bbe6da..1b0d6ebcbf507 100644 --- a/agent/xds/testcommon/testcommon.go +++ b/agent/xds/testcommon/testcommon.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package testcommon diff --git a/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-local-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-local-grpc-service.latest.golden index f790cfd0dfd40..1955aa84d62d3 100644 --- a/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-local-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-local-grpc-service.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,23 +137,23 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "loadAssignment": { - "clusterName": "local_ext_authz", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_ext_authz", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_ext_authz", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9191 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 } } } @@ -142,18 +162,16 @@ } ] }, - "name": "local_ext_authz", - "type": "STATIC", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} } } } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-local-http-service.latest.golden b/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-local-http-service.latest.golden index 75698e93949ec..992da1ae684be 100644 --- a/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-local-http-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-local-http-service.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,23 +137,23 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "loadAssignment": { - "clusterName": "local_ext_authz", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_ext_authz", + "type": "STRICT_DNS", + "loadAssignment": { + "clusterName": "local_ext_authz", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "localhost", - "portValue": 9191 + "endpoint": { + "address": { + "socketAddress": { + "address": "localhost", + "portValue": 9191 } } } @@ -141,11 +161,9 @@ ] } ] - }, - "name": "local_ext_authz", - "type": "STRICT_DNS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-upstream-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-upstream-grpc-service.latest.golden index 5a25e882ab312..cf55c30e6de55 100644 --- a/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-upstream-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-upstream-grpc-service.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-upstream-http-service.latest.golden b/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-upstream-http-service.latest.golden index 5a25e882ab312..cf55c30e6de55 100644 --- a/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-upstream-http-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/ext-authz-http-upstream-http-service.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/clusters/ext-authz-tcp-local-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/clusters/ext-authz-tcp-local-grpc-service.latest.golden index f790cfd0dfd40..1955aa84d62d3 100644 --- a/agent/xds/testdata/builtin_extension/clusters/ext-authz-tcp-local-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/ext-authz-tcp-local-grpc-service.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,23 +137,23 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "loadAssignment": { - "clusterName": "local_ext_authz", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_ext_authz", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_ext_authz", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9191 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 } } } @@ -142,18 +162,16 @@ } ] }, - "name": "local_ext_authz", - "type": "STATIC", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} } } } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/clusters/ext-authz-tcp-upstream-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/clusters/ext-authz-tcp-upstream-grpc-service.latest.golden index 5a25e882ab312..cf55c30e6de55 100644 --- a/agent/xds/testdata/builtin_extension/clusters/ext-authz-tcp-upstream-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/ext-authz-tcp-upstream-grpc-service.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/clusters/lambda-and-lua-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-and-lua-connect-proxy.latest.golden index 81032f1d2d3da..fe0b5358e7b73 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lambda-and-lua-connect-proxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lambda-and-lua-connect-proxy.latest.golden @@ -1,21 +1,22 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "loadAssignment": { - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "lambda.us-east-1.amazonaws.com", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "lambda.us-east-1.amazonaws.com", + "portValue": 443 } } } @@ -24,84 +25,85 @@ } ] }, - "metadata": { - "filterMetadata": { - "com.amazonaws.lambda": { - "egress_gateway": true - } + "dnsLookupFamily": "V4_ONLY", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "sni": "*.amazonaws.com" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "sni": "*.amazonaws.com" + "metadata": { + "filterMetadata": { + "com.amazonaws.lambda": { + "egress_gateway": true + } } - }, - "type": "LOGICAL_DNS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -109,11 +111,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-opposite-meta.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-opposite-meta.latest.golden index 81032f1d2d3da..fe0b5358e7b73 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-opposite-meta.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-opposite-meta.latest.golden @@ -1,21 +1,22 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "loadAssignment": { - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "lambda.us-east-1.amazonaws.com", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "lambda.us-east-1.amazonaws.com", + "portValue": 443 } } } @@ -24,84 +25,85 @@ } ] }, - "metadata": { - "filterMetadata": { - "com.amazonaws.lambda": { - "egress_gateway": true - } + "dnsLookupFamily": "V4_ONLY", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "sni": "*.amazonaws.com" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "sni": "*.amazonaws.com" + "metadata": { + "filterMetadata": { + "com.amazonaws.lambda": { + "egress_gateway": true + } } - }, - "type": "LOGICAL_DNS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -109,11 +111,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-tproxy.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-tproxy.latest.golden index bc6a584cb234f..994358b0137e1 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-tproxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-tproxy.latest.golden @@ -1,116 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "loadAssignment": { - "clusterName": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "lambda.us-east-1.amazonaws.com", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "lambda.us-east-1.amazonaws.com", + "portValue": 443 } } } @@ -119,37 +120,38 @@ } ] }, - "metadata": { - "filterMetadata": { - "com.amazonaws.lambda": { - "egress_gateway": true - } + "dnsLookupFamily": "V4_ONLY", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "sni": "*.amazonaws.com" } }, - "name": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "sni": "*.amazonaws.com" + "metadata": { + "filterMetadata": { + "com.amazonaws.lambda": { + "egress_gateway": true + } } - }, - "type": "LOGICAL_DNS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -157,66 +159,64 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/no-endpoints" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/no-endpoints" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "original-destination", - "type": "ORIGINAL_DST" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "original-destination", + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy.latest.golden index 81032f1d2d3da..fe0b5358e7b73 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lambda-connect-proxy.latest.golden @@ -1,21 +1,22 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "loadAssignment": { - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "lambda.us-east-1.amazonaws.com", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "lambda.us-east-1.amazonaws.com", + "portValue": 443 } } } @@ -24,84 +25,85 @@ } ] }, - "metadata": { - "filterMetadata": { - "com.amazonaws.lambda": { - "egress_gateway": true - } + "dnsLookupFamily": "V4_ONLY", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "sni": "*.amazonaws.com" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "sni": "*.amazonaws.com" + "metadata": { + "filterMetadata": { + "com.amazonaws.lambda": { + "egress_gateway": true + } } - }, - "type": "LOGICAL_DNS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -109,11 +111,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden index a3d97479df4a6..d942a95a0daf8 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway-with-service-resolvers.latest.golden @@ -1,105 +1,106 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.altdomain", - "portValue": 8081 + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "filename": "api.cert.pem" + "certificateChain": { + "filename": "api.cert.pem" }, - "privateKey": { - "filename": "api.key.pem" + "privateKey": { + "filename": "api.key.pem" } } ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" } } } } - }, - "type": "LOGICAL_DNS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "loadAssignment": { - "clusterName": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "lambda.us-east-1.amazonaws.com", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "lambda.us-east-1.amazonaws.com", + "portValue": 443 } } } @@ -108,38 +109,38 @@ } ] }, - "metadata": { - "filterMetadata": { - "com.amazonaws.lambda": { - "egress_gateway": true - } + "dnsLookupFamily": "V4_ONLY", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "sni": "*.amazonaws.com" } }, - "name": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "sni": "*.amazonaws.com" + "metadata": { + "filterMetadata": { + "com.amazonaws.lambda": { + "egress_gateway": true + } } - }, - "type": "LOGICAL_DNS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "loadAssignment": { - "clusterName": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "lambda.us-east-1.amazonaws.com", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "lambda.us-east-1.amazonaws.com", + "portValue": 443 } } } @@ -148,68 +149,68 @@ } ] }, - "metadata": { - "filterMetadata": { - "com.amazonaws.lambda": { - "egress_gateway": true - } + "dnsLookupFamily": "V4_ONLY", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "sni": "*.amazonaws.com" } }, - "name": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "sni": "*.amazonaws.com" + "metadata": { + "filterMetadata": { + "com.amazonaws.lambda": { + "egress_gateway": true + } } - }, - "type": "LOGICAL_DNS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "db.mydomain", - "portValue": 8081 + "endpoint": { + "address": { + "socketAddress": { + "address": "db.mydomain", + "portValue": 8081 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "loadAssignment": { - "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "lambda.us-east-1.amazonaws.com", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "lambda.us-east-1.amazonaws.com", + "portValue": 443 } } } @@ -218,24 +219,23 @@ } ] }, - "metadata": { - "filterMetadata": { - "com.amazonaws.lambda": { - "egress_gateway": true - } + "dnsLookupFamily": "V4_ONLY", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "sni": "*.amazonaws.com" } }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "sni": "*.amazonaws.com" + "metadata": { + "filterMetadata": { + "com.amazonaws.lambda": { + "egress_gateway": true + } } - }, - "type": "LOGICAL_DNS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway.latest.golden index 71c4629b6db64..cef591c242a08 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lambda-terminating-gateway.latest.golden @@ -1,135 +1,136 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "api.altdomain", - "portValue": 8081 + "endpoint": { + "address": { + "socketAddress": { + "address": "api.altdomain", + "portValue": 8081 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "filename": "api.cert.pem" + "certificateChain": { + "filename": "api.cert.pem" }, - "privateKey": { - "filename": "api.key.pem" + "privateKey": { + "filename": "api.key.pem" } } ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "filename": "ca.cert.pem" + "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" } } } } - }, - "type": "LOGICAL_DNS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "cache.mydomain", - "portValue": 8081 + "endpoint": { + "address": { + "socketAddress": { + "address": "cache.mydomain", + "portValue": 8081 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "db.mydomain", - "portValue": 8081 + "endpoint": { + "address": { + "socketAddress": { + "address": "db.mydomain", + "portValue": 8081 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "loadAssignment": { - "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "lambda.us-east-1.amazonaws.com", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "lambda.us-east-1.amazonaws.com", + "portValue": 443 } } } @@ -138,24 +139,23 @@ } ] }, - "metadata": { - "filterMetadata": { - "com.amazonaws.lambda": { - "egress_gateway": true - } + "dnsLookupFamily": "V4_ONLY", + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "sni": "*.amazonaws.com" } }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "sni": "*.amazonaws.com" + "metadata": { + "filterMetadata": { + "com.amazonaws.lambda": { + "egress_gateway": true + } } - }, - "type": "LOGICAL_DNS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-inbound-applies-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-inbound-applies-to-inbound.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lua-inbound-applies-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lua-inbound-applies-to-inbound.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden index 43ffe1773a932..3938673d585fd 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden @@ -1,27 +1,29 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -32,43 +34,43 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -79,43 +81,43 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -126,43 +128,43 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka2" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -173,43 +175,43 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka2" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -220,40 +222,40 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/google" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -264,8 +266,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -273,19 +277,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -305,11 +307,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-local-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-local-upstreams.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-local-upstreams.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-applies-to-local-upstreams.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-inbound.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-inbound.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/otel-access-logging-http.latest.golden b/agent/xds/testdata/builtin_extension/clusters/otel-access-logging-http.latest.golden deleted file mode 100644 index 5a25e882ab312..0000000000000 --- a/agent/xds/testdata/builtin_extension/clusters/otel-access-logging-http.latest.golden +++ /dev/null @@ -1,127 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" - }, - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - "name": "local_app", - "type": "STATIC" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-keepalive.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-keepalive.latest.golden index cb4e0cec1ef8e..e026cc77941f3 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-keepalive.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-keepalive.latest.golden @@ -1,125 +1,127 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } }, - "type": "EDS", - "upstreamConnectionOptions": { - "tcpKeepalive": { - "keepaliveProbes": 5 + "upstreamConnectionOptions": { + "tcpKeepalive": { + "keepaliveProbes": 5 } } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } }, - "type": "EDS", - "upstreamConnectionOptions": { - "tcpKeepalive": { - "keepaliveProbes": 5 + "upstreamConnectionOptions": { + "tcpKeepalive": { + "keepaliveProbes": 5 } } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -127,11 +129,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-outlier-detection-multiple.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-outlier-detection-multiple.latest.golden index eb17f11f4849b..9f4ad3c4ee403 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-outlier-detection-multiple.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-outlier-detection-multiple.latest.golden @@ -1,121 +1,123 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": { - "failurePercentageRequestVolume": 2345, - "successRateMinimumHosts": 1234 + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": { + "successRateMinimumHosts": 1234, + "failurePercentageRequestVolume": 2345 + }, + "commonLbConfig": { + "healthyPanicThreshold": {} }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": { - "failurePercentageRequestVolume": 2345, - "successRateMinimumHosts": 1234 + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": { + "successRateMinimumHosts": 1234, + "failurePercentageRequestVolume": 2345 }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -123,11 +125,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-outlier-detection.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-outlier-detection.latest.golden index 9432eb1b72e9b..c93afcc4682b4 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-outlier-detection.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-outlier-detection.latest.golden @@ -1,119 +1,121 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": { - "successRateMinimumHosts": 1234 + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": { + "successRateMinimumHosts": 1234 + }, + "commonLbConfig": { + "healthyPanicThreshold": {} }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": { - "successRateMinimumHosts": 1234 + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": { + "successRateMinimumHosts": 1234 }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -121,11 +123,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-round-robin-lb-config.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-round-robin-lb-config.latest.golden index 680271c7235e5..b63a9206fd3d9 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-round-robin-lb-config.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-add-round-robin-lb-config.latest.golden @@ -1,117 +1,119 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "roundRobinLbConfig": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "roundRobinLbConfig": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "roundRobinLbConfig": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "roundRobinLbConfig": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -119,11 +121,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-cluster-load-assignment-inbound-add.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-cluster-load-assignment-inbound-add.latest.golden index 7362f44a57753..21af00530dffc 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-cluster-load-assignment-inbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-cluster-load-assignment-inbound-add.latest.golden @@ -1,27 +1,29 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +34,40 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +78,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +89,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -120,11 +122,9 @@ "policy": { "overprovisioningFactor": 123 } - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-cluster-load-assignment-outbound-add.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-cluster-load-assignment-outbound-add.latest.golden index 5a25e882ab312..24d45fbc6c379 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-cluster-load-assignment-outbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-cluster-load-assignment-outbound-add.latest.golden @@ -1,27 +1,29 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +34,40 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +78,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +89,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-listener-inbound-add.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-listener-inbound-add.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-listener-inbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-listener-inbound-add.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-listener-outbound-add.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-listener-outbound-add.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-listener-outbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-listener-outbound-add.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden index 5a25e882ab312..c010ac87b0f43 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-patch-specific-upstream-service-failover.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-patch-specific-upstream-service-failover.latest.golden index 4b9c16277584c..9e1f64a8c0bb1 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-patch-specific-upstream-service-failover.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-patch-specific-upstream-service-failover.latest.golden @@ -1,187 +1,189 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": { - "successRateMinimumHosts": 1234 + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": { + "successRateMinimumHosts": 1234 } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": { - "successRateMinimumHosts": 1234 + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": { + "successRateMinimumHosts": 1234 + }, + "commonLbConfig": { + "healthyPanicThreshold": {} }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": { - "successRateMinimumHosts": 1234 + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": { + "successRateMinimumHosts": 1234 }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/fail" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/fail" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "fail.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "fail.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -189,11 +191,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-patch-specific-upstream-service-splitter.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-patch-specific-upstream-service-splitter.latest.golden index 0dcc1ca7521e5..2c2413ee3bd68 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-patch-specific-upstream-service-splitter.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-patch-specific-upstream-service-splitter.latest.golden @@ -1,23 +1,25 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -28,8 +30,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -37,19 +41,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -69,33 +71,33 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": { "successRateMinimumHosts": 1234 }, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -106,46 +108,46 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": { "successRateMinimumHosts": 1234 }, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -156,24 +158,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-remove-outlier-detection.latest.golden b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-remove-outlier-detection.latest.golden index fe41565d6e507..3e04345bbe61c 100644 --- a/agent/xds/testdata/builtin_extension/clusters/propertyoverride-remove-outlier-detection.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/propertyoverride-remove-outlier-detection.latest.golden @@ -1,113 +1,115 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -115,11 +117,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/wasm-http-local-file.latest.golden b/agent/xds/testdata/builtin_extension/clusters/wasm-http-local-file.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/builtin_extension/clusters/wasm-http-local-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/wasm-http-local-file.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/wasm-http-remote-file.latest.golden b/agent/xds/testdata/builtin_extension/clusters/wasm-http-remote-file.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/builtin_extension/clusters/wasm-http-remote-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/wasm-http-remote-file.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-local-file-outbound.latest.golden b/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-local-file-outbound.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-local-file-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-local-file-outbound.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-local-file.latest.golden b/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-local-file.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-local-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-local-file.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-remote-file-outbound.latest.golden b/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-remote-file-outbound.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-remote-file-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-remote-file-outbound.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-remote-file.latest.golden b/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-remote-file.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-remote-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/clusters/wasm-tcp-remote-file.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-local-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-local-grpc-service.latest.golden index b4372a3439e81..b48a1f6d924dd 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-local-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-local-grpc-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-local-http-service.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-local-http-service.latest.golden index b4372a3439e81..b48a1f6d924dd 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-local-http-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-local-http-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-upstream-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-upstream-grpc-service.latest.golden index b4372a3439e81..b48a1f6d924dd 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-upstream-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-upstream-grpc-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-upstream-http-service.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-upstream-http-service.latest.golden index b4372a3439e81..b48a1f6d924dd 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-upstream-http-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-http-upstream-http-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-tcp-local-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-tcp-local-grpc-service.latest.golden index b4372a3439e81..b48a1f6d924dd 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-tcp-local-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-tcp-local-grpc-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-tcp-upstream-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-tcp-upstream-grpc-service.latest.golden index b4372a3439e81..b48a1f6d924dd 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/ext-authz-tcp-upstream-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/ext-authz-tcp-upstream-grpc-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/endpoints/lambda-and-lua-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-and-lua-connect-proxy.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lambda-and-lua-connect-proxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lambda-and-lua-connect-proxy.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-opposite-meta.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-opposite-meta.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-opposite-meta.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-opposite-meta.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-tproxy.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-tproxy.latest.golden index ebf0eb91d97e9..bbd1f5f720353 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-tproxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-tproxy.latest.golden @@ -1,104 +1,104 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "9.9.9.9", - "portValue": 9090 + "endpoint": { + "address": { + "socketAddress": { + "address": "9.9.9.9", + "portValue": 9090 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ {} ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lambda-connect-proxy.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden index afe73871daa9d..d3c3e7ddb7477 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway-with-service-resolvers.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway.latest.golden index 0b67b10323e3f..54ff27d6529ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lambda-terminating-gateway.latest.golden @@ -1,41 +1,41 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-applies-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-applies-to-inbound.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-applies-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-applies-to-inbound.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden index a0896e11577bb..284d7722a6d0e 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -159,5 +159,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-local-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-local-upstreams.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-local-upstreams.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-applies-to-local-upstreams.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-inbound.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-inbound.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/otel-access-logging-http.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/otel-access-logging-http.latest.golden deleted file mode 100644 index b4372a3439e81..0000000000000 --- a/agent/xds/testdata/builtin_extension/endpoints/otel-access-logging-http.latest.golden +++ /dev/null @@ -1,75 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-keepalive.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-keepalive.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-keepalive.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-keepalive.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-outlier-detection-multiple.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-outlier-detection-multiple.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-outlier-detection-multiple.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-outlier-detection-multiple.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-outlier-detection.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-outlier-detection.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-outlier-detection.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-outlier-detection.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-round-robin-lb-config.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-round-robin-lb-config.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-round-robin-lb-config.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-add-round-robin-lb-config.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-cluster-load-assignment-inbound-add.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-cluster-load-assignment-inbound-add.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-cluster-load-assignment-inbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-cluster-load-assignment-inbound-add.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-cluster-load-assignment-outbound-add.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-cluster-load-assignment-outbound-add.latest.golden index 27105269cdd37..4eb9f4c5728bb 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-cluster-load-assignment-outbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-cluster-load-assignment-outbound-add.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -77,5 +77,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-listener-inbound-add.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-listener-inbound-add.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-listener-inbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-listener-inbound-add.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-listener-outbound-add.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-listener-outbound-add.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-listener-outbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-listener-outbound-add.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden index b4372a3439e81..5cb4171b97300 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-patch-specific-upstream-service-failover.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-patch-specific-upstream-service-failover.latest.golden index 5300fb0c6d188..ba96001dde79b 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-patch-specific-upstream-service-failover.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-patch-specific-upstream-service-failover.latest.golden @@ -1,115 +1,115 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ], - "policy": { - "overprovisioningFactor": 1234 + "policy": { + "overprovisioningFactor": 1234 } }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ], - "policy": { - "overprovisioningFactor": 1234 + "policy": { + "overprovisioningFactor": 1234 } }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-patch-specific-upstream-service-splitter.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-patch-specific-upstream-service-splitter.latest.golden index eb778f318856d..98e3abe7e92d9 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-patch-specific-upstream-service-splitter.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-patch-specific-upstream-service-splitter.latest.golden @@ -1,115 +1,115 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ], - "policy": { - "overprovisioningFactor": 1234 + "policy": { + "overprovisioningFactor": 1234 } }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ], - "policy": { - "overprovisioningFactor": 1234 + "policy": { + "overprovisioningFactor": 1234 } } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-remove-outlier-detection.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-remove-outlier-detection.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-remove-outlier-detection.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/propertyoverride-remove-outlier-detection.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/wasm-http-local-file.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/wasm-http-local-file.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/wasm-http-local-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/wasm-http-local-file.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/wasm-http-remote-file.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/wasm-http-remote-file.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/wasm-http-remote-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/wasm-http-remote-file.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-local-file-outbound.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-local-file-outbound.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-local-file-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-local-file-outbound.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-local-file.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-local-file.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-local-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-local-file.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-remote-file-outbound.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-remote-file-outbound.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-remote-file-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-remote-file-outbound.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-remote-file.latest.golden b/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-remote-file.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-remote-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/endpoints/wasm-tcp-remote-file.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-local-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-local-grpc-service.latest.golden index 2492e2ffaf4d7..370a98fbe6f05 100644 --- a/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-local-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-local-grpc-service.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -157,17 +179,17 @@ "name": "envoy.filters.http.ext_authz", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", - "failureModeAllow": true, "grpcService": { "envoyGrpc": { "clusterName": "local_ext_authz" } }, + "transportApiVersion": "V3", + "failureModeAllow": true, "metadataContextNamespaces": [ "consul" ], - "statPrefix": "response", - "transportApiVersion": "V3" + "statPrefix": "response" } }, { @@ -177,38 +199,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -222,9 +223,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -235,22 +234,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-local-http-service.latest.golden b/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-local-http-service.latest.golden index 120bb1ee6fda6..7f7bffd9a4d47 100644 --- a/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-local-http-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-local-http-service.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -157,18 +179,18 @@ "name": "envoy.filters.http.ext_authz", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", - "failureModeAllow": true, "httpService": { "serverUri": { - "cluster": "local_ext_authz", - "uri": "local_ext_authz" + "uri": "local_ext_authz", + "cluster": "local_ext_authz" } }, + "transportApiVersion": "V3", + "failureModeAllow": true, "metadataContextNamespaces": [ "consul" ], - "statPrefix": "response", - "transportApiVersion": "V3" + "statPrefix": "response" } }, { @@ -178,38 +200,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -223,9 +224,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -236,22 +235,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-upstream-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-upstream-grpc-service.latest.golden index 69dd07bf63403..489708b8364ae 100644 --- a/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-upstream-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-upstream-grpc-service.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -157,13 +179,12 @@ "name": "envoy.filters.http.ext_authz", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", - "bootstrapMetadataLabelsKey": "test-labels-key", - "clearRouteCache": true, "grpcService": { "envoyGrpc": { - "authority": "test-authority", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "authority": "test-authority" }, + "timeout": "2s", "initialMetadata": [ { "key": "init-metadata-1", @@ -173,25 +194,26 @@ "key": "init-metadata-2", "value": "value 2" } - ], - "timeout": "2s" + ] + }, + "transportApiVersion": "V3", + "withRequestBody": { + "maxRequestBytes": 10000, + "allowPartialMessage": true, + "packAsBytes": true + }, + "clearRouteCache": true, + "statusOnError": { + "code": "ExpectationFailed" }, - "includePeerCertificate": true, "metadataContextNamespaces": [ "test-ns-1", "test-ns-2", "consul" ], + "includePeerCertificate": true, "statPrefix": "ext_authz_stats", - "statusOnError": { - "code": "ExpectationFailed" - }, - "transportApiVersion": "V3", - "withRequestBody": { - "allowPartialMessage": true, - "maxRequestBytes": 10000, - "packAsBytes": true - } + "bootstrapMetadataLabelsKey": "test-labels-key" } }, { @@ -201,38 +223,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -246,9 +247,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -259,22 +258,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-upstream-http-service.latest.golden b/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-upstream-http-service.latest.golden index 52ff163ef6073..dc6cf35f49da1 100644 --- a/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-upstream-http-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/ext-authz-http-upstream-http-service.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -79,9 +101,13 @@ "name": "envoy.filters.http.ext_authz", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", - "bootstrapMetadataLabelsKey": "test-labels-key", - "clearRouteCache": true, "httpService": { + "serverUri": { + "uri": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "2s" + }, + "pathPrefix": "/ext_authz", "authorizationRequest": { "allowedHeaders": { "patterns": [ @@ -106,52 +132,52 @@ ] }, "authorizationResponse": { - "allowedClientHeaders": { + "allowedUpstreamHeaders": { "patterns": [ { - "prefix": "client-header-1" + "contains": "upstream-header-1" }, { - "ignoreCase": true, - "prefix": "client-header-2" + "contains": "upstream-header-2", + "ignoreCase": true } ] }, - "allowedClientHeadersOnSuccess": { + "allowedUpstreamHeadersToAppend": { "patterns": [ { - "safeRegex": { - "googleRe2": {}, - "regex": "client-ok-header-1" - } + "exact": "add-upstream-1" }, { - "safeRegex": { - "googleRe2": {}, - "regex": "client-ok-header-2" - } + "exact": "add-upstream-2", + "ignoreCase": true } ] }, - "allowedUpstreamHeaders": { + "allowedClientHeaders": { "patterns": [ { - "contains": "upstream-header-1" + "prefix": "client-header-1" }, { - "contains": "upstream-header-2", + "prefix": "client-header-2", "ignoreCase": true } ] }, - "allowedUpstreamHeadersToAppend": { + "allowedClientHeadersOnSuccess": { "patterns": [ { - "exact": "add-upstream-1" + "safeRegex": { + "googleRe2": {}, + "regex": "client-ok-header-1" + } }, { - "exact": "add-upstream-2", - "ignoreCase": true + "safeRegex": { + "googleRe2": {}, + "regex": "client-ok-header-2" + } } ] }, @@ -161,35 +187,31 @@ "suffix": "dynamic-header-1" }, { - "ignoreCase": true, - "suffix": "dynamic-header-2" + "suffix": "dynamic-header-2", + "ignoreCase": true } ] } - }, - "pathPrefix": "/ext_authz", - "serverUri": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "2s", - "uri": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } }, - "includePeerCertificate": true, + "transportApiVersion": "V3", + "withRequestBody": { + "maxRequestBytes": 10000, + "allowPartialMessage": true, + "packAsBytes": true + }, + "clearRouteCache": true, + "statusOnError": { + "code": "ExpectationFailed" + }, "metadataContextNamespaces": [ "test-ns-1", "test-ns-2", "consul" ], + "includePeerCertificate": true, "statPrefix": "ext_authz_stats", - "statusOnError": { - "code": "ExpectationFailed" - }, - "transportApiVersion": "V3", - "withRequestBody": { - "allowPartialMessage": true, - "maxRequestBytes": 10000, - "packAsBytes": true - } + "bootstrapMetadataLabelsKey": "test-labels-key" } }, { @@ -200,8 +222,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -214,8 +236,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -228,8 +250,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -242,8 +264,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -256,8 +278,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -277,38 +299,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -322,9 +323,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -335,22 +334,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/ext-authz-tcp-local-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/listeners/ext-authz-tcp-local-grpc-service.latest.golden index 2ff95a6b1d00c..61e2ff733931c 100644 --- a/agent/xds/testdata/builtin_extension/listeners/ext-authz-tcp-local-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/ext-authz-tcp-local-grpc-service.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -74,13 +75,13 @@ "name": "envoy.filters.network.ext_authz", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.ext_authz.v3.ExtAuthz", - "failureModeAllow": true, + "statPrefix": "response", "grpcService": { "envoyGrpc": { "clusterName": "local_ext_authz" } }, - "statPrefix": "response", + "failureModeAllow": true, "transportApiVersion": "V3" } }, @@ -88,8 +89,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -98,6 +99,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -108,7 +110,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -120,10 +121,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/listeners/ext-authz-tcp-upstream-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/listeners/ext-authz-tcp-upstream-grpc-service.latest.golden index e69b6d10ed23c..9683a52f0e58d 100644 --- a/agent/xds/testdata/builtin_extension/listeners/ext-authz-tcp-upstream-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/ext-authz-tcp-upstream-grpc-service.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -74,11 +75,13 @@ "name": "envoy.filters.network.ext_authz", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.ext_authz.v3.ExtAuthz", + "statPrefix": "ext_authz_stats", "grpcService": { "envoyGrpc": { - "authority": "test-authority", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "authority": "test-authority" }, + "timeout": "2s", "initialMetadata": [ { "key": "init-metadata-1", @@ -88,11 +91,9 @@ "key": "init-metadata-2", "value": "value 2" } - ], - "timeout": "2s" + ] }, "includePeerCertificate": true, - "statPrefix": "ext_authz_stats", "transportApiVersion": "V3" } }, @@ -100,8 +101,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -110,6 +111,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -120,7 +122,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -132,10 +133,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/listeners/lambda-and-lua-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-and-lua-connect-proxy.latest.golden index bf09509b375db..945be5c4032fb 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lambda-and-lua-connect-proxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lambda-and-lua-connect-proxy.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,30 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.aws_lambda", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config", - "arn": "arn:aws:lambda:us-east-1:111111111111:function:lambda-1234", - "invocationMode": "ASYNCHRONOUS" - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -53,8 +39,22 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", - "stripAnyHostPort": true, + "httpFilters": [ + { + "name": "envoy.filters.http.aws_lambda", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config", + "arn": "arn:aws:lambda:us-east-1:111111111111:function:lambda-1234", + "invocationMode": "ASYNCHRONOUS" + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -62,17 +62,18 @@ { "upgradeType": "websocket" } - ] + ], + "stripAnyHostPort": true } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -86,18 +87,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -111,7 +112,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -128,8 +150,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -142,8 +164,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -156,8 +178,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -170,8 +192,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -184,8 +206,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -212,38 +234,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -257,9 +258,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -270,22 +269,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-opposite-meta.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-opposite-meta.latest.golden index 0a9f960337082..59b2bd7719b28 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-opposite-meta.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-opposite-meta.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,30 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.aws_lambda", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config", - "arn": "arn:aws:lambda:us-east-1:111111111111:function:lambda-1234", - "invocationMode": "ASYNCHRONOUS" - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -53,8 +39,22 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", - "stripAnyHostPort": true, + "httpFilters": [ + { + "name": "envoy.filters.http.aws_lambda", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config", + "arn": "arn:aws:lambda:us-east-1:111111111111:function:lambda-1234", + "invocationMode": "ASYNCHRONOUS" + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -62,17 +62,18 @@ { "upgradeType": "websocket" } - ] + ], + "stripAnyHostPort": true } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -86,18 +87,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -119,8 +120,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -129,6 +130,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -139,7 +141,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -151,10 +152,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-tproxy.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-tproxy.latest.golden index d81c622fcfb7b..647c3898ca331 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-tproxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-tproxy.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,36 +17,24 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 15001 } }, - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "original-destination", - "statPrefix": "upstream.original-destination" - } - } - ] - }, "filterChains": [ { "filterChainMatch": { @@ -65,30 +54,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.aws_lambda", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config", - "arn": "arn:aws:lambda:us-east-1:111111111111:function:lambda-1234", - "payloadPassthrough": true - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.google.default.default.dc1", "routeConfig": { "name": "google", "virtualHosts": [ { + "name": "google.default.default.dc1", "domains": [ "*" ], - "name": "google.default.default.dc1", "routes": [ { "match": { @@ -102,8 +76,22 @@ } ] }, - "statPrefix": "upstream.google.default.default.dc1", - "stripAnyHostPort": true, + "httpFilters": [ + { + "name": "envoy.filters.http.aws_lambda", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config", + "arn": "arn:aws:lambda:us-east-1:111111111111:function:lambda-1234", + "payloadPassthrough": true + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -111,12 +99,25 @@ { "upgradeType": "websocket" } - ] + ], + "stripAnyHostPort": true } } ] } ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, "listenerFilters": [ { "name": "envoy.filters.listener.original_dst", @@ -125,11 +126,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -143,18 +144,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -176,8 +177,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -186,6 +187,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -196,7 +198,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -208,10 +209,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden index 1d8fd316ec2fc..0814b07f46dfb 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,22 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -45,7 +39,14 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -59,11 +60,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -77,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -110,8 +111,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -120,6 +121,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -130,7 +132,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -142,10 +143,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy.latest.golden index e51680301e623..172f32d6506ff 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lambda-connect-proxy.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,30 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.aws_lambda", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config", - "arn": "arn:aws:lambda:us-east-1:111111111111:function:lambda-1234", - "payloadPassthrough": true - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -53,8 +39,22 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", - "stripAnyHostPort": true, + "httpFilters": [ + { + "name": "envoy.filters.http.aws_lambda", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.aws_lambda.v3.Config", + "arn": "arn:aws:lambda:us-east-1:111111111111:function:lambda-1234", + "payloadPassthrough": true + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -62,17 +62,18 @@ { "upgradeType": "websocket" } - ] + ], + "stripAnyHostPort": true } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -86,18 +87,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -119,8 +120,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -129,6 +130,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -139,7 +141,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -151,10 +152,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden index 44e207f0f8081..0b77bf2a2f6b7 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway-with-service-resolvers.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -29,8 +30,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +40,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -49,7 +51,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -79,8 +80,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -89,6 +90,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -99,7 +101,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -121,7 +122,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.web.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -145,30 +153,23 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.web.default.default.dc1", - "stripAnyHostPort": true, - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" } - ] + ], + "stripAnyHostPort": true } } ], @@ -177,6 +178,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -187,7 +189,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -209,7 +210,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.web.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -233,30 +241,23 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.web.default.default.dc1", - "stripAnyHostPort": true, - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" } - ] + ], + "stripAnyHostPort": true } } ], @@ -265,6 +266,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -275,7 +277,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -305,8 +306,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -315,6 +316,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -325,7 +327,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -347,7 +348,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.web.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -371,30 +379,23 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.web.default.default.dc1", - "stripAnyHostPort": true, - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" } - ] + ], + "stripAnyHostPort": true } } ], @@ -403,6 +404,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -413,7 +415,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -436,8 +437,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -451,10 +452,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway.latest.golden index 9bd00c3f0c88d..fe380613af027 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lambda-terminating-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -29,8 +30,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +40,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -49,7 +51,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -79,8 +80,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -89,6 +90,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -99,7 +101,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -129,8 +130,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -139,6 +140,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -149,7 +151,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -171,7 +172,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.web.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -195,30 +203,23 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.web.default.default.dc1", - "stripAnyHostPort": true, - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" } - ] + ], + "stripAnyHostPort": true } } ], @@ -227,6 +228,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -237,7 +239,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -260,8 +261,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -275,10 +276,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden index 1d8fd316ec2fc..0814b07f46dfb 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,22 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -45,7 +39,14 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -59,11 +60,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -77,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -110,8 +111,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -120,6 +121,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -130,7 +132,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -142,10 +143,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-inbound-applies-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-inbound-applies-to-inbound.latest.golden index f0b2d4684088a..be339e7a190e8 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lua-inbound-applies-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lua-inbound-applies-to-inbound.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -167,38 +189,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -212,9 +213,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -225,22 +224,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden index 3b2dab64b526a..7f91026f6cf9b 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,22 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -45,7 +39,14 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -59,11 +60,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -77,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -102,7 +103,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -119,8 +141,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -133,8 +155,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -147,8 +169,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -161,8 +183,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -175,8 +197,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -203,38 +225,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -248,9 +249,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -261,22 +260,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden index 0b349be9433bd..20bb59055ada6 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", @@ -44,6 +45,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.lua", @@ -59,14 +68,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - }, - "statPrefix": "upstream.destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "tracing": { "randomSampling": {} }, @@ -88,6 +89,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.lua", @@ -103,14 +112,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - }, - "statPrefix": "upstream.destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "tracing": { "randomSampling": {} }, @@ -138,11 +139,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -156,18 +157,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -181,7 +182,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -198,8 +220,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -212,8 +234,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -226,8 +248,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -240,8 +262,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -254,8 +276,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -275,38 +297,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -320,9 +321,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -333,22 +332,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-local-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-local-upstreams.latest.golden index ade1593e2eabd..e6859902f5a69 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-local-upstreams.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-applies-to-local-upstreams.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,29 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.lua", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua", - "inlineCode": "\nfunction envoy_on_request(request_handle)\n request_handle:headers():add(\"test\", \"test\")\nend" - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -52,7 +39,21 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", + "httpFilters": [ + { + "name": "envoy.filters.http.lua", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua", + "inlineCode": "\nfunction envoy_on_request(request_handle)\n request_handle:headers():add(\"test\", \"test\")\nend" + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -66,11 +67,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -84,18 +85,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -109,7 +110,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -126,8 +148,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -140,8 +162,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -154,8 +176,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -168,8 +190,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -182,8 +204,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -203,38 +225,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -248,9 +249,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -261,22 +260,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-inbound.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-inbound.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden index e8a4a1432082b..36c29ce4c004d 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,22 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -45,7 +39,14 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -59,11 +60,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -77,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -102,7 +103,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -119,8 +141,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -133,8 +155,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -147,8 +169,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -161,8 +183,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -175,8 +197,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -196,38 +218,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -241,9 +242,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -254,22 +253,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden index e8a4a1432082b..36c29ce4c004d 100644 --- a/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,22 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -45,7 +39,14 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -59,11 +60,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -77,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -102,7 +103,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -119,8 +141,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -133,8 +155,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -147,8 +169,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -161,8 +183,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -175,8 +197,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -196,38 +218,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -241,9 +242,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -254,22 +253,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/otel-access-logging-http.latest.golden b/agent/xds/testdata/builtin_extension/listeners/otel-access-logging-http.latest.golden deleted file mode 100644 index ad4cde37e91f0..0000000000000 --- a/agent/xds/testdata/builtin_extension/listeners/otel-access-logging-http.latest.golden +++ /dev/null @@ -1,289 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9191 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" - } - } - ] - } - ], - "name": "db:127.0.0.1:9191", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.10.10.10", - "portValue": 8181 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" - } - } - ] - } - ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "0.0.0.0", - "portValue": 9999 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "accessLog": [ - { - "name": "envoy.access_loggers.open_telemetry", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.access_loggers.open_telemetry.v3.OpenTelemetryAccessLogConfig", - "attributes": { - "values": [ - { - "key": "name", - "value": { - "stringValue": "Bugs Bunny" - } - } - ] - }, - "commonConfig": { - "bufferFlushInterval": "0.001s", - "bufferSizeBytes": 4096, - "filterStateObjectsToLog": [ - "obj-1", - "obj-2" - ], - "grpcService": { - "envoyGrpc": { - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - }, - "grpcStreamRetryPolicy": { - "numRetries": 5, - "retryBackOff": { - "baseInterval": "1s", - "maxInterval": "10s" - } - }, - "logName": "otel-logger", - "transportApiVersion": "V3" - }, - "resourceAttributes": { - "values": [ - { - "key": "type", - "value": { - "stringValue": "compute" - } - } - ] - } - } - } - ], - "forwardClientCertDetails": "APPEND_FORWARD", - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.header_to_metadata", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config", - "requestRules": [ - { - "header": "x-forwarded-client-cert", - "onHeaderPresent": { - "key": "trust-domain", - "metadataNamespace": "consul", - "regexValueRewrite": { - "pattern": { - "googleRe2": {}, - "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" - }, - "substitution": "\\1" - } - } - }, - { - "header": "x-forwarded-client-cert", - "onHeaderPresent": { - "key": "partition", - "metadataNamespace": "consul", - "regexValueRewrite": { - "pattern": { - "googleRe2": {}, - "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" - }, - "substitution": "\\2" - } - } - }, - { - "header": "x-forwarded-client-cert", - "onHeaderPresent": { - "key": "namespace", - "metadataNamespace": "consul", - "regexValueRewrite": { - "pattern": { - "googleRe2": {}, - "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" - }, - "substitution": "\\3" - } - } - }, - { - "header": "x-forwarded-client-cert", - "onHeaderPresent": { - "key": "datacenter", - "metadataNamespace": "consul", - "regexValueRewrite": { - "pattern": { - "googleRe2": {}, - "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" - }, - "substitution": "\\4" - } - } - }, - { - "header": "x-forwarded-client-cert", - "onHeaderPresent": { - "key": "service", - "metadataNamespace": "consul", - "regexValueRewrite": { - "pattern": { - "googleRe2": {}, - "regex": ".*URI=spiffe://([^/]+.[^/]+)(?:/ap/([^/]+))?/ns/([^/]+)/dc/([^/]+)/svc/([^/;,]+).*" - }, - "substitution": "\\5" - } - } - } - ] - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] - }, - "setCurrentClientCertDetails": { - "cert": true, - "chain": true, - "dns": true, - "subject": true, - "uri": true - }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-keepalive.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-keepalive.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-keepalive.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-keepalive.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-outlier-detection-multiple.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-outlier-detection-multiple.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-outlier-detection-multiple.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-outlier-detection-multiple.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-outlier-detection.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-outlier-detection.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-outlier-detection.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-outlier-detection.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-round-robin-lb-config.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-round-robin-lb-config.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-round-robin-lb-config.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-add-round-robin-lb-config.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-cluster-load-assignment-inbound-add.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-cluster-load-assignment-inbound-add.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-cluster-load-assignment-inbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-cluster-load-assignment-inbound-add.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-cluster-load-assignment-outbound-add.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-cluster-load-assignment-outbound-add.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-cluster-load-assignment-outbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-cluster-load-assignment-outbound-add.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden index 63986a898dfc8..a0e8a85b6080e 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden @@ -1,14 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 9191 } }, + "statPrefix": "custom.stats.outbound.only", "filterChains": [ { "filters": [ @@ -16,25 +18,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", - "statPrefix": "custom.stats.outbound.only", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", "portValue": 8181 } }, + "statPrefix": "custom.stats.outbound.only", "filterChains": [ { "filters": [ @@ -42,25 +44,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "statPrefix": "custom.stats.outbound.only", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", "portValue": 9999 } }, + "statPrefix": "custom.stats.inbound.only", "filterChains": [ { "filters": [ @@ -68,7 +70,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -85,8 +108,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -99,8 +122,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -113,8 +136,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -127,8 +150,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -141,8 +164,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -162,38 +185,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -207,9 +209,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -220,23 +220,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", - "statPrefix": "custom.stats.inbound.only", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-listener-inbound-add.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-listener-inbound-add.latest.golden index 9b756b88ea5f4..84589156e704b 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-listener-inbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-listener-inbound-add.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,24 +42,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", "portValue": 9999 } }, + "statPrefix": "custom.stats", "filterChains": [ { "filters": [ @@ -66,7 +68,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +106,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +120,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +134,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +148,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +162,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +183,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +207,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,23 +218,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", - "statPrefix": "custom.stats", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-listener-outbound-add.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-listener-outbound-add.latest.golden index 91b69ea92489e..696de54e635fb 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-listener-outbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-listener-outbound-add.latest.golden @@ -1,14 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 9191 } }, + "statPrefix": "custom.stats", "filterChains": [ { "filters": [ @@ -16,25 +18,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", - "statPrefix": "custom.stats", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", "portValue": 8181 } }, + "statPrefix": "custom.stats", "filterChains": [ { "filters": [ @@ -42,19 +44,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "statPrefix": "custom.stats", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -68,7 +69,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -85,8 +107,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -99,8 +121,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -113,8 +135,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -127,8 +149,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -141,8 +163,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -162,38 +184,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -207,9 +208,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -220,22 +219,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden index 63986a898dfc8..a0e8a85b6080e 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden @@ -1,14 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 9191 } }, + "statPrefix": "custom.stats.outbound.only", "filterChains": [ { "filters": [ @@ -16,25 +18,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", - "statPrefix": "custom.stats.outbound.only", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", "portValue": 8181 } }, + "statPrefix": "custom.stats.outbound.only", "filterChains": [ { "filters": [ @@ -42,25 +44,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "statPrefix": "custom.stats.outbound.only", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", "portValue": 9999 } }, + "statPrefix": "custom.stats.inbound.only", "filterChains": [ { "filters": [ @@ -68,7 +70,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -85,8 +108,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -99,8 +122,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -113,8 +136,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -127,8 +150,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -141,8 +164,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -162,38 +185,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -207,9 +209,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -220,23 +220,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", - "statPrefix": "custom.stats.inbound.only", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-patch-specific-upstream-service-failover.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-patch-specific-upstream-service-failover.latest.golden index 81fdba1d66413..979ffd3ba98dc 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-patch-specific-upstream-service-failover.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-patch-specific-upstream-service-failover.latest.golden @@ -1,14 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 9191 } }, + "statPrefix": "custom.stats.outbound.only", "filterChains": [ { "filters": [ @@ -16,19 +18,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", - "statPrefix": "custom.stats.outbound.only", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -42,18 +43,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -67,7 +68,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -84,8 +106,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -98,8 +120,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -112,8 +134,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -126,8 +148,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -140,8 +162,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -161,38 +183,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -206,9 +207,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -219,22 +218,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-patch-specific-upstream-service-splitter.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-patch-specific-upstream-service-splitter.latest.golden index 680526bfbcf3c..36efed784d0ef 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-patch-specific-upstream-service-splitter.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-patch-specific-upstream-service-splitter.latest.golden @@ -1,14 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 9191 } }, + "statPrefix": "custom.stats.outbound.only", "filterChains": [ { "filters": [ @@ -16,6 +18,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.db.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "db" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +34,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "db" - }, - "statPrefix": "upstream.db.default.default.dc1", "tracing": { "randomSampling": {} }, @@ -45,12 +47,11 @@ ] } ], - "name": "db:127.0.0.1:9191", - "statPrefix": "custom.stats.outbound.only", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -64,18 +65,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -89,7 +90,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -106,8 +128,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -120,8 +142,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -134,8 +156,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -148,8 +170,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -162,8 +184,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -183,38 +205,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -228,9 +229,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -241,22 +240,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-remove-outlier-detection.latest.golden b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-remove-outlier-detection.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/builtin_extension/listeners/propertyoverride-remove-outlier-detection.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/propertyoverride-remove-outlier-detection.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/wasm-http-local-file.latest.golden b/agent/xds/testdata/builtin_extension/listeners/wasm-http-local-file.latest.golden index f7420d09994d1..9a80ae3050b7c 100644 --- a/agent/xds/testdata/builtin_extension/listeners/wasm-http-local-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/wasm-http-local-file.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -158,19 +180,19 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm", "config": { - "configuration": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "{\"foo\": \"bar\"}" - }, - "failOpen": true, "vmConfig": { + "runtime": "envoy.wasm.runtime.v8", "code": { "local": { "filename": "/path/to/extension.wasm" } - }, - "runtime": "envoy.wasm.runtime.v8" - } + } + }, + "configuration": { + "@type": "type.googleapis.com/google.protobuf.StringValue", + "value": "{\"foo\": \"bar\"}" + }, + "failOpen": true } } }, @@ -181,38 +203,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -226,9 +227,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -239,22 +238,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/wasm-http-remote-file.latest.golden b/agent/xds/testdata/builtin_extension/listeners/wasm-http-remote-file.latest.golden index 6dfde3d213e3d..220c7ce18c352 100644 --- a/agent/xds/testdata/builtin_extension/listeners/wasm-http-remote-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/wasm-http-remote-file.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -158,24 +180,24 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm", "config": { - "configuration": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "{\"foo\": \"bar\"}" - }, - "failOpen": true, "vmConfig": { + "runtime": "envoy.wasm.runtime.v8", "code": { "remote": { "httpUri": { + "uri": "https://db/plugin.wasm", "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "1s", - "uri": "https://db/plugin.wasm" + "timeout": "1s" }, "sha256": "d05d88b0ce8a8f1d5176481e0af3ae5c65ed82cbfb8c61506c5354b076078545" } - }, - "runtime": "envoy.wasm.runtime.v8" - } + } + }, + "configuration": { + "@type": "type.googleapis.com/google.protobuf.StringValue", + "value": "{\"foo\": \"bar\"}" + }, + "failOpen": true } } }, @@ -186,38 +208,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -231,9 +232,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -244,22 +243,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-local-file-outbound.latest.golden b/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-local-file-outbound.latest.golden index cc35634ac9fa0..967a2d4d29ee2 100644 --- a/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-local-file-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-local-file-outbound.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -17,19 +18,19 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm", "config": { - "configuration": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "{\"foo\": \"bar\"}" - }, - "failOpen": true, "vmConfig": { + "runtime": "envoy.wasm.runtime.v8", "code": { "local": { "filename": "/path/to/extension.wasm" } - }, - "runtime": "envoy.wasm.runtime.v8" - } + } + }, + "configuration": { + "@type": "type.googleapis.com/google.protobuf.StringValue", + "value": "{\"foo\": \"bar\"}" + }, + "failOpen": true } } }, @@ -37,18 +38,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -63,19 +64,19 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm", "config": { - "configuration": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "{\"foo\": \"bar\"}" - }, - "failOpen": true, "vmConfig": { + "runtime": "envoy.wasm.runtime.v8", "code": { "local": { "filename": "/path/to/extension.wasm" } - }, - "runtime": "envoy.wasm.runtime.v8" - } + } + }, + "configuration": { + "@type": "type.googleapis.com/google.protobuf.StringValue", + "value": "{\"foo\": \"bar\"}" + }, + "failOpen": true } } }, @@ -83,18 +84,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -116,8 +117,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -126,6 +127,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -136,7 +138,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -148,10 +149,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-local-file.latest.golden b/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-local-file.latest.golden index 93bda48c296cd..f97ca49ff94ab 100644 --- a/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-local-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-local-file.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -75,19 +76,19 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm", "config": { - "configuration": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "{\"foo\": \"bar\"}" - }, - "failOpen": true, "vmConfig": { + "runtime": "envoy.wasm.runtime.v8", "code": { "local": { "filename": "/path/to/extension.wasm" } - }, - "runtime": "envoy.wasm.runtime.v8" - } + } + }, + "configuration": { + "@type": "type.googleapis.com/google.protobuf.StringValue", + "value": "{\"foo\": \"bar\"}" + }, + "failOpen": true } } }, @@ -95,8 +96,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -105,6 +106,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -115,7 +117,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -127,10 +128,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-remote-file-outbound.latest.golden b/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-remote-file-outbound.latest.golden index ade444364aaa6..c67156dbf7975 100644 --- a/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-remote-file-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-remote-file-outbound.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -17,24 +18,24 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm", "config": { - "configuration": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "{\"foo\": \"bar\"}" - }, - "failOpen": true, "vmConfig": { + "runtime": "envoy.wasm.runtime.v8", "code": { "remote": { "httpUri": { + "uri": "https://db/plugin.wasm", "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "1s", - "uri": "https://db/plugin.wasm" + "timeout": "1s" }, "sha256": "d05d88b0ce8a8f1d5176481e0af3ae5c65ed82cbfb8c61506c5354b076078545" } - }, - "runtime": "envoy.wasm.runtime.v8" - } + } + }, + "configuration": { + "@type": "type.googleapis.com/google.protobuf.StringValue", + "value": "{\"foo\": \"bar\"}" + }, + "failOpen": true } } }, @@ -42,18 +43,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -68,24 +69,24 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm", "config": { - "configuration": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "{\"foo\": \"bar\"}" - }, - "failOpen": true, "vmConfig": { + "runtime": "envoy.wasm.runtime.v8", "code": { "remote": { "httpUri": { + "uri": "https://db/plugin.wasm", "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "1s", - "uri": "https://db/plugin.wasm" + "timeout": "1s" }, "sha256": "d05d88b0ce8a8f1d5176481e0af3ae5c65ed82cbfb8c61506c5354b076078545" } - }, - "runtime": "envoy.wasm.runtime.v8" - } + } + }, + "configuration": { + "@type": "type.googleapis.com/google.protobuf.StringValue", + "value": "{\"foo\": \"bar\"}" + }, + "failOpen": true } } }, @@ -93,18 +94,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -126,8 +127,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -136,6 +137,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -146,7 +148,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -158,10 +159,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-remote-file.latest.golden b/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-remote-file.latest.golden index 27a18061e60c8..438caaf8417b9 100644 --- a/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-remote-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/listeners/wasm-tcp-remote-file.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -75,24 +76,24 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm", "config": { - "configuration": { - "@type": "type.googleapis.com/google.protobuf.StringValue", - "value": "{\"foo\": \"bar\"}" - }, - "failOpen": true, "vmConfig": { + "runtime": "envoy.wasm.runtime.v8", "code": { "remote": { "httpUri": { + "uri": "https://db/plugin.wasm", "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "1s", - "uri": "https://db/plugin.wasm" + "timeout": "1s" }, "sha256": "d05d88b0ce8a8f1d5176481e0af3ae5c65ed82cbfb8c61506c5354b076078545" } - }, - "runtime": "envoy.wasm.runtime.v8" - } + } + }, + "configuration": { + "@type": "type.googleapis.com/google.protobuf.StringValue", + "value": "{\"foo\": \"bar\"}" + }, + "failOpen": true } } }, @@ -100,8 +101,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -110,6 +111,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -120,7 +122,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -132,10 +133,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/ext-authz-http-local-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/routes/ext-authz-http-local-grpc-service.latest.golden index 8b919343d21a9..15e82aa72ff56 100644 --- a/agent/xds/testdata/builtin_extension/routes/ext-authz-http-local-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/ext-authz-http-local-grpc-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/routes/ext-authz-http-local-http-service.latest.golden b/agent/xds/testdata/builtin_extension/routes/ext-authz-http-local-http-service.latest.golden index 8b919343d21a9..15e82aa72ff56 100644 --- a/agent/xds/testdata/builtin_extension/routes/ext-authz-http-local-http-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/ext-authz-http-local-http-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/routes/ext-authz-http-upstream-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/routes/ext-authz-http-upstream-grpc-service.latest.golden index 8b919343d21a9..15e82aa72ff56 100644 --- a/agent/xds/testdata/builtin_extension/routes/ext-authz-http-upstream-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/ext-authz-http-upstream-grpc-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/routes/ext-authz-http-upstream-http-service.latest.golden b/agent/xds/testdata/builtin_extension/routes/ext-authz-http-upstream-http-service.latest.golden index 8b919343d21a9..15e82aa72ff56 100644 --- a/agent/xds/testdata/builtin_extension/routes/ext-authz-http-upstream-http-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/ext-authz-http-upstream-http-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/routes/ext-authz-tcp-local-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/routes/ext-authz-tcp-local-grpc-service.latest.golden index 8b919343d21a9..15e82aa72ff56 100644 --- a/agent/xds/testdata/builtin_extension/routes/ext-authz-tcp-local-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/ext-authz-tcp-local-grpc-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/routes/ext-authz-tcp-upstream-grpc-service.latest.golden b/agent/xds/testdata/builtin_extension/routes/ext-authz-tcp-upstream-grpc-service.latest.golden index 8b919343d21a9..15e82aa72ff56 100644 --- a/agent/xds/testdata/builtin_extension/routes/ext-authz-tcp-upstream-grpc-service.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/ext-authz-tcp-upstream-grpc-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/builtin_extension/routes/lambda-and-lua-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-and-lua-connect-proxy.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lambda-and-lua-connect-proxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lambda-and-lua-connect-proxy.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-opposite-meta.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-opposite-meta.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-opposite-meta.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-opposite-meta.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-tproxy.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-tproxy.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-tproxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-tproxy.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lambda-connect-proxy.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden index 192eed0b6cbe0..eddaf9ef92fc2 100644 --- a/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway-with-service-resolvers.latest.golden @@ -1,76 +1,76 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ { - "domains": [ + "name": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ "*" ], - "name": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "route": { + "cluster": "canary1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } - ] + ], + "validateClusters": true }, { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ { - "domains": [ + "name": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ "*" ], - "name": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "route": { + "cluster": "canary2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } - ] + ], + "validateClusters": true }, { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ { - "domains": [ + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ "*" ], - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway.latest.golden b/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway.latest.golden index 5e25d5fdfafc3..51185834173b7 100644 --- a/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lambda-terminating-gateway.latest.golden @@ -1,30 +1,30 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "virtualHosts": [ { - "domains": [ + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "domains": [ "*" ], - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lua-connect-proxy-with-terminating-gateway-upstream.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-inbound-applies-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-inbound-applies-to-inbound.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lua-inbound-applies-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lua-inbound-applies-to-inbound.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lua-inbound-doesnt-apply-to-local-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden index 0f3440e32e347..173aa56476f6d 100644 --- a/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-local-upstreams-tproxy.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "www.google.com" ], - "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -22,18 +21,18 @@ } ] } - ] + ], + "validateClusters": true }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "192.168.2.3" ], - "name": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -46,10 +45,10 @@ ] }, { + "name": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "192.168.2.2" ], - "name": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -62,10 +61,10 @@ ] }, { + "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "192.168.2.1" ], - "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -77,9 +76,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-local-upstreams.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-local-upstreams.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-local-upstreams.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lua-outbound-applies-to-local-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-inbound.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-inbound.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-local-upstreams-with-consul-constraint-violation.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden b/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/lua-outbound-doesnt-apply-to-local-upstreams-with-envoy-constraint-violation.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/otel-access-logging-http.latest.golden b/agent/xds/testdata/builtin_extension/routes/otel-access-logging-http.latest.golden deleted file mode 100644 index 8b919343d21a9..0000000000000 --- a/agent/xds/testdata/builtin_extension/routes/otel-access-logging-http.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-keepalive.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-keepalive.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-keepalive.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-keepalive.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-outlier-detection-multiple.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-outlier-detection-multiple.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-outlier-detection-multiple.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-outlier-detection-multiple.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-outlier-detection.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-outlier-detection.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-outlier-detection.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-outlier-detection.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-round-robin-lb-config.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-round-robin-lb-config.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-round-robin-lb-config.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-add-round-robin-lb-config.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-cluster-load-assignment-inbound-add.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-cluster-load-assignment-inbound-add.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-cluster-load-assignment-inbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-cluster-load-assignment-inbound-add.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-cluster-load-assignment-outbound-add.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-cluster-load-assignment-outbound-add.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-cluster-load-assignment-outbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-cluster-load-assignment-outbound-add.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-inbound-doesnt-apply-to-outbound.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-listener-inbound-add.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-listener-inbound-add.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-listener-inbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-listener-inbound-add.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-listener-outbound-add.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-listener-outbound-add.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-listener-outbound-add.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-listener-outbound-add.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-outbound-doesnt-apply-to-inbound.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-failover.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-failover.latest.golden index 63ede4b9ebe1e..3c51e370a4a89 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-failover.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-failover.latest.golden @@ -1,32 +1,32 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "mostSpecificHeaderMutationsWins": true, - "name": "db", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "virtualHosts": [ { - "domains": [ + "name": "db", + "domains": [ "*" ], - "name": "db", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "33s" + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "33s" } } ] } - ] + ], + "mostSpecificHeaderMutationsWins": true, + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-splitter.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-splitter.latest.golden index dc51ff588d730..0f6260527b48d 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-splitter.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-splitter.latest.golden @@ -1,43 +1,43 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "mostSpecificHeaderMutationsWins": true, - "name": "db", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "virtualHosts": [ { - "domains": [ + "name": "db", + "domains": [ "*" ], - "name": "db", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "weightedClusters": { - "clusters": [ + "route": { + "weightedClusters": { + "clusters": [ { - "name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "weight": 5000 + "name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 5000 }, { - "name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "weight": 5000 + "name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 5000 } ], - "totalWeight": 10000 + "totalWeight": 10000 } } } ] } - ] + ], + "mostSpecificHeaderMutationsWins": true, + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-remove-outlier-detection.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-remove-outlier-detection.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-remove-outlier-detection.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-remove-outlier-detection.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/wasm-http-local-file.latest.golden b/agent/xds/testdata/builtin_extension/routes/wasm-http-local-file.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/wasm-http-local-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/wasm-http-local-file.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/wasm-http-remote-file.latest.golden b/agent/xds/testdata/builtin_extension/routes/wasm-http-remote-file.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/wasm-http-remote-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/wasm-http-remote-file.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/wasm-tcp-local-file-outbound.latest.golden b/agent/xds/testdata/builtin_extension/routes/wasm-tcp-local-file-outbound.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/wasm-tcp-local-file-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/wasm-tcp-local-file-outbound.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/wasm-tcp-local-file.latest.golden b/agent/xds/testdata/builtin_extension/routes/wasm-tcp-local-file.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/wasm-tcp-local-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/wasm-tcp-local-file.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/wasm-tcp-remote-file-outbound.latest.golden b/agent/xds/testdata/builtin_extension/routes/wasm-tcp-remote-file-outbound.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/wasm-tcp-remote-file-outbound.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/wasm-tcp-remote-file-outbound.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/builtin_extension/routes/wasm-tcp-remote-file.latest.golden b/agent/xds/testdata/builtin_extension/routes/wasm-tcp-remote-file.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/builtin_extension/routes/wasm-tcp-remote-file.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/wasm-tcp-remote-file.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/api-gateway-with-http-route-and-inline-certificate.latest.golden b/agent/xds/testdata/clusters/api-gateway-with-http-route-and-inline-certificate.latest.golden new file mode 100644 index 0000000000000..e20479dfd1cfc --- /dev/null +++ b/agent/xds/testdata/clusters/api-gateway-with-http-route-and-inline-certificate.latest.golden @@ -0,0 +1,55 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ + { + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/service" + } + ] + } + }, + "sni": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/api-gateway-with-http-route.latest.golden b/agent/xds/testdata/clusters/api-gateway-with-http-route.latest.golden deleted file mode 100644 index 6ffbd421e0686..0000000000000 --- a/agent/xds/testdata/clusters/api-gateway-with-http-route.latest.golden +++ /dev/null @@ -1,55 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/service" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/api-gateway-with-multiple-inline-certificates.latest.golden b/agent/xds/testdata/clusters/api-gateway-with-tcp-route-and-inline-certificate.envoy-1-21-x.golden similarity index 59% rename from agent/xds/testdata/clusters/api-gateway-with-multiple-inline-certificates.latest.golden rename to agent/xds/testdata/clusters/api-gateway-with-tcp-route-and-inline-certificate.envoy-1-21-x.golden index 6ffbd421e0686..0f1acf2588380 100644 --- a/agent/xds/testdata/clusters/api-gateway-with-multiple-inline-certificates.latest.golden +++ b/agent/xds/testdata/clusters/api-gateway-with-tcp-route-and-inline-certificate.envoy-1-21-x.golden @@ -1,55 +1,55 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "name": "my-tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "my-tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICBTCCAaugAwIBAgIIDUmSJn0rk7IwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAxML\nVGVzdCBDQSA5OTcwHhcNMjMwMjEzMTk1NzI2WhcNMzMwMjEwMTk1NzI2WjAAMFkw\nEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEg0SW0HLUZjEG9lnmnVT8g/1i+zdPVrCq\nWIltXSdtS3xbwaiP+5Vnc4sr/MqLhIC46BfyjrQWlz8bH+AGmn6pqKOB+DCB9TAO\nBgNVHQ8BAf8EBAMCA7gwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAwG\nA1UdEwEB/wQCMAAwKQYDVR0OBCIEIJhaXpuR2wfoxMchnGF3jGjSlhq4ldWkWnbj\nTjqghzzBMCsGA1UdIwQkMCKAIPSY/nP8UYJ63YM3PU3r4pUr6PujDyRaz1fyqlsJ\njZOZMF4GA1UdEQEB/wRUMFKCAIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMz\nLTQ0NDQtNTU1NTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMv\nd2ViMAoGCCqGSM49BAMCA0gAMEUCIQCWa5SsdXjVOHrIymFBFDYaB63G37I7G4fS\nnwHSTUX4WgIgRSmlLlZyYAC7iVfxYawVF00jlJgiI9BR15jZKX7AbQY=\n-----END CERTIFICATE-----\n" }, "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIAXRcUw9WfqWXNpB17uKREas/k4BEXmfTrHuMipy4cBYoAoGCCqGSM49\nAwEHoUQDQgAEg0SW0HLUZjEG9lnmnVT8g/1i+zdPVrCqWIltXSdtS3xbwaiP+5Vn\nc4sr/MqLhIC46BfyjrQWlz8bH+AGmn6pqA==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/service" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/my-tcp-service" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "my-tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/api-gateway-with-tcp-route-and-inline-certificate.latest.golden b/agent/xds/testdata/clusters/api-gateway-with-tcp-route-and-inline-certificate.latest.golden index 6ffbd421e0686..f18e7e0d97665 100644 --- a/agent/xds/testdata/clusters/api-gateway-with-tcp-route-and-inline-certificate.latest.golden +++ b/agent/xds/testdata/clusters/api-gateway-with-tcp-route-and-inline-certificate.latest.golden @@ -1,27 +1,29 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": {}, "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -32,24 +34,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/service" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-exported-to-peers.latest.golden b/agent/xds/testdata/clusters/connect-proxy-exported-to-peers.latest.golden index 7d992a068e265..0d8375ae075ee 100644 --- a/agent/xds/testdata/clusters/connect-proxy-exported-to-peers.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-exported-to-peers.latest.golden @@ -1,8 +1,10 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -22,11 +24,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.latest.golden b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.latest.golden index dc004b4e22040..15a17807e4342 100644 --- a/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-lb-in-resolver.latest.golden @@ -1,32 +1,44 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, + "connectTimeout": "5s", "lbPolicy": "RING_HASH", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "ringHashLbConfig": { - "maximumRingSize": "30", - "minimumRingSize": "20" + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -37,40 +49,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -81,8 +101,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -90,19 +112,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -122,31 +142,41 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -157,24 +187,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/something-else" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden index 9a7a84c48bf98..6faea0cb24f25 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden @@ -1,180 +1,182 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "peer1-root-1\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "peer1-root-1\n" - } + ] } }, - "sni": "db.default.default.cluster-01.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" + "sni": "db.default.default.cluster-01.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -182,11 +184,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover.latest.golden index a6c7b69749e67..2f37bfe304d4e 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-failover.latest.golden @@ -1,180 +1,182 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/fail" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/fail" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "fail.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "fail.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -182,11 +184,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-overrides.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-overrides.latest.golden index d438330c606b1..fd63324de86c4 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-overrides.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-overrides.latest.golden @@ -1,27 +1,49 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "78ebd528~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "78ebd528~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "66s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "78ebd528~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "66s", + "circuitBreakers": { + + }, + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": { + + } + } + } + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,48 +54,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -84,8 +106,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -93,19 +117,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -125,11 +147,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden index 820039ff1385e..5b20a297d0406 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden @@ -1,115 +1,117 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.cluster-01.external.peer1.domain", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.cluster-01.external.peer1.domain", + "altStatName": "db.default.cluster-01.external.peer1.domain", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.cluster-01.external.peer1.domain", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "peer1-root-1\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "peer1-root-1\n" - } + ] } }, - "sni": "db.default.default.cluster-01.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" + "sni": "db.default.default.cluster-01.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -117,11 +119,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-chain-external-sni.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-chain-external-sni.latest.golden index 26f0e477774d5..e030aed25abc7 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-chain-external-sni.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "33s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.some.other.service.mesh" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-chain-http2.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-chain-http2.latest.golden deleted file mode 100644 index f03d8c0ffcc9a..0000000000000 --- a/agent/xds/testdata/clusters/connect-proxy-with-chain-http2.latest.golden +++ /dev/null @@ -1,135 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" - }, - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - "name": "local_app", - "type": "STATIC" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-chain.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-chain.latest.golden index 69904e61ca163..69b7fbb652845 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-chain.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-chain.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "33s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-jwt-config-entry-with-local.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-jwt-config-entry-with-local.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-jwt-config-entry-with-local.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-jwt-config-entry-with-local.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-jwt-config-entry-with-remote-jwks.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-jwt-config-entry-with-remote-jwks.latest.golden index b3aeed5b63808..9b8a8b373551b 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-jwt-config-entry-with-remote-jwks.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-jwt-config-entry-with-remote-jwks.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "jwks_cluster_okta", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", @@ -118,7 +138,6 @@ } ] }, - "name": "jwks_cluster_okta", "transportSocket": { "name": "tls", "typedConfig": { @@ -131,11 +150,12 @@ } } } - }, - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -155,11 +175,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden deleted file mode 100644 index d7aa33d71a7cf..0000000000000 --- a/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden +++ /dev/null @@ -1,135 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - "name": "local_app", - "type": "STATIC" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "15s", - "loadAssignment": { - "clusterName": "payments?peer=cloud:custom-upstream", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8443 - } - } - } - } - ] - } - ] - }, - "name": "payments?peer=cloud:custom-upstream", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/payments" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "payments.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "outlierDetection": { - "maxEjectionPercent": 100 - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/refunds" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "refunds.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" - } - }, - "type": "EDS" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams-http2.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams-http2.latest.golden deleted file mode 100644 index 091cbbb5aa1cb..0000000000000 --- a/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams-http2.latest.golden +++ /dev/null @@ -1,163 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - "name": "local_app", - "type": "STATIC" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "123.us-east-1.elb.notaws.com", - "portValue": 8443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "name": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "outlierDetection": { - "maxEjectionPercent": 100 - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/payments" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "payments.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" - } - }, - "type": "LOGICAL_DNS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "outlierDetection": { - "maxEjectionPercent": 100 - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/refunds" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "refunds.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" - } - }, - "type": "EDS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams.latest.golden index 018997d5d0b8b..29059b1435492 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-peered-upstreams.latest.golden @@ -1,8 +1,10 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -22,19 +24,13 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, + "name": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", "endpoints": [ @@ -56,15 +52,27 @@ } ] }, - "name": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "circuitBreakers": { + + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", "outlierDetection": { "maxEjectionPercent": 100 }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -75,45 +83,53 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/payments" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "payments.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "name": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "connectTimeout": "5s", + "circuitBreakers": { + + }, "outlierDetection": { "maxEjectionPercent": 100 }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -124,24 +140,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/refunds" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "refunds.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden index eeff916358296..35a149b726138 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden @@ -1,229 +1,231 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -231,11 +233,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-local-gateway.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-local-gateway.latest.golden index eeff916358296..35a149b726138 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-local-gateway.latest.golden @@ -1,229 +1,231 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -231,11 +233,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden index eeff916358296..35a149b726138 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden @@ -1,229 +1,231 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -231,11 +233,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway.latest.golden index eeff916358296..35a149b726138 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway.latest.golden @@ -1,229 +1,231 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -231,11 +233,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden index e5c67ced9193c..e6d7abfe32de4 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden @@ -1,180 +1,182 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -182,11 +184,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden index e5c67ced9193c..e6d7abfe32de4 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden @@ -1,180 +1,182 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -182,11 +184,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden index e5c67ced9193c..e6d7abfe32de4 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden @@ -1,180 +1,182 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -182,11 +184,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden index e5c67ced9193c..e6d7abfe32de4 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden @@ -1,180 +1,182 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -182,11 +184,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-cipher-suites.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-cipher-suites.latest.golden index 8f405e7dd3337..3efce306b73de 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-cipher-suites.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-cipher-suites.latest.golden @@ -1,27 +1,42 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -32,45 +47,51 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -81,13 +102,10 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -95,19 +113,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -127,11 +143,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-max-version.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-max-version.latest.golden index 24554d780d29d..afef227a25ae1 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-max-version.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-max-version.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -32,42 +44,48 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -78,10 +96,10 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -89,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -121,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-min-version-auto.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-min-version-auto.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-min-version-auto.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-min-version-auto.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-min-version.latest.golden b/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-min-version.latest.golden index 29763283b9616..9d8c283a4ee0d 100644 --- a/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-min-version.latest.golden +++ b/agent/xds/testdata/clusters/connect-proxy-with-tls-outgoing-min-version.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -32,42 +44,48 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -78,10 +96,10 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -89,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -121,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-limits-max-connections-only.latest.golden b/agent/xds/testdata/clusters/custom-limits-max-connections-only.latest.golden index f2f27cd06f27f..e4b870241b316 100644 --- a/agent/xds/testdata/clusters/custom-limits-max-connections-only.latest.golden +++ b/agent/xds/testdata/clusters/custom-limits-max-connections-only.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", "circuitBreakers": { "thresholds": [ { @@ -11,23 +22,22 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} + "outlierDetection": { + }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "commonLbConfig": { + "healthyPanicThreshold": { + } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -38,25 +48,34 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", "circuitBreakers": { "thresholds": [ { @@ -64,20 +83,17 @@ } ] }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } + "outlierDetection": { + }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -88,8 +104,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -97,19 +115,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -129,11 +145,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-limits-set-to-zero.latest.golden b/agent/xds/testdata/clusters/custom-limits-set-to-zero.latest.golden index d3e8277df935d..43b09aeae6aec 100644 --- a/agent/xds/testdata/clusters/custom-limits-set-to-zero.latest.golden +++ b/agent/xds/testdata/clusters/custom-limits-set-to-zero.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", "circuitBreakers": { "thresholds": [ { @@ -13,23 +24,22 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} + "outlierDetection": { + }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "commonLbConfig": { + "healthyPanicThreshold": { + } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -40,25 +50,34 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", "circuitBreakers": { "thresholds": [ { @@ -68,20 +87,17 @@ } ] }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } + "outlierDetection": { + }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -92,8 +108,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -101,19 +119,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -133,11 +149,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-limits.latest.golden b/agent/xds/testdata/clusters/custom-limits.latest.golden index ac187b5ab0030..bbb8a3bac9346 100644 --- a/agent/xds/testdata/clusters/custom-limits.latest.golden +++ b/agent/xds/testdata/clusters/custom-limits.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", "circuitBreakers": { "thresholds": [ { @@ -13,23 +24,22 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} + "outlierDetection": { + }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "commonLbConfig": { + "healthyPanicThreshold": { + } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -40,25 +50,34 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "5s", "circuitBreakers": { "thresholds": [ { @@ -68,20 +87,17 @@ } ] }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } + "outlierDetection": { + }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -92,8 +108,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -101,19 +119,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -133,11 +149,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-local-app.latest.golden b/agent/xds/testdata/clusters/custom-local-app.latest.golden index 9e5f75c55b3e4..9b2bfb4f979f4 100644 --- a/agent/xds/testdata/clusters/custom-local-app.latest.golden +++ b/agent/xds/testdata/clusters/custom-local-app.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,16 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "mylocal", "connectTimeout": "15s", "loadAssignment": { "clusterName": "mylocal", @@ -117,10 +136,9 @@ ] } ] - }, - "name": "mylocal" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-max-inbound-connections.latest.golden b/agent/xds/testdata/clusters/custom-max-inbound-connections.latest.golden index 8763544644cb2..2306689c775e3 100644 --- a/agent/xds/testdata/clusters/custom-max-inbound-connections.latest.golden +++ b/agent/xds/testdata/clusters/custom-max-inbound-connections.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,26 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": { - "thresholds": [ - { - "maxConnections": 3456 - } - ] - }, + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -125,10 +138,15 @@ } ] }, - "name": "local_app", - "type": "STATIC" + "circuitBreakers": { + "thresholds": [ + { + "maxConnections": 3456 + } + ] + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-passive-healthcheck-zero-consecutive_5xx.latest.golden b/agent/xds/testdata/clusters/custom-passive-healthcheck-zero-consecutive_5xx.latest.golden deleted file mode 100644 index 7ccbda45902db..0000000000000 --- a/agent/xds/testdata/clusters/custom-passive-healthcheck-zero-consecutive_5xx.latest.golden +++ /dev/null @@ -1,133 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": { - "baseEjectionTime": "10s", - "consecutive5xx": 5, - "enforcingConsecutive5xx": 0, - "interval": "10s", - "maxEjectionPercent": 100 - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" - }, - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - "name": "local_app", - "type": "STATIC" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-passive-healthcheck.latest.golden b/agent/xds/testdata/clusters/custom-passive-healthcheck.latest.golden index 2f501e3ee8570..e00633358e579 100644 --- a/agent/xds/testdata/clusters/custom-passive-healthcheck.latest.golden +++ b/agent/xds/testdata/clusters/custom-passive-healthcheck.latest.golden @@ -1,33 +1,43 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "connectTimeout": "5s", + "circuitBreakers": { + + }, "outlierDetection": { - "baseEjectionTime": "10s", "consecutive5xx": 5, - "enforcingConsecutive5xx": 80, "interval": "10s", - "maxEjectionPercent": 100 + "enforcingConsecutive5xx": 80, + "maxEjectionPercent": 100, + "baseEjectionTime": "10s" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -38,40 +48,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -82,8 +100,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -91,19 +111,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -123,11 +141,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-timeouts.latest.golden b/agent/xds/testdata/clusters/custom-timeouts.latest.golden index 688adfb4c5698..80b6f3cb9a407 100644 --- a/agent/xds/testdata/clusters/custom-timeouts.latest.golden +++ b/agent/xds/testdata/clusters/custom-timeouts.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "1.234s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-upstream-default-chain.latest.golden b/agent/xds/testdata/clusters/custom-upstream-default-chain.latest.golden index 8ec7314419f19..20c2760e21bd4 100644 --- a/agent/xds/testdata/clusters/custom-upstream-default-chain.latest.golden +++ b/agent/xds/testdata/clusters/custom-upstream-default-chain.latest.golden @@ -1,23 +1,33 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -28,8 +38,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -37,19 +49,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -69,12 +79,11 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "myservice", "connectTimeout": "15s", "loadAssignment": { "clusterName": "myservice", @@ -95,12 +104,14 @@ } ] }, - "name": "myservice", "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -111,16 +122,15 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -129,5 +139,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-upstream-with-prepared-query.latest.golden b/agent/xds/testdata/clusters/custom-upstream-with-prepared-query.latest.golden deleted file mode 100644 index b82511b15e2f9..0000000000000 --- a/agent/xds/testdata/clusters/custom-upstream-with-prepared-query.latest.golden +++ /dev/null @@ -1,136 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "15s", - "loadAssignment": { - "clusterName": "db:custom-upstream", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8443 - } - } - } - } - ] - } - ] - }, - "name": "db:custom-upstream", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "db.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" - }, - { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" - } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - "name": "local_app", - "type": "STATIC" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/custom-upstream.latest.golden b/agent/xds/testdata/clusters/custom-upstream.latest.golden index 8ec7314419f19..20c2760e21bd4 100644 --- a/agent/xds/testdata/clusters/custom-upstream.latest.golden +++ b/agent/xds/testdata/clusters/custom-upstream.latest.golden @@ -1,23 +1,33 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -28,8 +38,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -37,19 +49,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -69,12 +79,11 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "myservice", "connectTimeout": "15s", "loadAssignment": { "clusterName": "myservice", @@ -95,12 +104,14 @@ } ] }, - "name": "myservice", "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -111,16 +122,15 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -129,5 +139,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/defaults.latest.golden b/agent/xds/testdata/clusters/defaults.latest.golden index 5a25e882ab312..2e3c9ea20e8ff 100644 --- a/agent/xds/testdata/clusters/defaults.latest.golden +++ b/agent/xds/testdata/clusters/defaults.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -117,11 +137,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/downstream-service-with-unix-sockets.latest.golden b/agent/xds/testdata/clusters/downstream-service-with-unix-sockets.latest.golden index a6d0025aeca35..0fbc15b716f79 100644 --- a/agent/xds/testdata/clusters/downstream-service-with-unix-sockets.latest.golden +++ b/agent/xds/testdata/clusters/downstream-service-with-unix-sockets.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,19 +107,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -116,11 +136,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/expose-checks.latest.golden b/agent/xds/testdata/clusters/expose-checks.latest.golden deleted file mode 100644 index 59d8b46b80e29..0000000000000 --- a/agent/xds/testdata/clusters/expose-checks.latest.golden +++ /dev/null @@ -1,57 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "exposed_cluster_8181", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8181 - } - } - } - } - ] - } - ] - }, - "name": "exposed_cluster_8181", - "type": "STATIC" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - "name": "local_app", - "type": "STATIC" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/expose-paths-grpc-new-cluster-http1.latest.golden b/agent/xds/testdata/clusters/expose-paths-grpc-new-cluster-http1.latest.golden index 9bc45fc802957..b86715755a91a 100644 --- a/agent/xds/testdata/clusters/expose-paths-grpc-new-cluster-http1.latest.golden +++ b/agent/xds/testdata/clusters/expose-paths-grpc-new-cluster-http1.latest.golden @@ -1,8 +1,10 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exposed_cluster_8090", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "exposed_cluster_8090", @@ -22,12 +24,12 @@ ] } ] - }, - "name": "exposed_cluster_8090", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -48,19 +50,18 @@ } ] }, - "name": "local_app", - "type": "STATIC", "typedExtensionProtocolOptions": { "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "useDownstreamProtocolConfig": { - "http2ProtocolOptions": {}, - "httpProtocolOptions": {} + "explicitHttpConfig": { + "http2ProtocolOptions": { + + } } } } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/expose-paths-local-app-paths.latest.golden b/agent/xds/testdata/clusters/expose-paths-local-app-paths.latest.golden index 7d992a068e265..0d8375ae075ee 100644 --- a/agent/xds/testdata/clusters/expose-paths-local-app-paths.latest.golden +++ b/agent/xds/testdata/clusters/expose-paths-local-app-paths.latest.golden @@ -1,8 +1,10 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -22,11 +24,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/expose-paths-new-cluster-http2.latest.golden b/agent/xds/testdata/clusters/expose-paths-new-cluster-http2.latest.golden index 0c94321dbb68b..b42be025bb855 100644 --- a/agent/xds/testdata/clusters/expose-paths-new-cluster-http2.latest.golden +++ b/agent/xds/testdata/clusters/expose-paths-new-cluster-http2.latest.golden @@ -1,8 +1,10 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exposed_cluster_9090", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "exposed_cluster_9090", @@ -23,19 +25,21 @@ } ] }, - "name": "exposed_cluster_9090", - "type": "STATIC", "typedExtensionProtocolOptions": { "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", "explicitHttpConfig": { - "http2ProtocolOptions": {} + "http2ProtocolOptions": { + + } } } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -55,11 +59,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-gateway-nil-config-entry.latest.golden b/agent/xds/testdata/clusters/ingress-gateway-nil-config-entry.latest.golden index 04106b67f20ad..cd8f56517eb6f 100644 --- a/agent/xds/testdata/clusters/ingress-gateway-nil-config-entry.latest.golden +++ b/agent/xds/testdata/clusters/ingress-gateway-nil-config-entry.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-gateway-no-services.latest.golden b/agent/xds/testdata/clusters/ingress-gateway-no-services.latest.golden index 04106b67f20ad..cd8f56517eb6f 100644 --- a/agent/xds/testdata/clusters/ingress-gateway-no-services.latest.golden +++ b/agent/xds/testdata/clusters/ingress-gateway-no-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-cipher-suites.latest.golden b/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-cipher-suites.latest.golden index 5451b36da4879..6a64ad79bbf78 100644 --- a/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-cipher-suites.latest.golden +++ b/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-cipher-suites.latest.golden @@ -1,27 +1,42 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -32,29 +47,22 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-max-version.latest.golden b/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-max-version.latest.golden index 6e1bd3beafd13..eb24656ebb3de 100644 --- a/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-max-version.latest.golden +++ b/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-max-version.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -32,26 +44,22 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-min-version.latest.golden b/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-min-version.latest.golden index 17b04f2d27d06..1c29f4d251a76 100644 --- a/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-min-version.latest.golden +++ b/agent/xds/testdata/clusters/ingress-gateway-with-tls-outgoing-min-version.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -32,26 +44,22 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-gateway.latest.golden index 699ed14e9cc25..332d1b2ea970e 100644 --- a/agent/xds/testdata/clusters/ingress-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-gateway.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,24 +44,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-lb-in-resolver.latest.golden b/agent/xds/testdata/clusters/ingress-lb-in-resolver.latest.golden index ff94a34cac863..d99713992c478 100644 --- a/agent/xds/testdata/clusters/ingress-lb-in-resolver.latest.golden +++ b/agent/xds/testdata/clusters/ingress-lb-in-resolver.latest.golden @@ -1,32 +1,44 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, + "connectTimeout": "5s", "lbPolicy": "RING_HASH", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "ringHashLbConfig": { - "maximumRingSize": "30", - "minimumRingSize": "20" + "minimumRingSize": "20", + "maximumRingSize": "30" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -37,44 +49,54 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -85,24 +107,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/something-else" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-multiple-listeners-duplicate-service.latest.golden b/agent/xds/testdata/clusters/ingress-multiple-listeners-duplicate-service.latest.golden index 3d83307a008da..8927d8065ec83 100644 --- a/agent/xds/testdata/clusters/ingress-multiple-listeners-duplicate-service.latest.golden +++ b/agent/xds/testdata/clusters/ingress-multiple-listeners-duplicate-service.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,44 +44,54 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/bar" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -80,24 +102,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/foo" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-splitter-with-resolver-redirect.latest.golden b/agent/xds/testdata/clusters/ingress-splitter-with-resolver-redirect.latest.golden index 5280ee7a98b88..1de8a759d0643 100644 --- a/agent/xds/testdata/clusters/ingress-splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/clusters/ingress-splitter-with-resolver-redirect.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,44 +44,54 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -80,24 +102,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/clusters/ingress-with-chain-and-failover-to-cluster-peer.latest.golden index 17649071505c9..d28f6764bf0c2 100644 --- a/agent/xds/testdata/clusters/ingress-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-chain-and-failover-to-cluster-peer.latest.golden @@ -1,121 +1,121 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "peer1-root-1\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "peer1-root-1\n" - } + ] } }, - "sni": "db.default.default.cluster-01.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" + "sni": "db.default.default.cluster-01.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-chain-and-failover.latest.golden b/agent/xds/testdata/clusters/ingress-with-chain-and-failover.latest.golden index 8a2f77a98f719..44f5bdab67698 100644 --- a/agent/xds/testdata/clusters/ingress-with-chain-and-failover.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-chain-and-failover.latest.golden @@ -1,121 +1,121 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/fail" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/fail" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "fail.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "fail.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-chain-external-sni.latest.golden b/agent/xds/testdata/clusters/ingress-with-chain-external-sni.latest.golden index e1dedd23fc2b2..345d7d2d8b8d8 100644 --- a/agent/xds/testdata/clusters/ingress-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-chain-external-sni.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "33s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,24 +44,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.some.other.service.mesh" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-chain.latest.golden b/agent/xds/testdata/clusters/ingress-with-chain.latest.golden index 3c3dec4ccf0ea..88f1f67978078 100644 --- a/agent/xds/testdata/clusters/ingress-with-chain.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-chain.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "33s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,24 +44,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-defaults-passive-health-check.latest.golden b/agent/xds/testdata/clusters/ingress-with-defaults-passive-health-check.latest.golden index 854e52edbd2e8..fbbcc9856c65f 100644 --- a/agent/xds/testdata/clusters/ingress-with-defaults-passive-health-check.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-defaults-passive-health-check.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "33s", "circuitBreakers": { "thresholds": [ { @@ -13,28 +24,24 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "outlierDetection": { "consecutive5xx": 10, - "enforcingConsecutive5xx": 80, "interval": "5s", - "maxEjectionPercent": 90 + "enforcingConsecutive5xx": 80 + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -45,24 +52,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-defaults-service-max-connections.latest.golden b/agent/xds/testdata/clusters/ingress-with-defaults-service-max-connections.latest.golden index bd9ac9dcb6615..24bb5835d7d64 100644 --- a/agent/xds/testdata/clusters/ingress-with-defaults-service-max-connections.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-defaults-service-max-connections.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "33s", "circuitBreakers": { "thresholds": [ { @@ -13,23 +24,22 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} + "outlierDetection": { + }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "commonLbConfig": { + "healthyPanicThreshold": { + } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -40,24 +50,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-passive-health-check.latest.golden b/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-passive-health-check.latest.golden index 63621f39f60af..6c9e0802a3dcc 100644 --- a/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-passive-health-check.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-passive-health-check.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "33s", "circuitBreakers": { "thresholds": [ { @@ -12,28 +23,23 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "outlierDetection": { - "baseEjectionTime": "12s", - "enforcingConsecutive5xx": 50, "interval": "8s", - "maxEjectionPercent": 90 + "enforcingConsecutive5xx": 50 + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,24 +50,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-service-max-connections.latest.golden b/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-service-max-connections.latest.golden index f38254450d940..2ea775950303c 100644 --- a/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-service-max-connections.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-service-max-connections.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "33s", "circuitBreakers": { "thresholds": [ { @@ -12,23 +23,22 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} + "outlierDetection": { + }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "commonLbConfig": { + "healthyPanicThreshold": { + } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -39,24 +49,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden b/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-service-passive-health-check.latest.golden similarity index 79% rename from agent/xds/testdata/clusters/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden rename to agent/xds/testdata/clusters/ingress-with-overwrite-defaults-service-passive-health-check.latest.golden index 6ffbd421e0686..8fb725c90185a 100644 --- a/agent/xds/testdata/clusters/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-overwrite-defaults-service-passive-health-check.latest.golden @@ -1,27 +1,45 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "33s", + "circuitBreakers": { + "thresholds": [ + { + "maxConnections": 4096, + "maxPendingRequests": 2048 + } + ] + }, + "outlierDetection": { + "interval": "8s", + "enforcingConsecutive5xx": 50 + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,24 +50,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/service" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-service-max-connections.latest.golden b/agent/xds/testdata/clusters/ingress-with-service-max-connections.latest.golden index e8c73c3b771c6..3ac392d40117a 100644 --- a/agent/xds/testdata/clusters/ingress-with-service-max-connections.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-service-max-connections.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "33s", "circuitBreakers": { "thresholds": [ { @@ -11,23 +22,22 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} + "outlierDetection": { + }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "commonLbConfig": { + "healthyPanicThreshold": { + } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -38,24 +48,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-service-passive-health-check.latest.golden b/agent/xds/testdata/clusters/ingress-with-service-passive-health-check.latest.golden index 5bea45a5757c4..892846151b9a3 100644 --- a/agent/xds/testdata/clusters/ingress-with-service-passive-health-check.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-service-passive-health-check.latest.golden @@ -1,9 +1,20 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": { + + }, + "resourceApiVersion": "V3" + } + }, + "connectTimeout": "33s", "circuitBreakers": { "thresholds": [ { @@ -11,27 +22,23 @@ } ] }, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "outlierDetection": { "consecutive5xx": 10, - "interval": "5s", - "maxEjectionPercent": 90 + "interval": "5s" + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -42,24 +49,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden index 36da92cce8f24..316328604f50e 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden @@ -1,170 +1,170 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden index 36da92cce8f24..316328604f50e 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden @@ -1,170 +1,170 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden index 36da92cce8f24..316328604f50e 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden @@ -1,170 +1,170 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden index 36da92cce8f24..316328604f50e 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden @@ -1,170 +1,170 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc3/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc3.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden index 37a8bbfcdc170..52a3fdcc9d02a 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden @@ -1,121 +1,121 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden index 37a8bbfcdc170..52a3fdcc9d02a 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden @@ -1,121 +1,121 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden index 37a8bbfcdc170..52a3fdcc9d02a 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden @@ -1,121 +1,121 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden index 37a8bbfcdc170..52a3fdcc9d02a 100644 --- a/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/clusters/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden @@ -1,121 +1,121 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "clusterType": { + "name": "envoy.clusters.aggregate", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", + "clusters": [ "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" ] } }, - "connectTimeout": "33s", - "lbPolicy": "CLUSTER_PROVIDED", - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {} + "connectTimeout": "33s", + "lbPolicy": "CLUSTER_PROVIDED", + "outlierDetection": {} }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "33s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/local-mesh-gateway-with-peered-upstreams.latest.golden b/agent/xds/testdata/clusters/local-mesh-gateway-with-peered-upstreams.latest.golden index 018997d5d0b8b..29059b1435492 100644 --- a/agent/xds/testdata/clusters/local-mesh-gateway-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/clusters/local-mesh-gateway-with-peered-upstreams.latest.golden @@ -1,8 +1,10 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -22,19 +24,13 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, + "name": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", "endpoints": [ @@ -56,15 +52,27 @@ } ] }, - "name": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "circuitBreakers": { + + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", "outlierDetection": { "maxEjectionPercent": 100 }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -75,45 +83,53 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/payments" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "payments.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "name": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "connectTimeout": "5s", + "circuitBreakers": { + + }, "outlierDetection": { "maxEjectionPercent": 100 }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -124,24 +140,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/refunds" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "refunds.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.latest.golden index 2374ba211b365..0d001e0b78180 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-hash-lb-ignored.latest.golden @@ -1,37 +1,45 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -53,15 +61,17 @@ } ] }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -83,50 +93,64 @@ } ] }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.latest.golden index 2374ba211b365..0d001e0b78180 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-ignore-extra-resolvers.latest.golden @@ -1,37 +1,45 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -53,15 +61,17 @@ } ] }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -83,50 +93,64 @@ } ] }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-no-services.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-no-services.latest.golden index 04106b67f20ad..cd8f56517eb6f 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-no-services.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-no-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.latest.golden index b43674c945090..1d6b63996be7f 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-non-hash-lb-injected.latest.golden @@ -1,41 +1,49 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, + "connectTimeout": "5s", "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, "leastRequestLbConfig": { "choiceCount": 5 - }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -57,15 +65,17 @@ } ] }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -87,58 +97,72 @@ } ] }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, + "connectTimeout": "5s", "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, "leastRequestLbConfig": { "choiceCount": 5 - }, - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, + "connectTimeout": "5s", "lbPolicy": "LEAST_REQUEST", + "outlierDetection": { + + }, "leastRequestLbConfig": { "choiceCount": 5 - }, - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-peering-control-plane.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-peering-control-plane.latest.golden index 5aa517fb5d7ca..a16659b28a550 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-peering-control-plane.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-peering-control-plane.latest.golden @@ -1,20 +1,24 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "server.dc1.peering.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "server.dc1.peering.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.latest.golden index 2374ba211b365..0d001e0b78180 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-subsets.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-subsets.latest.golden @@ -1,37 +1,45 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -53,15 +61,17 @@ } ] }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -83,50 +93,64 @@ } ] }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.latest.golden index c6b34b0f3fb8e..e6ff978acb4e7 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-service-timeouts.latest.golden @@ -1,37 +1,45 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "10s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "10s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -53,15 +61,17 @@ } ] }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -83,50 +93,64 @@ } ] }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "10s", + "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v1.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "10s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "10s", + "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v2.bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "10s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-tcp-keepalives.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-tcp-keepalives.latest.golden index a47ca5c369bb1..b2204c59acfb7 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-tcp-keepalives.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-tcp-keepalives.latest.golden @@ -1,44 +1,52 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS", + "connectTimeout": "5s", + "outlierDetection": { + + }, "upstreamConnectionOptions": { "tcpKeepalive": { - "keepaliveInterval": 60, "keepaliveProbes": 7, - "keepaliveTime": 120 + "keepaliveTime": 120, + "keepaliveInterval": 60 } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -60,22 +68,24 @@ } ] }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS", + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "upstreamConnectionOptions": { "tcpKeepalive": { - "keepaliveInterval": 60, "keepaliveProbes": 7, - "keepaliveTime": 120 + "keepaliveTime": 120, + "keepaliveInterval": 60 } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -97,31 +107,37 @@ } ] }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS", + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "upstreamConnectionOptions": { "tcpKeepalive": { - "keepaliveInterval": 60, "keepaliveProbes": 7, - "keepaliveTime": 120 + "keepaliveTime": 120, + "keepaliveInterval": 60 } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-using-federation-control-plane.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-using-federation-control-plane.latest.golden deleted file mode 100644 index 5568bf15ed9dc..0000000000000 --- a/agent/xds/testdata/clusters/mesh-gateway-using-federation-control-plane.latest.golden +++ /dev/null @@ -1,205 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "123.us-west-2.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "123.us-east-1.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "node1.server.dc1.consul", - "outlierDetection": {}, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "node2.server.dc1.consul", - "outlierDetection": {}, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "server.dc2.consul", - "outlierDetection": {}, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "server.dc4.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "123.us-west-2.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "name": "server.dc4.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", - "loadAssignment": { - "clusterName": "server.dc6.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "123.us-east-1.elb.notaws.com", - "portValue": 443 - } - } - }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - "name": "server.dc6.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-using-federation-states.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-using-federation-states.latest.golden index caa140aac2d50..bc9669beff36b 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-using-federation-states.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-using-federation-states.latest.golden @@ -1,37 +1,45 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -53,15 +61,17 @@ } ] }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -83,24 +93,30 @@ } ] }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden index f420e3236f1cd..8c85bbc827ad1 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden @@ -1,66 +1,73 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "alt.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "alt.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "exported~alt.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "exported~alt.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "exported~alt.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + } }, - "name": "exported~alt.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -71,44 +78,54 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/alt" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "alt.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exported~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "exported~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "exported~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "33s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -119,44 +136,54 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exported~v2.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "exported~v2.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "exported~v2.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -167,50 +194,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/api" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "v2.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "v1.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "name": "v2.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services-http.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services-http.latest.golden index 3c41ffedbce95..a41025e9fd8d4 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services-http.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services-http.latest.golden @@ -1,40 +1,56 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exported~bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "exported~bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "exported~bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -45,44 +61,54 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/bar" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exported~foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "exported~foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "exported~foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -93,44 +119,54 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/foo" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exported~gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "exported~gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "exported~gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -141,50 +177,56 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/gir" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services.latest.golden index deba3d5c3e7a1..eea8fc86ac970 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-with-exported-peered-services.latest.golden @@ -1,100 +1,136 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exported~bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "exported~bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "exported~bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exported~foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "exported~foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "exported~foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exported~gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "exported~gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "exported~gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-with-imported-peered-services.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-with-imported-peered-services.latest.golden index f9a606aed12b7..88f75c8868909 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-with-imported-peered-services.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-with-imported-peered-services.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "alt.default.default.peer-b.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "alt.default.default.peer-b.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", "endpoints": [ @@ -27,24 +27,30 @@ } ] }, - "name": "alt.default.default.peer-b.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "outlierDetection": {}, - "type": "STRICT_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "db.default.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden index 2d1ec4439e702..86cac4c9b3f8a 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden @@ -1,37 +1,37 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "server.dc2.peering.6d942ff2-6a78-46f4-a52f-915e26c48797", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "server.dc2.peering.6d942ff2-6a78-46f4-a52f-915e26c48797", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": {} }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "server.dc2.peering.f3f41279-001d-42bb-912e-f6103fb036b8", + "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" } }, - "name": "server.dc2.peering.f3f41279-001d-42bb-912e-f6103fb036b8", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": {} }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "server.dc3.peering.f622dc37-7238-4485-ab58-0f53864a9ae5", + "type": "STRICT_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "server.dc3.peering.f622dc37-7238-4485-ab58-0f53864a9ae5", "endpoints": [ @@ -51,11 +51,11 @@ } ] }, - "name": "server.dc3.peering.f622dc37-7238-4485-ab58-0f53864a9ae5", - "outlierDetection": {}, - "type": "STRICT_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": {} } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/mesh-gateway.latest.golden b/agent/xds/testdata/clusters/mesh-gateway.latest.golden index caa140aac2d50..bc9669beff36b 100644 --- a/agent/xds/testdata/clusters/mesh-gateway.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway.latest.golden @@ -1,37 +1,45 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -53,15 +61,17 @@ } ] }, - "name": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -83,24 +93,30 @@ } ] }, - "name": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "EDS" + "connectTimeout": "5s", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/splitter-with-resolver-redirect.latest.golden b/agent/xds/testdata/clusters/splitter-with-resolver-redirect.latest.golden index 72e8c720e9b28..9296b8bd751da 100644 --- a/agent/xds/testdata/clusters/splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/clusters/splitter-with-resolver-redirect.latest.golden @@ -1,23 +1,33 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -28,8 +38,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -37,19 +49,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -69,31 +79,41 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -104,44 +124,54 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "v1.db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -152,24 +182,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "v2.db.default.dc2.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/telemetry-collector.latest.golden b/agent/xds/testdata/clusters/telemetry-collector.latest.golden index d9c8f4f8b8ccc..0f936dbf4e93d 100644 --- a/agent/xds/testdata/clusters/telemetry-collector.latest.golden +++ b/agent/xds/testdata/clusters/telemetry-collector.latest.golden @@ -1,171 +1,173 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" + } }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "connectTimeout": "5s", + "circuitBreakers": {}, + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } } }, - "name": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/consul-telemetry-collector" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/consul-telemetry-collector" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - }, - "type": "EDS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } + "sni": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "commonLbConfig": { + "healthyPanicThreshold": {} + }, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "connectTimeout": "5s", + "circuitBreakers": {}, + "outlierDetection": {}, + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, + "matchSubjectAltNames": [ { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" }, { - "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" + "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, - "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" + "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "loadAssignment": { - "clusterName": "local_app", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", + "connectTimeout": "5s", + "loadAssignment": { + "clusterName": "local_app", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 } } } @@ -173,11 +175,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.latest.golden index 6f77e8d92b854..3bf0c6eb4cba1 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-hostname-service-subsets.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,13 +27,19 @@ } ] }, - "name": "alt.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,7 +50,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -52,14 +57,13 @@ } } } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -81,13 +85,19 @@ } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -98,7 +108,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -106,14 +115,13 @@ } } } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -135,15 +143,17 @@ } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -165,15 +175,17 @@ } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -195,27 +207,36 @@ } ] }, - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -223,10 +244,9 @@ } } } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-http2-upstream-subsets.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-http2-upstream-subsets.latest.golden index 75150c9fd3659..953a207e68b66 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-http2-upstream-subsets.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-http2-upstream-subsets.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,14 +27,29 @@ } ] }, - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": { + + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -42,22 +57,13 @@ } } } - }, - "type": "LOGICAL_DNS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -79,14 +85,29 @@ } ] }, - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": { + + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -94,22 +115,13 @@ } } } - }, - "type": "LOGICAL_DNS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -131,14 +143,29 @@ } ] }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": { + + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -146,18 +173,9 @@ } } } - }, - "type": "LOGICAL_DNS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-http2-upstream.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-http2-upstream.latest.golden index 70be44beb0128..9a8e2bdf43969 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-http2-upstream.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-http2-upstream.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,14 +27,29 @@ } ] }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": { + + } + } + } + }, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -42,18 +57,9 @@ } } } - }, - "type": "LOGICAL_DNS", - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.latest.golden index 067195261be88..d2efb57f5db44 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-ignore-extra-resolvers.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,13 +27,19 @@ } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,7 +50,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -52,14 +57,13 @@ } } } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -81,15 +85,17 @@ } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -111,27 +117,36 @@ } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -139,26 +154,32 @@ } } } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -166,26 +187,32 @@ } } } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -193,10 +220,9 @@ } } } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-lb-config.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-lb-config.latest.golden index 2820af6f1e977..a505f4f785f14 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-lb-config.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-lb-config.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,13 +27,19 @@ } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,7 +50,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -52,14 +57,13 @@ } } } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -81,15 +85,17 @@ } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -111,32 +117,41 @@ } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, + "connectTimeout": "5s", "lbPolicy": "RING_HASH", - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "outlierDetection": { + + }, "ringHashLbConfig": { - "maximumRingSize": "50", - "minimumRingSize": "20" + "minimumRingSize": "20", + "maximumRingSize": "50" }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -144,31 +159,37 @@ } } } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, + "connectTimeout": "5s", "lbPolicy": "RING_HASH", - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "outlierDetection": { + + }, "ringHashLbConfig": { - "maximumRingSize": "50", - "minimumRingSize": "20" + "minimumRingSize": "20", + "maximumRingSize": "50" }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -176,31 +197,37 @@ } } } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, + "connectTimeout": "5s", "lbPolicy": "RING_HASH", - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "outlierDetection": { + + }, "ringHashLbConfig": { - "maximumRingSize": "50", - "minimumRingSize": "20" + "minimumRingSize": "20", + "maximumRingSize": "50" }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -208,10 +235,9 @@ } } } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-no-services.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-no-services.latest.golden index 04106b67f20ad..cd8f56517eb6f 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-no-services.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-no-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.latest.golden index eebba5aef3586..87cf1d771822e 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-service-subsets.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-service-subsets.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,13 +27,19 @@ } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,7 +50,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -52,14 +57,13 @@ } } } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -81,15 +85,17 @@ } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -111,15 +117,17 @@ } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -141,27 +149,36 @@ } ] }, - "name": "prod.cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -169,26 +186,32 @@ } } } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -196,26 +219,32 @@ } } } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -223,10 +252,9 @@ } } } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-sni.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-sni.latest.golden index 160e9bfdffcd2..5b784eabc7738 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-sni.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-sni.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,13 +27,19 @@ } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,28 +50,26 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + }, "matchSubjectAltNames": [ { "exact": "bar.com" } - ], - "trustedCa": { - "filename": "ca.cert.pem" - } + ] } }, "sni": "bar.com" } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -87,15 +91,17 @@ } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -117,44 +123,52 @@ } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { + "trustedCa": { + "filename": "ca.cert.pem" + }, "matchSubjectAltNames": [ { "exact": "foo.com" } - ], - "trustedCa": { - "filename": "ca.cert.pem" - } + ] } }, "sni": "foo.com" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway-tcp-keepalives.latest.golden b/agent/xds/testdata/clusters/terminating-gateway-tcp-keepalives.latest.golden index b3533ea3196b1..1ab63951c741d 100644 --- a/agent/xds/testdata/clusters/terminating-gateway-tcp-keepalives.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway-tcp-keepalives.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,13 +27,19 @@ } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,7 +50,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -53,20 +58,19 @@ } } }, - "type": "LOGICAL_DNS", "upstreamConnectionOptions": { "tcpKeepalive": { - "keepaliveInterval": 27, "keepaliveProbes": 5, - "keepaliveTime": 133 + "keepaliveTime": 133, + "keepaliveInterval": 27 } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -88,22 +92,24 @@ } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS", + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "upstreamConnectionOptions": { "tcpKeepalive": { - "keepaliveInterval": 27, "keepaliveProbes": 5, - "keepaliveTime": 133 + "keepaliveTime": 133, + "keepaliveInterval": 27 } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -125,34 +131,43 @@ } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS", + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "upstreamConnectionOptions": { "tcpKeepalive": { - "keepaliveInterval": 27, "keepaliveProbes": 5, - "keepaliveTime": 133 + "keepaliveTime": 133, + "keepaliveInterval": 27 } } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -161,16 +176,15 @@ } } }, - "type": "EDS", "upstreamConnectionOptions": { "tcpKeepalive": { - "keepaliveInterval": 27, "keepaliveProbes": 5, - "keepaliveTime": 133 + "keepaliveTime": 133, + "keepaliveInterval": 27 } } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/terminating-gateway.latest.golden b/agent/xds/testdata/clusters/terminating-gateway.latest.golden index 07cf25087bd1c..343730b5c0d3d 100644 --- a/agent/xds/testdata/clusters/terminating-gateway.latest.golden +++ b/agent/xds/testdata/clusters/terminating-gateway.latest.golden @@ -1,11 +1,11 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -27,13 +27,19 @@ } ] }, - "name": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,7 +50,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -52,14 +57,13 @@ } } } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -81,15 +85,17 @@ } ] }, - "name": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -111,27 +117,36 @@ } ] }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { "trustedCa": { "filename": "ca.cert.pem" @@ -139,10 +154,9 @@ } } } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/transparent-proxy-catalog-destinations-only.latest.golden b/agent/xds/testdata/clusters/transparent-proxy-catalog-destinations-only.latest.golden index 3a3556a8617d8..6b2c84d60c59e 100644 --- a/agent/xds/testdata/clusters/transparent-proxy-catalog-destinations-only.latest.golden +++ b/agent/xds/testdata/clusters/transparent-proxy-catalog-destinations-only.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,38 +107,46 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -127,25 +157,25 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/google" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -165,31 +195,41 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -200,24 +240,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/no-endpoints" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/transparent-proxy-destination-http.latest.golden b/agent/xds/testdata/clusters/transparent-proxy-destination-http.latest.golden index 43ffe1773a932..e3c9f59ff06e5 100644 --- a/agent/xds/testdata/clusters/transparent-proxy-destination-http.latest.golden +++ b/agent/xds/testdata/clusters/transparent-proxy-destination-http.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,43 +44,51 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -79,43 +99,51 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -126,43 +154,51 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka2" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -173,43 +209,51 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka2" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -220,40 +264,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/google" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -264,8 +316,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -273,19 +327,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -305,11 +357,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/transparent-proxy-destination.latest.golden b/agent/xds/testdata/clusters/transparent-proxy-destination.latest.golden index 3fdcc1c264867..dd5d736e5d305 100644 --- a/agent/xds/testdata/clusters/transparent-proxy-destination.latest.golden +++ b/agent/xds/testdata/clusters/transparent-proxy-destination.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,43 +44,51 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -79,43 +99,51 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-2-2.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.192-168-2-2.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "destination.192-168-2-2.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -126,43 +154,51 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.192-168-2-2.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.api-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.api-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "destination.api-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -173,43 +209,51 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/google" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.api-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -220,40 +264,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/google" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -264,8 +316,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -273,19 +327,17 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -305,11 +357,9 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/transparent-proxy-dial-instances-directly.latest.golden b/agent/xds/testdata/clusters/transparent-proxy-dial-instances-directly.latest.golden index 490ef2d07c19f..ff729a66d2ccc 100644 --- a/agent/xds/testdata/clusters/transparent-proxy-dial-instances-directly.latest.golden +++ b/agent/xds/testdata/clusters/transparent-proxy-dial-instances-directly.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,38 +107,46 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -127,25 +157,25 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -165,31 +195,41 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "33s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "33s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -200,40 +240,42 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/mongo" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED", "name": "original-destination", - "type": "ORIGINAL_DST" + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "passthrough~kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "ORIGINAL_DST", "connectTimeout": "5s", "lbPolicy": "CLUSTER_PROVIDED", - "name": "passthrough~kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -244,33 +286,35 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/kafka" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "ORIGINAL_DST" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "passthrough~mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "ORIGINAL_DST", "connectTimeout": "33s", "lbPolicy": "CLUSTER_PROVIDED", - "name": "passthrough~mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -281,24 +325,22 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/mongo" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "ORIGINAL_DST" + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/transparent-proxy-terminating-gateway-destinations-only.latest.golden b/agent/xds/testdata/clusters/transparent-proxy-terminating-gateway-destinations-only.latest.golden index 980d7f4ec7ddc..58fa4e7e8f3ab 100644 --- a/agent/xds/testdata/clusters/transparent-proxy-terminating-gateway-destinations-only.latest.golden +++ b/agent/xds/testdata/clusters/transparent-proxy-terminating-gateway-destinations-only.latest.golden @@ -1,8 +1,10 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-0-1.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "destination.192-168-0-1.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -23,12 +25,14 @@ } ] }, - "name": "destination.192-168-0-1.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "STATIC" + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-0-2.external-IP-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "destination.192-168-0-2.external-IP-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -49,12 +53,14 @@ } ] }, - "name": "destination.192-168-0-2.external-IP-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "STATIC" + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-0-2.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "destination.192-168-0-2.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -75,12 +81,14 @@ } ] }, - "name": "destination.192-168-0-2.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "STATIC" + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.192-168-0-3.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "destination.192-168-0-3.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -101,15 +109,15 @@ } ] }, - "name": "destination.192-168-0-3.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "STATIC" + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.api-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "destination.api-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -129,15 +137,17 @@ } ] }, - "name": "destination.api-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -157,35 +167,39 @@ } ] }, - "name": "destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "tlsParams": {}, + "tlsParams": { + + }, "validationContext": { + "trustedCa": { + "filename": "cert.pem" + }, "matchSubjectAltNames": [ { "exact": "api.test.com" } - ], - "trustedCa": { - "filename": "cert.pem" - } + ] } }, "sni": "api.test.com" } - }, - "type": "LOGICAL_DNS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -205,15 +219,17 @@ } ] }, - "name": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "destination.web-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "type": "LOGICAL_DNS", "connectTimeout": "5s", - "dnsLookupFamily": "V4_ONLY", - "dnsRefreshRate": "10s", "loadAssignment": { "clusterName": "destination.web-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ @@ -233,11 +249,13 @@ } ] }, - "name": "destination.web-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, - "type": "LOGICAL_DNS" + "dnsRefreshRate": "10s", + "dnsLookupFamily": "V4_ONLY", + "outlierDetection": { + + } } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/transparent-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/clusters/transparent-proxy-with-peered-upstreams.latest.golden index 4e9ce5333bb6d..d1f6d0bb0e1c8 100644 --- a/agent/xds/testdata/clusters/transparent-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/clusters/transparent-proxy-with-peered-upstreams.latest.golden @@ -1,28 +1,38 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "name": "api-a.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "api-a.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "connectTimeout": "5s", + "circuitBreakers": { + + }, "outlierDetection": { "maxEjectionPercent": 100 }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -33,45 +43,53 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/api-a" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "api-a.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "name": "db.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "connectTimeout": "5s", + "circuitBreakers": { + + }, "outlierDetection": { "maxEjectionPercent": 100 }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -82,25 +100,25 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://1c053652-8512-4373-90cf-5a7f6263a994.consul/ns/default/dc/cloud-dc/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -120,32 +138,40 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "name": "no-endpoints.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "no-endpoints.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", + "connectTimeout": "5s", + "circuitBreakers": { + + }, "outlierDetection": { "maxEjectionPercent": 100 }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -156,7 +182,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICczCCAdwCCQC3BLnEmLCrSjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQVoxEjAQBgNVBAcMCUZsYWdzdGFmZjEMMAoGA1UECgwDRm9v\nMRAwDgYDVQQLDAdleGFtcGxlMQ8wDQYDVQQDDAZwZWVyLWExHTAbBgkqhkiG9w0B\nCQEWDmZvb0BwZWVyLWEuY29tMB4XDTIyMDUyNjAxMDQ0NFoXDTIzMDUyNjAxMDQ0\nNFowfjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkFaMRIwEAYDVQQHDAlGbGFnc3Rh\nZmYxDDAKBgNVBAoMA0ZvbzEQMA4GA1UECwwHZXhhbXBsZTEPMA0GA1UEAwwGcGVl\nci1hMR0wGwYJKoZIhvcNAQkBFg5mb29AcGVlci1hLmNvbTCBnzANBgkqhkiG9w0B\nAQEFAAOBjQAwgYkCgYEA2zFYGTbXDAntT5pLTpZ2+VTiqx4J63VRJH1kdu11f0FV\nc2jl1pqCuYDbQXknDU0Pv1Q5y0+nSAihD2KqGS571r+vHQiPtKYPYRqPEe9FzAhR\n2KhWH6v/tk5DG1HqOjV9/zWRKB12gdFNZZqnw/e7NjLNq3wZ2UAwxXip5uJ8uwMC\nAwEAATANBgkqhkiG9w0BAQsFAAOBgQC/CJ9Syf4aL91wZizKTejwouRYoWv4gRAk\nyto45ZcNMHfJ0G2z+XAMl9ZbQsLgXmzAx4IM6y5Jckq8pKC4PEijCjlKTktLHlEy\n0ggmFxtNB1tid2NC8dOzcQ3l45+gDjDqdILhAvLDjlAIebdkqVqb2CfFNW/I2CQH\nZAuKN1aoKA==\n-----END CERTIFICATE-----\n" @@ -164,17 +189,16 @@ } } } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED", "name": "original-destination", - "type": "ORIGINAL_DST" + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/clusters/transparent-proxy.latest.golden b/agent/xds/testdata/clusters/transparent-proxy.latest.golden index fdc8e773170d0..d3a37c2cebdbf 100644 --- a/agent/xds/testdata/clusters/transparent-proxy.latest.golden +++ b/agent/xds/testdata/clusters/transparent-proxy.latest.golden @@ -1,27 +1,39 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -32,40 +44,48 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/db" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "circuitBreakers": {}, - "connectTimeout": "5s", + "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -76,8 +96,10 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/geo-cache-target" @@ -85,38 +107,46 @@ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc2/svc/geo-cache-target" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -127,25 +157,25 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/google" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app", + "type": "STATIC", "connectTimeout": "5s", "loadAssignment": { "clusterName": "local_app", @@ -165,31 +195,41 @@ ] } ] - }, - "name": "local_app", - "type": "STATIC" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "altStatName": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "circuitBreakers": {}, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "connectTimeout": "5s", + "type": "EDS", "edsClusterConfig": { "edsConfig": { - "ads": {}, + "ads": { + + }, "resourceApiVersion": "V3" } }, - "name": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "outlierDetection": {}, + "connectTimeout": "5s", + "circuitBreakers": { + + }, + "outlierDetection": { + + }, + "commonLbConfig": { + "healthyPanicThreshold": { + + } + }, "transportSocket": { "name": "tls", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -200,31 +240,29 @@ } } ], - "tlsParams": {}, "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + }, "matchSubjectAltNames": [ { "exact": "spiffe://11111111-2222-3333-4444-555555555555.consul/ns/default/dc/dc1/svc/no-endpoints" } - ], - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } + ] } }, "sni": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } - }, - "type": "EDS" + } }, { "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED", "name": "original-destination", - "type": "ORIGINAL_DST" + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports.golden b/agent/xds/testdata/endpoints/api-gateway-with-http-route-and-inline-certificate.latest.golden similarity index 60% rename from agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports.golden rename to agent/xds/testdata/endpoints/api-gateway-with-http-route-and-inline-certificate.latest.golden index 916fbc26ceab7..18adccd10c833 100644 --- a/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports.golden +++ b/agent/xds/testdata/endpoints/api-gateway-with-http-route-and-inline-certificate.latest.golden @@ -3,7 +3,7 @@ "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:admin-port", + "clusterName": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ { "lbEndpoints": [ @@ -11,31 +11,25 @@ "endpoint": { "address": { "socketAddress": { - "address": "127.0.0.1", + "address": "10.10.1.1", "portValue": 8080 } } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:api-port", - "endpoints": [ - { - "lbEndpoints": [ + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 + }, { "endpoint": { "address": { "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 + "address": "10.10.1.2", + "portValue": 8080 } } - } + }, + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } diff --git a/agent/xds/testdata/endpoints/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden b/agent/xds/testdata/endpoints/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden deleted file mode 100644 index b748098952a54..0000000000000 --- a/agent/xds/testdata/endpoints/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden +++ /dev/null @@ -1,41 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/api-gateway-with-http-route.latest.golden b/agent/xds/testdata/endpoints/api-gateway-with-http-route.latest.golden deleted file mode 100644 index b748098952a54..0000000000000 --- a/agent/xds/testdata/endpoints/api-gateway-with-http-route.latest.golden +++ /dev/null @@ -1,41 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/api-gateway-with-multiple-inline-certificates.latest.golden b/agent/xds/testdata/endpoints/api-gateway-with-multiple-inline-certificates.latest.golden deleted file mode 100644 index 96ee5c7094687..0000000000000 --- a/agent/xds/testdata/endpoints/api-gateway-with-multiple-inline-certificates.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/api-gateway-with-tcp-route-and-inline-certificate.latest.golden b/agent/xds/testdata/endpoints/api-gateway-with-tcp-route-and-inline-certificate.latest.golden index 96ee5c7094687..8504dae2b8400 100644 --- a/agent/xds/testdata/endpoints/api-gateway-with-tcp-route-and-inline-certificate.latest.golden +++ b/agent/xds/testdata/endpoints/api-gateway-with-tcp-route-and-inline-certificate.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-exported-to-peers.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-exported-to-peers.latest.golden index 96ee5c7094687..8504dae2b8400 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-exported-to-peers.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-exported-to-peers.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden index 2b5c371b065db..c12175fbb3bd1 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden @@ -1,97 +1,97 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.40.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.40.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover.latest.golden index ffaf0a6bae06e..49a84f09b247f 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-failover.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-overrides.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-overrides.latest.golden index 90aed27580770..f7efacb5fc223 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-overrides.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-overrides.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden index 974546d846d5f..e55cdc39f7a18 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden @@ -1,63 +1,63 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.cluster-01.external.peer1.domain", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.cluster-01.external.peer1.domain", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.40.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.40.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-chain-external-sni.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-chain-external-sni.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-chain-external-sni.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-chain.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-chain.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-chain.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-chain.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-default-chain-and-custom-cluster.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-default-chain-and-custom-cluster.latest.golden index c0d604ae53a7b..8e6f1f243fa76 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-default-chain-and-custom-cluster.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-default-chain-and-custom-cluster.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden deleted file mode 100644 index 060259960f01a..0000000000000 --- a/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden +++ /dev/null @@ -1,29 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "106.96.90.233", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams-http2.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams-http2.latest.golden deleted file mode 100644 index 060259960f01a..0000000000000 --- a/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams-http2.latest.golden +++ /dev/null @@ -1,29 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "106.96.90.233", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams.latest.golden index 060259960f01a..9dc909faf7c06 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -25,5 +25,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden index bc6e5db758e17..b98fbf6d4e48d 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden @@ -1,143 +1,143 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-local-gateway.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-local-gateway.latest.golden index ce68d858a192f..e830304436c68 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-local-gateway.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden index cd18ed8443d2a..3450b9128adb8 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden @@ -1,143 +1,143 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.1", + "portValue": 443 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.2", + "portValue": 443 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.38.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.38.1.1", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.38.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.38.1.2", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway.latest.golden index 3942a2ac583b7..d2922125cb913 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-double-failover-through-remote-gateway.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.38.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.38.1.1", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.38.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.38.1.2", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden index 5ed86bce531b9..9a8ebe103219e 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden index a32c5b39ab5cc..5cc24cc5e95b0 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden index fdbb0e7ac0d85..1e390a85c8222 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.1", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.2", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden index dad058f837029..c90fef8a1ba83 100644 --- a/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.1", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.2", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/defaults.latest.golden b/agent/xds/testdata/endpoints/defaults.latest.golden index b4372a3439e81..6e4d37bc327ce 100644 --- a/agent/xds/testdata/endpoints/defaults.latest.golden +++ b/agent/xds/testdata/endpoints/defaults.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-gateway-nil-config-entry.latest.golden b/agent/xds/testdata/endpoints/ingress-gateway-nil-config-entry.latest.golden index 96ee5c7094687..8504dae2b8400 100644 --- a/agent/xds/testdata/endpoints/ingress-gateway-nil-config-entry.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-gateway-nil-config-entry.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-gateway-no-services.latest.golden b/agent/xds/testdata/endpoints/ingress-gateway-no-services.latest.golden index 96ee5c7094687..8504dae2b8400 100644 --- a/agent/xds/testdata/endpoints/ingress-gateway-no-services.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-gateway-no-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-gateway.latest.golden b/agent/xds/testdata/endpoints/ingress-gateway.latest.golden index 2a1b29370b637..ff38886424cfd 100644 --- a/agent/xds/testdata/endpoints/ingress-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-gateway.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -37,5 +37,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-multiple-listeners-duplicate-service.latest.golden b/agent/xds/testdata/endpoints/ingress-multiple-listeners-duplicate-service.latest.golden index 5e54266e9e11c..260ef92c2abcc 100644 --- a/agent/xds/testdata/endpoints/ingress-multiple-listeners-duplicate-service.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-multiple-listeners-duplicate-service.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-splitter-with-resolver-redirect.latest.golden b/agent/xds/testdata/endpoints/ingress-splitter-with-resolver-redirect.latest.golden index c57f0a91a7e41..9cdc78d73ea00 100644 --- a/agent/xds/testdata/endpoints/ingress-splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-splitter-with-resolver-redirect.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -71,5 +71,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/endpoints/ingress-with-chain-and-failover-to-cluster-peer.latest.golden index bc0585ce3b47f..3635a4779da59 100644 --- a/agent/xds/testdata/endpoints/ingress-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-chain-and-failover-to-cluster-peer.latest.golden @@ -1,63 +1,63 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.40.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.40.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-chain-and-failover.latest.golden b/agent/xds/testdata/endpoints/ingress-with-chain-and-failover.latest.golden index 0c21bcde23702..7aa8a3f569c1d 100644 --- a/agent/xds/testdata/endpoints/ingress-with-chain-and-failover.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-chain-and-failover.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-chain-external-sni.latest.golden b/agent/xds/testdata/endpoints/ingress-with-chain-external-sni.latest.golden index 2a1b29370b637..ff38886424cfd 100644 --- a/agent/xds/testdata/endpoints/ingress-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-chain-external-sni.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -37,5 +37,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-chain.latest.golden b/agent/xds/testdata/endpoints/ingress-with-chain.latest.golden index 2a1b29370b637..ff38886424cfd 100644 --- a/agent/xds/testdata/endpoints/ingress-with-chain.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-chain.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -37,5 +37,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden index c638ef0e4df09..5d356df4408b3 100644 --- a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-local-gateway-triggered.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden index 5da7c8c067383..243c820508555 100644 --- a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-local-gateway.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden index a46187cb0a848..e7e9eb4196b4c 100644 --- a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-remote-gateway-triggered.latest.golden @@ -1,109 +1,109 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.1", + "portValue": 443 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.2", + "portValue": 443 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.38.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.38.1.1", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.38.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.38.1.2", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden index a85f35e138c50..9a62663e8e274 100644 --- a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-double-failover-through-remote-gateway.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~2~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.38.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.38.1.1", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.38.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.38.1.2", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden index c104c6763019e..61e7ed645f6a3 100644 --- a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-local-gateway-triggered.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden index efe338808f879..eedd23fc1ef99 100644 --- a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8443 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden index 12bc8260e52d7..583a49bd3e219 100644 --- a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-remote-gateway-triggered.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "UNHEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "UNHEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.1", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.2", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden index d2f4ff74ca45a..879669138a48d 100644 --- a/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden @@ -1,75 +1,75 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~0~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "failover-target~1~db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.1", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.1", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.2", - "portValue": 443 + "endpoint": { + "address": { + "socketAddress": { + "address": "198.18.1.2", + "portValue": 443 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/local-mesh-gateway-with-peered-upstreams.latest.golden b/agent/xds/testdata/endpoints/local-mesh-gateway-with-peered-upstreams.latest.golden index f89565bd3391f..e488115ae3afa 100644 --- a/agent/xds/testdata/endpoints/local-mesh-gateway-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/endpoints/local-mesh-gateway-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -25,5 +25,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-default-service-subset.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-default-service-subset.latest.golden index 3822ab931b383..938d0b792eebc 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-default-service-subset.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-default-service-subset.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -217,5 +217,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-newer-information-in-federation-states.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-newer-information-in-federation-states.latest.golden index 02af43dfe7442..8c3d619cafcb8 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-newer-information-in-federation-states.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-newer-information-in-federation-states.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -129,5 +129,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-no-services.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-no-services.latest.golden index 96ee5c7094687..8504dae2b8400 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-no-services.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-no-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-older-information-in-federation-states.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-older-information-in-federation-states.latest.golden index 4853c9dc932a1..81f2a3eecae55 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-older-information-in-federation-states.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-older-information-in-federation-states.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -141,5 +141,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-peering-control-plane.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-peering-control-plane.latest.golden index 2445f74d51221..58ce9101bcae6 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-peering-control-plane.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-peering-control-plane.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -33,5 +33,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-service-subsets.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-service-subsets.latest.golden index f4e0c1e258b04..a68fb5b7a4c09 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-service-subsets.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-service-subsets.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -265,5 +265,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-using-federation-control-plane.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-using-federation-control-plane.latest.golden deleted file mode 100644 index 0cc0209281f9e..0000000000000 --- a/agent/xds/testdata/endpoints/mesh-gateway-using-federation-control-plane.latest.golden +++ /dev/null @@ -1,249 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "172.16.1.6", - "portValue": 2222 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "172.16.1.7", - "portValue": 2222 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "172.16.1.8", - "portValue": 2222 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.1", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.2", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "172.16.1.3", - "portValue": 2222 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "172.16.1.4", - "portValue": 2222 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "172.16.1.5", - "portValue": 2222 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "172.16.1.9", - "portValue": 2222 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "node1.server.dc1.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 0 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "node2.server.dc1.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.2", - "portValue": 0 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "server.dc1.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 0 - } - } - } - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.2", - "portValue": 0 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "server.dc2.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.1", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "198.18.1.2", - "portValue": 443 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-using-federation-states.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-using-federation-states.latest.golden index 4853c9dc932a1..81f2a3eecae55 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-using-federation-states.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-using-federation-states.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -141,5 +141,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden index 56781f49cf9b7..b993f6a71e49f 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -35,40 +35,6 @@ } ] }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.3", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 128 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.4", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", @@ -170,74 +136,8 @@ ] } ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "exported~v2.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.4", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "v1.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.3", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 128 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "v2.api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.4", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services-http.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services-http.latest.golden index ce19eaa7ffcb4..2d3e39d305e22 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services-http.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services-http.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -207,5 +207,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services.latest.golden index ce19eaa7ffcb4..2d3e39d305e22 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-with-exported-peered-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -207,5 +207,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-with-imported-peered-services.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-with-imported-peered-services.latest.golden index 54aad58279a1f..efb3c588be98f 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-with-imported-peered-services.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-with-imported-peered-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -37,5 +37,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden index 740be0d4c78e2..2f88c1fb5a826 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -53,5 +53,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/mesh-gateway.latest.golden b/agent/xds/testdata/endpoints/mesh-gateway.latest.golden index 4853c9dc932a1..81f2a3eecae55 100644 --- a/agent/xds/testdata/endpoints/mesh-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/mesh-gateway.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -141,5 +141,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/splitter-with-resolver-redirect.latest.golden b/agent/xds/testdata/endpoints/splitter-with-resolver-redirect.latest.golden index e47c38cb8a6a1..8eece2e37d099 100644 --- a/agent/xds/testdata/endpoints/splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/endpoints/splitter-with-resolver-redirect.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -105,5 +105,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/telemetry-collector.latest.golden b/agent/xds/testdata/endpoints/telemetry-collector.latest.golden index f8cc5efc2db05..fb14b9d3a86b3 100644 --- a/agent/xds/testdata/endpoints/telemetry-collector.latest.golden +++ b/agent/xds/testdata/endpoints/telemetry-collector.latest.golden @@ -1,97 +1,97 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "9.9.9.9", - "portValue": 9090 + "endpoint": { + "address": { + "socketAddress": { + "address": "9.9.9.9", + "portValue": 9090 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] }, { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", + "endpoints": [ { - "lbEndpoints": [ + "lbEndpoints": [ { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.10.1.1", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 }, { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 + "endpoint": { + "address": { + "socketAddress": { + "address": "10.20.1.2", + "portValue": 8080 } } }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 + "healthStatus": "HEALTHY", + "loadBalancingWeight": 1 } ] } ] } ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/terminating-gateway-default-service-subset.latest.golden b/agent/xds/testdata/endpoints/terminating-gateway-default-service-subset.latest.golden index 4c043024998e9..30607da56da89 100644 --- a/agent/xds/testdata/endpoints/terminating-gateway-default-service-subset.latest.golden +++ b/agent/xds/testdata/endpoints/terminating-gateway-default-service-subset.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -69,5 +69,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/terminating-gateway-no-services.latest.golden b/agent/xds/testdata/endpoints/terminating-gateway-no-services.latest.golden index 96ee5c7094687..8504dae2b8400 100644 --- a/agent/xds/testdata/endpoints/terminating-gateway-no-services.latest.golden +++ b/agent/xds/testdata/endpoints/terminating-gateway-no-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/terminating-gateway-service-subsets.latest.golden b/agent/xds/testdata/endpoints/terminating-gateway-service-subsets.latest.golden index 038021dd86772..13470d4879944 100644 --- a/agent/xds/testdata/endpoints/terminating-gateway-service-subsets.latest.golden +++ b/agent/xds/testdata/endpoints/terminating-gateway-service-subsets.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -81,5 +81,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/terminating-gateway.latest.golden b/agent/xds/testdata/endpoints/terminating-gateway.latest.golden index 0b67b10323e3f..f33244f4e7b2c 100644 --- a/agent/xds/testdata/endpoints/terminating-gateway.latest.golden +++ b/agent/xds/testdata/endpoints/terminating-gateway.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -37,5 +37,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/transparent-proxy-destination-http.latest.golden b/agent/xds/testdata/endpoints/transparent-proxy-destination-http.latest.golden index a0896e11577bb..284d7722a6d0e 100644 --- a/agent/xds/testdata/endpoints/transparent-proxy-destination-http.latest.golden +++ b/agent/xds/testdata/endpoints/transparent-proxy-destination-http.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -159,5 +159,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/transparent-proxy-destination.latest.golden b/agent/xds/testdata/endpoints/transparent-proxy-destination.latest.golden index 3c027c838dca8..33fa4f7081d84 100644 --- a/agent/xds/testdata/endpoints/transparent-proxy-destination.latest.golden +++ b/agent/xds/testdata/endpoints/transparent-proxy-destination.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -159,5 +159,5 @@ } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/transparent-proxy-terminating-gateway-destinations-only.latest.golden b/agent/xds/testdata/endpoints/transparent-proxy-terminating-gateway-destinations-only.latest.golden index 96ee5c7094687..8504dae2b8400 100644 --- a/agent/xds/testdata/endpoints/transparent-proxy-terminating-gateway-destinations-only.latest.golden +++ b/agent/xds/testdata/endpoints/transparent-proxy-terminating-gateway-destinations-only.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/transparent-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/endpoints/transparent-proxy-with-peered-upstreams.latest.golden index 8896b21315a6e..2a4371492ea8f 100644 --- a/agent/xds/testdata/endpoints/transparent-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/endpoints/transparent-proxy-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -49,10 +49,12 @@ "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", "clusterName": "no-endpoints.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", "endpoints": [ - {} + { + + } ] } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/transparent-proxy.latest.golden b/agent/xds/testdata/endpoints/transparent-proxy.latest.golden index ebf0eb91d97e9..fb13b6259b9fd 100644 --- a/agent/xds/testdata/endpoints/transparent-proxy.latest.golden +++ b/agent/xds/testdata/endpoints/transparent-proxy.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", @@ -95,10 +95,12 @@ "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", "clusterName": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "endpoints": [ - {} + { + + } ] } ], "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn/intention-with-path.golden b/agent/xds/testdata/jwt_authn/intention-with-path.golden index 3de3f31ec3995..3a66e2dcf362b 100644 --- a/agent/xds/testdata/jwt_authn/intention-with-path.golden +++ b/agent/xds/testdata/jwt_authn/intention-with-path.golden @@ -7,13 +7,13 @@ "issuer": "test-issuer", "payloadInMetadata": "jwt_payload_okta", "remoteJwks": { - "asyncFetch": { - "fastListener": true - }, "httpUri": { + "uri": "https://example-okta.com/.well-known/jwks.json", "cluster": "jwks_cluster_okta", - "timeout": "1s", - "uri": "https://example-okta.com/.well-known/jwks.json" + "timeout": "1s" + }, + "asyncFetch": { + "fastListener": true } } } @@ -26,12 +26,8 @@ "requires": { "requiresAny": { "requirements": [ - { - "providerName": "okta" - }, - { - "allowMissingOrFailed": {} - } + {"providerName": "okta"}, + {"allowMissingOrFailed": {}} ] } } diff --git a/agent/xds/testdata/jwt_authn/local-provider.golden b/agent/xds/testdata/jwt_authn/local-provider.golden index 5fe99469a53f3..528c0556a94b8 100644 --- a/agent/xds/testdata/jwt_authn/local-provider.golden +++ b/agent/xds/testdata/jwt_authn/local-provider.golden @@ -5,10 +5,10 @@ "providers": { "okta": { "issuer": "test-issuer", + "payloadInMetadata": "jwt_payload_okta", "localJwks": { "inlineString": "{\"keys\": [{\n \"crv\": \"P-256\",\n \"key_ops\": [\n \"verify\"\n ],\n \"kty\": \"EC\",\n \"x\": \"Wc9uZuPaB7Kh2FMc9wtJjRe8XD4yT2AYNAAkrYbVjuw\",\n \"y\": \"68hRTJiJNOwtrh4EoPXeVnRuH7hiSDJ_lmbbjfDfWq0\",\n \"alg\": \"ES256\",\n \"use\": \"sig\",\n \"kid\": \"ac1e8f90eddf61c429c61ca05b4f2e07\"\n}]}" - }, - "payloadInMetadata": "jwt_payload_okta" + } } }, "rules": [ @@ -19,12 +19,8 @@ "requires": { "requiresAny": { "requirements": [ - { - "providerName": "okta" - }, - { - "allowMissingOrFailed": {} - } + {"providerName": "okta"}, + {"allowMissingOrFailed": {}} ] } } diff --git a/agent/xds/testdata/jwt_authn/multiple-providers-and-one-permission.golden b/agent/xds/testdata/jwt_authn/multiple-providers-and-one-permission.golden index ea3f738ae4f33..7c970bde424da 100644 --- a/agent/xds/testdata/jwt_authn/multiple-providers-and-one-permission.golden +++ b/agent/xds/testdata/jwt_authn/multiple-providers-and-one-permission.golden @@ -3,31 +3,31 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication", "providers": { - "auth0": { - "issuer": "another-issuer", - "payloadInMetadata": "jwt_payload_auth0", + "okta": { + "issuer": "test-issuer", + "payloadInMetadata": "jwt_payload_okta", "remoteJwks": { + "httpUri": { + "uri": "https://example-okta.com/.well-known/jwks.json", + "cluster": "jwks_cluster_okta", + "timeout": "1s" + }, "asyncFetch": { "fastListener": true - }, - "httpUri": { - "cluster": "jwks_cluster_auth0", - "timeout": "1s", - "uri": "https://example-auth0.com/.well-known/jwks.json" } } }, - "okta": { - "issuer": "test-issuer", - "payloadInMetadata": "jwt_payload_okta", + "auth0": { + "issuer": "another-issuer", + "payloadInMetadata": "jwt_payload_auth0", "remoteJwks": { + "httpUri": { + "uri": "https://example-auth0.com/.well-known/jwks.json", + "cluster": "jwks_cluster_auth0", + "timeout": "1s" + }, "asyncFetch": { "fastListener": true - }, - "httpUri": { - "cluster": "jwks_cluster_okta", - "timeout": "1s", - "uri": "https://example-okta.com/.well-known/jwks.json" } } } @@ -43,29 +43,22 @@ { "requiresAny": { "requirements": [ - { - "providerName": "okta" - }, - { - "allowMissingOrFailed": {} - } + {"providerName": "okta"}, + {"allowMissingOrFailed": {}} ] } }, { "requiresAny": { "requirements": [ - { - "providerName": "auth0" - }, - { - "allowMissingOrFailed": {} - } + {"providerName": "auth0"}, + {"allowMissingOrFailed": {}} ] } } ] } + } } ] diff --git a/agent/xds/testdata/jwt_authn/remote-provider.golden b/agent/xds/testdata/jwt_authn/remote-provider.golden index 3de3f31ec3995..3a66e2dcf362b 100644 --- a/agent/xds/testdata/jwt_authn/remote-provider.golden +++ b/agent/xds/testdata/jwt_authn/remote-provider.golden @@ -7,13 +7,13 @@ "issuer": "test-issuer", "payloadInMetadata": "jwt_payload_okta", "remoteJwks": { - "asyncFetch": { - "fastListener": true - }, "httpUri": { + "uri": "https://example-okta.com/.well-known/jwks.json", "cluster": "jwks_cluster_okta", - "timeout": "1s", - "uri": "https://example-okta.com/.well-known/jwks.json" + "timeout": "1s" + }, + "asyncFetch": { + "fastListener": true } } } @@ -26,12 +26,8 @@ "requires": { "requiresAny": { "requirements": [ - { - "providerName": "okta" - }, - { - "allowMissingOrFailed": {} - } + {"providerName": "okta"}, + {"allowMissingOrFailed": {}} ] } } diff --git a/agent/xds/testdata/jwt_authn/top-level-provider-with-permission.golden b/agent/xds/testdata/jwt_authn/top-level-provider-with-permission.golden index 3de3f31ec3995..1b0ded7fcb4d8 100644 --- a/agent/xds/testdata/jwt_authn/top-level-provider-with-permission.golden +++ b/agent/xds/testdata/jwt_authn/top-level-provider-with-permission.golden @@ -7,13 +7,13 @@ "issuer": "test-issuer", "payloadInMetadata": "jwt_payload_okta", "remoteJwks": { - "asyncFetch": { - "fastListener": true - }, "httpUri": { + "uri": "https://example-okta.com/.well-known/jwks.json", "cluster": "jwks_cluster_okta", - "timeout": "1s", - "uri": "https://example-okta.com/.well-known/jwks.json" + "timeout": "1s" + }, + "asyncFetch": { + "fastListener": true } } } @@ -26,14 +26,11 @@ "requires": { "requiresAny": { "requirements": [ - { - "providerName": "okta" - }, - { - "allowMissingOrFailed": {} - } + {"providerName": "okta"}, + {"allowMissingOrFailed": {}} ] } + } } ] diff --git a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-and-port.golden b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-and-port.golden index 03124b0b2f683..b151d8accb21e 100644 --- a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-and-port.golden +++ b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-and-port.golden @@ -1,5 +1,4 @@ { - "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", "endpoints": [ @@ -20,5 +19,6 @@ ] }, "name": "jwks_cluster_okta", + "connectTimeout": "5s", "type": "STATIC" } \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-no-port.golden b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-no-port.golden index b6d28c80658ad..10ac676c1dfdf 100644 --- a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-no-port.golden +++ b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-hostname-no-port.golden @@ -1,5 +1,4 @@ { - "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", "endpoints": [ @@ -20,5 +19,6 @@ ] }, "name": "jwks_cluster_okta", + "connectTimeout": "5s", "type": "STATIC" } \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-and-port.golden b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-and-port.golden index 4203107ef0adf..87191735aa61d 100644 --- a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-and-port.golden +++ b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-and-port.golden @@ -1,5 +1,4 @@ { - "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", "endpoints": [ @@ -20,5 +19,6 @@ ] }, "name": "jwks_cluster_okta", + "connectTimeout": "5s", "type": "STATIC" } \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-no-port.golden b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-no-port.golden index eb83b9ebc8b11..c71fded4e94da 100644 --- a/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-no-port.golden +++ b/agent/xds/testdata/jwt_authn_clusters/http-provider-with-ip-no-port.golden @@ -1,5 +1,4 @@ { - "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", "endpoints": [ @@ -20,5 +19,6 @@ ] }, "name": "jwks_cluster_okta", + "connectTimeout": "5s", "type": "STATIC" } \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-and-port.golden b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-and-port.golden index ef4a341f6bfbe..4aa4e9dab4d03 100644 --- a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-and-port.golden +++ b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-and-port.golden @@ -1,5 +1,4 @@ { - "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", "endpoints": [ @@ -23,7 +22,7 @@ "transportSocket": { "name": "tls", "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { "validationContext": { "trustedCa": { @@ -33,5 +32,6 @@ } } }, + "connectTimeout": "5s", "type": "STATIC" } \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-no-port.golden b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-no-port.golden index f75b2c4f1ef2d..57a6abf9d585b 100644 --- a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-no-port.golden +++ b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-hostname-no-port.golden @@ -1,5 +1,4 @@ { - "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", "endpoints": [ @@ -23,7 +22,7 @@ "transportSocket": { "name": "tls", "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { "validationContext": { "trustedCa": { @@ -33,5 +32,6 @@ } } }, + "connectTimeout": "5s", "type": "STATIC" } \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-and-port.golden b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-and-port.golden index c396e70deb183..6688e701fe3d7 100644 --- a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-and-port.golden +++ b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-and-port.golden @@ -1,5 +1,4 @@ { - "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", "endpoints": [ @@ -23,9 +22,9 @@ "transportSocket": { "name": "tls", "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { - "validationContext": { + "validationContext": { "trustedCa": { "filename": "mycert.crt" } @@ -33,5 +32,6 @@ } } }, + "connectTimeout": "5s", "type": "STATIC" } \ No newline at end of file diff --git a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-no-port.golden b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-no-port.golden index cf1a77039b18b..54dc704d6d294 100644 --- a/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-no-port.golden +++ b/agent/xds/testdata/jwt_authn_clusters/https-provider-with-ip-no-port.golden @@ -1,5 +1,4 @@ { - "connectTimeout": "5s", "loadAssignment": { "clusterName": "jwks_cluster_okta", "endpoints": [ @@ -23,7 +22,7 @@ "transportSocket": { "name": "tls", "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "@type":"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", "commonTlsContext": { "validationContext": { "trustedCa": { @@ -33,5 +32,6 @@ } } }, + "connectTimeout": "5s", "type": "STATIC" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/access-logs-defaults.latest.golden b/agent/xds/testdata/listeners/access-logs-defaults.latest.golden index 179cffe4e57f5..6a6bb2b7ed1c9 100644 --- a/agent/xds/testdata/listeners/access-logs-defaults.latest.golden +++ b/agent/xds/testdata/listeners/access-logs-defaults.latest.golden @@ -1,51 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "accessLog": [ - { - "filter": { - "responseFlagFilter": { - "flags": [ - "NR" - ] - } - }, - "name": "Consul Listener Log", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog", - "logFormat": { - "jsonFormat": { - "authority": "%REQ(:AUTHORITY)%", - "bytes_received": "%BYTES_RECEIVED%", - "bytes_sent": "%BYTES_SENT%", - "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", - "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", - "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", - "duration": "%DURATION%", - "method": "%REQ(:METHOD)%", - "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", - "protocol": "%PROTOCOL%", - "request_id": "%REQ(X-REQUEST-ID)%", - "requested_server_name": "%REQUESTED_SERVER_NAME%", - "response_code": "%RESPONSE_CODE%", - "response_code_details": "%RESPONSE_CODE_DETAILS%", - "response_flags": "%RESPONSE_FLAGS%", - "route_name": "%ROUTE_NAME%", - "start_time": "%START_TIME%", - "upstream_cluster": "%UPSTREAM_CLUSTER%", - "upstream_host": "%UPSTREAM_HOST%", - "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", - "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", - "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", - "user_agent": "%REQ(USER-AGENT)%", - "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" - } - } - } - } - ], + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -59,6 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "accessLog": [ { "name": "Consul Listener Filter Log", @@ -66,49 +26,44 @@ "@type": "type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog", "logFormat": { "jsonFormat": { - "authority": "%REQ(:AUTHORITY)%", - "bytes_received": "%BYTES_RECEIVED%", - "bytes_sent": "%BYTES_SENT%", - "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", - "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", - "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", - "duration": "%DURATION%", - "method": "%REQ(:METHOD)%", - "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", - "protocol": "%PROTOCOL%", - "request_id": "%REQ(X-REQUEST-ID)%", - "requested_server_name": "%REQUESTED_SERVER_NAME%", - "response_code": "%RESPONSE_CODE%", - "response_code_details": "%RESPONSE_CODE_DETAILS%", - "response_flags": "%RESPONSE_FLAGS%", - "route_name": "%ROUTE_NAME%", - "start_time": "%START_TIME%", - "upstream_cluster": "%UPSTREAM_CLUSTER%", - "upstream_host": "%UPSTREAM_HOST%", - "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", - "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", - "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", - "user_agent": "%REQ(USER-AGENT)%", - "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" - } + "authority": "%REQ(:AUTHORITY)%", + "bytes_received": "%BYTES_RECEIVED%", + "bytes_sent": "%BYTES_SENT%", + "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", + "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", + "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", + "duration": "%DURATION%", + "method": "%REQ(:METHOD)%", + "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", + "protocol": "%PROTOCOL%", + "request_id": "%REQ(X-REQUEST-ID)%", + "requested_server_name": "%REQUESTED_SERVER_NAME%", + "response_code": "%RESPONSE_CODE%", + "response_code_details": "%RESPONSE_CODE_DETAILS%", + "response_flags": "%RESPONSE_FLAGS%", + "route_name": "%ROUTE_NAME%", + "start_time": "%START_TIME%", + "upstream_cluster": "%UPSTREAM_CLUSTER%", + "upstream_host": "%UPSTREAM_HOST%", + "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", + "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", + "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", + "user_agent": "%REQ(USER-AGENT)%", + "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" + } } } } - ], - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + ] } } ] } ], - "name": "db:127.0.0.1:9191", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "trafficDirection": "OUTBOUND", "accessLog": [ { + "name": "Consul Listener Log", "filter": { "responseFlagFilter": { "flags": [ @@ -116,40 +71,43 @@ ] } }, - "name": "Consul Listener Log", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog", "logFormat": { "jsonFormat": { - "authority": "%REQ(:AUTHORITY)%", - "bytes_received": "%BYTES_RECEIVED%", - "bytes_sent": "%BYTES_SENT%", - "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", - "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", - "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", - "duration": "%DURATION%", - "method": "%REQ(:METHOD)%", - "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", - "protocol": "%PROTOCOL%", - "request_id": "%REQ(X-REQUEST-ID)%", - "requested_server_name": "%REQUESTED_SERVER_NAME%", - "response_code": "%RESPONSE_CODE%", - "response_code_details": "%RESPONSE_CODE_DETAILS%", - "response_flags": "%RESPONSE_FLAGS%", - "route_name": "%ROUTE_NAME%", - "start_time": "%START_TIME%", - "upstream_cluster": "%UPSTREAM_CLUSTER%", - "upstream_host": "%UPSTREAM_HOST%", - "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", - "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", - "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", - "user_agent": "%REQ(USER-AGENT)%", - "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" - } + "authority": "%REQ(:AUTHORITY)%", + "bytes_received": "%BYTES_RECEIVED%", + "bytes_sent": "%BYTES_SENT%", + "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", + "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", + "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", + "duration": "%DURATION%", + "method": "%REQ(:METHOD)%", + "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", + "protocol": "%PROTOCOL%", + "request_id": "%REQ(X-REQUEST-ID)%", + "requested_server_name": "%REQUESTED_SERVER_NAME%", + "response_code": "%RESPONSE_CODE%", + "response_code_details": "%RESPONSE_CODE_DETAILS%", + "response_flags": "%RESPONSE_FLAGS%", + "route_name": "%ROUTE_NAME%", + "start_time": "%START_TIME%", + "upstream_cluster": "%UPSTREAM_CLUSTER%", + "upstream_host": "%UPSTREAM_HOST%", + "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", + "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", + "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", + "user_agent": "%REQ(USER-AGENT)%", + "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" + } } } } - ], + ] + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -163,6 +121,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", "accessLog": [ { "name": "Consul Listener Filter Log", @@ -170,49 +130,44 @@ "@type": "type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog", "logFormat": { "jsonFormat": { - "authority": "%REQ(:AUTHORITY)%", - "bytes_received": "%BYTES_RECEIVED%", - "bytes_sent": "%BYTES_SENT%", - "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", - "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", - "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", - "duration": "%DURATION%", - "method": "%REQ(:METHOD)%", - "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", - "protocol": "%PROTOCOL%", - "request_id": "%REQ(X-REQUEST-ID)%", - "requested_server_name": "%REQUESTED_SERVER_NAME%", - "response_code": "%RESPONSE_CODE%", - "response_code_details": "%RESPONSE_CODE_DETAILS%", - "response_flags": "%RESPONSE_FLAGS%", - "route_name": "%ROUTE_NAME%", - "start_time": "%START_TIME%", - "upstream_cluster": "%UPSTREAM_CLUSTER%", - "upstream_host": "%UPSTREAM_HOST%", - "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", - "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", - "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", - "user_agent": "%REQ(USER-AGENT)%", - "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" - } + "authority": "%REQ(:AUTHORITY)%", + "bytes_received": "%BYTES_RECEIVED%", + "bytes_sent": "%BYTES_SENT%", + "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", + "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", + "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", + "duration": "%DURATION%", + "method": "%REQ(:METHOD)%", + "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", + "protocol": "%PROTOCOL%", + "request_id": "%REQ(X-REQUEST-ID)%", + "requested_server_name": "%REQUESTED_SERVER_NAME%", + "response_code": "%RESPONSE_CODE%", + "response_code_details": "%RESPONSE_CODE_DETAILS%", + "response_flags": "%RESPONSE_FLAGS%", + "route_name": "%ROUTE_NAME%", + "start_time": "%START_TIME%", + "upstream_cluster": "%UPSTREAM_CLUSTER%", + "upstream_host": "%UPSTREAM_HOST%", + "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", + "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", + "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", + "user_agent": "%REQ(USER-AGENT)%", + "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" + } } } } - ], - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + ] } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "trafficDirection": "OUTBOUND", "accessLog": [ { + "name": "Consul Listener Log", "filter": { "responseFlagFilter": { "flags": [ @@ -220,40 +175,43 @@ ] } }, - "name": "Consul Listener Log", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog", "logFormat": { "jsonFormat": { - "authority": "%REQ(:AUTHORITY)%", - "bytes_received": "%BYTES_RECEIVED%", - "bytes_sent": "%BYTES_SENT%", - "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", - "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", - "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", - "duration": "%DURATION%", - "method": "%REQ(:METHOD)%", - "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", - "protocol": "%PROTOCOL%", - "request_id": "%REQ(X-REQUEST-ID)%", - "requested_server_name": "%REQUESTED_SERVER_NAME%", - "response_code": "%RESPONSE_CODE%", - "response_code_details": "%RESPONSE_CODE_DETAILS%", - "response_flags": "%RESPONSE_FLAGS%", - "route_name": "%ROUTE_NAME%", - "start_time": "%START_TIME%", - "upstream_cluster": "%UPSTREAM_CLUSTER%", - "upstream_host": "%UPSTREAM_HOST%", - "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", - "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", - "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", - "user_agent": "%REQ(USER-AGENT)%", - "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" - } + "authority": "%REQ(:AUTHORITY)%", + "bytes_received": "%BYTES_RECEIVED%", + "bytes_sent": "%BYTES_SENT%", + "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", + "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", + "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", + "duration": "%DURATION%", + "method": "%REQ(:METHOD)%", + "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", + "protocol": "%PROTOCOL%", + "request_id": "%REQ(X-REQUEST-ID)%", + "requested_server_name": "%REQUESTED_SERVER_NAME%", + "response_code": "%RESPONSE_CODE%", + "response_code_details": "%RESPONSE_CODE_DETAILS%", + "response_flags": "%RESPONSE_FLAGS%", + "route_name": "%ROUTE_NAME%", + "start_time": "%START_TIME%", + "upstream_cluster": "%UPSTREAM_CLUSTER%", + "upstream_host": "%UPSTREAM_HOST%", + "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", + "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", + "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", + "user_agent": "%REQ(USER-AGENT)%", + "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" + } } } } - ], + ] + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -267,7 +225,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -275,6 +235,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app", "accessLog": [ { "name": "Consul Listener Filter Log", @@ -282,37 +244,35 @@ "@type": "type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog", "logFormat": { "jsonFormat": { - "authority": "%REQ(:AUTHORITY)%", - "bytes_received": "%BYTES_RECEIVED%", - "bytes_sent": "%BYTES_SENT%", - "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", - "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", - "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", - "duration": "%DURATION%", - "method": "%REQ(:METHOD)%", - "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", - "protocol": "%PROTOCOL%", - "request_id": "%REQ(X-REQUEST-ID)%", - "requested_server_name": "%REQUESTED_SERVER_NAME%", - "response_code": "%RESPONSE_CODE%", - "response_code_details": "%RESPONSE_CODE_DETAILS%", - "response_flags": "%RESPONSE_FLAGS%", - "route_name": "%ROUTE_NAME%", - "start_time": "%START_TIME%", - "upstream_cluster": "%UPSTREAM_CLUSTER%", - "upstream_host": "%UPSTREAM_HOST%", - "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", - "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", - "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", - "user_agent": "%REQ(USER-AGENT)%", - "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" - } + "authority": "%REQ(:AUTHORITY)%", + "bytes_received": "%BYTES_RECEIVED%", + "bytes_sent": "%BYTES_SENT%", + "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", + "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", + "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", + "duration": "%DURATION%", + "method": "%REQ(:METHOD)%", + "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", + "protocol": "%PROTOCOL%", + "request_id": "%REQ(X-REQUEST-ID)%", + "requested_server_name": "%REQUESTED_SERVER_NAME%", + "response_code": "%RESPONSE_CODE%", + "response_code_details": "%RESPONSE_CODE_DETAILS%", + "response_flags": "%RESPONSE_FLAGS%", + "route_name": "%ROUTE_NAME%", + "start_time": "%START_TIME%", + "upstream_cluster": "%UPSTREAM_CLUSTER%", + "upstream_host": "%UPSTREAM_HOST%", + "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", + "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", + "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", + "user_agent": "%REQ(USER-AGENT)%", + "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" + } } } } - ], - "cluster": "local_app", - "statPrefix": "public_listener" + ] } } ], @@ -321,6 +281,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -331,7 +294,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -343,10 +305,52 @@ } } ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" + "trafficDirection": "INBOUND", + "accessLog": [ + { + "name": "Consul Listener Log", + "filter": { + "responseFlagFilter": { + "flags": [ + "NR" + ] + } + }, + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog", + "logFormat": { + "jsonFormat": { + "authority": "%REQ(:AUTHORITY)%", + "bytes_received": "%BYTES_RECEIVED%", + "bytes_sent": "%BYTES_SENT%", + "connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%", + "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", + "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", + "duration": "%DURATION%", + "method": "%REQ(:METHOD)%", + "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", + "protocol": "%PROTOCOL%", + "request_id": "%REQ(X-REQUEST-ID)%", + "requested_server_name": "%REQUESTED_SERVER_NAME%", + "response_code": "%RESPONSE_CODE%", + "response_code_details": "%RESPONSE_CODE_DETAILS%", + "response_flags": "%RESPONSE_FLAGS%", + "route_name": "%ROUTE_NAME%", + "start_time": "%START_TIME%", + "upstream_cluster": "%UPSTREAM_CLUSTER%", + "upstream_host": "%UPSTREAM_HOST%", + "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", + "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", + "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", + "user_agent": "%REQ(USER-AGENT)%", + "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%" + } + } + } + } + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/access-logs-json-file.latest.golden b/agent/xds/testdata/listeners/access-logs-json-file.latest.golden index f4979a942cc49..c4cfdd467fff1 100644 --- a/agent/xds/testdata/listeners/access-logs-json-file.latest.golden +++ b/agent/xds/testdata/listeners/access-logs-json-file.latest.golden @@ -1,29 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "accessLog": [ - { - "filter": { - "responseFlagFilter": { - "flags": [ - "NR" - ] - } - }, - "name": "Consul Listener Log", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog", - "logFormat": { - "jsonFormat": { - "custom_start_time": "%START_TIME%" - } - }, - "path": "/tmp/accesslog.txt" - } - } - ], + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -37,34 +17,31 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "accessLog": [ { "name": "Consul Listener Filter Log", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog", + "path": "/tmp/accesslog.txt", "logFormat": { "jsonFormat": { - "custom_start_time": "%START_TIME%" - } - }, - "path": "/tmp/accesslog.txt" + "custom_start_time": "%START_TIME%" + } + } } } - ], - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + ] } } ] } ], - "name": "db:127.0.0.1:9191", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "trafficDirection": "OUTBOUND", "accessLog": [ { + "name": "Consul Listener Log", "filter": { "responseFlagFilter": { "flags": [ @@ -72,18 +49,21 @@ ] } }, - "name": "Consul Listener Log", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog", + "path": "/tmp/accesslog.txt", "logFormat": { "jsonFormat": { - "custom_start_time": "%START_TIME%" - } - }, - "path": "/tmp/accesslog.txt" + "custom_start_time": "%START_TIME%" + } + } } } - ], + ] + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -97,34 +77,31 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", "accessLog": [ { "name": "Consul Listener Filter Log", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog", + "path": "/tmp/accesslog.txt", "logFormat": { "jsonFormat": { - "custom_start_time": "%START_TIME%" - } - }, - "path": "/tmp/accesslog.txt" + "custom_start_time": "%START_TIME%" + } + } } } - ], - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + ] } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "trafficDirection": "OUTBOUND", "accessLog": [ { + "name": "Consul Listener Log", "filter": { "responseFlagFilter": { "flags": [ @@ -132,18 +109,21 @@ ] } }, - "name": "Consul Listener Log", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog", + "path": "/tmp/accesslog.txt", "logFormat": { "jsonFormat": { - "custom_start_time": "%START_TIME%" - } - }, - "path": "/tmp/accesslog.txt" + "custom_start_time": "%START_TIME%" + } + } } } - ], + ] + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -157,7 +137,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -165,22 +147,22 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app", "accessLog": [ { "name": "Consul Listener Filter Log", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog", + "path": "/tmp/accesslog.txt", "logFormat": { "jsonFormat": { - "custom_start_time": "%START_TIME%" - } - }, - "path": "/tmp/accesslog.txt" + "custom_start_time": "%START_TIME%" + } + } } } - ], - "cluster": "local_app", - "statPrefix": "public_listener" + ] } } ], @@ -189,6 +171,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -199,7 +184,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -211,10 +195,30 @@ } } ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" + "trafficDirection": "INBOUND", + "accessLog": [ + { + "name": "Consul Listener Log", + "filter": { + "responseFlagFilter": { + "flags": [ + "NR" + ] + } + }, + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog", + "path": "/tmp/accesslog.txt", + "logFormat": { + "jsonFormat": { + "custom_start_time": "%START_TIME%" + } + } + } + } + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/access-logs-text-stderr-disablelistenerlogs.latest.golden b/agent/xds/testdata/listeners/access-logs-text-stderr-disablelistenerlogs.latest.golden index 24e3dac32f743..2a83b761df50d 100644 --- a/agent/xds/testdata/listeners/access-logs-text-stderr-disablelistenerlogs.latest.golden +++ b/agent/xds/testdata/listeners/access-logs-text-stderr-disablelistenerlogs.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,6 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "accessLog": [ { "name": "Consul Listener Filter Log", @@ -28,19 +31,17 @@ } } } - ], - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + ] } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -54,6 +55,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", "accessLog": [ { "name": "Consul Listener Filter Log", @@ -66,19 +69,17 @@ } } } - ], - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + ] } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -92,7 +93,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -100,6 +103,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app", "accessLog": [ { "name": "Consul Listener Filter Log", @@ -112,9 +117,7 @@ } } } - ], - "cluster": "local_app", - "statPrefix": "public_listener" + ] } } ], @@ -123,6 +126,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -133,7 +139,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -145,10 +150,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-http-listener-with-http-route.latest.golden b/agent/xds/testdata/listeners/api-gateway-http-listener-with-http-route.latest.golden index 6469727f97989..97fe8332eecf1 100644 --- a/agent/xds/testdata/listeners/api-gateway-http-listener-with-http-route.latest.golden +++ b/agent/xds/testdata/listeners/api-gateway-http-listener-with-http-route.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -45,10 +46,9 @@ ] } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-http-listener.latest.golden b/agent/xds/testdata/listeners/api-gateway-http-listener.latest.golden index 97cdec41ef13e..d2d839adf9567 100644 --- a/agent/xds/testdata/listeners/api-gateway-http-listener.latest.golden +++ b/agent/xds/testdata/listeners/api-gateway-http-listener.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-nil-config-entry.latest.golden b/agent/xds/testdata/listeners/api-gateway-nil-config-entry.latest.golden index 97cdec41ef13e..d2d839adf9567 100644 --- a/agent/xds/testdata/listeners/api-gateway-nil-config-entry.latest.golden +++ b/agent/xds/testdata/listeners/api-gateway-nil-config-entry.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden b/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden index e901812ae0026..f754b2636bdc6 100644 --- a/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden +++ b/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-and-http-route.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8081", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8081", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8081" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", "tracing": { "randomSampling": {} }, @@ -45,11 +46,11 @@ ] } ], - "name": "http:1.2.3.4:8081", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "tcp-service:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -63,17 +64,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.tcp-service.default.default.dc1" + "statPrefix": "upstream.tcp-service.default.default.dc1", + "cluster": "tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "tcp-service:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-route.latest.golden b/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-route.latest.golden index 4fe269a90dcb5..ffcb5830b9a4d 100644 --- a/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-route.latest.golden +++ b/agent/xds/testdata/listeners/api-gateway-tcp-listener-with-tcp-route.latest.golden @@ -1,32 +1,32 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8080 + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "tcp-service:1.2.3.4:8080", + "address": { + "socketAddress": { + "address": "1.2.3.4", + "portValue": 8080 } }, - "filterChains": [ + "filterChains": [ { - "filters": [ + "filters": [ { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.tcp-service.default.default.dc1" + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp-service.default.default.dc1", + "cluster": "tcp-service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "tcp-service:1.2.3.4:8080", - "trafficDirection": "OUTBOUND" + "trafficDirection": "OUTBOUND" } ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-tcp-listener.latest.golden b/agent/xds/testdata/listeners/api-gateway-tcp-listener.latest.golden index 97cdec41ef13e..d2d839adf9567 100644 --- a/agent/xds/testdata/listeners/api-gateway-tcp-listener.latest.golden +++ b/agent/xds/testdata/listeners/api-gateway-tcp-listener.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-tcp-listeners.latest.golden b/agent/xds/testdata/listeners/api-gateway-tcp-listeners.latest.golden new file mode 100644 index 0000000000000..d2d839adf9567 --- /dev/null +++ b/agent/xds/testdata/listeners/api-gateway-tcp-listeners.latest.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-with-http-route-and-inline-certificate.latest.golden b/agent/xds/testdata/listeners/api-gateway-with-http-route-and-inline-certificate.latest.golden new file mode 100644 index 0000000000000..97fe8332eecf1 --- /dev/null +++ b/agent/xds/testdata/listeners/api-gateway-with-http-route-and-inline-certificate.latest.golden @@ -0,0 +1,54 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", + "address": { + "socketAddress": { + "address": "1.2.3.4", + "portValue": 8080 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden b/agent/xds/testdata/listeners/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden deleted file mode 100644 index dbb15d8751eaf..0000000000000 --- a/agent/xds/testdata/listeners/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden +++ /dev/null @@ -1,85 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8080 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_certificate", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICljCCAX4CCQCQMDsYO8FrPjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJV\nUzAeFw0yMjEyMjAxNzUwMjVaFw0yNzEyMTkxNzUwMjVaMA0xCzAJBgNVBAYTAlVT\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx95Opa6t4lGEpiTUogEB\nptqOdam2ch4BHQGhNhX/MrDwwuZQhttBwMfngQ/wd9NmYEPAwj0dumUoAITIq6i2\njQlhqTodElkbsd5vWY8R/bxJWQSoNvVE12TlzECxGpJEiHt4W0r8pGffk+rvplji\nUyCfnT1kGF3znOSjK1hRMTn6RKWCyYaBvXQiB4SGilfLgJcEpOJKtISIxmZ+S409\ng9X5VU88/Bmmrz4cMyxce86Kc2ug5/MOv0CjWDJwlrv8njneV2zvraQ61DDwQftr\nXOvuCbO5IBRHMOBHiHTZ4rtGuhMaIr21V4vb6n8c4YzXiFvhUYcyX7rltGZzVd+W\nmQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBfCqoUIdPf/HGSbOorPyZWbyizNtHJ\nGL7x9cAeIYxpI5Y/WcO1o5v94lvrgm3FNfJoGKbV66+JxOge731FrfMpHplhar1Z\nRahYIzNLRBTLrwadLAZkApUpZvB8qDK4knsTWFYujNsylCww2A6ajzIMFNU4GkUK\nNtyHRuD+KYRmjXtyX1yHNqfGN3vOQmwavHq2R8wHYuBSc6LAHHV9vG+j0VsgMELO\nqwxn8SmLkSKbf2+MsQVzLCXXN5u+D8Yv+4py+oKP4EQ5aFZuDEx+r/G/31rTthww\nAAJAMaoXmoYVdgXV+CPuBb2M4XCpuzLu3bcA2PXm5ipSyIgntMKwXV7r\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAx95Opa6t4lGEpiTUogEBptqOdam2ch4BHQGhNhX/MrDwwuZQ\nhttBwMfngQ/wd9NmYEPAwj0dumUoAITIq6i2jQlhqTodElkbsd5vWY8R/bxJWQSo\nNvVE12TlzECxGpJEiHt4W0r8pGffk+rvpljiUyCfnT1kGF3znOSjK1hRMTn6RKWC\nyYaBvXQiB4SGilfLgJcEpOJKtISIxmZ+S409g9X5VU88/Bmmrz4cMyxce86Kc2ug\n5/MOv0CjWDJwlrv8njneV2zvraQ61DDwQftrXOvuCbO5IBRHMOBHiHTZ4rtGuhMa\nIr21V4vb6n8c4YzXiFvhUYcyX7rltGZzVd+WmQIDAQABAoIBACYvceUzp2MK4gYA\nGWPOP2uKbBdM0l+hHeNV0WAM+dHMfmMuL4pkT36ucqt0ySOLjw6rQyOZG5nmA6t9\nsv0g4ae2eCMlyDIeNi1Yavu4Wt6YX4cTXbQKThm83C6W2X9THKbauBbxD621bsDK\n7PhiGPN60yPue7YwFQAPqqD4YaK+s22HFIzk9gwM/rkvAUNwRv7SyHMiFe4Igc1C\nEev7iHWzvj5Heoz6XfF+XNF9DU+TieSUAdjd56VyUb8XL4+uBTOhHwLiXvAmfaMR\nHvpcxeKnYZusS6NaOxcUHiJnsLNWrxmJj9WEGgQzuLxcLjTe4vVmELVZD8t3QUKj\nPAxu8tUCgYEA7KIWVn9dfVpokReorFym+J8FzLwSktP9RZYEMonJo00i8aii3K9s\nu/aSwRWQSCzmON1ZcxZzWhwQF9usz6kGCk//9+4hlVW90GtNK0RD+j7sp4aT2JI8\n9eLEjTG+xSXa7XWe98QncjjL9lu/yrRncSTxHs13q/XP198nn2aYuQ8CgYEA2Dnt\nsRBzv0fFEvzzFv7G/5f85mouN38TUYvxNRTjBLCXl9DeKjDkOVZ2b6qlfQnYXIru\nH+W+v+AZEb6fySXc8FRab7lkgTMrwE+aeI4rkW7asVwtclv01QJ5wMnyT84AgDD/\nDgt/RThFaHgtU9TW5GOZveL+l9fVPn7vKFdTJdcCgYEArJ99zjHxwJ1whNAOk1av\n09UmRPm6TvRo4heTDk8oEoIWCNatoHI0z1YMLuENNSnT9Q280FFDayvnrY/qnD7A\nkktT/sjwJOG8q8trKzIMqQS4XWm2dxoPcIyyOBJfCbEY6XuRsUuePxwh5qF942EB\nyS9a2s6nC4Ix0lgPrqAIr48CgYBgS/Q6riwOXSU8nqCYdiEkBYlhCJrKpnJxF9T1\nofa0yPzKZP/8ZEfP7VzTwHjxJehQ1qLUW9pG08P2biH1UEKEWdzo8vT6wVJT1F/k\nHtTycR8+a+Hlk2SHVRHqNUYQGpuIe8mrdJ1as4Pd0d/F/P0zO9Rlh+mAsGPM8HUM\nT0+9gwKBgHDoerX7NTskg0H0t8O+iSMevdxpEWp34ZYa9gHiftTQGyrRgERCa7Gj\nnZPAxKb2JoWyfnu3v7G5gZ8fhDFsiOxLbZv6UZJBbUIh1MjJISpXrForDrC2QNLX\nkHrHfwBFDB3KMudhQknsJzEJKCL/KmFH6o0MvsoaT9yzEl3K+ah/\n-----END RSA PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {} - }, - "requireClientCertificate": false - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "name": "http:1.2.3.4:8080", - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-with-http-route.latest.golden b/agent/xds/testdata/listeners/api-gateway-with-http-route.latest.golden deleted file mode 100644 index dbb15d8751eaf..0000000000000 --- a/agent/xds/testdata/listeners/api-gateway-with-http-route.latest.golden +++ /dev/null @@ -1,85 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8080 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_certificate", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICljCCAX4CCQCQMDsYO8FrPjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJV\nUzAeFw0yMjEyMjAxNzUwMjVaFw0yNzEyMTkxNzUwMjVaMA0xCzAJBgNVBAYTAlVT\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx95Opa6t4lGEpiTUogEB\nptqOdam2ch4BHQGhNhX/MrDwwuZQhttBwMfngQ/wd9NmYEPAwj0dumUoAITIq6i2\njQlhqTodElkbsd5vWY8R/bxJWQSoNvVE12TlzECxGpJEiHt4W0r8pGffk+rvplji\nUyCfnT1kGF3znOSjK1hRMTn6RKWCyYaBvXQiB4SGilfLgJcEpOJKtISIxmZ+S409\ng9X5VU88/Bmmrz4cMyxce86Kc2ug5/MOv0CjWDJwlrv8njneV2zvraQ61DDwQftr\nXOvuCbO5IBRHMOBHiHTZ4rtGuhMaIr21V4vb6n8c4YzXiFvhUYcyX7rltGZzVd+W\nmQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBfCqoUIdPf/HGSbOorPyZWbyizNtHJ\nGL7x9cAeIYxpI5Y/WcO1o5v94lvrgm3FNfJoGKbV66+JxOge731FrfMpHplhar1Z\nRahYIzNLRBTLrwadLAZkApUpZvB8qDK4knsTWFYujNsylCww2A6ajzIMFNU4GkUK\nNtyHRuD+KYRmjXtyX1yHNqfGN3vOQmwavHq2R8wHYuBSc6LAHHV9vG+j0VsgMELO\nqwxn8SmLkSKbf2+MsQVzLCXXN5u+D8Yv+4py+oKP4EQ5aFZuDEx+r/G/31rTthww\nAAJAMaoXmoYVdgXV+CPuBb2M4XCpuzLu3bcA2PXm5ipSyIgntMKwXV7r\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAx95Opa6t4lGEpiTUogEBptqOdam2ch4BHQGhNhX/MrDwwuZQ\nhttBwMfngQ/wd9NmYEPAwj0dumUoAITIq6i2jQlhqTodElkbsd5vWY8R/bxJWQSo\nNvVE12TlzECxGpJEiHt4W0r8pGffk+rvpljiUyCfnT1kGF3znOSjK1hRMTn6RKWC\nyYaBvXQiB4SGilfLgJcEpOJKtISIxmZ+S409g9X5VU88/Bmmrz4cMyxce86Kc2ug\n5/MOv0CjWDJwlrv8njneV2zvraQ61DDwQftrXOvuCbO5IBRHMOBHiHTZ4rtGuhMa\nIr21V4vb6n8c4YzXiFvhUYcyX7rltGZzVd+WmQIDAQABAoIBACYvceUzp2MK4gYA\nGWPOP2uKbBdM0l+hHeNV0WAM+dHMfmMuL4pkT36ucqt0ySOLjw6rQyOZG5nmA6t9\nsv0g4ae2eCMlyDIeNi1Yavu4Wt6YX4cTXbQKThm83C6W2X9THKbauBbxD621bsDK\n7PhiGPN60yPue7YwFQAPqqD4YaK+s22HFIzk9gwM/rkvAUNwRv7SyHMiFe4Igc1C\nEev7iHWzvj5Heoz6XfF+XNF9DU+TieSUAdjd56VyUb8XL4+uBTOhHwLiXvAmfaMR\nHvpcxeKnYZusS6NaOxcUHiJnsLNWrxmJj9WEGgQzuLxcLjTe4vVmELVZD8t3QUKj\nPAxu8tUCgYEA7KIWVn9dfVpokReorFym+J8FzLwSktP9RZYEMonJo00i8aii3K9s\nu/aSwRWQSCzmON1ZcxZzWhwQF9usz6kGCk//9+4hlVW90GtNK0RD+j7sp4aT2JI8\n9eLEjTG+xSXa7XWe98QncjjL9lu/yrRncSTxHs13q/XP198nn2aYuQ8CgYEA2Dnt\nsRBzv0fFEvzzFv7G/5f85mouN38TUYvxNRTjBLCXl9DeKjDkOVZ2b6qlfQnYXIru\nH+W+v+AZEb6fySXc8FRab7lkgTMrwE+aeI4rkW7asVwtclv01QJ5wMnyT84AgDD/\nDgt/RThFaHgtU9TW5GOZveL+l9fVPn7vKFdTJdcCgYEArJ99zjHxwJ1whNAOk1av\n09UmRPm6TvRo4heTDk8oEoIWCNatoHI0z1YMLuENNSnT9Q280FFDayvnrY/qnD7A\nkktT/sjwJOG8q8trKzIMqQS4XWm2dxoPcIyyOBJfCbEY6XuRsUuePxwh5qF942EB\nyS9a2s6nC4Ix0lgPrqAIr48CgYBgS/Q6riwOXSU8nqCYdiEkBYlhCJrKpnJxF9T1\nofa0yPzKZP/8ZEfP7VzTwHjxJehQ1qLUW9pG08P2biH1UEKEWdzo8vT6wVJT1F/k\nHtTycR8+a+Hlk2SHVRHqNUYQGpuIe8mrdJ1as4Pd0d/F/P0zO9Rlh+mAsGPM8HUM\nT0+9gwKBgHDoerX7NTskg0H0t8O+iSMevdxpEWp34ZYa9gHiftTQGyrRgERCa7Gj\nnZPAxKb2JoWyfnu3v7G5gZ8fhDFsiOxLbZv6UZJBbUIh1MjJISpXrForDrC2QNLX\nkHrHfwBFDB3KMudhQknsJzEJKCL/KmFH6o0MvsoaT9yzEl3K+ah/\n-----END RSA PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {} - }, - "requireClientCertificate": false - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "name": "http:1.2.3.4:8080", - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-with-multiple-inline-certificates.latest.golden b/agent/xds/testdata/listeners/api-gateway-with-multiple-inline-certificates.latest.golden deleted file mode 100644 index 4cd71ba606b0e..0000000000000 --- a/agent/xds/testdata/listeners/api-gateway-with-multiple-inline-certificates.latest.golden +++ /dev/null @@ -1,102 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8080 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "serverNames": [ - "" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "ingress_upstream_certificate" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICljCCAX4CCQCQMDsYO8FrPjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJV\nUzAeFw0yMjEyMjAxNzUwMjVaFw0yNzEyMTkxNzUwMjVaMA0xCzAJBgNVBAYTAlVT\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx95Opa6t4lGEpiTUogEB\nptqOdam2ch4BHQGhNhX/MrDwwuZQhttBwMfngQ/wd9NmYEPAwj0dumUoAITIq6i2\njQlhqTodElkbsd5vWY8R/bxJWQSoNvVE12TlzECxGpJEiHt4W0r8pGffk+rvplji\nUyCfnT1kGF3znOSjK1hRMTn6RKWCyYaBvXQiB4SGilfLgJcEpOJKtISIxmZ+S409\ng9X5VU88/Bmmrz4cMyxce86Kc2ug5/MOv0CjWDJwlrv8njneV2zvraQ61DDwQftr\nXOvuCbO5IBRHMOBHiHTZ4rtGuhMaIr21V4vb6n8c4YzXiFvhUYcyX7rltGZzVd+W\nmQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBfCqoUIdPf/HGSbOorPyZWbyizNtHJ\nGL7x9cAeIYxpI5Y/WcO1o5v94lvrgm3FNfJoGKbV66+JxOge731FrfMpHplhar1Z\nRahYIzNLRBTLrwadLAZkApUpZvB8qDK4knsTWFYujNsylCww2A6ajzIMFNU4GkUK\nNtyHRuD+KYRmjXtyX1yHNqfGN3vOQmwavHq2R8wHYuBSc6LAHHV9vG+j0VsgMELO\nqwxn8SmLkSKbf2+MsQVzLCXXN5u+D8Yv+4py+oKP4EQ5aFZuDEx+r/G/31rTthww\nAAJAMaoXmoYVdgXV+CPuBb2M4XCpuzLu3bcA2PXm5ipSyIgntMKwXV7r\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAx95Opa6t4lGEpiTUogEBptqOdam2ch4BHQGhNhX/MrDwwuZQ\nhttBwMfngQ/wd9NmYEPAwj0dumUoAITIq6i2jQlhqTodElkbsd5vWY8R/bxJWQSo\nNvVE12TlzECxGpJEiHt4W0r8pGffk+rvpljiUyCfnT1kGF3znOSjK1hRMTn6RKWC\nyYaBvXQiB4SGilfLgJcEpOJKtISIxmZ+S409g9X5VU88/Bmmrz4cMyxce86Kc2ug\n5/MOv0CjWDJwlrv8njneV2zvraQ61DDwQftrXOvuCbO5IBRHMOBHiHTZ4rtGuhMa\nIr21V4vb6n8c4YzXiFvhUYcyX7rltGZzVd+WmQIDAQABAoIBACYvceUzp2MK4gYA\nGWPOP2uKbBdM0l+hHeNV0WAM+dHMfmMuL4pkT36ucqt0ySOLjw6rQyOZG5nmA6t9\nsv0g4ae2eCMlyDIeNi1Yavu4Wt6YX4cTXbQKThm83C6W2X9THKbauBbxD621bsDK\n7PhiGPN60yPue7YwFQAPqqD4YaK+s22HFIzk9gwM/rkvAUNwRv7SyHMiFe4Igc1C\nEev7iHWzvj5Heoz6XfF+XNF9DU+TieSUAdjd56VyUb8XL4+uBTOhHwLiXvAmfaMR\nHvpcxeKnYZusS6NaOxcUHiJnsLNWrxmJj9WEGgQzuLxcLjTe4vVmELVZD8t3QUKj\nPAxu8tUCgYEA7KIWVn9dfVpokReorFym+J8FzLwSktP9RZYEMonJo00i8aii3K9s\nu/aSwRWQSCzmON1ZcxZzWhwQF9usz6kGCk//9+4hlVW90GtNK0RD+j7sp4aT2JI8\n9eLEjTG+xSXa7XWe98QncjjL9lu/yrRncSTxHs13q/XP198nn2aYuQ8CgYEA2Dnt\nsRBzv0fFEvzzFv7G/5f85mouN38TUYvxNRTjBLCXl9DeKjDkOVZ2b6qlfQnYXIru\nH+W+v+AZEb6fySXc8FRab7lkgTMrwE+aeI4rkW7asVwtclv01QJ5wMnyT84AgDD/\nDgt/RThFaHgtU9TW5GOZveL+l9fVPn7vKFdTJdcCgYEArJ99zjHxwJ1whNAOk1av\n09UmRPm6TvRo4heTDk8oEoIWCNatoHI0z1YMLuENNSnT9Q280FFDayvnrY/qnD7A\nkktT/sjwJOG8q8trKzIMqQS4XWm2dxoPcIyyOBJfCbEY6XuRsUuePxwh5qF942EB\nyS9a2s6nC4Ix0lgPrqAIr48CgYBgS/Q6riwOXSU8nqCYdiEkBYlhCJrKpnJxF9T1\nofa0yPzKZP/8ZEfP7VzTwHjxJehQ1qLUW9pG08P2biH1UEKEWdzo8vT6wVJT1F/k\nHtTycR8+a+Hlk2SHVRHqNUYQGpuIe8mrdJ1as4Pd0d/F/P0zO9Rlh+mAsGPM8HUM\nT0+9gwKBgHDoerX7NTskg0H0t8O+iSMevdxpEWp34ZYa9gHiftTQGyrRgERCa7Gj\nnZPAxKb2JoWyfnu3v7G5gZ8fhDFsiOxLbZv6UZJBbUIh1MjJISpXrForDrC2QNLX\nkHrHfwBFDB3KMudhQknsJzEJKCL/KmFH6o0MvsoaT9yzEl3K+ah/\n-----END RSA PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {} - }, - "requireClientCertificate": false - } - } - }, - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "ingress_upstream_default" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": false - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "name": "service:1.2.3.4:8080", - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway-with-tcp-route-and-inline-certificate.latest.golden b/agent/xds/testdata/listeners/api-gateway-with-tcp-route-and-inline-certificate.latest.golden index a13881b7e525d..0287ebcc4a17f 100644 --- a/agent/xds/testdata/listeners/api-gateway-with-tcp-route-and-inline-certificate.latest.golden +++ b/agent/xds/testdata/listeners/api-gateway-with-tcp-route-and-inline-certificate.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "service:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,8 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "ingress_upstream_certificate" + "statPrefix": "ingress_upstream_certificate", + "cluster": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -26,6 +27,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -35,8 +37,7 @@ "inlineString": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAx95Opa6t4lGEpiTUogEBptqOdam2ch4BHQGhNhX/MrDwwuZQ\nhttBwMfngQ/wd9NmYEPAwj0dumUoAITIq6i2jQlhqTodElkbsd5vWY8R/bxJWQSo\nNvVE12TlzECxGpJEiHt4W0r8pGffk+rvpljiUyCfnT1kGF3znOSjK1hRMTn6RKWC\nyYaBvXQiB4SGilfLgJcEpOJKtISIxmZ+S409g9X5VU88/Bmmrz4cMyxce86Kc2ug\n5/MOv0CjWDJwlrv8njneV2zvraQ61DDwQftrXOvuCbO5IBRHMOBHiHTZ4rtGuhMa\nIr21V4vb6n8c4YzXiFvhUYcyX7rltGZzVd+WmQIDAQABAoIBACYvceUzp2MK4gYA\nGWPOP2uKbBdM0l+hHeNV0WAM+dHMfmMuL4pkT36ucqt0ySOLjw6rQyOZG5nmA6t9\nsv0g4ae2eCMlyDIeNi1Yavu4Wt6YX4cTXbQKThm83C6W2X9THKbauBbxD621bsDK\n7PhiGPN60yPue7YwFQAPqqD4YaK+s22HFIzk9gwM/rkvAUNwRv7SyHMiFe4Igc1C\nEev7iHWzvj5Heoz6XfF+XNF9DU+TieSUAdjd56VyUb8XL4+uBTOhHwLiXvAmfaMR\nHvpcxeKnYZusS6NaOxcUHiJnsLNWrxmJj9WEGgQzuLxcLjTe4vVmELVZD8t3QUKj\nPAxu8tUCgYEA7KIWVn9dfVpokReorFym+J8FzLwSktP9RZYEMonJo00i8aii3K9s\nu/aSwRWQSCzmON1ZcxZzWhwQF9usz6kGCk//9+4hlVW90GtNK0RD+j7sp4aT2JI8\n9eLEjTG+xSXa7XWe98QncjjL9lu/yrRncSTxHs13q/XP198nn2aYuQ8CgYEA2Dnt\nsRBzv0fFEvzzFv7G/5f85mouN38TUYvxNRTjBLCXl9DeKjDkOVZ2b6qlfQnYXIru\nH+W+v+AZEb6fySXc8FRab7lkgTMrwE+aeI4rkW7asVwtclv01QJ5wMnyT84AgDD/\nDgt/RThFaHgtU9TW5GOZveL+l9fVPn7vKFdTJdcCgYEArJ99zjHxwJ1whNAOk1av\n09UmRPm6TvRo4heTDk8oEoIWCNatoHI0z1YMLuENNSnT9Q280FFDayvnrY/qnD7A\nkktT/sjwJOG8q8trKzIMqQS4XWm2dxoPcIyyOBJfCbEY6XuRsUuePxwh5qF942EB\nyS9a2s6nC4Ix0lgPrqAIr48CgYBgS/Q6riwOXSU8nqCYdiEkBYlhCJrKpnJxF9T1\nofa0yPzKZP/8ZEfP7VzTwHjxJehQ1qLUW9pG08P2biH1UEKEWdzo8vT6wVJT1F/k\nHtTycR8+a+Hlk2SHVRHqNUYQGpuIe8mrdJ1as4Pd0d/F/P0zO9Rlh+mAsGPM8HUM\nT0+9gwKBgHDoerX7NTskg0H0t8O+iSMevdxpEWp34ZYa9gHiftTQGyrRgERCa7Gj\nnZPAxKb2JoWyfnu3v7G5gZ8fhDFsiOxLbZv6UZJBbUIh1MjJISpXrForDrC2QNLX\nkHrHfwBFDB3KMudhQknsJzEJKCL/KmFH6o0MvsoaT9yzEl3K+ah/\n-----END RSA PRIVATE KEY-----\n" } } - ], - "tlsParams": {} + ] }, "requireClientCertificate": false } @@ -51,10 +52,9 @@ } } ], - "name": "service:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/api-gateway.latest.golden b/agent/xds/testdata/listeners/api-gateway.latest.golden index 97cdec41ef13e..d2d839adf9567 100644 --- a/agent/xds/testdata/listeners/api-gateway.latest.golden +++ b/agent/xds/testdata/listeners/api-gateway.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-exported-to-peers.latest.golden b/agent/xds/testdata/listeners/connect-proxy-exported-to-peers.latest.golden index 87c86078e7a4f..c61cb12d7139f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-exported-to-peers.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-exported-to-peers.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -16,7 +17,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -24,8 +27,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -34,6 +37,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,7 +50,6 @@ } } ], - "tlsParams": {}, "validationContext": { "customValidatorConfig": { "name": "envoy.tls.cert_validator.spiffe", @@ -79,10 +84,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-upstream-defaults.latest.golden b/agent/xds/testdata/listeners/connect-proxy-upstream-defaults.latest.golden index 0254a224d513b..57d50f71c367f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-upstream-defaults.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-upstream-defaults.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden index 0254a224d513b..5fdd2e351c0e1 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden @@ -1,115 +1,115 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9191 + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 } }, - "filterChains": [ + "filterChains": [ { - "filters": [ + "filters": [ { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", - "trafficDirection": "OUTBOUND" + "trafficDirection": "OUTBOUND" }, { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.10.10.10", - "portValue": 8181 + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", + "address": { + "socketAddress": { + "address": "127.10.10.10", + "portValue": 8181 } }, - "filterChains": [ + "filterChains": [ { - "filters": [ + "filters": [ { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "trafficDirection": "OUTBOUND" + "trafficDirection": "OUTBOUND" }, { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "0.0.0.0", - "portValue": 9999 + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", + "address": { + "socketAddress": { + "address": "0.0.0.0", + "portValue": 9999 } }, - "filterChains": [ + "filterChains": [ { - "filters": [ + "filters": [ { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" + "name": "envoy.filters.network.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", + "rules": {}, + "statPrefix": "connect_authz" } }, { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app" } } ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } } }, - "requireClientCertificate": true + "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" + "trafficDirection": "INBOUND" } ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-chain-and-overrides.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-overrides.latest.golden index bdfe7aa7bd6fa..03e15abeaa728 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-chain-and-overrides.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-overrides.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,7 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "upstream.db.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "db" + }, "httpFilters": [ { "name": "envoy.filters.http.grpc_stats", @@ -38,17 +46,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "db" - }, - "statPrefix": "upstream.db.default.default.dc1", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -59,11 +60,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -77,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -110,8 +111,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -120,6 +121,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -130,7 +132,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -142,10 +143,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden index 7763739e9b6fc..02d749a2c5c25 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden @@ -1,115 +1,115 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9191 + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9191 } }, - "filterChains": [ + "filterChains": [ { - "filters": [ + "filters": [ { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.cluster-01.external.peer1.domain", - "statPrefix": "upstream.db.default.default.dc1" + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.cluster-01.external.peer1.domain" } } ] } ], - "name": "db:127.0.0.1:9191", - "trafficDirection": "OUTBOUND" + "trafficDirection": "OUTBOUND" }, { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.10.10.10", - "portValue": 8181 + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", + "address": { + "socketAddress": { + "address": "127.10.10.10", + "portValue": 8181 } }, - "filterChains": [ + "filterChains": [ { - "filters": [ + "filters": [ { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "trafficDirection": "OUTBOUND" + "trafficDirection": "OUTBOUND" }, { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "0.0.0.0", - "portValue": 9999 + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", + "address": { + "socketAddress": { + "address": "0.0.0.0", + "portValue": 9999 } }, - "filterChains": [ + "filterChains": [ { - "filters": [ + "filters": [ { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" + "name": "envoy.filters.network.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", + "rules": {}, + "statPrefix": "connect_authz" } }, { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app" } } ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" + "validationContext": { + "trustedCa": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } } }, - "requireClientCertificate": true + "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" + "trafficDirection": "INBOUND" } ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-chain-external-sni.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-chain-external-sni.latest.golden index 0254a224d513b..57d50f71c367f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-chain-external-sni.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-grpc-chain.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-grpc-chain.latest.golden index bdfe7aa7bd6fa..03e15abeaa728 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-grpc-chain.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-grpc-chain.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,7 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "upstream.db.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "db" + }, "httpFilters": [ { "name": "envoy.filters.http.grpc_stats", @@ -38,17 +46,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "db" - }, - "statPrefix": "upstream.db.default.default.dc1", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -59,11 +60,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -77,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -110,8 +111,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -120,6 +121,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -130,7 +132,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -142,10 +143,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-http-chain.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-http-chain.latest.golden index 96c6814291eb7..7f85cbeb72575 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-http-chain.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-http-chain.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.db.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "db" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "db" - }, - "statPrefix": "upstream.db.default.default.dc1", "tracing": { "randomSampling": {} }, @@ -45,11 +46,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -63,18 +64,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -96,8 +97,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -106,6 +107,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -116,7 +118,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -128,10 +129,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-http2-chain.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-http2-chain.latest.golden index e4e738f7751f3..98b090c7839b5 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-http2-chain.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-http2-chain.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,7 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "upstream.db.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "db" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -25,17 +33,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "db" - }, - "statPrefix": "upstream.db.default.default.dc1", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -46,11 +47,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -64,18 +65,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -97,8 +98,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -107,6 +108,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -117,7 +119,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -129,10 +130,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-jwt-config-entry-with-local.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-jwt-config-entry-with-local.latest.golden index e543143959774..44ac849aa4cb8 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-jwt-config-entry-with-local.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-jwt-config-entry-with-local.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.jwt_authn", @@ -74,15 +96,15 @@ "@type": "type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication", "providers": { "okta": { - "fromCookies": [ + "localJwks": { + "inlineString": "hello world\n" + }, + "fromParams": [ "token" ], - "fromParams": [ + "fromCookies": [ "token" ], - "localJwks": { - "inlineString": "hello world\n" - }, "payloadInMetadata": "jwt_payload_okta" } }, @@ -122,8 +144,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -136,8 +158,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -150,8 +172,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -164,8 +186,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -178,8 +200,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -199,38 +221,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -244,9 +245,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -257,22 +256,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden deleted file mode 100644 index 84090d6834380..0000000000000 --- a/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden +++ /dev/null @@ -1,114 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "11.11.11.11", - "portValue": 11111 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "random-cluster", - "statPrefix": "foo-stats" - } - } - ] - } - ], - "name": "payments?peer=cloud:custom-upstream" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "0.0.0.0", - "portValue": 9999 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "statPrefix": "upstream_peered.refunds.default.cloud" - } - } - ] - } - ], - "name": "refunds?peer=cloud:127.0.0.1:9090", - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams-http2.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams-http2.latest.golden deleted file mode 100644 index 1454379bec488..0000000000000 --- a/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams-http2.latest.golden +++ /dev/null @@ -1,189 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "routeConfig": { - "name": "payments?peer=cloud", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "payments.default.cloud", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" - } - } - ] - } - ] - }, - "statPrefix": "upstream_peered.payments.default.cloud", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "name": "payments?peer=cloud:127.0.0.1:9090", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "0.0.0.0", - "portValue": 9999 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "routeConfig": { - "name": "refunds?peer=cloud", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "refunds.default.cloud", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" - } - } - ] - } - ] - }, - "statPrefix": "upstream_peered.refunds.default.cloud", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "name": "refunds?peer=cloud:127.0.0.1:9090", - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams.latest.golden index bb4e12a9a6058..d062f6dd5199f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-peered-upstreams.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "payments?peer=cloud:127.0.0.1:9090", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "statPrefix": "upstream_peered.payments.default.cloud" + "statPrefix": "upstream_peered.payments.default.cloud", + "cluster": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } } ] } ], - "name": "payments?peer=cloud:127.0.0.1:9090", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -41,7 +42,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -49,8 +52,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -59,6 +62,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -69,7 +75,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -81,11 +86,11 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "refunds?peer=cloud:127.0.0.1:9090", "address": { "socketAddress": { "address": "127.0.0.1", @@ -99,17 +104,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "statPrefix": "upstream_peered.refunds.default.cloud" + "statPrefix": "upstream_peered.refunds.default.cloud", + "cluster": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } } ] } ], - "name": "refunds?peer=cloud:127.0.0.1:9090", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden index 0254a224d513b..57d50f71c367f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain-failover-through-local-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden index 0254a224d513b..57d50f71c367f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain-failover-through-remote-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain.latest.golden index 0254a224d513b..57d50f71c367f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-tcp-chain.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-cipher-suites.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-cipher-suites.latest.golden index 356a860c79202..05ed17d4e2df4 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-cipher-suites.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-cipher-suites.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,12 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -94,12 +103,6 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -111,10 +114,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-max-version.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-max-version.latest.golden index 14f03de9b90f3..8f157291cddbe 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-max-version.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-max-version.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -94,9 +100,6 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -108,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-min-version.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-min-version.latest.golden index 781d64acee504..1081c4431cb2f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-min-version.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-tls-incoming-min-version.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -94,9 +100,6 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -108,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-tls-outgoing-min-version-auto.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-tls-outgoing-min-version-auto.latest.golden index 0254a224d513b..57d50f71c367f 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-tls-outgoing-min-version-auto.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-tls-outgoing-min-version-auto.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-tproxy-and-permissive-mtls.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-tproxy-and-permissive-mtls.latest.golden index 93df4d5ac7ecd..549af29cb4456 100644 --- a/agent/xds/testdata/listeners/connect-proxy-with-tproxy-and-permissive-mtls.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-with-tproxy-and-permissive-mtls.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,22 +17,22 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", - "portValue": 1234 + "portValue": 15001 } }, "defaultFilterChain": { @@ -40,8 +41,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "original-destination", - "statPrefix": "upstream.original-destination" + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" } } ] @@ -54,11 +55,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:1234", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -72,18 +73,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -105,8 +106,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -115,6 +116,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -125,7 +127,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -145,8 +146,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "permissive_public_listener" + "statPrefix": "permissive_public_listener", + "cluster": "local_app" } } ] @@ -160,10 +161,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/listeners/connect-proxy-without-tproxy-and-permissive-mtls.latest.golden b/agent/xds/testdata/listeners/connect-proxy-without-tproxy-and-permissive-mtls.latest.golden index 0254a224d513b..b15ccf4a148a5 100644 --- a/agent/xds/testdata/listeners/connect-proxy-without-tproxy-and-permissive-mtls.latest.golden +++ b/agent/xds/testdata/listeners/connect-proxy-without-tproxy-and-permissive-mtls.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -74,8 +75,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +85,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +96,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +107,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file + "nonce": "00000001" +} diff --git a/agent/xds/testdata/listeners/custom-public-listener-http-2.latest.golden b/agent/xds/testdata/listeners/custom-public-listener-http-2.latest.golden index 6ac91607b8af2..4a44d3f6f1f42 100644 --- a/agent/xds/testdata/listeners/custom-public-listener-http-2.latest.golden +++ b/agent/xds/testdata/listeners/custom-public-listener-http-2.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "custom-public-listen", "address": { "socketAddress": { "address": "11.11.11.11", @@ -16,26 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router" - } - ], "routeConfig": { "name": "public_listener", "virtualHosts": [ { + "name": "public_listener", "domains": [ "*" ], - "name": "public_listener", "routes": [ { "match": { @@ -48,7 +37,21 @@ ] } ] - } + }, + "httpFilters": [ + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": { + + } + } + }, + { + "name": "envoy.filters.http.router" + } + ] } } ], @@ -57,9 +60,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -70,22 +73,24 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } - ], - "name": "custom-public-listen" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -99,18 +104,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -124,17 +129,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/custom-public-listener-http-missing.latest.golden b/agent/xds/testdata/listeners/custom-public-listener-http-missing.latest.golden index 3a4a224f3c678..bca30941327e4 100644 --- a/agent/xds/testdata/listeners/custom-public-listener-http-missing.latest.golden +++ b/agent/xds/testdata/listeners/custom-public-listener-http-missing.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "custom-public-listen", "address": { "socketAddress": { "address": "11.11.11.11", @@ -16,7 +17,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -24,8 +27,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "random-cluster", - "statPrefix": "foo-stats" + "statPrefix": "foo-stats", + "cluster": "random-cluster" } } ], @@ -34,9 +37,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -47,22 +50,24 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } - ], - "name": "custom-public-listen" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -76,18 +81,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -101,17 +106,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/custom-public-listener-http.latest.golden b/agent/xds/testdata/listeners/custom-public-listener-http.latest.golden index 6ac91607b8af2..4a44d3f6f1f42 100644 --- a/agent/xds/testdata/listeners/custom-public-listener-http.latest.golden +++ b/agent/xds/testdata/listeners/custom-public-listener-http.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "custom-public-listen", "address": { "socketAddress": { "address": "11.11.11.11", @@ -16,26 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router" - } - ], "routeConfig": { "name": "public_listener", "virtualHosts": [ { + "name": "public_listener", "domains": [ "*" ], - "name": "public_listener", "routes": [ { "match": { @@ -48,7 +37,21 @@ ] } ] - } + }, + "httpFilters": [ + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": { + + } + } + }, + { + "name": "envoy.filters.http.router" + } + ] } } ], @@ -57,9 +60,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -70,22 +73,24 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } - ], - "name": "custom-public-listen" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -99,18 +104,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -124,17 +129,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/custom-public-listener.latest.golden b/agent/xds/testdata/listeners/custom-public-listener.latest.golden index 03c834c4d7506..99c8f31391b07 100644 --- a/agent/xds/testdata/listeners/custom-public-listener.latest.golden +++ b/agent/xds/testdata/listeners/custom-public-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "custom-public-listen", "address": { "socketAddress": { "address": "11.11.11.11", @@ -16,7 +17,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -24,8 +27,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "random-cluster", - "statPrefix": "foo-stats" + "statPrefix": "foo-stats", + "cluster": "random-cluster" } } ], @@ -34,6 +37,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -44,7 +50,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -55,11 +60,11 @@ } } } - ], - "name": "custom-public-listen" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -73,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -98,17 +103,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/custom-trace-listener.latest.golden b/agent/xds/testdata/listeners/custom-trace-listener.latest.golden index b72487ffba023..90d89e1de9e7c 100644 --- a/agent/xds/testdata/listeners/custom-trace-listener.latest.golden +++ b/agent/xds/testdata/listeners/custom-trace-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,48 +182,19 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] - }, - "setCurrentClientCertDetails": { - "cert": true, - "chain": true, - "dns": true, - "subject": true, - "uri": true - }, - "statPrefix": "public_listener", "tracing": { "customTags": [ { + "tag": "custom_header", "requestHeader": { "name": "x-custom-traceid" - }, - "tag": "custom_header" + } }, { + "tag": "alloc_id", "environment": { "name": "NOMAD_ALLOC_ID" - }, - "tag": "alloc_id" + } } ], "provider": { @@ -210,11 +203,19 @@ "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig", "collectorCluster": "otelcolector", "collectorEndpoint": "/api/v2/spans", - "collectorEndpointVersion": "HTTP_JSON", - "sharedSpanContext": false + "sharedSpanContext": false, + "collectorEndpointVersion": "HTTP_JSON" } } }, + "forwardClientCertDetails": "APPEND_FORWARD", + "setCurrentClientCertDetails": { + "subject": true, + "cert": true, + "chain": true, + "dns": true, + "uri": true + }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -228,9 +229,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -241,22 +240,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/custom-upstream-ignored-with-disco-chain.latest.golden b/agent/xds/testdata/listeners/custom-upstream-ignored-with-disco-chain.latest.golden index 0254a224d513b..57d50f71c367f 100644 --- a/agent/xds/testdata/listeners/custom-upstream-ignored-with-disco-chain.latest.golden +++ b/agent/xds/testdata/listeners/custom-upstream-ignored-with-disco-chain.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/custom-upstream-with-prepared-query.latest.golden b/agent/xds/testdata/listeners/custom-upstream-with-prepared-query.latest.golden deleted file mode 100644 index ca92cf2177a55..0000000000000 --- a/agent/xds/testdata/listeners/custom-upstream-with-prepared-query.latest.golden +++ /dev/null @@ -1,114 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "11.11.11.11", - "portValue": 11111 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "random-cluster", - "statPrefix": "foo-stats" - } - } - ] - } - ], - "name": "db:custom-upstream" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.10.10.10", - "portValue": 8181 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" - } - } - ] - } - ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "0.0.0.0", - "portValue": 9999 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/custom-upstream.latest.golden b/agent/xds/testdata/listeners/custom-upstream.latest.golden index ca92cf2177a55..d12bdaf998bdc 100644 --- a/agent/xds/testdata/listeners/custom-upstream.latest.golden +++ b/agent/xds/testdata/listeners/custom-upstream.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:custom-upstream", "address": { "socketAddress": { "address": "11.11.11.11", @@ -16,17 +17,17 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "random-cluster", - "statPrefix": "foo-stats" + "statPrefix": "foo-stats", + "cluster": "random-cluster" } } ] } - ], - "name": "db:custom-upstream" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -40,18 +41,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -65,7 +66,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -73,8 +76,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -83,6 +86,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -93,7 +99,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -105,10 +110,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/defaults.latest.golden b/agent/xds/testdata/listeners/defaults.latest.golden index 0254a224d513b..57d50f71c367f 100644 --- a/agent/xds/testdata/listeners/defaults.latest.golden +++ b/agent/xds/testdata/listeners/defaults.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/expose-checks-grpc.latest.golden b/agent/xds/testdata/listeners/expose-checks-grpc.latest.golden deleted file mode 100644 index 38e62d80485f0..0000000000000 --- a/agent/xds/testdata/listeners/expose-checks-grpc.latest.golden +++ /dev/null @@ -1,143 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 21501 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "sourcePrefixRanges": [ - { - "addressPrefix": "127.0.0.1", - "prefixLen": 8 - }, - { - "addressPrefix": "192.0.2.1", - "prefixLen": 32 - }, - { - "addressPrefix": "::1", - "prefixLen": 128 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "routeConfig": { - "name": "exposed_path_filter_grpchealthv1HealthCheck_21501", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_filter_grpchealthv1HealthCheck_21501", - "routes": [ - { - "match": { - "path": "/grpc.health.v1.Health/Check" - }, - "route": { - "cluster": "exposed_cluster_9090" - } - } - ] - } - ] - }, - "statPrefix": "exposed_path_filter_grpchealthv1HealthCheck_21501", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "name": "exposed_path_grpchealthv1HealthCheck:1.2.3.4:21501", - "trafficDirection": "INBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 9090 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "name": "public_listener:1.2.3.4:9090", - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/expose-checks-http-with-bind-override.latest.golden b/agent/xds/testdata/listeners/expose-checks-http-with-bind-override.latest.golden deleted file mode 100644 index 4a112483bfb4c..0000000000000 --- a/agent/xds/testdata/listeners/expose-checks-http-with-bind-override.latest.golden +++ /dev/null @@ -1,142 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "6.7.8.9", - "portValue": 21500 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "sourcePrefixRanges": [ - { - "addressPrefix": "127.0.0.1", - "prefixLen": 8 - }, - { - "addressPrefix": "192.0.2.1", - "prefixLen": 32 - }, - { - "addressPrefix": "::1", - "prefixLen": 128 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "routeConfig": { - "name": "exposed_path_filter_debug_21500", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_filter_debug_21500", - "routes": [ - { - "match": { - "path": "/debug" - }, - "route": { - "cluster": "exposed_cluster_8181" - } - } - ] - } - ] - }, - "statPrefix": "exposed_path_filter_debug_21500", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "name": "exposed_path_debug:6.7.8.9:21500", - "trafficDirection": "INBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "6.7.8.9", - "portValue": 8080 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "name": "public_listener:6.7.8.9:8080", - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/expose-checks-http.latest.golden b/agent/xds/testdata/listeners/expose-checks.latest.golden similarity index 97% rename from agent/xds/testdata/listeners/expose-checks-http.latest.golden rename to agent/xds/testdata/listeners/expose-checks.latest.golden index 2299f061ddec7..50f3c5778a769 100644 --- a/agent/xds/testdata/listeners/expose-checks-http.latest.golden +++ b/agent/xds/testdata/listeners/expose-checks.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_debug:1.2.3.4:21500", "address": { "socketAddress": { "address": "1.2.3.4", @@ -32,22 +33,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "exposed_path_filter_debug_21500", "routeConfig": { "name": "exposed_path_filter_debug_21500", "virtualHosts": [ { + "name": "exposed_path_filter_debug_21500", "domains": [ "*" ], - "name": "exposed_path_filter_debug_21500", "routes": [ { "match": { @@ -61,7 +55,14 @@ } ] }, - "statPrefix": "exposed_path_filter_debug_21500", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -75,11 +76,11 @@ ] } ], - "name": "exposed_path_debug:1.2.3.4:21500", "trafficDirection": "INBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -101,8 +102,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -111,6 +112,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -121,7 +123,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -133,10 +134,9 @@ } } ], - "name": "public_listener:1.2.3.4:8080", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/expose-paths-local-app-paths.latest.golden b/agent/xds/testdata/listeners/expose-paths-local-app-paths.latest.golden index 819a0c0bbf261..6d0f665a45aad 100644 --- a/agent/xds/testdata/listeners/expose-paths-local-app-paths.latest.golden +++ b/agent/xds/testdata/listeners/expose-paths-local-app-paths.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_health1:1.2.3.4:21500", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,22 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "exposed_path_filter_health1_21500", "routeConfig": { "name": "exposed_path_filter_health1_21500", "virtualHosts": [ { + "name": "exposed_path_filter_health1_21500", "domains": [ "*" ], - "name": "exposed_path_filter_health1_21500", "routes": [ { "match": { @@ -45,7 +39,14 @@ } ] }, - "statPrefix": "exposed_path_filter_health1_21500", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -59,11 +60,11 @@ ] } ], - "name": "exposed_path_health1:1.2.3.4:21500", "trafficDirection": "INBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_health2:1.2.3.4:21501", "address": { "socketAddress": { "address": "1.2.3.4", @@ -77,22 +78,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "exposed_path_filter_health2_21501", "routeConfig": { "name": "exposed_path_filter_health2_21501", "virtualHosts": [ { + "name": "exposed_path_filter_health2_21501", "domains": [ "*" ], - "name": "exposed_path_filter_health2_21501", "routes": [ { "match": { @@ -106,7 +100,14 @@ } ] }, - "statPrefix": "exposed_path_filter_health2_21501", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -120,11 +121,11 @@ ] } ], - "name": "exposed_path_health2:1.2.3.4:21501", "trafficDirection": "INBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -146,8 +147,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -156,6 +157,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -166,7 +168,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -178,10 +179,9 @@ } } ], - "name": "public_listener:1.2.3.4:8080", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/expose-paths-new-cluster-http2.latest.golden b/agent/xds/testdata/listeners/expose-paths-new-cluster-http2.latest.golden index 5b19b4e74dbbb..e29af617f6998 100644 --- a/agent/xds/testdata/listeners/expose-paths-new-cluster-http2.latest.golden +++ b/agent/xds/testdata/listeners/expose-paths-new-cluster-http2.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_grpchealthv1HealthCheck:1.2.3.4:21501", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,23 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "exposed_path_filter_grpchealthv1HealthCheck_21501", "routeConfig": { "name": "exposed_path_filter_grpchealthv1HealthCheck_21501", "virtualHosts": [ { + "name": "exposed_path_filter_grpchealthv1HealthCheck_21501", "domains": [ "*" ], - "name": "exposed_path_filter_grpchealthv1HealthCheck_21501", "routes": [ { "match": { @@ -46,10 +39,18 @@ } ] }, - "statPrefix": "exposed_path_filter_grpchealthv1HealthCheck_21501", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -60,11 +61,11 @@ ] } ], - "name": "exposed_path_grpchealthv1HealthCheck:1.2.3.4:21501", "trafficDirection": "INBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_health1:1.2.3.4:21500", "address": { "socketAddress": { "address": "1.2.3.4", @@ -78,22 +79,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "exposed_path_filter_health1_21500", "routeConfig": { "name": "exposed_path_filter_health1_21500", "virtualHosts": [ { + "name": "exposed_path_filter_health1_21500", "domains": [ "*" ], - "name": "exposed_path_filter_health1_21500", "routes": [ { "match": { @@ -107,7 +101,14 @@ } ] }, - "statPrefix": "exposed_path_filter_health1_21500", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -121,11 +122,11 @@ ] } ], - "name": "exposed_path_health1:1.2.3.4:21500", "trafficDirection": "INBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -147,8 +148,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -157,6 +158,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -167,7 +169,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -179,10 +180,9 @@ } } ], - "name": "public_listener:1.2.3.4:8080", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/grpc-public-listener.latest.golden b/agent/xds/testdata/listeners/grpc-public-listener.latest.golden index ac7d70ab1f27f..eea407e422d1d 100644 --- a/agent/xds/testdata/listeners/grpc-public-listener.latest.golden +++ b/agent/xds/testdata/listeners/grpc-public-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.grpc_stats", @@ -95,31 +117,10 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] - }, - "statPrefix": "public_listener", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -133,10 +134,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "h2", - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -147,22 +145,24 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "h2", + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/http-listener-with-timeouts.latest.golden b/agent/xds/testdata/listeners/http-listener-with-timeouts.latest.golden index a5e8bc06745f7..9637b76bfb2d9 100644 --- a/agent/xds/testdata/listeners/http-listener-with-timeouts.latest.golden +++ b/agent/xds/testdata/listeners/http-listener-with-timeouts.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,30 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app", + "timeout": "2.345s", + "idleTimeout": "3.456s" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +107,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +121,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +135,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +149,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +163,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,40 +184,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app", - "idleTimeout": "3.456s", - "timeout": "2.345s" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -207,9 +208,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -220,22 +219,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/http-public-listener-no-xfcc.latest.golden b/agent/xds/testdata/listeners/http-public-listener-no-xfcc.latest.golden index 66401ec1169d7..5b65b60e3a439 100644 --- a/agent/xds/testdata/listeners/http-public-listener-no-xfcc.latest.golden +++ b/agent/xds/testdata/listeners/http-public-listener-no-xfcc.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,29 +67,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "public_listener", "routeConfig": { "name": "public_listener", "virtualHosts": [ { + "name": "public_listener", "domains": [ "*" ], - "name": "public_listener", "routes": [ { "match": { @@ -102,7 +89,21 @@ } ] }, - "statPrefix": "public_listener", + "httpFilters": [ + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": {} + } + }, + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -119,9 +120,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -132,22 +131,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/http-public-listener.latest.golden b/agent/xds/testdata/listeners/http-public-listener.latest.golden index cec77f10e445b..461b8379f7d58 100644 --- a/agent/xds/testdata/listeners/http-public-listener.latest.golden +++ b/agent/xds/testdata/listeners/http-public-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -83,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -97,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -111,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -125,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -139,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -160,38 +182,17 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -205,9 +206,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -218,22 +217,23 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/http-upstream.latest.golden b/agent/xds/testdata/listeners/http-upstream.latest.golden index 1d8fd316ec2fc..0814b07f46dfb 100644 --- a/agent/xds/testdata/listeners/http-upstream.latest.golden +++ b/agent/xds/testdata/listeners/http-upstream.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,22 +17,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.db.default.default.dc1", "routeConfig": { "name": "db", "virtualHosts": [ { + "name": "db.default.default.dc1", "domains": [ "*" ], - "name": "db.default.default.dc1", "routes": [ { "match": { @@ -45,7 +39,14 @@ } ] }, - "statPrefix": "upstream.db.default.default.dc1", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -59,11 +60,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -77,18 +78,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -110,8 +111,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -120,6 +121,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -130,7 +132,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -142,10 +143,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/http2-public-listener.latest.golden b/agent/xds/testdata/listeners/http2-public-listener.latest.golden index f78e46d253489..bb0d81ac36076 100644 --- a/agent/xds/testdata/listeners/http2-public-listener.latest.golden +++ b/agent/xds/testdata/listeners/http2-public-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,8 +67,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", - "http2ProtocolOptions": {}, + "statPrefix": "public_listener", + "routeConfig": { + "name": "public_listener", + "virtualHosts": [ + { + "name": "public_listener", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -84,8 +105,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "trust-domain", "metadataNamespace": "consul", + "key": "trust-domain", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -98,8 +119,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "partition", "metadataNamespace": "consul", + "key": "partition", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -112,8 +133,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "namespace", "metadataNamespace": "consul", + "key": "namespace", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -126,8 +147,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "datacenter", "metadataNamespace": "consul", + "key": "datacenter", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -140,8 +161,8 @@ { "header": "x-forwarded-client-cert", "onHeaderPresent": { - "key": "service", "metadataNamespace": "consul", + "key": "service", "regexValueRewrite": { "pattern": { "googleRe2": {}, @@ -161,38 +182,18 @@ } } ], - "routeConfig": { - "name": "public_listener", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app" - } - } - ] - } - ] + "tracing": { + "randomSampling": {} }, + "http2ProtocolOptions": {}, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "public_listener", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -206,10 +207,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "h2", - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -220,22 +218,24 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "h2", + "http/1.1" + ] }, "requireClientCertificate": true } } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-gateway-bind-addrs.latest.golden b/agent/xds/testdata/listeners/ingress-gateway-bind-addrs.latest.golden index bc0850f80a6ec..dc299d550663c 100644 --- a/agent/xds/testdata/listeners/ingress-gateway-bind-addrs.latest.golden +++ b/agent/xds/testdata/listeners/ingress-gateway-bind-addrs.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:10.0.0.1:8080", "address": { "socketAddress": { "address": "10.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:10.0.0.1:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:172.16.0.1:8080", "address": { "socketAddress": { "address": "172.16.0.1", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:172.16.0.1:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:8.8.8.8:8080", "address": { "socketAddress": { "address": "8.8.8.8", @@ -66,17 +67,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:8.8.8.8:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-gateway-nil-config-entry.latest.golden b/agent/xds/testdata/listeners/ingress-gateway-nil-config-entry.latest.golden index 97cdec41ef13e..53b67bb37300e 100644 --- a/agent/xds/testdata/listeners/ingress-gateway-nil-config-entry.latest.golden +++ b/agent/xds/testdata/listeners/ingress-gateway-nil-config-entry.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-gateway-no-services.latest.golden b/agent/xds/testdata/listeners/ingress-gateway-no-services.latest.golden index 97cdec41ef13e..53b67bb37300e 100644 --- a/agent/xds/testdata/listeners/ingress-gateway-no-services.latest.golden +++ b/agent/xds/testdata/listeners/ingress-gateway-no-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-gateway.latest.golden b/agent/xds/testdata/listeners/ingress-gateway.latest.golden index 068e01983c926..30994abe6e1d8 100644 --- a/agent/xds/testdata/listeners/ingress-gateway.latest.golden +++ b/agent/xds/testdata/listeners/ingress-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,17 +17,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-grpc-multiple-services.latest.golden b/agent/xds/testdata/listeners/ingress-grpc-multiple-services.latest.golden index 803d57e307850..26fa9469ca356 100644 --- a/agent/xds/testdata/listeners/ingress-grpc-multiple-services.latest.golden +++ b/agent/xds/testdata/listeners/ingress-grpc-multiple-services.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "grpc:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,7 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.grpc_stats", @@ -38,17 +46,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -59,10 +60,9 @@ ] } ], - "name": "grpc:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-http-multiple-services.latest.golden b/agent/xds/testdata/listeners/ingress-http-multiple-services.latest.golden index 63affa4498850..4b94e26d2a707 100644 --- a/agent/xds/testdata/listeners/ingress-http-multiple-services.latest.golden +++ b/agent/xds/testdata/listeners/ingress-http-multiple-services.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_443", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "443" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "443" - }, - "statPrefix": "ingress_upstream_443", "tracing": { "randomSampling": {} }, @@ -45,11 +46,11 @@ ] } ], - "name": "http:1.2.3.4:443", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -63,6 +64,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -71,14 +80,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -92,10 +93,9 @@ ] } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-splitter-with-resolver-redirect.latest.golden b/agent/xds/testdata/listeners/ingress-splitter-with-resolver-redirect.latest.golden index 6469727f97989..97fe8332eecf1 100644 --- a/agent/xds/testdata/listeners/ingress-splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/listeners/ingress-splitter-with-resolver-redirect.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -45,10 +46,9 @@ ] } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-chain-external-sni.latest.golden b/agent/xds/testdata/listeners/ingress-with-chain-external-sni.latest.golden index 068e01983c926..30994abe6e1d8 100644 --- a/agent/xds/testdata/listeners/ingress-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-chain-external-sni.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,17 +17,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-grpc-single-tls-listener.latest.golden b/agent/xds/testdata/listeners/ingress-with-grpc-single-tls-listener.latest.golden index 77dc9a203001b..d4e98ecafe95c 100644 --- a/agent/xds/testdata/listeners/ingress-with-grpc-single-tls-listener.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-grpc-single-tls-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "grpc:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,7 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.grpc_stats", @@ -38,17 +46,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -59,11 +60,11 @@ ] } ], - "name": "grpc:1.2.3.4:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "grpc:1.2.3.4:8081", "address": { "socketAddress": { "address": "1.2.3.4", @@ -77,7 +78,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "ingress_upstream_8081", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8081" + }, "httpFilters": [ { "name": "envoy.filters.http.grpc_stats", @@ -99,17 +107,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -123,10 +124,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "h2", - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -137,24 +137,24 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "h2", + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "grpc:1.2.3.4:8081", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-http2-and-grpc-multiple-tls-listener.latest.golden b/agent/xds/testdata/listeners/ingress-with-http2-and-grpc-multiple-tls-listener.latest.golden index ce525f52e415c..74ec514a35b28 100644 --- a/agent/xds/testdata/listeners/ingress-with-http2-and-grpc-multiple-tls-listener.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-http2-and-grpc-multiple-tls-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "grpc:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,7 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.grpc_stats", @@ -38,17 +46,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -62,10 +63,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "h2", - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -76,25 +76,26 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "h2", + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "grpc:1.2.3.4:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http2:1.2.3.4:8081", "address": { "socketAddress": { "address": "1.2.3.4", @@ -108,7 +109,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "ingress_upstream_8081", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8081" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -117,17 +125,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -141,10 +142,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "h2", - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -155,24 +155,24 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "h2", + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http2:1.2.3.4:8081", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-http2-single-tls-listener.latest.golden b/agent/xds/testdata/listeners/ingress-with-http2-single-tls-listener.latest.golden index 0294349114cba..a8767e662d768 100644 --- a/agent/xds/testdata/listeners/ingress-with-http2-single-tls-listener.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-http2-single-tls-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http2:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,7 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -25,17 +33,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -46,11 +47,11 @@ ] } ], - "name": "http2:1.2.3.4:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http2:1.2.3.4:8081", "address": { "socketAddress": { "address": "1.2.3.4", @@ -64,7 +65,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "ingress_upstream_8081", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8081" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -73,17 +81,10 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -97,10 +98,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "h2", - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -111,24 +111,24 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "h2", + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http2:1.2.3.4:8081", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-sds-listener+service-level.latest.golden b/agent/xds/testdata/listeners/ingress-with-sds-listener+service-level.latest.golden index e43f5f67b4e56..6be862ddbe728 100644 --- a/agent/xds/testdata/listeners/ingress-with-sds-listener+service-level.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-sds-listener+service-level.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,6 +22,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080_s1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080_s1" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -29,14 +38,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080_s1" - }, - "statPrefix": "ingress_upstream_8080_s1", "tracing": { "randomSampling": {} }, @@ -53,15 +54,14 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificateSdsSecretConfigs": [ { "name": "s1.example.com-cert", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -69,14 +69,15 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } ], - "tlsParams": {} + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } @@ -88,6 +89,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -96,14 +105,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -120,15 +121,14 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificateSdsSecretConfigs": [ { "name": "*.example.com-cert", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -136,14 +136,15 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } ], - "tlsParams": {} + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } @@ -158,10 +159,9 @@ } } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level-http.latest.golden b/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level-http.latest.golden index b17f8d029099a..21c9c2cecd137 100644 --- a/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level-http.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level-http.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -48,15 +49,14 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificateSdsSecretConfigs": [ { "name": "listener-cert", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -64,24 +64,24 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } ], - "tlsParams": {} + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level-mixed-tls.latest.golden b/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level-mixed-tls.latest.golden index 0ce1816024d1d..8500d36f4dbb1 100644 --- a/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level-mixed-tls.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level-mixed-tls.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "insecure:1.2.3.4:9090", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "insecure.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.insecure.default.default.dc1" + "statPrefix": "upstream.insecure.default.default.dc1", + "cluster": "insecure.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "insecure:1.2.3.4:9090", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "secure:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -41,8 +42,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "secure.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.secure.default.default.dc1" + "statPrefix": "upstream.secure.default.default.dc1", + "cluster": "secure.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -51,12 +52,16 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificateSdsSecretConfigs": [ { "name": "listener-cert", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -64,24 +69,21 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } - ], - "tlsParams": {} + ] }, "requireClientCertificate": false } } } ], - "name": "secure:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level.latest.golden b/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level.latest.golden index ae51e3b211b8a..171b26a5a98c1 100644 --- a/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-sds-listener-gw-level.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,8 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -26,12 +27,16 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificateSdsSecretConfigs": [ { "name": "cert-resource", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -39,24 +44,21 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } - ], - "tlsParams": {} + ] }, "requireClientCertificate": false } } } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-sds-listener-listener-level.latest.golden b/agent/xds/testdata/listeners/ingress-with-sds-listener-listener-level.latest.golden index eefa56951233f..aabf3d6f9884f 100644 --- a/agent/xds/testdata/listeners/ingress-with-sds-listener-listener-level.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-sds-listener-listener-level.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,8 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -26,12 +27,16 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificateSdsSecretConfigs": [ { "name": "listener-cert", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -39,24 +44,21 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } - ], - "tlsParams": {} + ] }, "requireClientCertificate": false } } } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-sds-service-level-mixed-no-tls.latest.golden b/agent/xds/testdata/listeners/ingress-with-sds-service-level-mixed-no-tls.latest.golden index a91219b50697b..6e3114fe3ac6c 100644 --- a/agent/xds/testdata/listeners/ingress-with-sds-service-level-mixed-no-tls.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-sds-service-level-mixed-no-tls.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,6 +22,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080_s1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080_s1" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -29,14 +38,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080_s1" - }, - "statPrefix": "ingress_upstream_8080_s1", "tracing": { "randomSampling": {} }, @@ -53,15 +54,14 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificateSdsSecretConfigs": [ { "name": "s1.example.com-cert", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -69,14 +69,15 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } ], - "tlsParams": {} + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } @@ -88,6 +89,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -96,14 +105,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -125,10 +126,9 @@ } } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-sds-service-level.latest.golden b/agent/xds/testdata/listeners/ingress-with-sds-service-level.latest.golden index 7f7308a4f982a..2933c09318b37 100644 --- a/agent/xds/testdata/listeners/ingress-with-sds-service-level.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-sds-service-level.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,6 +22,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080_s1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080_s1" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -29,14 +38,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080_s1" - }, - "statPrefix": "ingress_upstream_8080_s1", "tracing": { "randomSampling": {} }, @@ -53,15 +54,14 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificateSdsSecretConfigs": [ { "name": "s1.example.com-cert", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -69,14 +69,15 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } ], - "tlsParams": {} + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } @@ -93,6 +94,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080_s2", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080_s2" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -101,14 +110,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080_s2" - }, - "statPrefix": "ingress_upstream_8080_s2", "tracing": { "randomSampling": {} }, @@ -125,15 +126,14 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificateSdsSecretConfigs": [ { "name": "s2.example.com-cert", "sdsConfig": { "apiConfigSource": { "apiType": "GRPC", + "transportApiVersion": "V3", "grpcServices": [ { "envoyGrpc": { @@ -141,14 +141,15 @@ }, "timeout": "5s" } - ], - "transportApiVersion": "V3" + ] }, "resourceApiVersion": "V3" } } ], - "tlsParams": {} + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } @@ -163,10 +164,9 @@ } } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-single-tls-listener.latest.golden b/agent/xds/testdata/listeners/ingress-with-single-tls-listener.latest.golden index 0eeae2d616952..fb88e51fc0c96 100644 --- a/agent/xds/testdata/listeners/ingress-with-single-tls-listener.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-single-tls-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -45,11 +46,11 @@ ] } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8081", "address": { "socketAddress": { "address": "1.2.3.4", @@ -63,6 +64,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8081", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8081" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -71,14 +80,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", "tracing": { "randomSampling": {} }, @@ -95,9 +96,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -108,24 +109,23 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8081", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden b/agent/xds/testdata/listeners/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden index 068e01983c926..30994abe6e1d8 100644 --- a/agent/xds/testdata/listeners/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tcp-chain-failover-through-local-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,17 +17,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden b/agent/xds/testdata/listeners/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden index 068e01983c926..30994abe6e1d8 100644 --- a/agent/xds/testdata/listeners/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tcp-chain-failover-through-remote-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,17 +17,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-listener-cipher-suites.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-listener-cipher-suites.latest.golden index f988e1a6ebb0e..516f4b8a25653 100644 --- a/agent/xds/testdata/listeners/ingress-with-tls-listener-cipher-suites.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tls-listener-cipher-suites.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,8 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -26,6 +27,12 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -36,12 +43,6 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -53,10 +54,9 @@ } } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-listener-max-version.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-listener-max-version.latest.golden index 15dd947391ddc..69c8fa3bbb251 100644 --- a/agent/xds/testdata/listeners/ingress-with-tls-listener-max-version.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tls-listener-max-version.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,8 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -26,6 +27,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -36,9 +40,6 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -50,10 +51,9 @@ } } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-listener-min-version.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-listener-min-version.latest.golden index 77528a40d923e..7bec506fad2c0 100644 --- a/agent/xds/testdata/listeners/ingress-with-tls-listener-min-version.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tls-listener-min-version.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,8 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -26,6 +27,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -36,9 +40,6 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -50,10 +51,9 @@ } } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-listener.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-listener.latest.golden index 91df315726f8f..b635a227e8db3 100644 --- a/agent/xds/testdata/listeners/ingress-with-tls-listener.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tls-listener.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,8 +17,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -26,6 +27,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -36,7 +40,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -48,10 +51,9 @@ } } ], - "name": "db:1.2.3.4:8080", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-min-version-listeners-gateway-defaults.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-min-version-listeners-gateway-defaults.latest.golden index fcc9e1ac5e2e8..00791b14f233a 100644 --- a/agent/xds/testdata/listeners/ingress-with-tls-min-version-listeners-gateway-defaults.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tls-min-version-listeners-gateway-defaults.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -48,9 +49,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -61,25 +62,25 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8081", "address": { "socketAddress": { "address": "1.2.3.4", @@ -93,6 +94,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8081", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8081" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -101,14 +110,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", "tracing": { "randomSampling": {} }, @@ -125,9 +126,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -138,25 +139,25 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8081", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8082", "address": { "socketAddress": { "address": "1.2.3.4", @@ -170,6 +171,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8082", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8082" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -178,14 +187,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8082" - }, - "statPrefix": "ingress_upstream_8082", "tracing": { "randomSampling": {} }, @@ -202,9 +203,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -215,25 +216,25 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8082", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8083", "address": { "socketAddress": { "address": "1.2.3.4", @@ -247,6 +248,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8083", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8083" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -255,14 +264,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8083" - }, - "statPrefix": "ingress_upstream_8083", "tracing": { "randomSampling": {} }, @@ -279,9 +280,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -292,23 +291,25 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8083", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8084", "address": { "socketAddress": { "address": "1.2.3.4", @@ -322,6 +323,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8084", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8084" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -330,14 +339,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8084" - }, - "statPrefix": "ingress_upstream_8084", "tracing": { "randomSampling": {} }, @@ -354,9 +355,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -367,24 +368,23 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8084", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-mixed-cipher-suites-listeners.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-mixed-cipher-suites-listeners.latest.golden deleted file mode 100644 index 106d66ad62cce..0000000000000 --- a/agent/xds/testdata/listeners/ingress-with-tls-mixed-cipher-suites-listeners.latest.golden +++ /dev/null @@ -1,166 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8080 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-RSA-AES256-SHA" - ] - }, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": false - } - } - } - ], - "name": "http:1.2.3.4:8080", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8081 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-RSA-CHACHA20-POLY1305", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": false - } - } - } - ], - "name": "http:1.2.3.4:8081", - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-mixed-listeners.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-mixed-listeners.latest.golden index c4947a132d673..da77ddc399f96 100644 --- a/agent/xds/testdata/listeners/ingress-with-tls-mixed-listeners.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tls-mixed-listeners.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -48,9 +49,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -61,23 +60,25 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:9090", "address": { "socketAddress": { "address": "1.2.3.4", @@ -91,6 +92,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_9090", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "9090" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -99,14 +108,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "9090" - }, - "statPrefix": "ingress_upstream_9090", "tracing": { "randomSampling": {} }, @@ -120,10 +121,9 @@ ] } ], - "name": "http:1.2.3.4:9090", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-mixed-max-version-listeners.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-mixed-max-version-listeners.latest.golden deleted file mode 100644 index b3b06eec07749..0000000000000 --- a/agent/xds/testdata/listeners/ingress-with-tls-mixed-max-version-listeners.latest.golden +++ /dev/null @@ -1,238 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8080 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": false - } - } - } - ], - "name": "http:1.2.3.4:8080", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8081 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_0" - }, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": false - } - } - } - ], - "name": "http:1.2.3.4:8081", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8082 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8082" - }, - "statPrefix": "ingress_upstream_8082", - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_3" - }, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": false - } - } - } - ], - "name": "http:1.2.3.4:8082", - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/ingress-with-tls-mixed-min-version-listeners.latest.golden b/agent/xds/testdata/listeners/ingress-with-tls-mixed-min-version-listeners.latest.golden index 34fe2d4c53d04..1033abd062488 100644 --- a/agent/xds/testdata/listeners/ingress-with-tls-mixed-min-version-listeners.latest.golden +++ b/agent/xds/testdata/listeners/ingress-with-tls-mixed-min-version-listeners.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8080", "address": { "socketAddress": { "address": "1.2.3.4", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8080", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8080" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8080" - }, - "statPrefix": "ingress_upstream_8080", "tracing": { "randomSampling": {} }, @@ -48,9 +49,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -61,25 +62,25 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8080", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8081", "address": { "socketAddress": { "address": "1.2.3.4", @@ -93,6 +94,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8081", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8081" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -101,14 +110,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8081" - }, - "statPrefix": "ingress_upstream_8081", "tracing": { "randomSampling": {} }, @@ -125,9 +126,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_0" + }, "tlsCertificates": [ { "certificateChain": { @@ -138,25 +139,25 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_0" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8081", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "http:1.2.3.4:8082", "address": { "socketAddress": { "address": "1.2.3.4", @@ -170,6 +171,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "ingress_upstream_8082", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "8082" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -178,14 +187,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "8082" - }, - "statPrefix": "ingress_upstream_8082", "tracing": { "randomSampling": {} }, @@ -202,9 +203,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { - "alpnProtocols": [ - "http/1.1" - ], + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -215,24 +216,23 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" } - } + }, + "alpnProtocols": [ + "http/1.1" + ] }, "requireClientCertificate": false } } } ], - "name": "http:1.2.3.4:8082", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/listener-balance-inbound-connections.latest.golden b/agent/xds/testdata/listeners/listener-balance-inbound-connections.latest.golden index 89689148b08e4..c04122640491b 100644 --- a/agent/xds/testdata/listeners/listener-balance-inbound-connections.latest.golden +++ b/agent/xds/testdata/listeners/listener-balance-inbound-connections.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,27 +42,24 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", "portValue": 9999 } }, - "connectionBalanceConfig": { - "exactBalance": {} - }, "filterChains": [ { "filters": [ @@ -69,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -77,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -87,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -97,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -109,10 +111,14 @@ } } ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" + "trafficDirection": "INBOUND", + "connectionBalanceConfig": { + "exactBalance": { + + } + } } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/listener-balance-outbound-connections-bind-port.latest.golden b/agent/xds/testdata/listeners/listener-balance-outbound-connections-bind-port.latest.golden index b588e8ac533e6..889873f55434d 100644 --- a/agent/xds/testdata/listeners/listener-balance-outbound-connections-bind-port.latest.golden +++ b/agent/xds/testdata/listeners/listener-balance-outbound-connections-bind-port.latest.golden @@ -1,17 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 9191 } }, - "connectionBalanceConfig": { - "exactBalance": {} - }, "filterChains": [ { "filters": [ @@ -19,18 +17,23 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", - "trafficDirection": "OUTBOUND" + "trafficDirection": "OUTBOUND", + "connectionBalanceConfig": { + "exactBalance": { + + } + } }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -44,18 +47,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -69,7 +72,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -77,8 +82,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -87,6 +92,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -97,7 +105,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -109,10 +116,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/listener-bind-address-port.latest.golden b/agent/xds/testdata/listeners/listener-bind-address-port.latest.golden index a6d0ff6730d69..1c9146861a194 100644 --- a/agent/xds/testdata/listeners/listener-bind-address-port.latest.golden +++ b/agent/xds/testdata/listeners/listener-bind-address-port.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:127.0.0.2:8888", "address": { "socketAddress": { "address": "127.0.0.2", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:127.0.0.2:8888", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/listener-bind-address.latest.golden b/agent/xds/testdata/listeners/listener-bind-address.latest.golden index f69ad7a5450a0..9f7bc6b28b266 100644 --- a/agent/xds/testdata/listeners/listener-bind-address.latest.golden +++ b/agent/xds/testdata/listeners/listener-bind-address.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:127.0.0.2:9999", "address": { "socketAddress": { "address": "127.0.0.2", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:127.0.0.2:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/listener-bind-port.latest.golden b/agent/xds/testdata/listeners/listener-bind-port.latest.golden index 3be52d7f8e9ac..a286e5232b862 100644 --- a/agent/xds/testdata/listeners/listener-bind-port.latest.golden +++ b/agent/xds/testdata/listeners/listener-bind-port.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:8888", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:8888", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/listener-max-inbound-connections.latest.golden b/agent/xds/testdata/listeners/listener-max-inbound-connections.latest.golden index 0ba53902e6e97..cbfda69f564ef 100644 --- a/agent/xds/testdata/listeners/listener-max-inbound-connections.latest.golden +++ b/agent/xds/testdata/listeners/listener-max-inbound-connections.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,16 +77,16 @@ "name": "envoy.filters.network.connection_limit", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit", - "maxConnections": "222", - "statPrefix": "inbound_connection_limit" + "statPrefix": "inbound_connection_limit", + "maxConnections": "222" } }, { "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -92,6 +95,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -102,7 +108,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -114,10 +119,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/listener-unix-domain-socket.latest.golden b/agent/xds/testdata/listeners/listener-unix-domain-socket.latest.golden index a13bb3681f3c3..6d4ee8880ebac 100644 --- a/agent/xds/testdata/listeners/listener-unix-domain-socket.latest.golden +++ b/agent/xds/testdata/listeners/listener-unix-domain-socket.latest.golden @@ -1,12 +1,13 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:/tmp/service-mesh/client-1/grpc-employee-server", "address": { "pipe": { - "mode": 416, - "path": "/tmp/service-mesh/client-1/grpc-employee-server" + "path": "/tmp/service-mesh/client-1/grpc-employee-server", + "mode": 416 } }, "filterChains": [ @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:/tmp/service-mesh/client-1/grpc-employee-server", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -41,18 +42,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -66,7 +67,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -74,8 +77,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -84,6 +87,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -94,7 +100,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -106,10 +111,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/local-mesh-gateway-with-peered-upstreams.latest.golden b/agent/xds/testdata/listeners/local-mesh-gateway-with-peered-upstreams.latest.golden index bb4e12a9a6058..d062f6dd5199f 100644 --- a/agent/xds/testdata/listeners/local-mesh-gateway-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/listeners/local-mesh-gateway-with-peered-upstreams.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "payments?peer=cloud:127.0.0.1:9090", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "statPrefix": "upstream_peered.payments.default.cloud" + "statPrefix": "upstream_peered.payments.default.cloud", + "cluster": "payments.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } } ] } ], - "name": "payments?peer=cloud:127.0.0.1:9090", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -41,7 +42,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -49,8 +52,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -59,6 +62,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -69,7 +75,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -81,11 +86,11 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "refunds?peer=cloud:127.0.0.1:9090", "address": { "socketAddress": { "address": "127.0.0.1", @@ -99,17 +104,16 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "statPrefix": "upstream_peered.refunds.default.cloud" + "statPrefix": "upstream_peered.refunds.default.cloud", + "cluster": "refunds.default.cloud.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } } ] } ], - "name": "refunds?peer=cloud:127.0.0.1:9090", "trafficDirection": "OUTBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-custom-addresses.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-custom-addresses.latest.golden index 2662d64f9f365..7c293d43d8ce0 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-custom-addresses.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-custom-addresses.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "bar:2001:db8::ff:9999", "address": { "socketAddress": { "address": "2001:db8::ff", @@ -21,8 +22,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.bar.dc2" + "statPrefix": "mesh_gateway_remote.bar.dc2", + "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -38,8 +39,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.bar.dc4" + "statPrefix": "mesh_gateway_remote.bar.dc4", + "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -55,8 +56,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.bar.dc6" + "statPrefix": "mesh_gateway_remote.bar.dc6", + "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -73,8 +74,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.bar" + "statPrefix": "mesh_gateway_local.bar", + "cluster": "" } } ] @@ -87,11 +88,11 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "bar:2001:db8::ff:9999" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "baz:127.0.0.1:8765", "address": { "socketAddress": { "address": "127.0.0.1", @@ -110,8 +111,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.baz.dc2" + "statPrefix": "mesh_gateway_remote.baz.dc2", + "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -127,8 +128,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.baz.dc4" + "statPrefix": "mesh_gateway_remote.baz.dc4", + "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -144,8 +145,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.baz.dc6" + "statPrefix": "mesh_gateway_remote.baz.dc6", + "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -162,8 +163,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.baz" + "statPrefix": "mesh_gateway_local.baz", + "cluster": "" } } ] @@ -176,11 +177,11 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "baz:127.0.0.1:8765" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -199,8 +200,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc2" + "statPrefix": "mesh_gateway_remote.default.dc2", + "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -216,8 +217,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc4" + "statPrefix": "mesh_gateway_remote.default.dc4", + "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -233,8 +234,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc6" + "statPrefix": "mesh_gateway_remote.default.dc6", + "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -251,8 +252,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -265,11 +266,11 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "foo:198.17.2.3:8080", "address": { "socketAddress": { "address": "198.17.2.3", @@ -288,8 +289,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.foo.dc2" + "statPrefix": "mesh_gateway_remote.foo.dc2", + "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -305,8 +306,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.foo.dc4" + "statPrefix": "mesh_gateway_remote.foo.dc4", + "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -322,8 +323,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.foo.dc6" + "statPrefix": "mesh_gateway_remote.foo.dc6", + "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -340,8 +341,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.foo" + "statPrefix": "mesh_gateway_local.foo", + "cluster": "" } } ] @@ -354,10 +355,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "foo:198.17.2.3:8080" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-no-services.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-no-services.latest.golden index 7cecb373468e3..40d5b919bd1e5 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-no-services.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-no-services.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -22,8 +23,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -36,10 +37,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-peering-control-plane.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-peering-control-plane.latest.golden index 6dd438c532457..5989bcb930af9 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-peering-control-plane.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-peering-control-plane.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,8 +22,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "server.dc1.peering.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_local_peering_server.default.dc1" + "statPrefix": "mesh_gateway_local_peering_server.default.dc1", + "cluster": "server.dc1.peering.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -39,8 +40,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -53,10 +54,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-tagged-addresses.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-tagged-addresses.latest.golden index 8d1e08cdf94ba..4c76beebb726a 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-tagged-addresses.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-tagged-addresses.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "lan:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,8 +22,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.lan.dc2" + "statPrefix": "mesh_gateway_remote.lan.dc2", + "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -38,8 +39,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.lan.dc4" + "statPrefix": "mesh_gateway_remote.lan.dc4", + "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -55,8 +56,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.lan.dc6" + "statPrefix": "mesh_gateway_remote.lan.dc6", + "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -73,8 +74,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.lan" + "statPrefix": "mesh_gateway_local.lan", + "cluster": "" } } ] @@ -87,11 +88,11 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "lan:1.2.3.4:8443" + ] }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "wan:198.18.0.1:443", "address": { "socketAddress": { "address": "198.18.0.1", @@ -110,8 +111,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.wan.dc2" + "statPrefix": "mesh_gateway_remote.wan.dc2", + "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -127,8 +128,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.wan.dc4" + "statPrefix": "mesh_gateway_remote.wan.dc4", + "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -144,8 +145,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.wan.dc6" + "statPrefix": "mesh_gateway_remote.wan.dc6", + "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -162,8 +163,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.wan" + "statPrefix": "mesh_gateway_local.wan", + "cluster": "" } } ] @@ -176,10 +177,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "wan:198.18.0.1:443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-using-federation-control-plane.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-using-federation-control-plane.latest.golden deleted file mode 100644 index 5fbce54c1df85..0000000000000 --- a/agent/xds/testdata/listeners/mesh-gateway-using-federation-control-plane.latest.golden +++ /dev/null @@ -1,181 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8443 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "serverNames": [ - "*.dc2.internal.11111111-2222-3333-4444-555555555555.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc2" - } - } - ] - }, - { - "filterChainMatch": { - "serverNames": [ - "*.dc4.internal.11111111-2222-3333-4444-555555555555.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc4" - } - } - ] - }, - { - "filterChainMatch": { - "serverNames": [ - "*.dc6.internal.11111111-2222-3333-4444-555555555555.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc6" - } - } - ] - }, - { - "filterChainMatch": { - "serverNames": [ - "*.server.dc2.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "server.dc2.consul", - "statPrefix": "mesh_gateway_remote.default.dc2" - } - } - ] - }, - { - "filterChainMatch": { - "serverNames": [ - "*.server.dc4.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "server.dc4.consul", - "statPrefix": "mesh_gateway_remote.default.dc4" - } - } - ] - }, - { - "filterChainMatch": { - "serverNames": [ - "*.server.dc6.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "server.dc6.consul", - "statPrefix": "mesh_gateway_remote.default.dc6" - } - } - ] - }, - { - "filterChainMatch": { - "serverNames": [ - "node1.server.dc1.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "node1.server.dc1.consul", - "statPrefix": "mesh_gateway_local_server.default.dc1" - } - } - ] - }, - { - "filterChainMatch": { - "serverNames": [ - "node2.server.dc1.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "node2.server.dc1.consul", - "statPrefix": "mesh_gateway_local_server.default.dc1" - } - } - ] - }, - { - "filters": [ - { - "name": "envoy.filters.network.sni_cluster", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.sni_cluster.v3.SniCluster" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" - } - } - ] - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "name": "default:1.2.3.4:8443" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-using-federation-states.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-using-federation-states.latest.golden index 3b77ccca9b996..7505e7c201cd2 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-using-federation-states.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-using-federation-states.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,8 +22,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc2" + "statPrefix": "mesh_gateway_remote.default.dc2", + "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -38,8 +39,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc4" + "statPrefix": "mesh_gateway_remote.default.dc4", + "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -55,8 +56,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc6" + "statPrefix": "mesh_gateway_remote.default.dc6", + "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -73,8 +74,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -87,10 +88,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden index fa164e94645b8..5e2ff2a897dca 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,7 +22,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "SANITIZE_SET", + "statPrefix": "mesh_gateway_local_peered.db.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "db" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -30,24 +38,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "db" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "SANITIZE_SET", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "mesh_gateway_local_peered.db.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -61,6 +62,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -71,7 +73,6 @@ } } ], - "tlsParams": {}, "validationContext": { "customValidatorConfig": { "name": "envoy.tls.cert_validator.spiffe", @@ -111,8 +112,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -125,10 +126,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services-http.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services-http.latest.golden index 0a9642cfe658e..acb9d896f69d9 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services-http.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services-http.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,7 +22,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "SANITIZE_SET", + "statPrefix": "mesh_gateway_local_peered.bar.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "bar" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -30,24 +38,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "bar" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "SANITIZE_SET", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "mesh_gateway_local_peered.bar.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -61,6 +62,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -71,7 +73,6 @@ } } ], - "tlsParams": {}, "validationContext": { "customValidatorConfig": { "name": "envoy.tls.cert_validator.spiffe", @@ -110,7 +111,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "SANITIZE_SET", + "statPrefix": "mesh_gateway_local_peered.foo.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "foo" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -119,24 +127,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "foo" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "SANITIZE_SET", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "mesh_gateway_local_peered.foo.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -150,6 +151,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -160,7 +162,6 @@ } } ], - "tlsParams": {}, "validationContext": { "customValidatorConfig": { "name": "envoy.tls.cert_validator.spiffe", @@ -199,7 +200,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "SANITIZE_SET", + "statPrefix": "mesh_gateway_local_peered.gir.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "gir" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -208,24 +216,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "gir" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "SANITIZE_SET", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "mesh_gateway_local_peered.gir.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -239,6 +240,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -249,7 +251,6 @@ } } ], - "tlsParams": {}, "validationContext": { "customValidatorConfig": { "name": "envoy.tls.cert_validator.spiffe", @@ -289,8 +290,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -303,10 +304,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services.latest.golden index e5bf3b25a2f3b..5d5ecb30f8cb5 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-with-exported-peered-services.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,8 +22,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "exported~bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_local_peered.bar.default.default.dc1" + "statPrefix": "mesh_gateway_local_peered.bar.default.default.dc1", + "cluster": "exported~bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -38,8 +39,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "exported~foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_local_peered.foo.default.default.dc1" + "statPrefix": "mesh_gateway_local_peered.foo.default.default.dc1", + "cluster": "exported~foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -55,8 +56,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "exported~gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_local_peered.gir.default.default.dc1" + "statPrefix": "mesh_gateway_local_peered.gir.default.default.dc1", + "cluster": "exported~gir.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -73,8 +74,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -87,10 +88,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-with-imported-peered-services.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-with-imported-peered-services.latest.golden index 7cecb373468e3..40d5b919bd1e5 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-with-imported-peered-services.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-with-imported-peered-services.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -22,8 +23,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -36,10 +37,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden b/agent/xds/testdata/listeners/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden index 74d349bf4ded1..faae8d00da671 100644 --- a/agent/xds/testdata/listeners/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,8 +22,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "server.dc2.peering.6d942ff2-6a78-46f4-a52f-915e26c48797", - "statPrefix": "mesh_gateway_remote_peering_servers.server.dc2.peering.6d942ff2-6a78-46f4-a52f-915e26c48797" + "statPrefix": "mesh_gateway_remote_peering_servers.server.dc2.peering.6d942ff2-6a78-46f4-a52f-915e26c48797", + "cluster": "server.dc2.peering.6d942ff2-6a78-46f4-a52f-915e26c48797" } } ] @@ -38,8 +39,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "server.dc2.peering.f3f41279-001d-42bb-912e-f6103fb036b8", - "statPrefix": "mesh_gateway_remote_peering_servers.server.dc2.peering.f3f41279-001d-42bb-912e-f6103fb036b8" + "statPrefix": "mesh_gateway_remote_peering_servers.server.dc2.peering.f3f41279-001d-42bb-912e-f6103fb036b8", + "cluster": "server.dc2.peering.f3f41279-001d-42bb-912e-f6103fb036b8" } } ] @@ -55,8 +56,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "server.dc3.peering.f622dc37-7238-4485-ab58-0f53864a9ae5", - "statPrefix": "mesh_gateway_remote_peering_servers.server.dc3.peering.f622dc37-7238-4485-ab58-0f53864a9ae5" + "statPrefix": "mesh_gateway_remote_peering_servers.server.dc3.peering.f622dc37-7238-4485-ab58-0f53864a9ae5", + "cluster": "server.dc3.peering.f622dc37-7238-4485-ab58-0f53864a9ae5" } } ] @@ -73,8 +74,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -87,10 +88,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/mesh-gateway.latest.golden b/agent/xds/testdata/listeners/mesh-gateway.latest.golden index 3b77ccca9b996..7505e7c201cd2 100644 --- a/agent/xds/testdata/listeners/mesh-gateway.latest.golden +++ b/agent/xds/testdata/listeners/mesh-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,8 +22,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc2" + "statPrefix": "mesh_gateway_remote.default.dc2", + "cluster": "dc2.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -38,8 +39,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc4" + "statPrefix": "mesh_gateway_remote.default.dc4", + "cluster": "dc4.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -55,8 +56,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "mesh_gateway_remote.default.dc6" + "statPrefix": "mesh_gateway_remote.default.dc6", + "cluster": "dc6.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -73,8 +74,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "mesh_gateway_local.default" + "statPrefix": "mesh_gateway_local.default", + "cluster": "" } } ] @@ -87,10 +88,9 @@ "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" } } - ], - "name": "default:1.2.3.4:8443" + ] } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/splitter-with-resolver-redirect.latest.golden b/agent/xds/testdata/listeners/splitter-with-resolver-redirect.latest.golden index 96c6814291eb7..7f85cbeb72575 100644 --- a/agent/xds/testdata/listeners/splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/listeners/splitter-with-resolver-redirect.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,6 +17,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.db.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "db" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -24,14 +33,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "db" - }, - "statPrefix": "upstream.db.default.default.dc1", "tracing": { "randomSampling": {} }, @@ -45,11 +46,11 @@ ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -63,18 +64,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -96,8 +97,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -106,6 +107,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -116,7 +118,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -128,10 +129,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/telemetry-collector.latest.golden b/agent/xds/testdata/listeners/telemetry-collector.latest.golden index 81208f9375f80..1c850d70c38ca 100644 --- a/agent/xds/testdata/listeners/telemetry-collector.latest.golden +++ b/agent/xds/testdata/listeners/telemetry-collector.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "consul-telemetry-collector:/tmp/consul/telemetry-collector/gqmuzdHCUPAEY5mbF8vgkZCNI14.sock", "address": { "pipe": { "path": "/tmp/consul/telemetry-collector/gqmuzdHCUPAEY5mbF8vgkZCNI14.sock" @@ -15,7 +16,28 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "http2ProtocolOptions": {}, + "statPrefix": "upstream.consul-telemetry-collector.default.default.dc1", + "routeConfig": { + "name": "consul-telemetry-collector", + "virtualHosts": [ + { + "name": "consul-telemetry-collector.default.default.dc1", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + } + } + ] + } + ] + }, "httpFilters": [ { "name": "envoy.filters.http.grpc_stats", @@ -37,31 +59,10 @@ } } ], - "routeConfig": { - "name": "consul-telemetry-collector", - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "consul-telemetry-collector.default.default.dc1", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "consul-telemetry-collector.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - } - ] - } - ] - }, - "statPrefix": "upstream.consul-telemetry-collector.default.default.dc1", "tracing": { "randomSampling": {} }, + "http2ProtocolOptions": {}, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -72,11 +73,11 @@ ] } ], - "name": "consul-telemetry-collector:/tmp/consul/telemetry-collector/gqmuzdHCUPAEY5mbF8vgkZCNI14.sock", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -90,18 +91,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -115,18 +116,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -148,8 +149,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -158,6 +159,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -168,7 +170,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -180,10 +181,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.latest.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.latest.golden index d526bbab4a379..26f56d3dd372d 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.latest.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-custom-and-tagged-addresses.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "foo:198.17.2.3:8080", "address": { "socketAddress": { "address": "198.17.2.3", @@ -21,7 +22,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -29,8 +32,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +42,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -49,7 +55,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -71,7 +76,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -79,8 +86,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -89,6 +96,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -99,7 +109,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -121,7 +130,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -129,8 +140,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -139,6 +150,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -149,7 +163,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -171,7 +184,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -179,8 +194,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.web.default.default.dc1" + "statPrefix": "upstream.web.default.default.dc1", + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -189,6 +204,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -199,7 +217,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -222,8 +239,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.foo" + "statPrefix": "terminating_gateway.foo", + "cluster": "" } } ] @@ -237,11 +254,11 @@ } } ], - "name": "foo:198.17.2.3:8080", "trafficDirection": "INBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "wan:198.18.0.1:443", "address": { "socketAddress": { "address": "198.18.0.1", @@ -260,7 +277,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -268,8 +287,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -278,6 +297,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -288,7 +310,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -310,7 +331,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -318,8 +341,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -328,6 +351,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -338,7 +364,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -360,7 +385,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -368,8 +395,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -378,6 +405,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -388,7 +418,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -410,7 +439,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -418,8 +449,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.web.default.default.dc1" + "statPrefix": "upstream.web.default.default.dc1", + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -428,6 +459,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -438,7 +472,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -461,8 +494,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.wan" + "statPrefix": "terminating_gateway.wan", + "cluster": "" } } ] @@ -476,10 +509,9 @@ } } ], - "name": "wan:198.18.0.1:443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-custom-trace-listener.latest.golden b/agent/xds/testdata/listeners/terminating-gateway-custom-trace-listener.latest.golden deleted file mode 100644 index 45ad9d29a0958..0000000000000 --- a/agent/xds/testdata/listeners/terminating-gateway-custom-trace-listener.latest.golden +++ /dev/null @@ -1,246 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "1.2.3.4", - "portValue": 8443 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "serverNames": [ - "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICnTCCAkKgAwIBAgIRAJrvEdaRAkSltrotd/l/j2cwCgYIKoZIzj0EAwIwgbgx\nCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj\nbzEaMBgGA1UECRMRMTAxIFNlY29uZCBTdHJlZXQxDjAMBgNVBBETBTk0MTA1MRcw\nFQYDVQQKEw5IYXNoaUNvcnAgSW5jLjE/MD0GA1UEAxM2Q29uc3VsIEFnZW50IENB\nIDk2NjM4NzM1MDkzNTU5NTIwNDk3MTQwOTU3MDY1MTc0OTg3NDMxMB4XDTIwMDQx\nNDIyMzE1MloXDTIxMDQxNDIyMzE1MlowHDEaMBgGA1UEAxMRc2VydmVyLmRjMS5j\nb25zdWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ4v0FoIYI0OWmxE2MR6w5l\n0pWGhc02RpsOPj/6RS1fmXMMu7JzPzwCmkGcR16RlwwhNFKCZsWpvAjVRHf/pTp+\no4HHMIHEMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\nBQUHAwIwDAYDVR0TAQH/BAIwADApBgNVHQ4EIgQgk7kABFitAy3PluyNtmzYiC7H\njSN8W/K/OXNJQAQAscMwKwYDVR0jBCQwIoAgNKbPPepvRHXSAPTc+a/BXBzFX1qJ\ny+Zi7qtjlFX7qtUwLQYDVR0RBCYwJIIRc2VydmVyLmRjMS5jb25zdWyCCWxvY2Fs\naG9zdIcEfwAAATAKBggqhkjOPQQDAgNJADBGAiEAhP4HmN5BWysWTbQWClXaWUah\nLpBGFrvc/2cCQuyEZKsCIQD6JyYCYMArtWwZ4G499zktxrFlqfX14bqyONrxtA5I\nDw==\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIE3KbKXHdsa0vvC1fysQaGdoJRgjRALIolI4XJanie+coAoGCCqGSM49\nAwEHoUQDQgAEOL9BaCGCNDlpsRNjEesOZdKVhoXNNkabDj4/+kUtX5lzDLuycz88\nAppBnEdekZcMITRSgmbFqbwI1UR3/6U6fg==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "serverNames": [ - "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICmjCCAkGgAwIBAgIQe1ZmC0rzRwer6jaH1YIUIjAKBggqhkjOPQQDAjCBuDEL\nMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv\nMRowGAYDVQQJExExMDEgU2Vjb25kIFN0cmVldDEOMAwGA1UEERMFOTQxMDUxFzAV\nBgNVBAoTDkhhc2hpQ29ycCBJbmMuMT8wPQYDVQQDEzZDb25zdWwgQWdlbnQgQ0Eg\nODE5ODAwNjg0MDM0MTM3ODkyNDYxNTA1MDk0NDU3OTU1MTQxNjEwHhcNMjAwNjE5\nMTU1MjAzWhcNMjEwNjE5MTU1MjAzWjAcMRowGAYDVQQDExFzZXJ2ZXIuZGMxLmNv\nbnN1bDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH2aWaaa3fpQLBayheHiKlrH\n+z53m0frfGknKjOhOPVYDVHV8x0OE01negswVQbKHAtxPf1M8Zy+WbI9rK7Ua1mj\ngccwgcQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF\nBQcDAjAMBgNVHRMBAf8EAjAAMCkGA1UdDgQiBCDf9CPBSUwwZvpeW73oJLTmgQE2\ntW1NKpL5t1uq9WFcqDArBgNVHSMEJDAigCCPPd/NxgZB0tq2M8pdVpPj3Cr79iTv\ni4/T1ysodfMb7zAtBgNVHREEJjAkghFzZXJ2ZXIuZGMxLmNvbnN1bIIJbG9jYWxo\nb3N0hwR/AAABMAoGCCqGSM49BAMCA0cAMEQCIFCjFZAoXq0s2ied2eIBv0i1KoW5\nIhCylnKFt6iHkyDeAiBBCByTcjHRgEQmqyPojQKoO584EFiczTub9aWdnf9tEw==\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEINsen3S8xzxMrKcRZIvxXzhKDn43Tw9ttqWEFU9TqS5hoAoGCCqGSM49\nAwEHoUQDQgAEfZpZpprd+lAsFrKF4eIqWsf7PnebR+t8aScqM6E49VgNUdXzHQ4T\nTWd6CzBVBsocC3E9/UzxnL5Zsj2srtRrWQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "serverNames": [ - "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICnTCCAkOgAwIBAgIRAKF+qDJbaOULNL1TIatrsBowCgYIKoZIzj0EAwIwgbkx\nCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj\nbzEaMBgGA1UECRMRMTAxIFNlY29uZCBTdHJlZXQxDjAMBgNVBBETBTk0MTA1MRcw\nFQYDVQQKEw5IYXNoaUNvcnAgSW5jLjFAMD4GA1UEAxM3Q29uc3VsIEFnZW50IENB\nIDE4Nzg3MDAwNjUzMDcxOTYzNTk1ODkwNTE1ODY1NjEzMDA2MTU0NDAeFw0yMDA2\nMTkxNTMxMzRaFw0yMTA2MTkxNTMxMzRaMBwxGjAYBgNVBAMTEXNlcnZlci5kYzEu\nY29uc3VsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdQ8Igci5f7ZvvCVsxXt9\ntLfvczD+60XHg0OC0+Aka7ZjQfbEjQwZbz/82EwPoS7Dqo3LTK4IuelOimoNNxuk\nkaOBxzCBxDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG\nAQUFBwMCMAwGA1UdEwEB/wQCMAAwKQYDVR0OBCIEILzTLkfJcdWQnTMKUcai/YJq\n0RqH1pjCqtY7SOU4gGOTMCsGA1UdIwQkMCKAIMa2vNcTEC5AGfHIYARJ/4sodX0o\nLzCj3lpw7BcEzPTcMC0GA1UdEQQmMCSCEXNlcnZlci5kYzEuY29uc3Vsgglsb2Nh\nbGhvc3SHBH8AAAEwCgYIKoZIzj0EAwIDSAAwRQIgBZ/Z4GSLEc98WvT/qjTVCNTG\n1WNaAaesVbkRx+J0yl8CIQDAVoqY9ByA5vKHjnQrxWlc/JUtJz8wudg7e/OCRriP\nSg==\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIN1v14FaNxgY4MgjDOOWthen8dgwB0lNMs9/j2TfrnxzoAoGCCqGSM49\nAwEHoUQDQgAEdQ8Igci5f7ZvvCVsxXt9tLfvczD+60XHg0OC0+Aka7ZjQfbEjQwZ\nbz/82EwPoS7Dqo3LTK4IuelOimoNNxukkQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "serverNames": [ - "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.web.default.default.dc1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - }, - { - "filters": [ - { - "name": "envoy.filters.network.sni_cluster", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.sni_cluster.v3.SniCluster" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" - } - } - ] - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "name": "default:1.2.3.4:8443", - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.latest.golden b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.latest.golden index 4c744e07a7891..acbcc16b42acb 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.latest.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-api-cert.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,7 +22,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -29,8 +32,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +42,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -49,7 +55,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -71,7 +76,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -79,8 +86,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -89,6 +96,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -99,7 +109,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -121,7 +130,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -129,8 +140,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.web.default.default.dc1" + "statPrefix": "upstream.web.default.default.dc1", + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -139,6 +150,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -149,7 +163,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -172,8 +185,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -187,10 +200,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-no-services.latest.golden b/agent/xds/testdata/listeners/terminating-gateway-no-services.latest.golden index 1e4dd317a7698..329a0cb6c3d81 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-no-services.latest.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-no-services.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -22,8 +23,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -37,10 +38,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.latest.golden b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.latest.golden index a508e82d51595..e4b6373c8766c 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-service-subsets.latest.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-service-subsets.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -29,8 +30,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +40,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -49,7 +51,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -79,8 +80,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -89,6 +90,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -99,7 +101,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -129,8 +130,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -139,6 +140,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -149,7 +151,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -171,7 +172,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.web.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -187,24 +195,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.web.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -218,6 +219,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -228,7 +230,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -250,7 +251,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.web.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -266,24 +274,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.web.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -297,6 +298,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -307,7 +309,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -329,7 +330,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.web.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -345,24 +353,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.web.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -376,6 +377,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -386,7 +388,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -409,8 +410,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -424,10 +425,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-cipher-suites.latest.golden b/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-cipher-suites.latest.golden index 617d1f53306a1..b3a94c9478865 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-cipher-suites.latest.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-cipher-suites.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,7 +22,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -29,8 +32,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +42,12 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -49,12 +58,6 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -76,7 +79,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -84,8 +89,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -94,6 +99,12 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -104,12 +115,6 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -131,7 +136,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -139,8 +146,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -149,6 +156,12 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -159,12 +172,6 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -186,7 +193,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -194,8 +203,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.web.default.default.dc1" + "statPrefix": "upstream.web.default.default.dc1", + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -204,6 +213,12 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "cipherSuites": [ + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305" + ] + }, "tlsCertificates": [ { "certificateChain": { @@ -214,12 +229,6 @@ } } ], - "tlsParams": { - "cipherSuites": [ - "ECDHE-ECDSA-AES128-GCM-SHA256", - "ECDHE-ECDSA-CHACHA20-POLY1305" - ] - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -242,8 +251,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -257,10 +266,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-max-version.latest.golden b/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-max-version.latest.golden index 1d3be93f33dfa..e2554002e0cda 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-max-version.latest.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-max-version.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,7 +22,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -29,8 +32,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +42,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -49,9 +55,6 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -73,7 +76,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -81,8 +86,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -91,6 +96,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -101,9 +109,6 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -125,7 +130,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -133,8 +140,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -143,6 +150,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -153,9 +163,6 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -177,7 +184,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -185,8 +194,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.web.default.default.dc1" + "statPrefix": "upstream.web.default.default.dc1", + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -195,6 +204,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMaximumProtocolVersion": "TLSv1_2" + }, "tlsCertificates": [ { "certificateChain": { @@ -205,9 +217,6 @@ } } ], - "tlsParams": { - "tlsMaximumProtocolVersion": "TLSv1_2" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -230,8 +239,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -245,10 +254,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-min-version.latest.golden b/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-min-version.latest.golden index cb2deaf63e441..daf9ca01fcee1 100644 --- a/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-min-version.latest.golden +++ b/agent/xds/testdata/listeners/terminating-gateway-with-tls-incoming-min-version.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,7 +22,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -29,8 +32,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +42,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -49,9 +55,6 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -73,7 +76,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -81,8 +86,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -91,6 +96,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -101,9 +109,6 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -125,7 +130,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -133,8 +140,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -143,6 +150,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -153,9 +163,6 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -177,7 +184,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -185,8 +194,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.web.default.default.dc1" + "statPrefix": "upstream.web.default.default.dc1", + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -195,6 +204,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + "tlsMinimumProtocolVersion": "TLSv1_3" + }, "tlsCertificates": [ { "certificateChain": { @@ -205,9 +217,6 @@ } } ], - "tlsParams": { - "tlsMinimumProtocolVersion": "TLSv1_3" - }, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -230,8 +239,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -245,10 +254,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/terminating-gateway.latest.golden b/agent/xds/testdata/listeners/terminating-gateway.latest.golden index 45ad9d29a0958..4af97913f84dd 100644 --- a/agent/xds/testdata/listeners/terminating-gateway.latest.golden +++ b/agent/xds/testdata/listeners/terminating-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -21,7 +22,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -29,8 +32,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.api.default.default.dc1" + "statPrefix": "upstream.api.default.default.dc1", + "cluster": "api.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +42,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -49,7 +55,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -71,7 +76,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -79,8 +86,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.cache.default.default.dc1" + "statPrefix": "upstream.cache.default.default.dc1", + "cluster": "cache.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -89,6 +96,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -99,7 +109,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -121,7 +130,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -129,8 +140,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -139,6 +150,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -149,7 +163,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -171,7 +184,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -179,8 +194,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.web.default.default.dc1" + "statPrefix": "upstream.web.default.default.dc1", + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -189,6 +204,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -199,7 +217,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -222,8 +239,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -237,10 +254,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-catalog-destinations-only.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-catalog-destinations-only.latest.golden index 96d66a6fd90b8..9d6d5003781ff 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-catalog-destinations-only.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-catalog-destinations-only.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", @@ -49,8 +50,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.google.default.default.dc1" + "statPrefix": "upstream.google.default.default.dc1", + "cluster": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -64,11 +65,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -82,18 +83,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -107,7 +108,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -115,8 +118,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -125,6 +128,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -135,7 +141,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -147,10 +152,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-destination-http.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-destination-http.latest.golden index c6cd171ee4c2d..6af38eb779795 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-destination-http.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-destination-http.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", @@ -44,6 +45,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -52,14 +61,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - }, - "statPrefix": "upstream.destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "tracing": { "randomSampling": {} }, @@ -81,6 +82,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.router", @@ -89,14 +98,6 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - }, - "statPrefix": "upstream.destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "tracing": { "randomSampling": {} }, @@ -124,11 +125,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -142,18 +143,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -175,8 +176,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -185,6 +186,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -195,7 +197,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -207,10 +208,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-destination.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-destination.latest.golden index 1f532d8ab0b36..9ebe596961610 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-destination.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-destination.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", @@ -50,8 +51,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "statPrefix": "upstream.destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "cluster": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -71,8 +72,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.192-168-2-2.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.destination.192-168-2-2.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "statPrefix": "upstream.destination.192-168-2-2.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "cluster": "destination.192-168-2-2.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -89,8 +90,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.api-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.destination.api-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "statPrefix": "upstream.destination.api-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "cluster": "destination.api-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -107,8 +108,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "statPrefix": "upstream.destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "cluster": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -128,11 +129,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -146,18 +147,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -171,7 +172,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -179,8 +182,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -189,6 +192,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -199,7 +205,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -211,10 +216,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-dial-instances-directly.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-dial-instances-directly.latest.golden index 8ab799ecc9f97..ddfaa45d5f64e 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-dial-instances-directly.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-dial-instances-directly.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,36 +17,24 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 15001 } }, - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "original-destination", - "statPrefix": "upstream.original-destination" - } - } - ] - }, "filterChains": [ { "filterChainMatch": { @@ -65,8 +54,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "passthrough~mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.mongo.default.default.dc1" + "statPrefix": "upstream.mongo.default.default.dc1", + "cluster": "passthrough~mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -85,8 +74,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.mongo.default.default.dc1" + "statPrefix": "upstream.mongo.default.default.dc1", + "cluster": "mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -105,13 +94,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "passthrough~kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.kafka.default.default.dc1" + "statPrefix": "upstream.kafka.default.default.dc1", + "cluster": "passthrough~kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, "listenerFilters": [ { "name": "envoy.filters.listener.original_dst", @@ -120,11 +121,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -138,18 +139,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -163,7 +164,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -171,8 +174,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -181,6 +184,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -191,7 +197,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -203,10 +208,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-http-upstream.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-http-upstream.latest.golden index ca7f40840fa3e..fa56fb8d3f022 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-http-upstream.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-http-upstream.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,36 +17,24 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 15001 } }, - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "original-destination", - "statPrefix": "upstream.original-destination" - } - } - ] - }, "filterChains": [ { "filterChainMatch": { @@ -65,22 +54,15 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], + "statPrefix": "upstream.google.default.default.dc1", "routeConfig": { "name": "google", "virtualHosts": [ { + "name": "google.default.default.dc1", "domains": [ "*" ], - "name": "google.default.default.dc1", "routes": [ { "match": { @@ -94,7 +76,14 @@ } ] }, - "statPrefix": "upstream.google.default.default.dc1", + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], "tracing": { "randomSampling": {} }, @@ -108,6 +97,18 @@ ] } ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, "listenerFilters": [ { "name": "envoy.filters.listener.original_dst", @@ -116,11 +117,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -134,18 +135,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -167,8 +168,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -177,6 +178,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -187,7 +189,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -199,10 +200,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-terminating-gateway-destinations-only.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-terminating-gateway-destinations-only.latest.golden index da8448a2065ff..769b3bb497907 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-terminating-gateway-destinations-only.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-terminating-gateway-destinations-only.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default:1.2.3.4:8443", "address": { "socketAddress": { "address": "1.2.3.4", @@ -29,8 +30,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.192-168-0-1.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.external-IP-TCP.default.default.dc1" + "statPrefix": "upstream.external-IP-TCP.default.default.dc1", + "cluster": "destination.192-168-0-1.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -39,6 +40,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -49,7 +51,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -71,7 +72,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.external-IP-HTTP.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "destination.192-168-0-2.external-IP-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -87,24 +95,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "destination.192-168-0-2.external-IP-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.external-IP-HTTP.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -118,6 +119,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -128,7 +130,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -158,8 +159,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.192-168-0-2.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.external-IP-TCP.default.default.dc1" + "statPrefix": "upstream.external-IP-TCP.default.default.dc1", + "cluster": "destination.192-168-0-2.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -168,6 +169,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -178,7 +180,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -208,8 +209,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.192-168-0-3.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.external-IP-TCP.default.default.dc1" + "statPrefix": "upstream.external-IP-TCP.default.default.dc1", + "cluster": "destination.192-168-0-3.external-IP-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -218,6 +219,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -228,7 +230,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -258,8 +259,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.api-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.external-hostname-TCP.default.default.dc1" + "statPrefix": "upstream.external-hostname-TCP.default.default.dc1", + "cluster": "destination.api-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -268,6 +269,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -278,7 +280,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -308,8 +309,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.external-hostname-with-SNI.default.default.dc1" + "statPrefix": "upstream.external-hostname-with-SNI.default.default.dc1", + "cluster": "destination.api-test-com.external-hostname-with-SNI.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -318,6 +319,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -328,7 +330,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -350,7 +351,14 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "forwardClientCertDetails": "APPEND_FORWARD", + "statPrefix": "upstream.external-hostname-HTTP.default.default.dc1", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "httpFilters": [ { "name": "envoy.filters.http.rbac", @@ -366,24 +374,17 @@ } } ], - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "tracing": { + "randomSampling": {} }, + "forwardClientCertDetails": "APPEND_FORWARD", "setCurrentClientCertDetails": { + "subject": true, "cert": true, "chain": true, "dns": true, - "subject": true, "uri": true }, - "statPrefix": "upstream.external-hostname-HTTP.default.default.dc1", - "tracing": { - "randomSampling": {} - }, "upgradeConfigs": [ { "upgradeType": "websocket" @@ -397,6 +398,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -407,7 +409,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -437,8 +438,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "destination.web-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.external-hostname-TCP.default.default.dc1" + "statPrefix": "upstream.external-hostname-TCP.default.default.dc1", + "cluster": "destination.web-hashicorp-com.external-hostname-TCP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ], @@ -447,6 +448,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -457,7 +459,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -480,8 +481,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "", - "statPrefix": "terminating_gateway.default" + "statPrefix": "terminating_gateway.default", + "cluster": "" } } ] @@ -495,10 +496,9 @@ } } ], - "name": "default:1.2.3.4:8443", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-terminating-gateway.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-terminating-gateway.latest.golden index fb8f3835e040e..949e2f8b0ca48 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-terminating-gateway.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-terminating-gateway.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", @@ -49,8 +50,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.google.default.default.dc1" + "statPrefix": "upstream.google.default.default.dc1", + "cluster": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -69,8 +70,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.kafka.default.default.dc1" + "statPrefix": "upstream.kafka.default.default.dc1", + "cluster": "kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] @@ -84,11 +85,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -102,18 +103,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -127,7 +128,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -135,8 +138,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -145,6 +148,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -155,7 +161,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -167,10 +172,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-with-peered-upstreams.latest.golden index d2deb2f56b69e..cc7f73ae96a00 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-with-peered-upstreams.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "api-a?peer=peer-a:127.0.0.1:9090", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,18 +17,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "api-a.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "statPrefix": "upstream_peered.api-a.default.peer-a" + "statPrefix": "upstream_peered.api-a.default.peer-a", + "cluster": "api-a.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } } ] } ], - "name": "api-a?peer=peer-a:127.0.0.1:9090", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "no-endpoints?peer=peer-a:127.0.0.1:1234", "address": { "socketAddress": { "address": "127.0.0.1", @@ -41,36 +42,24 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "no-endpoints.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "statPrefix": "upstream_peered.no-endpoints.default.peer-a" + "statPrefix": "upstream_peered.no-endpoints.default.peer-a", + "cluster": "no-endpoints.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } } ] } ], - "name": "no-endpoints?peer=peer-a:127.0.0.1:1234", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 15001 } }, - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "original-destination", - "statPrefix": "upstream.original-destination" - } - } - ] - }, "filterChains": [ { "filterChainMatch": { @@ -90,13 +79,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul", - "statPrefix": "upstream_peered.db.default.peer-a" + "statPrefix": "upstream_peered.db.default.peer-a", + "cluster": "db.default.peer-a.external.1c053652-8512-4373-90cf-5a7f6263a994.consul" } } ] } ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, "listenerFilters": [ { "name": "envoy.filters.listener.original_dst", @@ -105,11 +106,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -123,7 +124,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -131,8 +134,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -141,6 +144,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -151,7 +157,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -163,10 +168,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy-with-resolver-redirect-upstream.latest.golden b/agent/xds/testdata/listeners/transparent-proxy-with-resolver-redirect-upstream.latest.golden index d93388e64e22b..18102db969279 100644 --- a/agent/xds/testdata/listeners/transparent-proxy-with-resolver-redirect-upstream.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy-with-resolver-redirect-upstream.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db-redir:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,36 +17,24 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db-redir.default.default.dc1" + "statPrefix": "upstream.db-redir.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db-redir:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 15001 } }, - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "original-destination", - "statPrefix": "upstream.original-destination" - } - } - ] - }, "filterChains": [ { "filterChainMatch": { @@ -65,13 +54,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.google.default.default.dc1" + "statPrefix": "upstream.google.default.default.dc1", + "cluster": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, "listenerFilters": [ { "name": "envoy.filters.listener.original_dst", @@ -80,11 +81,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -98,18 +99,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -131,8 +132,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -141,6 +142,7 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": {}, "tlsCertificates": [ { "certificateChain": { @@ -151,7 +153,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -163,10 +164,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/listeners/transparent-proxy.latest.golden b/agent/xds/testdata/listeners/transparent-proxy.latest.golden index f1a3f22fad9df..ee4c90857d057 100644 --- a/agent/xds/testdata/listeners/transparent-proxy.latest.golden +++ b/agent/xds/testdata/listeners/transparent-proxy.latest.golden @@ -1,8 +1,9 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "db:127.0.0.1:9191", "address": { "socketAddress": { "address": "127.0.0.1", @@ -16,36 +17,24 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" + "statPrefix": "upstream.db.default.default.dc1", + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "db:127.0.0.1:9191", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener:127.0.0.1:15001", "address": { "socketAddress": { "address": "127.0.0.1", "portValue": 15001 } }, - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "original-destination", - "statPrefix": "upstream.original-destination" - } - } - ] - }, "filterChains": [ { "filterChainMatch": { @@ -65,13 +54,25 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.google.default.default.dc1" + "statPrefix": "upstream.google.default.default.dc1", + "cluster": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, "listenerFilters": [ { "name": "envoy.filters.listener.original_dst", @@ -80,11 +81,11 @@ } } ], - "name": "outbound_listener:127.0.0.1:15001", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "prepared_query:geo-cache:127.10.10.10:8181", "address": { "socketAddress": { "address": "127.10.10.10", @@ -98,18 +99,18 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" + "statPrefix": "upstream.prepared_query_geo-cache", + "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul" } } ] } ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", "trafficDirection": "OUTBOUND" }, { "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener:0.0.0.0:9999", "address": { "socketAddress": { "address": "0.0.0.0", @@ -123,7 +124,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } }, @@ -131,8 +134,8 @@ "name": "envoy.filters.network.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" + "statPrefix": "public_listener", + "cluster": "local_app" } } ], @@ -141,6 +144,9 @@ "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", "commonTlsContext": { + "tlsParams": { + + }, "tlsCertificates": [ { "certificateChain": { @@ -151,7 +157,6 @@ } } ], - "tlsParams": {}, "validationContext": { "trustedCa": { "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" @@ -163,10 +168,9 @@ } } ], - "name": "public_listener:0.0.0.0:9999", "trafficDirection": "INBOUND" } ], "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/default-allow-deny-all-and-path-allow--httpfilter.golden b/agent/xds/testdata/rbac/default-allow-deny-all-and-path-allow--httpfilter.golden index 0659f2c4afc92..b590b7135d872 100644 --- a/agent/xds/testdata/rbac/default-allow-deny-all-and-path-allow--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-allow-deny-all-and-path-allow--httpfilter.golden @@ -19,7 +19,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -30,7 +32,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-deny-all-and-path-allow.golden b/agent/xds/testdata/rbac/default-allow-deny-all-and-path-allow.golden index 956dd00006ccf..51346b03fa51f 100644 --- a/agent/xds/testdata/rbac/default-allow-deny-all-and-path-allow.golden +++ b/agent/xds/testdata/rbac/default-allow-deny-all-and-path-allow.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -29,7 +31,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -40,7 +44,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-deny-all-and-path-deny--httpfilter.golden b/agent/xds/testdata/rbac/default-allow-deny-all-and-path-deny--httpfilter.golden index d57d60bc770b4..62f4ba97eac4d 100644 --- a/agent/xds/testdata/rbac/default-allow-deny-all-and-path-deny--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-allow-deny-all-and-path-deny--httpfilter.golden @@ -19,7 +19,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -30,7 +32,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -57,7 +61,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-deny-all-and-path-deny.golden b/agent/xds/testdata/rbac/default-allow-deny-all-and-path-deny.golden index 956dd00006ccf..51346b03fa51f 100644 --- a/agent/xds/testdata/rbac/default-allow-deny-all-and-path-deny.golden +++ b/agent/xds/testdata/rbac/default-allow-deny-all-and-path-deny.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -29,7 +31,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -40,7 +44,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-kitchen-sink--httpfilter.golden b/agent/xds/testdata/rbac/default-allow-kitchen-sink--httpfilter.golden index b220a6d38ed6b..65da4d27fc376 100644 --- a/agent/xds/testdata/rbac/default-allow-kitchen-sink--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-allow-kitchen-sink--httpfilter.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" } } @@ -26,7 +28,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -39,7 +43,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -50,7 +56,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -62,7 +70,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/unsafe$" } } @@ -74,7 +84,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" } } diff --git a/agent/xds/testdata/rbac/default-allow-kitchen-sink.golden b/agent/xds/testdata/rbac/default-allow-kitchen-sink.golden index 6bb4e9e2ff2ec..21e94ee14eb3a 100644 --- a/agent/xds/testdata/rbac/default-allow-kitchen-sink.golden +++ b/agent/xds/testdata/rbac/default-allow-kitchen-sink.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" } } @@ -26,7 +28,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -39,7 +43,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -50,7 +56,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -62,7 +70,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/unsafe$" } } @@ -74,7 +84,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" } } diff --git a/agent/xds/testdata/rbac/default-allow-one-deny--httpfilter.golden b/agent/xds/testdata/rbac/default-allow-one-deny--httpfilter.golden index 851499ce9796a..f315c45e009b2 100644 --- a/agent/xds/testdata/rbac/default-allow-one-deny--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-allow-one-deny--httpfilter.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-one-deny.golden b/agent/xds/testdata/rbac/default-allow-one-deny.golden index 19f25b92ff5f0..45b6965e08b12 100644 --- a/agent/xds/testdata/rbac/default-allow-one-deny.golden +++ b/agent/xds/testdata/rbac/default-allow-one-deny.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-path-allow.golden b/agent/xds/testdata/rbac/default-allow-path-allow.golden index 19f25b92ff5f0..45b6965e08b12 100644 --- a/agent/xds/testdata/rbac/default-allow-path-allow.golden +++ b/agent/xds/testdata/rbac/default-allow-path-allow.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-path-deny--httpfilter.golden b/agent/xds/testdata/rbac/default-allow-path-deny--httpfilter.golden index fc818d19ec378..aa06ebe3d2ee2 100644 --- a/agent/xds/testdata/rbac/default-allow-path-deny--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-allow-path-deny--httpfilter.golden @@ -20,7 +20,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-path-deny.golden b/agent/xds/testdata/rbac/default-allow-path-deny.golden index 19f25b92ff5f0..45b6965e08b12 100644 --- a/agent/xds/testdata/rbac/default-allow-path-deny.golden +++ b/agent/xds/testdata/rbac/default-allow-path-deny.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-service-wildcard-deny--httpfilter.golden b/agent/xds/testdata/rbac/default-allow-service-wildcard-deny--httpfilter.golden index c16e12089d061..0c69fa84585bb 100644 --- a/agent/xds/testdata/rbac/default-allow-service-wildcard-deny--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-allow-service-wildcard-deny--httpfilter.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } diff --git a/agent/xds/testdata/rbac/default-allow-service-wildcard-deny.golden b/agent/xds/testdata/rbac/default-allow-service-wildcard-deny.golden index 907c9e06b1f45..d685342e93994 100644 --- a/agent/xds/testdata/rbac/default-allow-service-wildcard-deny.golden +++ b/agent/xds/testdata/rbac/default-allow-service-wildcard-deny.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } diff --git a/agent/xds/testdata/rbac/default-allow-single-intention-with-kitchen-sink-perms--httpfilter.golden b/agent/xds/testdata/rbac/default-allow-single-intention-with-kitchen-sink-perms--httpfilter.golden index c2e9504c390c0..ba1787d12fe97 100644 --- a/agent/xds/testdata/rbac/default-allow-single-intention-with-kitchen-sink-perms--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-allow-single-intention-with-kitchen-sink-perms--httpfilter.golden @@ -39,7 +39,9 @@ "urlPath": { "path": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "/v[123]" } } @@ -49,7 +51,9 @@ "header": { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|HEAD|OPTIONS" } } @@ -93,82 +97,70 @@ { "header": { "name": "x-bar", - "stringMatch": { - "exact": "xyz" - } + "exactMatch": "xyz" } }, { "header": { "name": "x-dib", - "stringMatch": { - "prefix": "gaz" - } + "prefixMatch": "gaz" } }, { "header": { "name": "x-gir", - "stringMatch": { - "suffix": "zim" - } + "suffixMatch": "zim" } }, { "header": { "name": "x-zim", - "stringMatch": { - "safeRegex": { - "googleRe2": {}, - "regex": "gi[rR]" - } + "safeRegexMatch": { + "googleRe2": { + + }, + "regex": "gi[rR]" } } }, { "header": { - "invertMatch": true, "name": "z-foo", - "presentMatch": true + "presentMatch": true, + "invertMatch": true } }, { "header": { - "invertMatch": true, "name": "z-bar", - "stringMatch": { - "exact": "xyz" - } + "exactMatch": "xyz", + "invertMatch": true } }, { "header": { - "invertMatch": true, "name": "z-dib", - "stringMatch": { - "prefix": "gaz" - } + "prefixMatch": "gaz", + "invertMatch": true } }, { "header": { - "invertMatch": true, "name": "z-gir", - "stringMatch": { - "suffix": "zim" - } + "suffixMatch": "zim", + "invertMatch": true } }, { "header": { - "invertMatch": true, "name": "z-zim", - "stringMatch": { - "safeRegex": { - "googleRe2": {}, - "regex": "gi[rR]" - } - } + "safeRegexMatch": { + "googleRe2": { + + }, + "regex": "gi[rR]" + }, + "invertMatch": true } } ] @@ -182,7 +174,9 @@ "urlPath": { "path": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "/v[123]" } } @@ -192,7 +186,9 @@ "header": { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|HEAD|OPTIONS" } } @@ -228,7 +224,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-single-intention-with-kitchen-sink-perms.golden b/agent/xds/testdata/rbac/default-allow-single-intention-with-kitchen-sink-perms.golden index 19f25b92ff5f0..45b6965e08b12 100644 --- a/agent/xds/testdata/rbac/default-allow-single-intention-with-kitchen-sink-perms.golden +++ b/agent/xds/testdata/rbac/default-allow-single-intention-with-kitchen-sink-perms.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-two-path-deny-and-path-allow--httpfilter.golden b/agent/xds/testdata/rbac/default-allow-two-path-deny-and-path-allow--httpfilter.golden index ec4f26e958c17..98f4142098861 100644 --- a/agent/xds/testdata/rbac/default-allow-two-path-deny-and-path-allow--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-allow-two-path-deny-and-path-allow--httpfilter.golden @@ -42,7 +42,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-allow-two-path-deny-and-path-allow.golden b/agent/xds/testdata/rbac/default-allow-two-path-deny-and-path-allow.golden index 19f25b92ff5f0..45b6965e08b12 100644 --- a/agent/xds/testdata/rbac/default-allow-two-path-deny-and-path-allow.golden +++ b/agent/xds/testdata/rbac/default-allow-two-path-deny-and-path-allow.golden @@ -16,7 +16,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-allow-deny--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-allow-deny--httpfilter.golden index cba46edc59cc6..3e48b7c566d56 100644 --- a/agent/xds/testdata/rbac/default-deny-allow-deny--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-allow-deny--httpfilter.golden @@ -18,7 +18,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -29,7 +31,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-allow-deny.golden b/agent/xds/testdata/rbac/default-deny-allow-deny.golden index 185bbc27343c7..d901cf42cf56d 100644 --- a/agent/xds/testdata/rbac/default-deny-allow-deny.golden +++ b/agent/xds/testdata/rbac/default-deny-allow-deny.golden @@ -18,7 +18,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -29,7 +31,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-deny-all-and-path-allow--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-deny-all-and-path-allow--httpfilter.golden index 880d5e18673fc..003fdb24bede8 100644 --- a/agent/xds/testdata/rbac/default-deny-deny-all-and-path-allow--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-deny-all-and-path-allow--httpfilter.golden @@ -19,7 +19,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-deny-all-and-path-allow.golden b/agent/xds/testdata/rbac/default-deny-deny-all-and-path-allow.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/default-deny-deny-all-and-path-allow.golden +++ b/agent/xds/testdata/rbac/default-deny-deny-all-and-path-allow.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/default-deny-deny-all-and-path-deny--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-deny-all-and-path-deny--httpfilter.golden index a435b1f2b8702..4ccd189bc0682 100644 --- a/agent/xds/testdata/rbac/default-deny-deny-all-and-path-deny--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-deny-all-and-path-deny--httpfilter.golden @@ -2,6 +2,8 @@ "name": "envoy.filters.http.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} + "rules": { + + } } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/default-deny-deny-all-and-path-deny.golden b/agent/xds/testdata/rbac/default-deny-deny-all-and-path-deny.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/default-deny-deny-all-and-path-deny.golden +++ b/agent/xds/testdata/rbac/default-deny-deny-all-and-path-deny.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/default-deny-kitchen-sink--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-kitchen-sink--httpfilter.golden index c551798d6bc20..426404d748b19 100644 --- a/agent/xds/testdata/rbac/default-deny-kitchen-sink--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-kitchen-sink--httpfilter.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" } } @@ -25,7 +27,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -38,7 +42,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -49,7 +55,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -61,7 +69,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/unsafe$" } } @@ -73,7 +83,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" } } diff --git a/agent/xds/testdata/rbac/default-deny-kitchen-sink.golden b/agent/xds/testdata/rbac/default-deny-kitchen-sink.golden index 173f54b3db167..912b64d95c00a 100644 --- a/agent/xds/testdata/rbac/default-deny-kitchen-sink.golden +++ b/agent/xds/testdata/rbac/default-deny-kitchen-sink.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" } } @@ -25,7 +27,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -38,7 +42,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -49,7 +55,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -61,7 +69,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/unsafe$" } } @@ -73,7 +83,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" } } diff --git a/agent/xds/testdata/rbac/default-deny-mixed-precedence--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-mixed-precedence--httpfilter.golden index fb2154c82e27f..c4795f46ef551 100644 --- a/agent/xds/testdata/rbac/default-deny-mixed-precedence--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-mixed-precedence--httpfilter.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-mixed-precedence.golden b/agent/xds/testdata/rbac/default-deny-mixed-precedence.golden index a02fd3518c1ec..3fc78b29552dd 100644 --- a/agent/xds/testdata/rbac/default-deny-mixed-precedence.golden +++ b/agent/xds/testdata/rbac/default-deny-mixed-precedence.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-one-allow--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-one-allow--httpfilter.golden index fb2154c82e27f..c4795f46ef551 100644 --- a/agent/xds/testdata/rbac/default-deny-one-allow--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-one-allow--httpfilter.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-one-allow.golden b/agent/xds/testdata/rbac/default-deny-one-allow.golden index a02fd3518c1ec..3fc78b29552dd 100644 --- a/agent/xds/testdata/rbac/default-deny-one-allow.golden +++ b/agent/xds/testdata/rbac/default-deny-one-allow.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-path-allow--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-path-allow--httpfilter.golden index 880d5e18673fc..003fdb24bede8 100644 --- a/agent/xds/testdata/rbac/default-deny-path-allow--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-path-allow--httpfilter.golden @@ -19,7 +19,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-path-allow.golden b/agent/xds/testdata/rbac/default-deny-path-allow.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/default-deny-path-allow.golden +++ b/agent/xds/testdata/rbac/default-deny-path-allow.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/default-deny-path-deny--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-path-deny--httpfilter.golden index a435b1f2b8702..4ccd189bc0682 100644 --- a/agent/xds/testdata/rbac/default-deny-path-deny--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-path-deny--httpfilter.golden @@ -2,6 +2,8 @@ "name": "envoy.filters.http.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} + "rules": { + + } } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/default-deny-path-deny.golden b/agent/xds/testdata/rbac/default-deny-path-deny.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/default-deny-path-deny.golden +++ b/agent/xds/testdata/rbac/default-deny-path-deny.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/default-deny-peered-kitchen-sink--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-peered-kitchen-sink--httpfilter.golden index 8b81593142cd7..2ffed83910341 100644 --- a/agent/xds/testdata/rbac/default-deny-peered-kitchen-sink--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-peered-kitchen-sink--httpfilter.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -28,7 +30,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/gateway/mesh/dc/[^/]+$" } } @@ -42,7 +46,9 @@ "name": "x-forwarded-client-cert", "stringMatch": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^[^,]+;URI=spiffe://peer1.domain/ap/part1/ns/default/dc/[^/]+/svc/[^/]+(?:,.*)?$" } } @@ -54,7 +60,9 @@ "name": "x-forwarded-client-cert", "stringMatch": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^[^,]+;URI=spiffe://peer1.domain/ap/part1/ns/default/dc/[^/]+/svc/web(?:,.*)?$" } } diff --git a/agent/xds/testdata/rbac/default-deny-peered-kitchen-sink.golden b/agent/xds/testdata/rbac/default-deny-peered-kitchen-sink.golden index ba7fc6b4d0d0f..eb480159407c9 100644 --- a/agent/xds/testdata/rbac/default-deny-peered-kitchen-sink.golden +++ b/agent/xds/testdata/rbac/default-deny-peered-kitchen-sink.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -28,7 +30,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://peer1.domain/ap/part1/ns/default/dc/[^/]+/svc/[^/]+$" } } @@ -39,7 +43,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://peer1.domain/ap/part1/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-service-wildcard-allow--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-service-wildcard-allow--httpfilter.golden index ce7174d5d0137..a65162f24fb96 100644 --- a/agent/xds/testdata/rbac/default-deny-service-wildcard-allow--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-service-wildcard-allow--httpfilter.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } diff --git a/agent/xds/testdata/rbac/default-deny-service-wildcard-allow.golden b/agent/xds/testdata/rbac/default-deny-service-wildcard-allow.golden index caad3988db147..3780a9079ebc7 100644 --- a/agent/xds/testdata/rbac/default-deny-service-wildcard-allow.golden +++ b/agent/xds/testdata/rbac/default-deny-service-wildcard-allow.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" } } diff --git a/agent/xds/testdata/rbac/default-deny-single-intention-with-kitchen-sink-perms--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-single-intention-with-kitchen-sink-perms--httpfilter.golden index e745e5278f366..f23112071b978 100644 --- a/agent/xds/testdata/rbac/default-deny-single-intention-with-kitchen-sink-perms--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-single-intention-with-kitchen-sink-perms--httpfilter.golden @@ -38,7 +38,9 @@ "urlPath": { "path": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "/v[123]" } } @@ -48,7 +50,9 @@ "header": { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|HEAD|OPTIONS" } } @@ -92,82 +96,70 @@ { "header": { "name": "x-bar", - "stringMatch": { - "exact": "xyz" - } + "exactMatch": "xyz" } }, { "header": { "name": "x-dib", - "stringMatch": { - "prefix": "gaz" - } + "prefixMatch": "gaz" } }, { "header": { "name": "x-gir", - "stringMatch": { - "suffix": "zim" - } + "suffixMatch": "zim" } }, { "header": { "name": "x-zim", - "stringMatch": { - "safeRegex": { - "googleRe2": {}, - "regex": "gi[rR]" - } + "safeRegexMatch": { + "googleRe2": { + + }, + "regex": "gi[rR]" } } }, { "header": { - "invertMatch": true, "name": "z-foo", - "presentMatch": true + "presentMatch": true, + "invertMatch": true } }, { "header": { - "invertMatch": true, "name": "z-bar", - "stringMatch": { - "exact": "xyz" - } + "exactMatch": "xyz", + "invertMatch": true } }, { "header": { - "invertMatch": true, "name": "z-dib", - "stringMatch": { - "prefix": "gaz" - } + "prefixMatch": "gaz", + "invertMatch": true } }, { "header": { - "invertMatch": true, "name": "z-gir", - "stringMatch": { - "suffix": "zim" - } + "suffixMatch": "zim", + "invertMatch": true } }, { "header": { - "invertMatch": true, "name": "z-zim", - "stringMatch": { - "safeRegex": { - "googleRe2": {}, - "regex": "gi[rR]" - } - } + "safeRegexMatch": { + "googleRe2": { + + }, + "regex": "gi[rR]" + }, + "invertMatch": true } } ] @@ -181,7 +173,9 @@ "urlPath": { "path": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "/v[123]" } } @@ -191,7 +185,9 @@ "header": { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|HEAD|OPTIONS" } } @@ -227,7 +223,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-single-intention-with-kitchen-sink-perms.golden b/agent/xds/testdata/rbac/default-deny-single-intention-with-kitchen-sink-perms.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/default-deny-single-intention-with-kitchen-sink-perms.golden +++ b/agent/xds/testdata/rbac/default-deny-single-intention-with-kitchen-sink-perms.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/default-deny-two-path-deny-and-path-allow--httpfilter.golden b/agent/xds/testdata/rbac/default-deny-two-path-deny-and-path-allow--httpfilter.golden index bfaa5c46c387d..75534cb10a9fa 100644 --- a/agent/xds/testdata/rbac/default-deny-two-path-deny-and-path-allow--httpfilter.golden +++ b/agent/xds/testdata/rbac/default-deny-two-path-deny-and-path-allow--httpfilter.golden @@ -43,7 +43,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/default-deny-two-path-deny-and-path-allow.golden b/agent/xds/testdata/rbac/default-deny-two-path-deny-and-path-allow.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/default-deny-two-path-deny-and-path-allow.golden +++ b/agent/xds/testdata/rbac/default-deny-two-path-deny-and-path-allow.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/empty-top-level-jwt-with-one-permission--httpfilter.golden b/agent/xds/testdata/rbac/empty-top-level-jwt-with-one-permission--httpfilter.golden index 28cb4df8f41d2..f5eb4bdbcb6ee 100644 --- a/agent/xds/testdata/rbac/empty-top-level-jwt-with-one-permission--httpfilter.golden +++ b/agent/xds/testdata/rbac/empty-top-level-jwt-with-one-permission--httpfilter.golden @@ -23,12 +23,8 @@ "metadata": { "filter": "envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_okta" - }, - { - "key": "iss" - } + {"key": "jwt_payload_okta"}, + {"key": "iss"} ], "value": { "stringMatch": { @@ -41,12 +37,8 @@ "metadata": { "filter": "envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_okta" - }, - { - "key": "roles" - } + {"key": "jwt_payload_okta"}, + {"key": "roles"} ], "value": { "stringMatch": { diff --git a/agent/xds/testdata/rbac/empty-top-level-jwt-with-one-permission.golden b/agent/xds/testdata/rbac/empty-top-level-jwt-with-one-permission.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/empty-top-level-jwt-with-one-permission.golden +++ b/agent/xds/testdata/rbac/empty-top-level-jwt-with-one-permission.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/top-level-jwt-no-permissions--httpfilter.golden b/agent/xds/testdata/rbac/top-level-jwt-no-permissions--httpfilter.golden index 522e134591fc3..efa9293f3c161 100644 --- a/agent/xds/testdata/rbac/top-level-jwt-no-permissions--httpfilter.golden +++ b/agent/xds/testdata/rbac/top-level-jwt-no-permissions--httpfilter.golden @@ -18,7 +18,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -27,16 +29,12 @@ { "andIds": { "ids": [ - { + { "metadata": { - "filter": "envoy.filters.http.jwt_authn", + "filter":"envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_okta" - }, - { - "key": "iss" - } + {"key": "jwt_payload_okta"}, + {"key": "iss"} ], "value": { "stringMatch": { @@ -45,16 +43,12 @@ } } }, - { + { "metadata": { - "filter": "envoy.filters.http.jwt_authn", + "filter":"envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_okta" - }, - { - "key": "roles" - } + {"key": "jwt_payload_okta"}, + {"key": "roles"} ], "value": { "stringMatch": { diff --git a/agent/xds/testdata/rbac/top-level-jwt-no-permissions.golden b/agent/xds/testdata/rbac/top-level-jwt-no-permissions.golden index a02fd3518c1ec..3fc78b29552dd 100644 --- a/agent/xds/testdata/rbac/top-level-jwt-no-permissions.golden +++ b/agent/xds/testdata/rbac/top-level-jwt-no-permissions.golden @@ -15,7 +15,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } diff --git a/agent/xds/testdata/rbac/top-level-jwt-with-multiple-permissions--httpfilter.golden b/agent/xds/testdata/rbac/top-level-jwt-with-multiple-permissions--httpfilter.golden index 461429f6c4992..6ce0662e3b095 100644 --- a/agent/xds/testdata/rbac/top-level-jwt-with-multiple-permissions--httpfilter.golden +++ b/agent/xds/testdata/rbac/top-level-jwt-with-multiple-permissions--httpfilter.golden @@ -23,12 +23,8 @@ "metadata": { "filter": "envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_auth0" - }, - { - "key": "iss" - } + {"key": "jwt_payload_auth0"}, + {"key": "iss"} ], "value": { "stringMatch": { @@ -41,15 +37,9 @@ "metadata": { "filter": "envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_auth0" - }, - { - "key": "perms" - }, - { - "key": "role" - } + {"key": "jwt_payload_auth0"}, + {"key": "perms"}, + {"key": "role"} ], "value": { "stringMatch": { @@ -90,49 +80,39 @@ } }, { - "andRules": { - "rules": [ - { - "metadata": { - "filter": "envoy.filters.http.jwt_authn", - "path": [ - { - "key": "jwt_payload_auth0" - }, - { - "key": "iss" - } - ], - "value": { - "stringMatch": { - "exact": "mytest.auth0-issuer" + "andRules": { + "rules": [ + { + "metadata": { + "filter": "envoy.filters.http.jwt_authn", + "path": [ + {"key": "jwt_payload_auth0"}, + {"key": "iss"} + ], + "value": { + "stringMatch": { + "exact": "mytest.auth0-issuer" + } } } - } - }, - { - "metadata": { - "filter": "envoy.filters.http.jwt_authn", - "path": [ - { - "key": "jwt_payload_auth0" - }, - { - "key": "perms" - }, - { - "key": "role" - } - ], - "value": { - "stringMatch": { - "exact": "admin" + }, + { + "metadata": { + "filter": "envoy.filters.http.jwt_authn", + "path": [ + {"key": "jwt_payload_auth0"}, + {"key": "perms"}, + {"key": "role"} + ], + "value": { + "stringMatch": { + "exact": "admin" + } } } } - } - ] - } + ] + } } ] } @@ -146,7 +126,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -155,16 +137,12 @@ { "andIds": { "ids": [ - { + { "metadata": { - "filter": "envoy.filters.http.jwt_authn", + "filter":"envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_okta" - }, - { - "key": "iss" - } + {"key": "jwt_payload_okta"}, + {"key": "iss"} ], "value": { "stringMatch": { @@ -173,16 +151,12 @@ } } }, - { + { "metadata": { - "filter": "envoy.filters.http.jwt_authn", + "filter":"envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_okta" - }, - { - "key": "roles" - } + {"key": "jwt_payload_okta"}, + {"key": "roles"} ], "value": { "stringMatch": { diff --git a/agent/xds/testdata/rbac/top-level-jwt-with-multiple-permissions.golden b/agent/xds/testdata/rbac/top-level-jwt-with-multiple-permissions.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/top-level-jwt-with-multiple-permissions.golden +++ b/agent/xds/testdata/rbac/top-level-jwt-with-multiple-permissions.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/top-level-jwt-with-one-permission--httpfilter.golden b/agent/xds/testdata/rbac/top-level-jwt-with-one-permission--httpfilter.golden index f384cbdd654b8..36ba23c29314d 100644 --- a/agent/xds/testdata/rbac/top-level-jwt-with-one-permission--httpfilter.golden +++ b/agent/xds/testdata/rbac/top-level-jwt-with-one-permission--httpfilter.golden @@ -23,12 +23,8 @@ "metadata": { "filter": "envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_auth0" - }, - { - "key": "iss" - } + {"key": "jwt_payload_auth0"}, + {"key": "iss"} ], "value": { "stringMatch": { @@ -41,15 +37,9 @@ "metadata": { "filter": "envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_auth0" - }, - { - "key": "perms" - }, - { - "key": "role" - } + {"key": "jwt_payload_auth0"}, + {"key": "perms"}, + {"key": "role"} ], "value": { "stringMatch": { @@ -95,7 +85,9 @@ "authenticated": { "principalName": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" } } @@ -104,16 +96,12 @@ { "andIds": { "ids": [ - { + { "metadata": { - "filter": "envoy.filters.http.jwt_authn", + "filter":"envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_okta" - }, - { - "key": "iss" - } + {"key": "jwt_payload_okta"}, + {"key": "iss"} ], "value": { "stringMatch": { @@ -122,16 +110,12 @@ } } }, - { + { "metadata": { - "filter": "envoy.filters.http.jwt_authn", + "filter":"envoy.filters.http.jwt_authn", "path": [ - { - "key": "jwt_payload_okta" - }, - { - "key": "roles" - } + {"key": "jwt_payload_okta"}, + {"key": "roles"} ], "value": { "stringMatch": { diff --git a/agent/xds/testdata/rbac/top-level-jwt-with-one-permission.golden b/agent/xds/testdata/rbac/top-level-jwt-with-one-permission.golden index b1fa47ea4c35b..92c7f921adc10 100644 --- a/agent/xds/testdata/rbac/top-level-jwt-with-one-permission.golden +++ b/agent/xds/testdata/rbac/top-level-jwt-with-one-permission.golden @@ -2,7 +2,9 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + + }, "statPrefix": "connect_authz" } } \ No newline at end of file diff --git a/agent/xds/testdata/rbac/v2-default-allow.golden b/agent/xds/testdata/rbac/v2-default-allow.golden deleted file mode 100644 index 9e26dfeeb6e64..0000000000000 --- a/agent/xds/testdata/rbac/v2-default-allow.golden +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/agent/xds/testdata/rbac/v2-default-deny.golden b/agent/xds/testdata/rbac/v2-default-deny.golden deleted file mode 100644 index b1fa47ea4c35b..0000000000000 --- a/agent/xds/testdata/rbac/v2-default-deny.golden +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } -} \ No newline at end of file diff --git a/agent/xds/testdata/rbac/v2-ignore-empty-permissions.golden b/agent/xds/testdata/rbac/v2-ignore-empty-permissions.golden deleted file mode 100644 index 4e71fce1916c3..0000000000000 --- a/agent/xds/testdata/rbac/v2-ignore-empty-permissions.golden +++ /dev/null @@ -1,22 +0,0 @@ -{ - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": { - "action": "DENY" - }, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - } - ] -} \ No newline at end of file diff --git a/agent/xds/testdata/rbac/v2-kitchen-sink.golden b/agent/xds/testdata/rbac/v2-kitchen-sink.golden deleted file mode 100644 index d298830ee9351..0000000000000 --- a/agent/xds/testdata/rbac/v2-kitchen-sink.golden +++ /dev/null @@ -1,122 +0,0 @@ -{ - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": { - "action": "DENY", - "policies": { - "consul-intentions-layer4": { - "permissions": [ - { - "any": true - } - ], - "principals": [ - { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/db$" - } - } - } - }, - { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" - } - } - } - } - ] - } - } - }, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": { - "policies": { - "consul-intentions-layer4-0": { - "permissions": [ - { - "any": true - } - ], - "principals": [ - { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/api$" - } - } - } - }, - { - "andIds": { - "ids": [ - { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" - } - } - } - }, - { - "notId": { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/unsafe$" - } - } - } - } - } - ] - } - } - ] - }, - "consul-intentions-layer4-1": { - "permissions": [ - { - "any": true - } - ], - "principals": [ - { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" - } - } - } - } - ] - } - } - }, - "statPrefix": "connect_authz" - } - } - ] -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden b/agent/xds/testdata/routes/api-gateway-with-http-route-and-inline-certificate.latest.golden similarity index 76% rename from agent/xds/testdata/routes/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden rename to agent/xds/testdata/routes/api-gateway-with-http-route-and-inline-certificate.latest.golden index 2c220ee70ef54..a1669268ec4e0 100644 --- a/agent/xds/testdata/routes/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden +++ b/agent/xds/testdata/routes/api-gateway-with-http-route-and-inline-certificate.latest.golden @@ -1,51 +1,50 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { + "name": "api-gateway-listener-9b9265b", "domains": [ "*", "*:8080" ], - "name": "api-gateway-listener-9b9265b", "routes": [ { "match": { "prefix": "/" }, + "route": { + "cluster": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "requestHeadersToAdd": [ { - "append": true, "header": { "key": "X-Header-Add", "value": "added" - } + }, + "append": true }, { - "append": false, "header": { "key": "X-Header-Set", "value": "set" - } + }, + "append": false } ], "requestHeadersToRemove": [ "X-Header-Remove" - ], - "route": { - "cluster": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "idleTimeout": "30s" - } + ] } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/api-gateway-with-http-route.latest.golden b/agent/xds/testdata/routes/api-gateway-with-http-route.latest.golden deleted file mode 100644 index 3137421e51881..0000000000000 --- a/agent/xds/testdata/routes/api-gateway-with-http-route.latest.golden +++ /dev/null @@ -1,59 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "8080", - "validateClusters": true, - "virtualHosts": [ - { - "domains": [ - "*", - "*:8080" - ], - "name": "api-gateway-listener-9b9265b", - "routes": [ - { - "match": { - "prefix": "/" - }, - "requestHeadersToAdd": [ - { - "append": true, - "header": { - "key": "X-Header-Add", - "value": "added" - } - }, - { - "append": false, - "header": { - "key": "X-Header-Set", - "value": "set" - } - } - ], - "requestHeadersToRemove": [ - "X-Header-Remove" - ], - "route": { - "cluster": "service.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "idleTimeout": "30s", - "retryPolicy": { - "numRetries": 3, - "retriableStatusCodes": [ - 500 - ], - "retryOn": "cancelled,connect-failure,retriable-status-codes" - }, - "timeout": "30s" - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/api-gateway-with-multiple-hostnames.latest.golden b/agent/xds/testdata/routes/api-gateway-with-multiple-hostnames.latest.golden index b268a5e5ac5e6..c4959e5668367 100644 --- a/agent/xds/testdata/routes/api-gateway-with-multiple-hostnames.latest.golden +++ b/agent/xds/testdata/routes/api-gateway-with-multiple-hostnames.latest.golden @@ -1,73 +1,73 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "8080", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "8080", + "virtualHosts": [ { - "domains": [ + "name": "api-gateway-http-54620b06", + "domains": [ "frontend.example.com", "frontend.example.com:8080" ], - "name": "api-gateway-http-54620b06", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "frontend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "route": { + "cluster": "frontend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] }, { - "domains": [ + "name": "api-gateway-http-5a84e719", + "domains": [ "backend.example.com", "backend.example.com:8080" ], - "name": "api-gateway-http-5a84e719", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "backend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "route": { + "cluster": "backend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] }, { - "domains": [ + "name": "api-gateway-http-aa289ce2", + "domains": [ "*.example.com", "*.example.com:8080" ], - "name": "api-gateway-http-aa289ce2", - "routes": [ + "routes": [ { - "match": { - "prefix": "/frontend" + "match": { + "prefix": "/frontend" }, - "route": { - "cluster": "frontend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "route": { + "cluster": "frontend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } }, { - "match": { - "prefix": "/backend" + "match": { + "prefix": "/backend" }, - "route": { - "cluster": "backend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "route": { + "cluster": "backend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/api-gateway-with-multiple-inline-certificates.latest.golden b/agent/xds/testdata/routes/api-gateway-with-multiple-inline-certificates.latest.golden deleted file mode 100644 index 8b919343d21a9..0000000000000 --- a/agent/xds/testdata/routes/api-gateway-with-multiple-inline-certificates.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/api-gateway-with-tcp-route-and-inline-certificate.latest.golden b/agent/xds/testdata/routes/api-gateway-with-tcp-route-and-inline-certificate.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/api-gateway-with-tcp-route-and-inline-certificate.latest.golden +++ b/agent/xds/testdata/routes/api-gateway-with-tcp-route-and-inline-certificate.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-exported-to-peers.latest.golden b/agent/xds/testdata/routes/connect-proxy-exported-to-peers.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/connect-proxy-exported-to-peers.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-exported-to-peers.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.latest.golden b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.latest.golden index f748c3e8208ed..9cac480402557 100644 --- a/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-lb-in-resolver.latest.golden @@ -1,22 +1,34 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "*" ], - "name": "db", "routes": [ { "match": { "prefix": "/" }, "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, "hashPolicy": [ { "cookie": { @@ -35,38 +47,21 @@ "headerName": "x-user-id" } }, - { - "queryParameter": { - "name": "my-pretty-param" - } - }, { "connectionProperties": { "sourceIp": true }, "terminal": true } - ], - "weightedClusters": { - "clusters": [ - { - "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "weight": 9550 - }, - { - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "weight": 450 - } - ], - "totalWeight": 10000 - } + ] } } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-resolver-with-lb.latest.golden b/agent/xds/testdata/routes/connect-proxy-resolver-with-lb.latest.golden deleted file mode 100644 index 6d9d5242037ef..0000000000000 --- a/agent/xds/testdata/routes/connect-proxy-resolver-with-lb.latest.golden +++ /dev/null @@ -1,30 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "db", - "validateClusters": true, - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "db", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-route-to-lb-resolver.latest.golden b/agent/xds/testdata/routes/connect-proxy-route-to-lb-resolver.latest.golden deleted file mode 100644 index 3ab67ba8f2219..0000000000000 --- a/agent/xds/testdata/routes/connect-proxy-route-to-lb-resolver.latest.golden +++ /dev/null @@ -1,38 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "db", - "validateClusters": true, - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "db", - "routes": [ - { - "match": { - "prefix": "/web" - }, - "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - }, - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-splitter-overweight.latest.golden b/agent/xds/testdata/routes/connect-proxy-splitter-overweight.latest.golden deleted file mode 100644 index b52cd3205ea8a..0000000000000 --- a/agent/xds/testdata/routes/connect-proxy-splitter-overweight.latest.golden +++ /dev/null @@ -1,99 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "db", - "validateClusters": true, - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "db", - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "weightedClusters": { - "clusters": [ - { - "name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "requestHeadersToAdd": [ - { - "append": false, - "header": { - "key": "x-split-leg", - "value": "big" - } - } - ], - "responseHeadersToAdd": [ - { - "append": false, - "header": { - "key": "x-split-leg", - "value": "big" - } - } - ], - "weight": 10000 - }, - { - "name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "requestHeadersToAdd": [ - { - "append": false, - "header": { - "key": "x-split-leg", - "value": "goldilocks" - } - } - ], - "responseHeadersToAdd": [ - { - "append": false, - "header": { - "key": "x-split-leg", - "value": "goldilocks" - } - } - ], - "weight": 10000 - }, - { - "name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "requestHeadersToAdd": [ - { - "append": false, - "header": { - "key": "x-split-leg", - "value": "small" - } - } - ], - "responseHeadersToAdd": [ - { - "append": false, - "header": { - "key": "x-split-leg", - "value": "small" - } - } - ], - "weight": 10000 - } - ] - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden index 9a73db46e0d6e..095330c68404e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden @@ -1,31 +1,31 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "db", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "virtualHosts": [ { - "domains": [ + "name": "db", + "domains": [ "*" ], - "name": "db", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "33s" + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "33s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-overrides.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-overrides.latest.golden index 5d8b1dd41e834..c40cfe9e90ef2 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-and-overrides.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-and-overrides.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "*" ], - "name": "db", "routes": [ { "match": { @@ -23,9 +22,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden index b5da244e3e67f..cf29d6729a0a7 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden @@ -1,31 +1,31 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "db", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "virtualHosts": [ { - "domains": [ + "name": "db", + "domains": [ "*" ], - "name": "db", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "db.default.cluster-01.external.peer1.domain", - "timeout": "33s" + "route": { + "cluster": "db.default.cluster-01.external.peer1.domain", + "timeout": "33s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-router.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-router.latest.golden index 958709e3477e8..d34194b932328 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-and-router.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-and-router.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "*" ], - "name": "db", "routes": [ { "match": { @@ -31,7 +30,9 @@ { "match": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "/regex" } }, @@ -41,13 +42,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", "presentMatch": true } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -55,14 +56,14 @@ }, { "match": { + "prefix": "/", "headers": [ { - "invertMatch": true, "name": "x-debug", - "presentMatch": true + "presentMatch": true, + "invertMatch": true } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-not-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -70,15 +71,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "exact": "exact" - } + "exactMatch": "exact" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-exact.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -86,15 +85,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "prefix": "prefix" - } + "prefixMatch": "prefix" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-prefix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -102,15 +99,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "suffix": "suffix" - } + "suffixMatch": "suffix" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-suffix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -118,18 +113,18 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "safeRegex": { - "googleRe2": {}, - "regex": "regex" - } + "safeRegexMatch": { + "googleRe2": { + + }, + "regex": "regex" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-regex.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -137,16 +132,18 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|PUT" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "just-methods.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -154,22 +151,22 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "exact": "exact" - } + "exactMatch": "exact" }, { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|PUT" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-exact-with-method.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -199,7 +196,9 @@ "name": "secretparam2", "stringMatch": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "regex" } } @@ -291,8 +290,8 @@ "route": { "cluster": "retry-connect.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { - "numRetries": 15, - "retryOn": "connect-failure" + "retryOn": "connect-failure", + "numRetries": 15 } } }, @@ -303,8 +302,8 @@ "route": { "cluster": "retry-reset.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { - "numRetries": 15, - "retryOn": "reset" + "retryOn": "reset", + "numRetries": 15 } } }, @@ -315,13 +314,13 @@ "route": { "cluster": "retry-codes.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { + "retryOn": "retriable-status-codes", "numRetries": 15, "retriableStatusCodes": [ 401, 409, 451 - ], - "retryOn": "retriable-status-codes" + ] } } }, @@ -332,12 +331,12 @@ "route": { "cluster": "retry-all.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { + "retryOn": "5xx,gateway-error,reset,connect-failure,envoy-ratelimited,retriable-4xx,refused-stream,cancelled,deadline-exceeded,internal,resource-exhausted,unavailable,retriable-status-codes", "retriableStatusCodes": [ 401, 409, 451 - ], - "retryOn": "5xx,gateway-error,reset,connect-failure,envoy-ratelimited,retriable-4xx,refused-stream,cancelled,deadline-exceeded,internal,resource-exhausted,unavailable,retriable-status-codes" + ] } } }, @@ -369,20 +368,23 @@ "match": { "path": "/header-manip" }, + "route": { + "cluster": "header-manip.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "requestHeadersToAdd": [ { - "append": true, "header": { "key": "request", "value": "bar" - } + }, + "append": true }, { - "append": false, "header": { "key": "bar", "value": "baz" - } + }, + "append": false } ], "requestHeadersToRemove": [ @@ -390,26 +392,23 @@ ], "responseHeadersToAdd": [ { - "append": true, "header": { "key": "response", "value": "bar" - } + }, + "append": true }, { - "append": false, "header": { "key": "bar", "value": "baz" - } + }, + "append": false } ], "responseHeadersToRemove": [ "qux" - ], - "route": { - "cluster": "header-manip.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } + ] }, { "match": { @@ -421,9 +420,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter.latest.golden index 564167abe06ea..9dde104442a9e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-and-splitter.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "*" ], - "name": "db", "routes": [ { "match": { @@ -21,69 +20,69 @@ "clusters": [ { "name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550, "requestHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "big" - } + }, + "append": false } ], "responseHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "big" - } + }, + "append": false } - ], - "weight": 9550 + ] }, { "name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 400, "requestHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "goldilocks" - } + }, + "append": false } ], "responseHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "goldilocks" - } + }, + "append": false } - ], - "weight": 400 + ] }, { "name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 50, "requestHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "small" - } + }, + "append": false } ], "responseHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "small" - } + }, + "append": false } - ], - "weight": 50 + ] } ], "totalWeight": 10000 @@ -92,9 +91,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-external-sni.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-external-sni.latest.golden index 9a73db46e0d6e..095330c68404e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-external-sni.latest.golden @@ -1,31 +1,31 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "db", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "virtualHosts": [ { - "domains": [ + "name": "db", + "domains": [ "*" ], - "name": "db", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "33s" + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "33s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain.latest.golden index 9a73db46e0d6e..095330c68404e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain.latest.golden @@ -1,31 +1,31 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "db", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "virtualHosts": [ { - "domains": [ + "name": "db", + "domains": [ "*" ], - "name": "db", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "33s" + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "33s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-grpc-router.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-grpc-router.latest.golden index 474ac19cd71b6..c042006a5f33c 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-grpc-router.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-grpc-router.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "*" ], - "name": "db", "routes": [ { "match": { @@ -30,9 +29,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden deleted file mode 100644 index 8b919343d21a9..0000000000000 --- a/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams-http2.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams-http2.latest.golden deleted file mode 100644 index 8b919343d21a9..0000000000000 --- a/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams-http2.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/defaults.latest.golden b/agent/xds/testdata/routes/defaults.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/defaults.latest.golden +++ b/agent/xds/testdata/routes/defaults.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-config-entry-nil.latest.golden b/agent/xds/testdata/routes/ingress-config-entry-nil.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/ingress-config-entry-nil.latest.golden +++ b/agent/xds/testdata/routes/ingress-config-entry-nil.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-defaults-no-chain.latest.golden b/agent/xds/testdata/routes/ingress-defaults-no-chain.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/ingress-defaults-no-chain.latest.golden +++ b/agent/xds/testdata/routes/ingress-defaults-no-chain.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-grpc-multiple-services.latest.golden b/agent/xds/testdata/routes/ingress-grpc-multiple-services.latest.golden index 41c70e3de169b..006bf5157b081 100644 --- a/agent/xds/testdata/routes/ingress-grpc-multiple-services.latest.golden +++ b/agent/xds/testdata/routes/ingress-grpc-multiple-services.latest.golden @@ -1,52 +1,52 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "8080", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "8080", + "virtualHosts": [ { - "domains": [ + "name": "foo", + "domains": [ "test1.example.com", "test2.example.com", "test2.example.com:8080", "test1.example.com:8080" ], - "name": "foo", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] }, { - "domains": [ + "name": "bar", + "domains": [ "bar.ingress.*", "bar.ingress.*:8080" ], - "name": "bar", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "bar.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-http-multiple-services.latest.golden b/agent/xds/testdata/routes/ingress-http-multiple-services.latest.golden index a15b997a8fd98..507c66a46d5b1 100644 --- a/agent/xds/testdata/routes/ingress-http-multiple-services.latest.golden +++ b/agent/xds/testdata/routes/ingress-http-multiple-services.latest.golden @@ -1,17 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "443", - "validateClusters": true, "virtualHosts": [ { + "name": "baz", "domains": [ "baz.ingress.*", "baz.ingress.*:443" ], - "name": "baz", "routes": [ { "match": { @@ -24,11 +23,11 @@ ] }, { + "name": "qux", "domains": [ "qux.ingress.*", "qux.ingress.*:443" ], - "name": "qux", "routes": [ { "match": { @@ -40,21 +39,21 @@ } ] } - ] + ], + "validateClusters": true }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { + "name": "foo", "domains": [ "test1.example.com", "test2.example.com", "test2.example.com:8080", "test1.example.com:8080" ], - "name": "foo", "routes": [ { "match": { @@ -68,11 +67,11 @@ ] }, { + "name": "bar", "domains": [ "bar.ingress.*", "bar.ingress.*:8080" ], - "name": "bar", "routes": [ { "match": { @@ -85,9 +84,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-lb-in-resolver.latest.golden b/agent/xds/testdata/routes/ingress-lb-in-resolver.latest.golden index 9660fb81a608a..f2bc276d8e99b 100644 --- a/agent/xds/testdata/routes/ingress-lb-in-resolver.latest.golden +++ b/agent/xds/testdata/routes/ingress-lb-in-resolver.latest.golden @@ -1,23 +1,35 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "db.ingress.*", "db.ingress.*:8080" ], - "name": "db", "routes": [ { "match": { "prefix": "/" }, "route": { + "weightedClusters": { + "clusters": [ + { + "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550 + }, + { + "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 450 + } + ], + "totalWeight": 10000 + }, "hashPolicy": [ { "cookie": { @@ -36,38 +48,21 @@ "headerName": "x-user-id" } }, - { - "queryParameter": { - "name": "my-pretty-param" - } - }, { "connectionProperties": { "sourceIp": true }, "terminal": true } - ], - "weightedClusters": { - "clusters": [ - { - "name": "something-else.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "weight": 9550 - }, - { - "name": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "weight": 450 - } - ], - "totalWeight": 10000 - } + ] } } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-splitter-with-resolver-redirect.latest.golden b/agent/xds/testdata/routes/ingress-splitter-with-resolver-redirect.latest.golden index bf15c92982e7e..4c3fee303cb62 100644 --- a/agent/xds/testdata/routes/ingress-splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/routes/ingress-splitter-with-resolver-redirect.latest.golden @@ -1,17 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "db.ingress.*", "db.ingress.*:8080" ], - "name": "db", "routes": [ { "match": { @@ -35,9 +34,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-chain-and-router-header-manip.latest.golden b/agent/xds/testdata/routes/ingress-with-chain-and-router-header-manip.latest.golden index 2a55ed3395002..1fa06838f8d83 100644 --- a/agent/xds/testdata/routes/ingress-with-chain-and-router-header-manip.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-chain-and-router-header-manip.latest.golden @@ -1,55 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "db.ingress.*", "db.ingress.*:8080" ], - "name": "db", - "requestHeadersToAdd": [ - { - "append": true, - "header": { - "key": "foo", - "value": "bar" - } - }, - { - "append": false, - "header": { - "key": "bar", - "value": "baz" - } - } - ], - "requestHeadersToRemove": [ - "qux" - ], - "responseHeadersToAdd": [ - { - "append": true, - "header": { - "key": "foo", - "value": "bar" - } - }, - { - "append": false, - "header": { - "key": "bar", - "value": "baz" - } - } - ], - "responseHeadersToRemove": [ - "qux" - ], "routes": [ { "match": { @@ -70,7 +31,9 @@ { "match": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "/regex" } }, @@ -80,13 +43,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", "presentMatch": true } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -94,14 +57,14 @@ }, { "match": { + "prefix": "/", "headers": [ { - "invertMatch": true, "name": "x-debug", - "presentMatch": true + "presentMatch": true, + "invertMatch": true } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-not-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -109,15 +72,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "exact": "exact" - } + "exactMatch": "exact" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-exact.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -125,15 +86,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "prefix": "prefix" - } + "prefixMatch": "prefix" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-prefix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -141,15 +100,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "suffix": "suffix" - } + "suffixMatch": "suffix" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-suffix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -157,18 +114,18 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "safeRegex": { - "googleRe2": {}, - "regex": "regex" - } + "safeRegexMatch": { + "googleRe2": { + + }, + "regex": "regex" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-regex.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -176,16 +133,18 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|PUT" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "just-methods.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -193,22 +152,22 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "exact": "exact" - } + "exactMatch": "exact" }, { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|PUT" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-exact-with-method.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -238,7 +197,9 @@ "name": "secretparam2", "stringMatch": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "regex" } } @@ -330,8 +291,8 @@ "route": { "cluster": "retry-connect.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { - "numRetries": 15, - "retryOn": "connect-failure" + "retryOn": "connect-failure", + "numRetries": 15 } } }, @@ -342,8 +303,8 @@ "route": { "cluster": "retry-reset.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { - "numRetries": 15, - "retryOn": "reset" + "retryOn": "reset", + "numRetries": 15 } } }, @@ -354,13 +315,13 @@ "route": { "cluster": "retry-codes.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { + "retryOn": "retriable-status-codes", "numRetries": 15, "retriableStatusCodes": [ 401, 409, 451 - ], - "retryOn": "retriable-status-codes" + ] } } }, @@ -371,12 +332,12 @@ "route": { "cluster": "retry-all.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { + "retryOn": "5xx,gateway-error,reset,connect-failure,envoy-ratelimited,retriable-4xx,refused-stream,cancelled,deadline-exceeded,internal,resource-exhausted,unavailable,retriable-status-codes", "retriableStatusCodes": [ 401, 409, 451 - ], - "retryOn": "5xx,gateway-error,reset,connect-failure,envoy-ratelimited,retriable-4xx,refused-stream,cancelled,deadline-exceeded,internal,resource-exhausted,unavailable,retriable-status-codes" + ] } } }, @@ -408,20 +369,23 @@ "match": { "path": "/header-manip" }, + "route": { + "cluster": "header-manip.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "requestHeadersToAdd": [ { - "append": true, "header": { "key": "request", "value": "bar" - } + }, + "append": true }, { - "append": false, "header": { "key": "bar", "value": "baz" - } + }, + "append": false } ], "requestHeadersToRemove": [ @@ -429,26 +393,23 @@ ], "responseHeadersToAdd": [ { - "append": true, "header": { "key": "response", "value": "bar" - } + }, + "append": true }, { - "append": false, "header": { "key": "bar", "value": "baz" - } + }, + "append": false } ], "responseHeadersToRemove": [ "qux" - ], - "route": { - "cluster": "header-manip.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } + ] }, { "match": { @@ -458,11 +419,50 @@ "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } + ], + "requestHeadersToAdd": [ + { + "header": { + "key": "foo", + "value": "bar" + }, + "append": true + }, + { + "header": { + "key": "bar", + "value": "baz" + }, + "append": false + } + ], + "requestHeadersToRemove": [ + "qux" + ], + "responseHeadersToAdd": [ + { + "header": { + "key": "foo", + "value": "bar" + }, + "append": true + }, + { + "header": { + "key": "bar", + "value": "baz" + }, + "append": false + } + ], + "responseHeadersToRemove": [ + "qux" ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-chain-and-router.latest.golden b/agent/xds/testdata/routes/ingress-with-chain-and-router.latest.golden index dac7fbcf0f281..ffe7313996f15 100644 --- a/agent/xds/testdata/routes/ingress-with-chain-and-router.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-chain-and-router.latest.golden @@ -1,17 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "db.ingress.*", "db.ingress.*:8080" ], - "name": "db", "routes": [ { "match": { @@ -32,7 +31,9 @@ { "match": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "/regex" } }, @@ -42,13 +43,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", "presentMatch": true } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -56,14 +57,14 @@ }, { "match": { + "prefix": "/", "headers": [ { - "invertMatch": true, "name": "x-debug", - "presentMatch": true + "presentMatch": true, + "invertMatch": true } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-not-present.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -71,15 +72,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "exact": "exact" - } + "exactMatch": "exact" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-exact.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -87,15 +86,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "prefix": "prefix" - } + "prefixMatch": "prefix" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-prefix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -103,15 +100,13 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "suffix": "suffix" - } + "suffixMatch": "suffix" } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-suffix.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -119,18 +114,18 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "safeRegex": { - "googleRe2": {}, - "regex": "regex" - } + "safeRegexMatch": { + "googleRe2": { + + }, + "regex": "regex" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-regex.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -138,16 +133,18 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|PUT" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "just-methods.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -155,22 +152,22 @@ }, { "match": { + "prefix": "/", "headers": [ { "name": "x-debug", - "stringMatch": { - "exact": "exact" - } + "exactMatch": "exact" }, { "name": ":method", "safeRegexMatch": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "GET|PUT" } } - ], - "prefix": "/" + ] }, "route": { "cluster": "hdr-exact-with-method.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" @@ -200,7 +197,9 @@ "name": "secretparam2", "stringMatch": { "safeRegex": { - "googleRe2": {}, + "googleRe2": { + + }, "regex": "regex" } } @@ -292,8 +291,8 @@ "route": { "cluster": "retry-connect.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { - "numRetries": 15, - "retryOn": "connect-failure" + "retryOn": "connect-failure", + "numRetries": 15 } } }, @@ -304,8 +303,8 @@ "route": { "cluster": "retry-reset.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { - "numRetries": 15, - "retryOn": "reset" + "retryOn": "reset", + "numRetries": 15 } } }, @@ -316,13 +315,13 @@ "route": { "cluster": "retry-codes.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { + "retryOn": "retriable-status-codes", "numRetries": 15, "retriableStatusCodes": [ 401, 409, 451 - ], - "retryOn": "retriable-status-codes" + ] } } }, @@ -333,12 +332,12 @@ "route": { "cluster": "retry-all.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "retryPolicy": { + "retryOn": "5xx,gateway-error,reset,connect-failure,envoy-ratelimited,retriable-4xx,refused-stream,cancelled,deadline-exceeded,internal,resource-exhausted,unavailable,retriable-status-codes", "retriableStatusCodes": [ 401, 409, 451 - ], - "retryOn": "5xx,gateway-error,reset,connect-failure,envoy-ratelimited,retriable-4xx,refused-stream,cancelled,deadline-exceeded,internal,resource-exhausted,unavailable,retriable-status-codes" + ] } } }, @@ -370,20 +369,23 @@ "match": { "path": "/header-manip" }, + "route": { + "cluster": "header-manip.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + }, "requestHeadersToAdd": [ { - "append": true, "header": { "key": "request", "value": "bar" - } + }, + "append": true }, { - "append": false, "header": { "key": "bar", "value": "baz" - } + }, + "append": false } ], "requestHeadersToRemove": [ @@ -391,26 +393,23 @@ ], "responseHeadersToAdd": [ { - "append": true, "header": { "key": "response", "value": "bar" - } + }, + "append": true }, { - "append": false, "header": { "key": "bar", "value": "baz" - } + }, + "append": false } ], "responseHeadersToRemove": [ "qux" - ], - "route": { - "cluster": "header-manip.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" - } + ] }, { "match": { @@ -422,9 +421,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-chain-and-splitter.latest.golden b/agent/xds/testdata/routes/ingress-with-chain-and-splitter.latest.golden index f5961883bcada..820de54764f3e 100644 --- a/agent/xds/testdata/routes/ingress-with-chain-and-splitter.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-chain-and-splitter.latest.golden @@ -1,17 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "db.ingress.*", "db.ingress.*:8080" ], - "name": "db", "routes": [ { "match": { @@ -22,69 +21,69 @@ "clusters": [ { "name": "big-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 9550, "requestHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "big" - } + }, + "append": false } ], "responseHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "big" - } + }, + "append": false } - ], - "weight": 9550 + ] }, { "name": "goldilocks-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 400, "requestHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "goldilocks" - } + }, + "append": false } ], "responseHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "goldilocks" - } + }, + "append": false } - ], - "weight": 400 + ] }, { "name": "lil-bit-side.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "weight": 50, "requestHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "small" - } + }, + "append": false } ], "responseHeadersToAdd": [ { - "append": false, "header": { "key": "x-split-leg", "value": "small" - } + }, + "append": false } - ], - "weight": 50 + ] } ], "totalWeight": 10000 @@ -93,9 +92,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-chain-external-sni.latest.golden b/agent/xds/testdata/routes/ingress-with-chain-external-sni.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/ingress-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-chain-external-sni.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-chain.latest.golden b/agent/xds/testdata/routes/ingress-with-chain.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/ingress-with-chain.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-chain.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-grpc-router.latest.golden b/agent/xds/testdata/routes/ingress-with-grpc-router.latest.golden index 25afe4ee6dac6..bc6d021fbba30 100644 --- a/agent/xds/testdata/routes/ingress-with-grpc-router.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-grpc-router.latest.golden @@ -1,17 +1,16 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "8080", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "db.ingress.*", "db.ingress.*:8080" ], - "name": "db", "routes": [ { "match": { @@ -31,9 +30,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-sds-listener-level-wildcard.latest.golden b/agent/xds/testdata/routes/ingress-with-sds-listener-level-wildcard.latest.golden index cf218b1c95749..cedfc99f6550c 100644 --- a/agent/xds/testdata/routes/ingress-with-sds-listener-level-wildcard.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-sds-listener-level-wildcard.latest.golden @@ -1,50 +1,50 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "9191", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "9191", + "virtualHosts": [ { - "domains": [ + "name": "web", + "domains": [ "web.ingress.*", "web.ingress.*:9191" ], - "name": "web", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] }, { - "domains": [ + "name": "foo", + "domains": [ "foo.ingress.*", "foo.ingress.*:9191" ], - "name": "foo", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-sds-listener-level.latest.golden b/agent/xds/testdata/routes/ingress-with-sds-listener-level.latest.golden index 350f1605f6451..3f2631217daf4 100644 --- a/agent/xds/testdata/routes/ingress-with-sds-listener-level.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-sds-listener-level.latest.golden @@ -1,50 +1,50 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "9191", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "9191", + "virtualHosts": [ { - "domains": [ + "name": "web", + "domains": [ "www.example.com", "www.example.com:9191" ], - "name": "web", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] }, { - "domains": [ + "name": "foo", + "domains": [ "foo.example.com", "foo.example.com:9191" ], - "name": "foo", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-sds-service-level-mixed-tls.latest.golden b/agent/xds/testdata/routes/ingress-with-sds-service-level-mixed-tls.latest.golden index 8cd0610d70ea3..7539ad4feb1ab 100644 --- a/agent/xds/testdata/routes/ingress-with-sds-service-level-mixed-tls.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-sds-service-level-mixed-tls.latest.golden @@ -1,57 +1,57 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "9191", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "9191", + "virtualHosts": [ { - "domains": [ + "name": "foo", + "domains": [ "foo.example.com", "foo.example.com:9191" ], - "name": "foo", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] } - ] + ], + "validateClusters": true }, { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "9191_web", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "9191_web", + "virtualHosts": [ { - "domains": [ + "name": "web", + "domains": [ "www.example.com", "www.example.com:9191" ], - "name": "web", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/ingress-with-sds-service-level.latest.golden b/agent/xds/testdata/routes/ingress-with-sds-service-level.latest.golden index 48d9d7b774439..6009fac723147 100644 --- a/agent/xds/testdata/routes/ingress-with-sds-service-level.latest.golden +++ b/agent/xds/testdata/routes/ingress-with-sds-service-level.latest.golden @@ -1,57 +1,57 @@ { - "nonce": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "9191_foo", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "9191_foo", + "virtualHosts": [ { - "domains": [ + "name": "foo", + "domains": [ "foo.example.com", "foo.example.com:9191" ], - "name": "foo", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "foo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] } - ] + ], + "validateClusters": true }, { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "9191_web", - "validateClusters": true, - "virtualHosts": [ + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "9191_web", + "virtualHosts": [ { - "domains": [ + "name": "web", + "domains": [ "www.example.com", "www.example.com:9191" ], - "name": "web", - "routes": [ + "routes": [ { - "match": { - "prefix": "/" + "match": { + "prefix": "/" }, - "route": { - "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "timeout": "22s" + "route": { + "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "22s" } } ] } - ] + ], + "validateClusters": true } ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/local-mesh-gateway-with-peered-upstreams.latest.golden b/agent/xds/testdata/routes/local-mesh-gateway-with-peered-upstreams.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/local-mesh-gateway-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/routes/local-mesh-gateway-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/mesh-gateway-peering-control-plane.latest.golden b/agent/xds/testdata/routes/mesh-gateway-peering-control-plane.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/mesh-gateway-peering-control-plane.latest.golden +++ b/agent/xds/testdata/routes/mesh-gateway-peering-control-plane.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden b/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden index 825473467d5ec..ce1c0ad2d5cbf 100644 --- a/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden +++ b/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "*" ], - "name": "db", "routes": [ { "match": { @@ -50,9 +49,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services-http.latest.golden b/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services-http.latest.golden index 4737a59e31562..5b64a2c7ed5c5 100644 --- a/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services-http.latest.golden +++ b/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services-http.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "bar", - "validateClusters": true, "virtualHosts": [ { + "name": "bar", "domains": [ "*" ], - "name": "bar", "routes": [ { "match": { @@ -22,18 +21,18 @@ } ] } - ] + ], + "validateClusters": true }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "foo", - "validateClusters": true, "virtualHosts": [ { + "name": "foo", "domains": [ "*" ], - "name": "foo", "routes": [ { "match": { @@ -45,18 +44,18 @@ } ] } - ] + ], + "validateClusters": true }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "gir", - "validateClusters": true, "virtualHosts": [ { + "name": "gir", "domains": [ "*" ], - "name": "gir", "routes": [ { "match": { @@ -68,9 +67,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services.latest.golden b/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services.latest.golden +++ b/agent/xds/testdata/routes/mesh-gateway-with-exported-peered-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/mesh-gateway-with-imported-peered-services.latest.golden b/agent/xds/testdata/routes/mesh-gateway-with-imported-peered-services.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/mesh-gateway-with-imported-peered-services.latest.golden +++ b/agent/xds/testdata/routes/mesh-gateway-with-imported-peered-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden b/agent/xds/testdata/routes/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden +++ b/agent/xds/testdata/routes/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/splitter-with-resolver-redirect.latest.golden b/agent/xds/testdata/routes/splitter-with-resolver-redirect.latest.golden index 8c192286007cf..dec26fd159944 100644 --- a/agent/xds/testdata/routes/splitter-with-resolver-redirect.latest.golden +++ b/agent/xds/testdata/routes/splitter-with-resolver-redirect.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "db", - "validateClusters": true, "virtualHosts": [ { + "name": "db", "domains": [ "*" ], - "name": "db", "routes": [ { "match": { @@ -34,9 +33,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/telemetry-collector.latest.golden b/agent/xds/testdata/routes/telemetry-collector.latest.golden index 8b919343d21a9..306f5220e7b9c 100644 --- a/agent/xds/testdata/routes/telemetry-collector.latest.golden +++ b/agent/xds/testdata/routes/telemetry-collector.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/terminating-gateway-lb-config.latest.golden b/agent/xds/testdata/routes/terminating-gateway-lb-config.latest.golden index 1e7cdde138faa..cc49c907cce5c 100644 --- a/agent/xds/testdata/routes/terminating-gateway-lb-config.latest.golden +++ b/agent/xds/testdata/routes/terminating-gateway-lb-config.latest.golden @@ -1,24 +1,23 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], - "name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { "prefix": "/" }, "route": { - "autoHostRewrite": true, "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "autoHostRewrite": true, "hashPolicy": [ { "cookie": { @@ -37,32 +36,31 @@ }, "terminal": true } - ], - "timeout": "0.200s" + ] } } ] } - ] + ], + "validateClusters": true }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], - "name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { "prefix": "/" }, "route": { - "autoHostRewrite": true, "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "autoHostRewrite": true, "hashPolicy": [ { "cookie": { @@ -81,32 +79,31 @@ }, "terminal": true } - ], - "timeout": "0.200s" + ] } } ] } - ] + ], + "validateClusters": true }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], - "name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { "prefix": "/" }, "route": { - "autoHostRewrite": true, "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "autoHostRewrite": true, "hashPolicy": [ { "cookie": { @@ -125,15 +122,15 @@ }, "terminal": true } - ], - "timeout": "0.200s" + ] } } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/transparent-proxy-destination-http.latest.golden b/agent/xds/testdata/routes/transparent-proxy-destination-http.latest.golden index 0f3440e32e347..173aa56476f6d 100644 --- a/agent/xds/testdata/routes/transparent-proxy-destination-http.latest.golden +++ b/agent/xds/testdata/routes/transparent-proxy-destination-http.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "destination.443.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "www.google.com" ], - "name": "destination.www-google-com.google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -22,18 +21,18 @@ } ] } - ] + ], + "validateClusters": true }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "destination.9093.~http.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "192.168.2.3" ], - "name": "destination.192-168-2-3.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -46,10 +45,10 @@ ] }, { + "name": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "192.168.2.2" ], - "name": "destination.192-168-2-2.kafka2.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -62,10 +61,10 @@ ] }, { + "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "192.168.2.1" ], - "name": "destination.192-168-2-1.kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -77,9 +76,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/transparent-proxy-destination.latest.golden b/agent/xds/testdata/routes/transparent-proxy-destination.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/transparent-proxy-destination.latest.golden +++ b/agent/xds/testdata/routes/transparent-proxy-destination.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/transparent-proxy-terminating-gateway-destinations-only.latest.golden b/agent/xds/testdata/routes/transparent-proxy-terminating-gateway-destinations-only.latest.golden index 14ac8198ffbd7..37cf2c0b00a8d 100644 --- a/agent/xds/testdata/routes/transparent-proxy-terminating-gateway-destinations-only.latest.golden +++ b/agent/xds/testdata/routes/transparent-proxy-terminating-gateway-destinations-only.latest.golden @@ -1,16 +1,15 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "resources": [ { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "destination.192-168-0-2.external-IP-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "destination.192-168-0-2.external-IP-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], - "name": "destination.192-168-0-2.external-IP-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -22,18 +21,18 @@ } ] } - ] + ], + "validateClusters": true }, { "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "name": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "validateClusters": true, "virtualHosts": [ { + "name": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "domains": [ "*" ], - "name": "destination.httpbin-org.external-hostname-HTTP.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "routes": [ { "match": { @@ -45,9 +44,10 @@ } ] } - ] + ], + "validateClusters": true } ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/transparent-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/routes/transparent-proxy-with-peered-upstreams.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/transparent-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/routes/transparent-proxy-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/transparent-proxy.latest.golden b/agent/xds/testdata/routes/transparent-proxy.latest.golden index 8b919343d21a9..9c050cbe6b4d4 100644 --- a/agent/xds/testdata/routes/transparent-proxy.latest.golden +++ b/agent/xds/testdata/routes/transparent-proxy.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden b/agent/xds/testdata/secrets/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/api-gateway-with-http-route-timeoutfilter-one-set.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/api-gateway-with-http-route.latest.golden b/agent/xds/testdata/secrets/api-gateway-with-http-route.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/api-gateway-with-http-route.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/api-gateway-with-multiple-inline-certificates.latest.golden b/agent/xds/testdata/secrets/api-gateway-with-multiple-inline-certificates.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/api-gateway-with-multiple-inline-certificates.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/api-gateway-with-tcp-route-and-inline-certificate.latest.golden b/agent/xds/testdata/secrets/api-gateway-with-tcp-route-and-inline-certificate.latest.golden index 82e45650658b4..95612291de707 100644 --- a/agent/xds/testdata/secrets/api-gateway-with-tcp-route-and-inline-certificate.latest.golden +++ b/agent/xds/testdata/secrets/api-gateway-with-tcp-route-and-inline-certificate.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", + "versionInfo": "00000001", "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-exported-to-peers.latest.golden b/agent/xds/testdata/secrets/connect-proxy-exported-to-peers.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/connect-proxy-exported-to-peers.latest.golden +++ b/agent/xds/testdata/secrets/connect-proxy-exported-to-peers.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/secrets/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/secrets/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-escape-overrides.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-http2.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-http2.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-http2.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-listener-override.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-listener-override.latest.golden deleted file mode 100644 index 95612291de707..0000000000000 --- a/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams-listener-override.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/secrets/connect-proxy-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/defaults.latest.golden b/agent/xds/testdata/secrets/defaults.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/defaults.latest.golden +++ b/agent/xds/testdata/secrets/defaults.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/local-mesh-gateway-with-peered-upstreams.latest.golden b/agent/xds/testdata/secrets/local-mesh-gateway-with-peered-upstreams.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/local-mesh-gateway-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/secrets/local-mesh-gateway-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/mesh-gateway-peering-control-plane.latest.golden b/agent/xds/testdata/secrets/mesh-gateway-peering-control-plane.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/mesh-gateway-peering-control-plane.latest.golden +++ b/agent/xds/testdata/secrets/mesh-gateway-peering-control-plane.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden b/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden +++ b/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services-http-with-router.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services-http.latest.golden b/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services-http.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services-http.latest.golden +++ b/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services-http.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services.latest.golden b/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services.latest.golden +++ b/agent/xds/testdata/secrets/mesh-gateway-with-exported-peered-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/mesh-gateway-with-imported-peered-services.latest.golden b/agent/xds/testdata/secrets/mesh-gateway-with-imported-peered-services.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/mesh-gateway-with-imported-peered-services.latest.golden +++ b/agent/xds/testdata/secrets/mesh-gateway-with-imported-peered-services.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden b/agent/xds/testdata/secrets/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden +++ b/agent/xds/testdata/secrets/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/telemetry-collector.latest.golden b/agent/xds/testdata/secrets/telemetry-collector.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/telemetry-collector.latest.golden +++ b/agent/xds/testdata/secrets/telemetry-collector.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/transparent-proxy-destination-http.latest.golden b/agent/xds/testdata/secrets/transparent-proxy-destination-http.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/transparent-proxy-destination-http.latest.golden +++ b/agent/xds/testdata/secrets/transparent-proxy-destination-http.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/transparent-proxy-destination.latest.golden b/agent/xds/testdata/secrets/transparent-proxy-destination.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/transparent-proxy-destination.latest.golden +++ b/agent/xds/testdata/secrets/transparent-proxy-destination.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/transparent-proxy-terminating-gateway-destinations-only.latest.golden b/agent/xds/testdata/secrets/transparent-proxy-terminating-gateway-destinations-only.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/transparent-proxy-terminating-gateway-destinations-only.latest.golden +++ b/agent/xds/testdata/secrets/transparent-proxy-terminating-gateway-destinations-only.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/transparent-proxy-with-peered-upstreams.latest.golden b/agent/xds/testdata/secrets/transparent-proxy-with-peered-upstreams.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/transparent-proxy-with-peered-upstreams.latest.golden +++ b/agent/xds/testdata/secrets/transparent-proxy-with-peered-upstreams.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/secrets/transparent-proxy.latest.golden b/agent/xds/testdata/secrets/transparent-proxy.latest.golden index 82e45650658b4..e6c25e165c65d 100644 --- a/agent/xds/testdata/secrets/transparent-proxy.latest.golden +++ b/agent/xds/testdata/secrets/transparent-proxy.latest.golden @@ -1,5 +1,5 @@ { - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xds/testing.go b/agent/xds/testing.go index 916bbd9b50777..446f1a37a6518 100644 --- a/agent/xds/testing.go +++ b/agent/xds/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds diff --git a/agent/xds/validateupstream-test/validateupstream_test.go b/agent/xds/validateupstream-test/validateupstream_test.go index 9c57bdf81aaf2..f2810bb1c02e4 100644 --- a/agent/xds/validateupstream-test/validateupstream_test.go +++ b/agent/xds/validateupstream-test/validateupstream_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package validateupstream_test diff --git a/agent/xds/xds.go b/agent/xds/xds.go index aab5bc7aaf14c..07fe1c4731079 100644 --- a/agent/xds/xds.go +++ b/agent/xds/xds.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package xds provides an implementation of a gRPC service that exports Envoy's // xDS API for config discovery. Specifically we support the Aggregated diff --git a/agent/xds/xds_protocol_helpers_test.go b/agent/xds/xds_protocol_helpers_test.go index 655e0458f49e0..958a27474c441 100644 --- a/agent/xds/xds_protocol_helpers_test.go +++ b/agent/xds/xds_protocol_helpers_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds @@ -9,7 +9,10 @@ import ( "testing" "time" - "github.com/armon/go-metrics" + "github.com/hashicorp/consul/agent/connect" + "github.com/hashicorp/consul/agent/grpc-external/limiter" + "github.com/hashicorp/consul/envoyextensions/xdscommon" + envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" @@ -24,6 +27,8 @@ import ( envoy_upstreams_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3" envoy_discovery_v3 "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" + + "github.com/armon/go-metrics" "github.com/mitchellh/copystructure" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" @@ -31,15 +36,8 @@ import ( "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/wrapperspb" - "github.com/hashicorp/consul/agent/connect" - "github.com/hashicorp/consul/agent/grpc-external/limiter" "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/proxycfg-sources/catalog" "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil" ) @@ -73,14 +71,14 @@ func newTestSnapshot( // testing. It also implements ConnectAuthz to allow control over authorization. type testManager struct { sync.Mutex - stateChans map[structs.ServiceID]chan proxysnapshot.ProxySnapshot + stateChans map[structs.ServiceID]chan *proxycfg.ConfigSnapshot drainChans map[structs.ServiceID]chan struct{} cancels chan structs.ServiceID } func newTestManager(t *testing.T) *testManager { return &testManager{ - stateChans: map[structs.ServiceID]chan proxysnapshot.ProxySnapshot{}, + stateChans: map[structs.ServiceID]chan *proxycfg.ConfigSnapshot{}, drainChans: map[structs.ServiceID]chan struct{}{}, cancels: make(chan structs.ServiceID, 10), } @@ -90,12 +88,12 @@ func newTestManager(t *testing.T) *testManager { func (m *testManager) RegisterProxy(t *testing.T, proxyID structs.ServiceID) { m.Lock() defer m.Unlock() - m.stateChans[proxyID] = make(chan proxysnapshot.ProxySnapshot, 1) + m.stateChans[proxyID] = make(chan *proxycfg.ConfigSnapshot, 1) m.drainChans[proxyID] = make(chan struct{}) } // Deliver simulates a proxy registration -func (m *testManager) DeliverConfig(t *testing.T, proxyID structs.ServiceID, cfg proxysnapshot.ProxySnapshot) { +func (m *testManager) DeliverConfig(t *testing.T, proxyID structs.ServiceID, cfg *proxycfg.ConfigSnapshot) { t.Helper() m.Lock() defer m.Unlock() @@ -122,10 +120,7 @@ func (m *testManager) DrainStreams(proxyID structs.ServiceID) { } // Watch implements ConfigManager -func (m *testManager) Watch(id *pbresource.ID, _ string, _ string) (<-chan proxysnapshot.ProxySnapshot, - limiter.SessionTerminatedChan, proxysnapshot.CancelFunc, error) { - // Create service ID - proxyID := structs.NewServiceID(id.Name, catalog.GetEnterpriseMetaFromResourceID(id)) +func (m *testManager) Watch(proxyID structs.ServiceID, _ string, _ string) (<-chan *proxycfg.ConfigSnapshot, limiter.SessionTerminatedChan, proxycfg.CancelFunc, error) { m.Lock() defer m.Unlock() @@ -233,7 +228,7 @@ func xdsNewEndpoint(ip string, port int) *envoy_endpoint_v3.LbEndpoint { return &envoy_endpoint_v3.LbEndpoint{ HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ Endpoint: &envoy_endpoint_v3.Endpoint{ - Address: response.MakeAddress(ip, port), + Address: makeAddress(ip, port), }, }, } @@ -242,7 +237,7 @@ func xdsNewEndpoint(ip string, port int) *envoy_endpoint_v3.LbEndpoint { func xdsNewEndpointWithHealth(ip string, port int, health envoy_core_v3.HealthStatus, weight int) *envoy_endpoint_v3.LbEndpoint { ep := xdsNewEndpoint(ip, port) ep.HealthStatus = health - ep.LoadBalancingWeight = response.MakeUint32Value(weight) + ep.LoadBalancingWeight = makeUint32Value(weight) return ep } @@ -302,7 +297,7 @@ func xdsNewTransportSocket( if downstream { var requireClientCertPB *wrapperspb.BoolValue if requireClientCert { - requireClientCertPB = response.MakeBoolValue(true) + requireClientCertPB = makeBoolValue(true) } tlsContext = &envoy_tls_v3.DownstreamTlsContext{ @@ -602,7 +597,7 @@ func makeTestListener(t *testing.T, snap *proxycfg.ConfigSnapshot, fixtureName s return &envoy_listener_v3.Listener{ // Envoy can't bind to port 1 Name: "public_listener:0.0.0.0:1", - Address: response.MakeAddress("0.0.0.0", 1), + Address: makeAddress("0.0.0.0", 1), TrafficDirection: envoy_core_v3.TrafficDirection_INBOUND, FilterChains: []*envoy_listener_v3.FilterChain{ { @@ -625,7 +620,7 @@ func makeTestListener(t *testing.T, snap *proxycfg.ConfigSnapshot, fixtureName s case "tcp:public_listener": return &envoy_listener_v3.Listener{ Name: "public_listener:0.0.0.0:9999", - Address: response.MakeAddress("0.0.0.0", 9999), + Address: makeAddress("0.0.0.0", 9999), TrafficDirection: envoy_core_v3.TrafficDirection_INBOUND, FilterChains: []*envoy_listener_v3.FilterChain{ { @@ -648,7 +643,7 @@ func makeTestListener(t *testing.T, snap *proxycfg.ConfigSnapshot, fixtureName s case "tcp:db": return &envoy_listener_v3.Listener{ Name: "db:127.0.0.1:9191", - Address: response.MakeAddress("127.0.0.1", 9191), + Address: makeAddress("127.0.0.1", 9191), TrafficDirection: envoy_core_v3.TrafficDirection_OUTBOUND, FilterChains: []*envoy_listener_v3.FilterChain{ { @@ -666,7 +661,7 @@ func makeTestListener(t *testing.T, snap *proxycfg.ConfigSnapshot, fixtureName s case "http2:db": return &envoy_listener_v3.Listener{ Name: "db:127.0.0.1:9191", - Address: response.MakeAddress("127.0.0.1", 9191), + Address: makeAddress("127.0.0.1", 9191), TrafficDirection: envoy_core_v3.TrafficDirection_OUTBOUND, FilterChains: []*envoy_listener_v3.FilterChain{ { @@ -694,7 +689,7 @@ func makeTestListener(t *testing.T, snap *proxycfg.ConfigSnapshot, fixtureName s case "http2:db:rds": return &envoy_listener_v3.Listener{ Name: "db:127.0.0.1:9191", - Address: response.MakeAddress("127.0.0.1", 9191), + Address: makeAddress("127.0.0.1", 9191), TrafficDirection: envoy_core_v3.TrafficDirection_OUTBOUND, FilterChains: []*envoy_listener_v3.FilterChain{ { @@ -725,7 +720,7 @@ func makeTestListener(t *testing.T, snap *proxycfg.ConfigSnapshot, fixtureName s case "http:db:rds": return &envoy_listener_v3.Listener{ Name: "db:127.0.0.1:9191", - Address: response.MakeAddress("127.0.0.1", 9191), + Address: makeAddress("127.0.0.1", 9191), TrafficDirection: envoy_core_v3.TrafficDirection_OUTBOUND, FilterChains: []*envoy_listener_v3.FilterChain{ { @@ -756,7 +751,7 @@ func makeTestListener(t *testing.T, snap *proxycfg.ConfigSnapshot, fixtureName s case "tcp:geo-cache": return &envoy_listener_v3.Listener{ Name: "prepared_query:geo-cache:127.10.10.10:8181", - Address: response.MakeAddress("127.10.10.10", 8181), + Address: makeAddress("127.10.10.10", 8181), TrafficDirection: envoy_core_v3.TrafficDirection_OUTBOUND, FilterChains: []*envoy_listener_v3.FilterChain{ { @@ -782,7 +777,7 @@ func makeTestRoute(t *testing.T, fixtureName string) *envoy_route_v3.RouteConfig case "http2:db", "http:db": return &envoy_route_v3.RouteConfiguration{ Name: "db", - ValidateClusters: response.MakeBoolValue(true), + ValidateClusters: makeBoolValue(true), VirtualHosts: []*envoy_route_v3.VirtualHost{ { Name: "db", diff --git a/agent/xds/z_xds_packages_test.go b/agent/xds/z_xds_packages_test.go index f5f0435189338..149490678cf27 100644 --- a/agent/xds/z_xds_packages_test.go +++ b/agent/xds/z_xds_packages_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xds diff --git a/agent/xdsv2/cluster_resources.go b/agent/xdsv2/cluster_resources.go deleted file mode 100644 index d32eeed2ec62b..0000000000000 --- a/agent/xdsv2/cluster_resources.go +++ /dev/null @@ -1,384 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xdsv2 - -import ( - "errors" - "fmt" - - envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" - envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_aggregate_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/clusters/aggregate/v3" - envoy_upstreams_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3" - envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -func (pr *ProxyResources) doesEnvoyClusterAlreadyExist(name string) bool { - // TODO(proxystate): consider using a map instead of [] for this kind of lookup - for _, envoyCluster := range pr.envoyResources[xdscommon.ClusterType] { - if envoyCluster.(*envoy_cluster_v3.Cluster).Name == name { - return true - } - } - return false -} - -func (pr *ProxyResources) makeXDSClusters() ([]proto.Message, error) { - clusters := make([]proto.Message, 0) - - for clusterName := range pr.proxyState.Clusters { - protoCluster, err := pr.makeClusters(clusterName) - // TODO: aggregate errors for clusters and still return any properly formed clusters. - if err != nil { - return nil, err - } - clusters = append(clusters, protoCluster...) - } - - return clusters, nil -} - -func (pr *ProxyResources) makeClusters(name string) ([]proto.Message, error) { - clusters := make([]proto.Message, 0) - proxyStateCluster, ok := pr.proxyState.Clusters[name] - if !ok { - return nil, fmt.Errorf("cluster %q not found", name) - } - - if pr.doesEnvoyClusterAlreadyExist(name) { - // don't error - return []proto.Message{}, nil - } - - switch proxyStateCluster.Group.(type) { - case *pbproxystate.Cluster_FailoverGroup: - fg := proxyStateCluster.GetFailoverGroup() - clusters, err := pr.makeEnvoyAggregateCluster(name, proxyStateCluster.Protocol, fg) - if err != nil { - return nil, err - } - for _, c := range clusters { - clusters = append(clusters, c) - } - - case *pbproxystate.Cluster_EndpointGroup: - eg := proxyStateCluster.GetEndpointGroup() - cluster, err := pr.makeEnvoyCluster(name, proxyStateCluster.Protocol, eg) - if err != nil { - return nil, err - } - clusters = append(clusters, cluster) - - default: - return nil, errors.New("cluster group type should be Endpoint Group or Failover Group") - } - return clusters, nil -} - -func (pr *ProxyResources) makeEnvoyCluster(name string, protocol pbproxystate.Protocol, eg *pbproxystate.EndpointGroup) (*envoy_cluster_v3.Cluster, error) { - if eg != nil { - switch t := eg.Group.(type) { - case *pbproxystate.EndpointGroup_Dynamic: - dynamic := eg.GetDynamic() - return pr.makeEnvoyDynamicCluster(name, protocol, dynamic) - case *pbproxystate.EndpointGroup_Static: - static := eg.GetStatic() - return pr.makeEnvoyStaticCluster(name, protocol, static) - case *pbproxystate.EndpointGroup_Dns: - dns := eg.GetDns() - return pr.makeEnvoyDnsCluster(name, protocol, dns) - case *pbproxystate.EndpointGroup_Passthrough: - passthrough := eg.GetPassthrough() - return pr.makeEnvoyPassthroughCluster(name, protocol, passthrough) - default: - return nil, fmt.Errorf("unsupported endpoint group type: %s", t) - } - } - return nil, fmt.Errorf("no endpoint group") -} - -func (pr *ProxyResources) makeEnvoyDynamicCluster(name string, protocol pbproxystate.Protocol, dynamic *pbproxystate.DynamicEndpointGroup) (*envoy_cluster_v3.Cluster, error) { - cluster := &envoy_cluster_v3.Cluster{ - Name: name, - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_EDS}, - EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: &envoy_core_v3.ConfigSource{ - ResourceApiVersion: envoy_core_v3.ApiVersion_V3, - ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_Ads{ - Ads: &envoy_core_v3.AggregatedConfigSource{}, - }, - }, - }, - } - err := addHttpProtocolOptions(protocol, cluster) - if err != nil { - return nil, err - } - if dynamic.Config != nil { - if dynamic.Config.UseAltStatName { - cluster.AltStatName = name - } - cluster.ConnectTimeout = dynamic.Config.ConnectTimeout - if dynamic.Config.DisablePanicThreshold { - cluster.CommonLbConfig = &envoy_cluster_v3.Cluster_CommonLbConfig{ - HealthyPanicThreshold: &envoy_type_v3.Percent{ - Value: 0, // disable panic threshold - }, - } - } - addEnvoyCircuitBreakers(dynamic.Config.CircuitBreakers, cluster) - addEnvoyOutlierDetection(dynamic.Config.OutlierDetection, cluster) - - err := addEnvoyLBToCluster(dynamic.Config, cluster) - if err != nil { - return nil, err - } - } - - if dynamic.OutboundTls != nil { - envoyTransportSocket, err := pr.makeEnvoyTransportSocket(dynamic.OutboundTls) - if err != nil { - return nil, err - } - cluster.TransportSocket = envoyTransportSocket - } - - return cluster, nil - -} - -func (pr *ProxyResources) makeEnvoyStaticCluster(name string, protocol pbproxystate.Protocol, static *pbproxystate.StaticEndpointGroup) (*envoy_cluster_v3.Cluster, error) { - cluster := &envoy_cluster_v3.Cluster{ - Name: name, - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_STATIC}, - } - - // todo (ishustava/v2): we need to be able to handle the case when empty endpoints are allowed on a cluster. - endpointList, ok := pr.proxyState.Endpoints[name] - if ok { - cluster.LoadAssignment = makeEnvoyClusterLoadAssignment(name, endpointList.Endpoints) - } - - var err error - if name == xdscommon.LocalAppClusterName { - err = addLocalAppHttpProtocolOptions(protocol, cluster) - } else { - err = addHttpProtocolOptions(protocol, cluster) - } - if err != nil { - return nil, err - } - - if static.Config != nil { - cluster.ConnectTimeout = static.Config.ConnectTimeout - addEnvoyCircuitBreakers(static.GetConfig().CircuitBreakers, cluster) - } - return cluster, nil -} - -func (pr *ProxyResources) makeEnvoyDnsCluster(name string, protocol pbproxystate.Protocol, dns *pbproxystate.DNSEndpointGroup) (*envoy_cluster_v3.Cluster, error) { - return nil, nil -} - -func (pr *ProxyResources) makeEnvoyPassthroughCluster(name string, protocol pbproxystate.Protocol, passthrough *pbproxystate.PassthroughEndpointGroup) (*envoy_cluster_v3.Cluster, error) { - cluster := &envoy_cluster_v3.Cluster{ - Name: name, - ConnectTimeout: passthrough.Config.ConnectTimeout, - LbPolicy: envoy_cluster_v3.Cluster_CLUSTER_PROVIDED, - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_ORIGINAL_DST}, - } - if passthrough.OutboundTls != nil { - envoyTransportSocket, err := pr.makeEnvoyTransportSocket(passthrough.OutboundTls) - if err != nil { - return nil, err - } - cluster.TransportSocket = envoyTransportSocket - } - err := addHttpProtocolOptions(protocol, cluster) - if err != nil { - return nil, err - } - return cluster, nil -} - -func (pr *ProxyResources) makeEnvoyAggregateCluster(name string, protocol pbproxystate.Protocol, fg *pbproxystate.FailoverGroup) ([]*envoy_cluster_v3.Cluster, error) { - var clusters []*envoy_cluster_v3.Cluster - if fg != nil { - var egNames []string - for _, eg := range fg.EndpointGroups { - cluster, err := pr.makeEnvoyCluster(eg.Name, protocol, eg) - if err != nil { - return nil, err - } - egNames = append(egNames, cluster.Name) - clusters = append(clusters, cluster) - } - aggregateClusterConfig, err := anypb.New(&envoy_aggregate_cluster_v3.ClusterConfig{ - Clusters: egNames, - }) - - if err != nil { - return nil, err - } - - c := &envoy_cluster_v3.Cluster{ - Name: name, - ConnectTimeout: fg.Config.ConnectTimeout, - LbPolicy: envoy_cluster_v3.Cluster_CLUSTER_PROVIDED, - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_ClusterType{ - ClusterType: &envoy_cluster_v3.Cluster_CustomClusterType{ - Name: "envoy.clusters.aggregate", - TypedConfig: aggregateClusterConfig, - }, - }, - } - if fg.Config.UseAltStatName { - c.AltStatName = name - } - err = addHttpProtocolOptions(protocol, c) - if err != nil { - return nil, err - } - clusters = append(clusters, c) - } - return clusters, nil -} - -func addLocalAppHttpProtocolOptions(protocol pbproxystate.Protocol, c *envoy_cluster_v3.Cluster) error { - if !(protocol == pbproxystate.Protocol_PROTOCOL_HTTP2 || protocol == pbproxystate.Protocol_PROTOCOL_GRPC) { - // do not error. returning nil means it won't get set. - return nil - } - cfg := &envoy_upstreams_v3.HttpProtocolOptions{ - UpstreamProtocolOptions: &envoy_upstreams_v3.HttpProtocolOptions_UseDownstreamProtocolConfig{ - UseDownstreamProtocolConfig: &envoy_upstreams_v3.HttpProtocolOptions_UseDownstreamHttpConfig{ - HttpProtocolOptions: &envoy_core_v3.Http1ProtocolOptions{}, - Http2ProtocolOptions: &envoy_core_v3.Http2ProtocolOptions{}, - }, - }, - } - any, err := anypb.New(cfg) - if err != nil { - return err - } - c.TypedExtensionProtocolOptions = map[string]*anypb.Any{ - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": any, - } - - return nil -} - -func addHttpProtocolOptions(protocol pbproxystate.Protocol, c *envoy_cluster_v3.Cluster) error { - if !(protocol == pbproxystate.Protocol_PROTOCOL_HTTP2 || protocol == pbproxystate.Protocol_PROTOCOL_GRPC) { - // do not error. returning nil means it won't get set. - return nil - } - cfg := &envoy_upstreams_v3.HttpProtocolOptions{ - UpstreamProtocolOptions: &envoy_upstreams_v3.HttpProtocolOptions_ExplicitHttpConfig_{ - ExplicitHttpConfig: &envoy_upstreams_v3.HttpProtocolOptions_ExplicitHttpConfig{ - ProtocolConfig: &envoy_upstreams_v3.HttpProtocolOptions_ExplicitHttpConfig_Http2ProtocolOptions{ - Http2ProtocolOptions: &envoy_core_v3.Http2ProtocolOptions{}, - }, - }, - }, - } - any, err := anypb.New(cfg) - if err != nil { - return err - } - c.TypedExtensionProtocolOptions = map[string]*anypb.Any{ - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": any, - } - return nil -} - -// addEnvoyOutlierDetection will add outlier detection config to the cluster, and if nil, add empty OutlierDetection to -// enable it with default values -func addEnvoyOutlierDetection(outlierDetection *pbproxystate.OutlierDetection, c *envoy_cluster_v3.Cluster) { - if outlierDetection == nil { - return - } - od := &envoy_cluster_v3.OutlierDetection{ - BaseEjectionTime: outlierDetection.GetBaseEjectionTime(), - Consecutive_5Xx: outlierDetection.GetConsecutive_5Xx(), - EnforcingConsecutive_5Xx: outlierDetection.GetEnforcingConsecutive_5Xx(), - Interval: outlierDetection.GetInterval(), - MaxEjectionPercent: outlierDetection.GetMaxEjectionPercent(), - } - c.OutlierDetection = od - -} - -func addEnvoyCircuitBreakers(circuitBreakers *pbproxystate.CircuitBreakers, c *envoy_cluster_v3.Cluster) { - if circuitBreakers != nil { - if circuitBreakers.UpstreamLimits == nil { - c.CircuitBreakers = &envoy_cluster_v3.CircuitBreakers{} - return - } - threshold := &envoy_cluster_v3.CircuitBreakers_Thresholds{} - threshold.MaxConnections = circuitBreakers.UpstreamLimits.MaxConnections - threshold.MaxPendingRequests = circuitBreakers.UpstreamLimits.MaxPendingRequests - threshold.MaxRequests = circuitBreakers.UpstreamLimits.MaxConcurrentRequests - - c.CircuitBreakers = &envoy_cluster_v3.CircuitBreakers{ - Thresholds: []*envoy_cluster_v3.CircuitBreakers_Thresholds{threshold}, - } - } -} - -func addEnvoyLBToCluster(dynamicConfig *pbproxystate.DynamicEndpointGroupConfig, c *envoy_cluster_v3.Cluster) error { - if dynamicConfig == nil || dynamicConfig.LbPolicy == nil { - return nil - } - - switch d := dynamicConfig.LbPolicy.(type) { - case *pbproxystate.DynamicEndpointGroupConfig_LeastRequest: - c.LbPolicy = envoy_cluster_v3.Cluster_LEAST_REQUEST - - lb := dynamicConfig.LbPolicy.(*pbproxystate.DynamicEndpointGroupConfig_LeastRequest) - if lb.LeastRequest != nil { - c.LbConfig = &envoy_cluster_v3.Cluster_LeastRequestLbConfig_{ - LeastRequestLbConfig: &envoy_cluster_v3.Cluster_LeastRequestLbConfig{ - ChoiceCount: lb.LeastRequest.ChoiceCount, - }, - } - } - case *pbproxystate.DynamicEndpointGroupConfig_RoundRobin: - c.LbPolicy = envoy_cluster_v3.Cluster_ROUND_ROBIN - - case *pbproxystate.DynamicEndpointGroupConfig_Random: - c.LbPolicy = envoy_cluster_v3.Cluster_RANDOM - - case *pbproxystate.DynamicEndpointGroupConfig_RingHash: - c.LbPolicy = envoy_cluster_v3.Cluster_RING_HASH - - lb := dynamicConfig.LbPolicy.(*pbproxystate.DynamicEndpointGroupConfig_RingHash) - if lb.RingHash != nil { - c.LbConfig = &envoy_cluster_v3.Cluster_RingHashLbConfig_{ - RingHashLbConfig: &envoy_cluster_v3.Cluster_RingHashLbConfig{ - MinimumRingSize: lb.RingHash.MinimumRingSize, - MaximumRingSize: lb.RingHash.MaximumRingSize, - }, - } - } - case *pbproxystate.DynamicEndpointGroupConfig_Maglev: - c.LbPolicy = envoy_cluster_v3.Cluster_MAGLEV - - default: - return fmt.Errorf("unsupported load balancer policy %q for cluster %q", d, c.Name) - } - return nil -} - -// TODO(proxystate): In a future PR this will create clusters and add it to ProxyResources.proxyState -// Currently, we do not traverse the listener -> endpoint paths and instead just generate each resource by iterating -// through its top level map. In the future we want to traverse these paths to ensure each listener has a cluster, etc. -func (pr *ProxyResources) makeEnvoyClusterFromL4Destination(l4 *pbproxystate.L4Destination) error { - return nil -} diff --git a/agent/xdsv2/endpoint_resources.go b/agent/xdsv2/endpoint_resources.go deleted file mode 100644 index fa3d39d8779fe..0000000000000 --- a/agent/xdsv2/endpoint_resources.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xdsv2 - -import ( - envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "google.golang.org/protobuf/proto" -) - -func makeEnvoyLbEndpoint(endpoint *pbproxystate.Endpoint) *envoy_endpoint_v3.LbEndpoint { - hs := int32(endpoint.GetHealthStatus().Number()) - return &envoy_endpoint_v3.LbEndpoint{ - HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ - Endpoint: makeEnvoyEndpoint(endpoint), - }, - HealthStatus: envoy_core_v3.HealthStatus(hs), - LoadBalancingWeight: endpoint.GetLoadBalancingWeight(), - } -} - -func makeEnvoyEndpoint(endpoint *pbproxystate.Endpoint) *envoy_endpoint_v3.Endpoint { - var address *envoy_core_v3.Address - if endpoint.GetUnixSocket() != nil { - address = response.MakePipeAddress(endpoint.GetUnixSocket().GetPath(), 0) - } else { - address = response.MakeAddress(endpoint.GetHostPort().GetHost(), int(endpoint.GetHostPort().Port)) - } - - return &envoy_endpoint_v3.Endpoint{ - Address: address, - } -} - -func makeEnvoyClusterLoadAssignment(clusterName string, endpoints []*pbproxystate.Endpoint) *envoy_endpoint_v3.ClusterLoadAssignment { - localityLbEndpoints := &envoy_endpoint_v3.LocalityLbEndpoints{} - for _, endpoint := range endpoints { - localityLbEndpoints.LbEndpoints = append(localityLbEndpoints.LbEndpoints, makeEnvoyLbEndpoint(endpoint)) - } - return &envoy_endpoint_v3.ClusterLoadAssignment{ - ClusterName: clusterName, - Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{localityLbEndpoints}, - } -} - -func (pr *ProxyResources) makeXDSEndpoints() ([]proto.Message, error) { - endpoints := make([]proto.Message, 0) - - for clusterName, eps := range pr.proxyState.GetEndpoints() { - if clusterName != xdscommon.LocalAppClusterName { - protoEndpoint := makeEnvoyClusterLoadAssignment(clusterName, eps.Endpoints) - endpoints = append(endpoints, protoEndpoint) - } - } - - return endpoints, nil -} diff --git a/agent/xdsv2/listener_resources.go b/agent/xdsv2/listener_resources.go deleted file mode 100644 index 1ccfb42a6d5e1..0000000000000 --- a/agent/xdsv2/listener_resources.go +++ /dev/null @@ -1,1146 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xdsv2 - -import ( - "fmt" - "sort" - "strconv" - - envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" - envoy_grpc_http1_bridge_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/grpc_http1_bridge/v3" - envoy_grpc_stats_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/grpc_stats/v3" - envoy_http_header_to_meta_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/header_to_metadata/v3" - envoy_http_router_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3" - envoy_extensions_filters_listener_http_inspector_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/http_inspector/v3" - envoy_original_dst_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/original_dst/v3" - envoy_tls_inspector_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/tls_inspector/v3" - envoy_connection_limit_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/connection_limit/v3" - envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" - envoy_sni_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/sni_cluster/v3" - envoy_tcp_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3" - envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" - envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" - envoy_type_v3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/lib" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -const ( - envoyNetworkFilterName = "envoy.filters.network.tcp_proxy" - envoyOriginalDestinationListenerFilterName = "envoy.filters.listener.original_dst" - envoyTLSInspectorListenerFilterName = "envoy.filters.listener.tls_inspector" - envoyHttpInspectorListenerFilterName = "envoy.filters.listener.http_inspector" - envoyHttpConnectionManagerFilterName = "envoy.filters.network.http_connection_manager" -) - -func (pr *ProxyResources) makeXDSListeners() ([]proto.Message, error) { - listeners := make([]proto.Message, 0) - - for _, l := range pr.proxyState.Listeners { - protoListener, err := pr.makeListener(l) - // TODO: aggregate errors for listeners and still return any properly formed listeners. - if err != nil { - return nil, err - } - listeners = append(listeners, protoListener) - } - return listeners, nil -} - -func (pr *ProxyResources) makeListener(listener *pbproxystate.Listener) (*envoy_listener_v3.Listener, error) { - envoyListener := &envoy_listener_v3.Listener{} - - // Listener Address - var address *envoy_core_v3.Address - switch listener.BindAddress.(type) { - case *pbproxystate.Listener_HostPort: - address = makeIpPortEnvoyAddress(listener.BindAddress.(*pbproxystate.Listener_HostPort)) - case *pbproxystate.Listener_UnixSocket: - address = makeUnixSocketEnvoyAddress(listener.BindAddress.(*pbproxystate.Listener_UnixSocket)) - default: - // This should be impossible to reach because we're using protobufs. - return nil, fmt.Errorf("invalid listener bind address type: %t", listener.BindAddress) - } - envoyListener.Address = address - - // Listener Direction - var direction envoy_core_v3.TrafficDirection - switch listener.Direction { - case pbproxystate.Direction_DIRECTION_OUTBOUND: - direction = envoy_core_v3.TrafficDirection_OUTBOUND - case pbproxystate.Direction_DIRECTION_INBOUND: - direction = envoy_core_v3.TrafficDirection_INBOUND - case pbproxystate.Direction_DIRECTION_UNSPECIFIED: - direction = envoy_core_v3.TrafficDirection_UNSPECIFIED - default: - return nil, fmt.Errorf("no direction for listener %+v", listener.Name) - } - envoyListener.TrafficDirection = direction - - // Before creating the filter chains, sort routers by match to avoid draining if the list is provided out of order. - sortRouters(listener.Routers) - - // Listener filter chains - for _, r := range listener.Routers { - filterChain, err := pr.makeEnvoyListenerFilterChain(r) - if err != nil { - return nil, fmt.Errorf("could not make filter chain: %w", err) - } - envoyListener.FilterChains = append(envoyListener.FilterChains, filterChain) - } - - if listener.DefaultRouter != nil { - defaultFilterChain, err := pr.makeEnvoyListenerFilterChain(listener.DefaultRouter) - if err != nil { - return nil, fmt.Errorf("could not make filter chain: %w", err) - } - envoyListener.DefaultFilterChain = defaultFilterChain - } - - // Envoy builtin listener filters - for _, c := range listener.Capabilities { - listenerFilter, err := makeEnvoyListenerFilter(c) - if err != nil { - return nil, fmt.Errorf("could not make listener filter: %w", err) - } - envoyListener.ListenerFilters = append(envoyListener.ListenerFilters, listenerFilter) - } - - err := addEnvoyListenerConnectionBalanceConfig(listener.BalanceConnections, envoyListener) - if err != nil { - return nil, err - } - - envoyListener.Name = listener.Name - envoyListener.Address = address - envoyListener.TrafficDirection = direction - - return envoyListener, nil -} - -func makeEnvoyConnectionLimitFilter(maxInboundConns uint64) (*envoy_listener_v3.Filter, error) { - cfg := &envoy_connection_limit_v3.ConnectionLimit{ - StatPrefix: "inbound_connection_limit", - MaxConnections: wrapperspb.UInt64(maxInboundConns), - } - - return makeEnvoyFilter("envoy.filters.network.connection_limit", cfg) -} - -func addEnvoyListenerConnectionBalanceConfig(balanceType pbproxystate.BalanceConnections, listener *envoy_listener_v3.Listener) error { - switch balanceType { - case pbproxystate.BalanceConnections_BALANCE_CONNECTIONS_DEFAULT: - // Default with no balancing. - return nil - case pbproxystate.BalanceConnections_BALANCE_CONNECTIONS_EXACT: - listener.ConnectionBalanceConfig = &envoy_listener_v3.Listener_ConnectionBalanceConfig{ - BalanceType: &envoy_listener_v3.Listener_ConnectionBalanceConfig_ExactBalance_{}, - } - return nil - default: - // This should be impossible using protobufs. - return fmt.Errorf("unsupported connection balance option: %+v", balanceType) - } -} - -func makeIpPortEnvoyAddress(address *pbproxystate.Listener_HostPort) *envoy_core_v3.Address { - return &envoy_core_v3.Address{ - Address: &envoy_core_v3.Address_SocketAddress{ - SocketAddress: &envoy_core_v3.SocketAddress{ - Address: address.HostPort.Host, - PortSpecifier: &envoy_core_v3.SocketAddress_PortValue{ - PortValue: address.HostPort.Port, - }, - }, - }, - } -} - -func makeUnixSocketEnvoyAddress(address *pbproxystate.Listener_UnixSocket) *envoy_core_v3.Address { - modeInt, err := strconv.ParseUint(address.UnixSocket.Mode, 0, 32) - if err != nil { - modeInt = 0 - } - return &envoy_core_v3.Address{ - Address: &envoy_core_v3.Address_Pipe{ - Pipe: &envoy_core_v3.Pipe{ - Path: address.UnixSocket.Path, - Mode: uint32(modeInt), - }, - }, - } -} - -func (pr *ProxyResources) makeEnvoyListenerFilterChain(router *pbproxystate.Router) (*envoy_listener_v3.FilterChain, error) { - envoyFilterChain := &envoy_listener_v3.FilterChain{} - - if router == nil { - return nil, fmt.Errorf("no router to create filter chain") - } - - // Router Match - match := makeEnvoyFilterChainMatch(router.Match) - if match != nil { - envoyFilterChain.FilterChainMatch = match - } - - // Router Destination - var envoyFilters []*envoy_listener_v3.Filter - switch router.Destination.(type) { - case *pbproxystate.Router_L4: - l4Filters, err := pr.makeEnvoyResourcesForL4Destination(router.Destination.(*pbproxystate.Router_L4)) - if err != nil { - return nil, err - } - envoyFilters = append(envoyFilters, l4Filters...) - case *pbproxystate.Router_L7: - l7 := router.Destination.(*pbproxystate.Router_L7) - l7Filters, err := pr.makeEnvoyResourcesForL7Destination(l7) - if err != nil { - return nil, err - } - - // Inject ALPN protocols to router's TLS if destination is L7 - if router.InboundTls != nil { - router.InboundTls.AlpnProtocols = getAlpnProtocols(l7.L7.Protocol) - } - envoyFilters = append(envoyFilters, l7Filters...) - case *pbproxystate.Router_Sni: - sniFilters, err := pr.makeEnvoyResourcesForSNIDestination(router.Destination.(*pbproxystate.Router_Sni)) - if err != nil { - return nil, err - } - envoyFilters = append(envoyFilters, sniFilters...) - default: - // This should be impossible using protobufs. - return nil, fmt.Errorf("unsupported destination type: %t", router.Destination) - - } - - // Router TLS - ts, err := pr.makeEnvoyTransportSocket(router.InboundTls) - if err != nil { - return nil, err - } - envoyFilterChain.TransportSocket = ts - - envoyFilterChain.Filters = envoyFilters - return envoyFilterChain, err -} - -func makeEnvoyFilterChainMatch(routerMatch *pbproxystate.Match) *envoy_listener_v3.FilterChainMatch { - var envoyFilterChainMatch *envoy_listener_v3.FilterChainMatch - if routerMatch != nil { - envoyFilterChainMatch = &envoy_listener_v3.FilterChainMatch{} - - envoyFilterChainMatch.DestinationPort = routerMatch.DestinationPort - - if len(routerMatch.ServerNames) > 0 { - var serverNames []string - for _, n := range routerMatch.ServerNames { - serverNames = append(serverNames, n) - } - envoyFilterChainMatch.ServerNames = serverNames - } - if len(routerMatch.PrefixRanges) > 0 { - sortPrefixRanges(routerMatch.PrefixRanges) - var ranges []*envoy_core_v3.CidrRange - for _, r := range routerMatch.PrefixRanges { - cidrRange := &envoy_core_v3.CidrRange{ - PrefixLen: r.PrefixLen, - AddressPrefix: r.AddressPrefix, - } - ranges = append(ranges, cidrRange) - } - envoyFilterChainMatch.PrefixRanges = ranges - } - if len(routerMatch.SourcePrefixRanges) > 0 { - var ranges []*envoy_core_v3.CidrRange - for _, r := range routerMatch.SourcePrefixRanges { - cidrRange := &envoy_core_v3.CidrRange{ - PrefixLen: r.PrefixLen, - AddressPrefix: r.AddressPrefix, - } - ranges = append(ranges, cidrRange) - } - envoyFilterChainMatch.SourcePrefixRanges = ranges - } - if len(routerMatch.AlpnProtocols) > 0 { - sort.Strings(routerMatch.AlpnProtocols) - var alpnProtocols []string - for _, protocol := range routerMatch.AlpnProtocols { - alpnProtocols = append(alpnProtocols, protocol) - } - envoyFilterChainMatch.ApplicationProtocols = alpnProtocols - } - } - return envoyFilterChainMatch -} - -func (pr *ProxyResources) makeEnvoyResourcesForSNIDestination(sni *pbproxystate.Router_Sni) ([]*envoy_listener_v3.Filter, error) { - var envoyFilters []*envoy_listener_v3.Filter - sniFilter, err := makeEnvoyFilter("envoy.filters.network.sni_cluster", &envoy_sni_cluster_v3.SniCluster{}) - if err != nil { - return nil, err - } - tcp := &envoy_tcp_proxy_v3.TcpProxy{ - StatPrefix: sni.Sni.StatPrefix, - ClusterSpecifier: &envoy_tcp_proxy_v3.TcpProxy_Cluster{Cluster: ""}, - } - tcpFilter, err := makeEnvoyFilter(envoyNetworkFilterName, tcp) - if err != nil { - return nil, err - } - envoyFilters = append(envoyFilters, sniFilter, tcpFilter) - return envoyFilters, err -} - -func (pr *ProxyResources) makeEnvoyResourcesForL4Destination(l4 *pbproxystate.Router_L4) ([]*envoy_listener_v3.Filter, error) { - err := pr.makeEnvoyClusterFromL4Destination(l4.L4) - if err != nil { - return nil, err - } - envoyFilters, err := makeL4Filters(l4.L4) - return envoyFilters, err -} - -func (pr *ProxyResources) makeEnvoyResourcesForL7Destination(l7 *pbproxystate.Router_L7) ([]*envoy_listener_v3.Filter, error) { - envoyFilters, err := pr.makeL7Filters(l7.L7) - if err != nil { - return nil, err - } - return envoyFilters, err -} - -func getAlpnProtocols(protocol pbproxystate.L7Protocol) []string { - var alpnProtocols []string - - switch protocol { - case pbproxystate.L7Protocol_L7_PROTOCOL_GRPC, pbproxystate.L7Protocol_L7_PROTOCOL_HTTP2: - alpnProtocols = append(alpnProtocols, "h2", "http/1.1") - case pbproxystate.L7Protocol_L7_PROTOCOL_HTTP: - alpnProtocols = append(alpnProtocols, "http/1.1") - } - - return alpnProtocols -} - -func makeL4Filters(l4 *pbproxystate.L4Destination) ([]*envoy_listener_v3.Filter, error) { - var envoyFilters []*envoy_listener_v3.Filter - if l4 != nil { - rbacFilters, err := MakeRBACNetworkFilters(l4.TrafficPermissions) - if err != nil { - return nil, err - } - - if len(rbacFilters) > 0 { - envoyFilters = append(envoyFilters, rbacFilters...) - } - - if l4.MaxInboundConnections > 0 { - connectionLimitFilter, err := makeEnvoyConnectionLimitFilter(l4.MaxInboundConnections) - if err != nil { - return nil, err - } - envoyFilters = append(envoyFilters, connectionLimitFilter) - } - - // Add tcp proxy filter - tcp := &envoy_tcp_proxy_v3.TcpProxy{ - StatPrefix: l4.StatPrefix, - } - - switch dest := l4.Destination.(type) { - case *pbproxystate.L4Destination_Cluster: - tcp.ClusterSpecifier = &envoy_tcp_proxy_v3.TcpProxy_Cluster{Cluster: dest.Cluster.Name} - case *pbproxystate.L4Destination_WeightedClusters: - clusters := make([]*envoy_tcp_proxy_v3.TcpProxy_WeightedCluster_ClusterWeight, 0, len(dest.WeightedClusters.Clusters)) - for _, cluster := range dest.WeightedClusters.Clusters { - clusters = append(clusters, &envoy_tcp_proxy_v3.TcpProxy_WeightedCluster_ClusterWeight{ - Name: cluster.Name, - Weight: cluster.Weight.GetValue(), - }) - } - - tcp.ClusterSpecifier = &envoy_tcp_proxy_v3.TcpProxy_WeightedClusters{ - WeightedClusters: &envoy_tcp_proxy_v3.TcpProxy_WeightedCluster{ - Clusters: clusters, - }, - } - default: - return nil, fmt.Errorf("unexpected l4 destination type: %T", l4.Destination) - } - - tcpFilter, err := makeEnvoyFilter(envoyNetworkFilterName, tcp) - if err != nil { - return nil, err - } - envoyFilters = append(envoyFilters, tcpFilter) - } - return envoyFilters, nil - -} - -// TODO: Forward client cert details will be added as part of L7 listeners task. -func (pr *ProxyResources) makeL7Filters(l7 *pbproxystate.L7Destination) ([]*envoy_listener_v3.Filter, error) { - var envoyFilters []*envoy_listener_v3.Filter - var httpConnMgr *envoy_http_v3.HttpConnectionManager - - if l7 != nil { - // TODO: Intentions will be added in the future. - if l7.MaxInboundConnections > 0 { - connLimitFilter, err := makeEnvoyConnectionLimitFilter(l7.MaxInboundConnections) - if err != nil { - return nil, err - } - envoyFilters = append(envoyFilters, connLimitFilter) - } - envoyHttpRouter, err := makeEnvoyHTTPFilter("envoy.filters.http.router", &envoy_http_router_v3.Router{}) - if err != nil { - return nil, err - } - - httpConnMgr = &envoy_http_v3.HttpConnectionManager{ - StatPrefix: l7.StatPrefix, - CodecType: envoy_http_v3.HttpConnectionManager_AUTO, - HttpFilters: []*envoy_http_v3.HttpFilter{ - envoyHttpRouter, - }, - Tracing: &envoy_http_v3.HttpConnectionManager_Tracing{ - // Don't trace any requests by default unless the client application - // explicitly propagates trace headers that indicate this should be - // sampled. - RandomSampling: &envoy_type_v3.Percent{Value: 0.0}, - }, - // Explicitly enable WebSocket upgrades for all HTTP listeners - UpgradeConfigs: []*envoy_http_v3.HttpConnectionManager_UpgradeConfig{ - {UpgradeType: "websocket"}, - }, - } - - if l7.Route == nil { - return nil, fmt.Errorf("route should not be nil") - } - routeConfig := pr.makeEnvoyRouteConfigFromProxystateRoute(l7.Route.Name, pr.proxyState.Routes[l7.Route.Name]) - if err != nil { - return nil, err - } - - if l7.StaticRoute { - routeConfig.ValidateClusters = nil - httpConnMgr.RouteSpecifier = &envoy_http_v3.HttpConnectionManager_RouteConfig{ - RouteConfig: routeConfig, - } - } else { - // Add Envoy route under the route resource since it's not inlined. - pr.envoyResources[xdscommon.RouteType] = append(pr.envoyResources[xdscommon.RouteType], routeConfig) - - httpConnMgr.RouteSpecifier = &envoy_http_v3.HttpConnectionManager_Rds{ - Rds: &envoy_http_v3.Rds{ - RouteConfigName: l7.Route.Name, - ConfigSource: &envoy_core_v3.ConfigSource{ - ResourceApiVersion: envoy_core_v3.ApiVersion_V3, - ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_Ads{ - Ads: &envoy_core_v3.AggregatedConfigSource{}, - }, - }, - }, - } - } - - if l7.IncludeXfccPolicy { - httpConnMgr.ForwardClientCertDetails = envoyXFCCPolicy[l7.XfccPolicy] - httpConnMgr.SetCurrentClientCertDetails = &envoy_http_v3.HttpConnectionManager_SetCurrentClientCertDetails{ - Subject: &wrapperspb.BoolValue{Value: true}, - Cert: true, - Chain: true, - Dns: true, - Uri: true, - } - } - - // Add http2 protocol options - if l7.Protocol == pbproxystate.L7Protocol_L7_PROTOCOL_HTTP2 || l7.Protocol == pbproxystate.L7Protocol_L7_PROTOCOL_GRPC { - httpConnMgr.Http2ProtocolOptions = &envoy_core_v3.Http2ProtocolOptions{} - } - - // Add http authorization filters. First are jwt auth filters (not yet implemented), then traffic permission filters (not yet implemented), then xfcc filters. - var httpAuthzFilters []*envoy_http_v3.HttpFilter - - // Add traffic permission filters. - // Currently only adds the empty filter since L7 traffic permissions are not yet implemented. - if l7.TrafficPermissions != nil { - // For now, MakeRBACHTTPFilters only has L4 granularity traffic permissions in it. - l7TrafficPermsFilters, err := MakeRBACHTTPFilters(l7.TrafficPermissions) - if err != nil { - return nil, err - } - httpAuthzFilters = append(httpAuthzFilters, l7TrafficPermsFilters...) - } - - if l7.ParseXfccHeaders { - parseXFCCFilter, err := parseXFCCToDynamicMetaHTTPFilter() - if err != nil { - return nil, err - } - httpAuthzFilters = append(httpAuthzFilters, parseXFCCFilter) - } - - // Here we ensure that the first filter - // (other than the "envoy.grpc_http1_bridge" filter) in the http filter - // chain of a public listener is the authz filter to prevent unauthorized - // access and that every filter chain uses our TLS certs. - if len(httpAuthzFilters) > 0 { - httpConnMgr.HttpFilters = append(httpAuthzFilters, httpConnMgr.HttpFilters...) - } - - // Add grpc envoy http filters. - if l7.Protocol == pbproxystate.L7Protocol_L7_PROTOCOL_GRPC { - grpcHttp1Bridge, err := makeEnvoyHTTPFilter( - "envoy.filters.http.grpc_http1_bridge", - &envoy_grpc_http1_bridge_v3.Config{}, - ) - if err != nil { - return nil, err - } - - // In envoy 1.14.x the default value "stats_for_all_methods=true" was - // deprecated, and was changed to "false" in 1.18.x. Avoid using the - // default. TODO: we may want to expose this to users somehow easily. - grpcStatsFilter, err := makeEnvoyHTTPFilter( - "envoy.filters.http.grpc_stats", - &envoy_grpc_stats_v3.FilterConfig{ - PerMethodStatSpecifier: &envoy_grpc_stats_v3.FilterConfig_StatsForAllMethods{ - StatsForAllMethods: &wrapperspb.BoolValue{Value: true}, - }, - }, - ) - if err != nil { - return nil, err - } - - // Add grpc bridge before envoyRouter and authz, and the stats in front of that. - httpConnMgr.HttpFilters = append([]*envoy_http_v3.HttpFilter{ - grpcStatsFilter, - grpcHttp1Bridge, - }, httpConnMgr.HttpFilters...) - } - - httpFilter, err := makeEnvoyFilter(envoyHttpConnectionManagerFilterName, httpConnMgr) - if err != nil { - return nil, err - } - envoyFilters = append(envoyFilters, httpFilter) - } - return envoyFilters, nil -} - -func (pr *ProxyResources) makeEnvoyTLSParameters(defaultParams *pbproxystate.TLSParameters, overrideParams *pbproxystate.TLSParameters) *envoy_tls_v3.TlsParameters { - tlsParams := &envoy_tls_v3.TlsParameters{} - - if overrideParams != nil { - if overrideParams.MinVersion != pbproxystate.TLSVersion_TLS_VERSION_UNSPECIFIED { - if minVersion, ok := envoyTLSVersions[overrideParams.MinVersion]; ok { - tlsParams.TlsMinimumProtocolVersion = minVersion - } - } - if overrideParams.MaxVersion != pbproxystate.TLSVersion_TLS_VERSION_UNSPECIFIED { - if maxVersion, ok := envoyTLSVersions[overrideParams.MaxVersion]; ok { - tlsParams.TlsMaximumProtocolVersion = maxVersion - } - } - if len(overrideParams.CipherSuites) != 0 { - tlsParams.CipherSuites = marshalEnvoyTLSCipherSuiteStrings(overrideParams.CipherSuites) - } - return tlsParams - } - - if defaultParams != nil { - if defaultParams.MinVersion != pbproxystate.TLSVersion_TLS_VERSION_UNSPECIFIED { - if minVersion, ok := envoyTLSVersions[defaultParams.MinVersion]; ok { - tlsParams.TlsMinimumProtocolVersion = minVersion - } - } - if defaultParams.MaxVersion != pbproxystate.TLSVersion_TLS_VERSION_UNSPECIFIED { - if maxVersion, ok := envoyTLSVersions[defaultParams.MaxVersion]; ok { - tlsParams.TlsMaximumProtocolVersion = maxVersion - } - } - if len(defaultParams.CipherSuites) != 0 { - tlsParams.CipherSuites = marshalEnvoyTLSCipherSuiteStrings(defaultParams.CipherSuites) - } - return tlsParams - } - - return tlsParams - -} - -func (pr *ProxyResources) makeEnvoyTransportSocket(ts *pbproxystate.TransportSocket) (*envoy_core_v3.TransportSocket, error) { - if ts == nil { - return nil, nil - } - commonTLSContext := &envoy_tls_v3.CommonTlsContext{} - if ts.AlpnProtocols != nil { - commonTLSContext.AlpnProtocols = ts.AlpnProtocols - } - - // Create connection TLS. Listeners should only look at inbound TLS. - switch ts.ConnectionTls.(type) { - case *pbproxystate.TransportSocket_InboundMesh: - downstreamContext := &envoy_tls_v3.DownstreamTlsContext{} - downstreamContext.CommonTlsContext = commonTLSContext - // Set TLS Parameters. - if pr.proxyState.Tls != nil { - tlsParams := pr.makeEnvoyTLSParameters(pr.proxyState.Tls.InboundTlsParameters, ts.TlsParameters) - commonTLSContext.TlsParams = tlsParams - } else { - commonTLSContext.TlsParams = &envoy_tls_v3.TlsParameters{} - } - - // Set the certificate config on the tls context. - // For inbound mesh, we need to add the identity certificate - // and the validation context for the mesh depending on the provided trust bundle names. - im := ts.ConnectionTls.(*pbproxystate.TransportSocket_InboundMesh).InboundMesh - leaf, ok := pr.proxyState.LeafCertificates[im.IdentityKey] - if !ok { - return nil, fmt.Errorf("failed to create transport socket: leaf certificate %q not found", im.IdentityKey) - } - err := pr.makeEnvoyCertConfig(commonTLSContext, leaf) - if err != nil { - return nil, fmt.Errorf("failed to create transport socket: %w", err) - } - - // Create validation context. - // When there's only one trust bundle name, we create a simple validation context - if len(im.ValidationContext.TrustBundlePeerNameKeys) == 1 { - peerName := im.ValidationContext.TrustBundlePeerNameKeys[0] - tb, ok := pr.proxyState.TrustBundles[peerName] - if !ok { - return nil, fmt.Errorf("failed to create transport socket: provided trust bundle name does not exist in proxystate trust bundle map: %s", peerName) - } - commonTLSContext.ValidationContextType = &envoy_tls_v3.CommonTlsContext_ValidationContext{ - ValidationContext: &envoy_tls_v3.CertificateValidationContext{ - // TODO(banks): later for L7 support we may need to configure ALPN here. - TrustedCa: &envoy_core_v3.DataSource{ - Specifier: &envoy_core_v3.DataSource_InlineString{ - InlineString: RootPEMsAsString(tb.Roots), - }, - }, - }, - } - } else if len(im.ValidationContext.TrustBundlePeerNameKeys) > 1 { - cfg := &envoy_tls_v3.SPIFFECertValidatorConfig{ - TrustDomains: make([]*envoy_tls_v3.SPIFFECertValidatorConfig_TrustDomain, 0, len(im.ValidationContext.TrustBundlePeerNameKeys)), - } - - for _, peerName := range im.ValidationContext.TrustBundlePeerNameKeys { - // Look up the trust bundle ca in the map. - tb, ok := pr.proxyState.TrustBundles[peerName] - if !ok { - return nil, fmt.Errorf("failed to create transport socket: provided bundle name does not exist in trust bundle map: %s", peerName) - } - cfg.TrustDomains = append(cfg.TrustDomains, &envoy_tls_v3.SPIFFECertValidatorConfig_TrustDomain{ - Name: tb.TrustDomain, - TrustBundle: &envoy_core_v3.DataSource{ - Specifier: &envoy_core_v3.DataSource_InlineString{ - InlineString: RootPEMsAsString(tb.Roots), - }, - }, - }) - } - // Sort the trust domains so the output is stable. - sortTrustDomains(cfg.TrustDomains) - - spiffeConfig, err := anypb.New(cfg) - if err != nil { - return nil, err - } - commonTLSContext.ValidationContextType = &envoy_tls_v3.CommonTlsContext_ValidationContext{ - ValidationContext: &envoy_tls_v3.CertificateValidationContext{ - CustomValidatorConfig: &envoy_core_v3.TypedExtensionConfig{ - // The typed config name is hard-coded because it is not available as a wellknown var in the control plane lib. - Name: "envoy.tls.cert_validator.spiffe", - TypedConfig: spiffeConfig, - }, - }, - } - } - // Always require client certificate - downstreamContext.RequireClientCertificate = &wrapperspb.BoolValue{Value: true} - transportSocket, err := makeTransportSocket("tls", downstreamContext) - if err != nil { - return nil, err - } - return transportSocket, nil - case *pbproxystate.TransportSocket_InboundNonMesh: - downstreamContext := &envoy_tls_v3.DownstreamTlsContext{} - downstreamContext.CommonTlsContext = commonTLSContext - // Set TLS Parameters. - if pr.proxyState.Tls != nil { - tlsParams := pr.makeEnvoyTLSParameters(pr.proxyState.Tls.InboundTlsParameters, ts.TlsParameters) - commonTLSContext.TlsParams = tlsParams - } else { - commonTLSContext.TlsParams = &envoy_tls_v3.TlsParameters{} - } - // For non-mesh, we don't care about validation context as currently we don't support mTLS for non-mesh connections. - nonMeshTLS := ts.ConnectionTls.(*pbproxystate.TransportSocket_InboundNonMesh).InboundNonMesh - err := pr.addNonMeshCertConfig(commonTLSContext, nonMeshTLS) - if err != nil { - return nil, fmt.Errorf("failed to create transport socket: %w", err) - } - transportSocket, err := makeTransportSocket("tls", downstreamContext) - if err != nil { - return nil, err - } - return transportSocket, nil - case *pbproxystate.TransportSocket_OutboundMesh: - upstreamContext := &envoy_tls_v3.UpstreamTlsContext{} - upstreamContext.CommonTlsContext = commonTLSContext - // Set TLS Parameters. - if pr.proxyState.Tls != nil { - tlsParams := pr.makeEnvoyTLSParameters(pr.proxyState.Tls.OutboundTlsParameters, ts.TlsParameters) - commonTLSContext.TlsParams = tlsParams - } else { - commonTLSContext.TlsParams = &envoy_tls_v3.TlsParameters{} - } - // For outbound mesh, we need to insert the mesh identity certificate - // and the validation context for the mesh depending on the provided trust bundle names. - om := ts.GetOutboundMesh() - leaf, ok := pr.proxyState.LeafCertificates[om.IdentityKey] - if !ok { - return nil, fmt.Errorf("leaf %s not found in proxyState", om.IdentityKey) - } - err := pr.makeEnvoyCertConfig(commonTLSContext, leaf) - if err != nil { - return nil, fmt.Errorf("failed to create transport socket: %w", err) - } - - // Create validation context - peerName := om.ValidationContext.TrustBundlePeerNameKey - tb, ok := pr.proxyState.TrustBundles[peerName] - if !ok { - return nil, fmt.Errorf("failed to create transport socket: provided peer name does not exist in trust bundle map: %s", peerName) - } - - var matchers []*envoy_matcher_v3.StringMatcher - if len(om.ValidationContext.SpiffeIds) > 0 { - matchers = make([]*envoy_matcher_v3.StringMatcher, 0) - for _, m := range om.ValidationContext.SpiffeIds { - matchers = append(matchers, &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ - Exact: m, - }, - }) - } - } - commonTLSContext.ValidationContextType = &envoy_tls_v3.CommonTlsContext_ValidationContext{ - ValidationContext: &envoy_tls_v3.CertificateValidationContext{ - // TODO(banks): later for L7 support we may need to configure ALPN here. - TrustedCa: &envoy_core_v3.DataSource{ - Specifier: &envoy_core_v3.DataSource_InlineString{ - InlineString: RootPEMsAsString(tb.Roots), - }, - }, - MatchSubjectAltNames: matchers, - }, - } - - upstreamContext.Sni = om.Sni - transportSocket, err := makeTransportSocket("tls", upstreamContext) - if err != nil { - return nil, err - } - return transportSocket, nil - default: - return nil, nil - } - -} - -func (pr *ProxyResources) makeEnvoyCertConfig(common *envoy_tls_v3.CommonTlsContext, certificate *pbproxystate.LeafCertificate) error { - if certificate == nil { - return fmt.Errorf("no leaf certificate provided") - } - common.TlsCertificates = []*envoy_tls_v3.TlsCertificate{ - { - CertificateChain: &envoy_core_v3.DataSource{ - Specifier: &envoy_core_v3.DataSource_InlineString{ - InlineString: lib.EnsureTrailingNewline(certificate.Cert), - }, - }, - PrivateKey: &envoy_core_v3.DataSource{ - Specifier: &envoy_core_v3.DataSource_InlineString{ - InlineString: lib.EnsureTrailingNewline(certificate.Key), - }, - }, - }, - } - return nil -} - -func (pr *ProxyResources) makeEnvoySDSCertConfig(common *envoy_tls_v3.CommonTlsContext, certificate *pbproxystate.SDSCertificate) error { - if certificate == nil { - return fmt.Errorf("no SDS certificate provided") - } - common.TlsCertificateSdsSecretConfigs = []*envoy_tls_v3.SdsSecretConfig{ - { - Name: certificate.CertResource, - SdsConfig: &envoy_core_v3.ConfigSource{ - ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_ApiConfigSource{ - ApiConfigSource: &envoy_core_v3.ApiConfigSource{ - ApiType: envoy_core_v3.ApiConfigSource_GRPC, - TransportApiVersion: envoy_core_v3.ApiVersion_V3, - // Note ClusterNames can't be set here - that's only for REST type - // we need a full GRPC config instead. - GrpcServices: []*envoy_core_v3.GrpcService{ - { - TargetSpecifier: &envoy_core_v3.GrpcService_EnvoyGrpc_{ - EnvoyGrpc: &envoy_core_v3.GrpcService_EnvoyGrpc{ - ClusterName: certificate.ClusterName, - }, - }, - Timeout: &durationpb.Duration{Seconds: 5}, - }, - }, - }, - }, - ResourceApiVersion: envoy_core_v3.ApiVersion_V3, - }, - }, - } - return nil -} - -func (pr *ProxyResources) addNonMeshCertConfig(common *envoy_tls_v3.CommonTlsContext, tls *pbproxystate.InboundNonMeshTLS) error { - if tls == nil { - return fmt.Errorf("no inbound non-mesh TLS provided") - } - - switch tls.Identity.(type) { - case *pbproxystate.InboundNonMeshTLS_LeafKey: - leafKey := tls.Identity.(*pbproxystate.InboundNonMeshTLS_LeafKey).LeafKey - leaf, ok := pr.proxyState.LeafCertificates[leafKey] - if !ok { - return fmt.Errorf("leaf key %s not found in leaf certificate map", leafKey) - } - common.TlsCertificates = []*envoy_tls_v3.TlsCertificate{ - { - CertificateChain: &envoy_core_v3.DataSource{ - Specifier: &envoy_core_v3.DataSource_InlineString{ - InlineString: lib.EnsureTrailingNewline(leaf.Cert), - }, - }, - PrivateKey: &envoy_core_v3.DataSource{ - Specifier: &envoy_core_v3.DataSource_InlineString{ - InlineString: lib.EnsureTrailingNewline(leaf.Key), - }, - }, - }, - } - case *pbproxystate.InboundNonMeshTLS_Sds: - c := tls.Identity.(*pbproxystate.InboundNonMeshTLS_Sds).Sds - common.TlsCertificateSdsSecretConfigs = []*envoy_tls_v3.SdsSecretConfig{ - { - Name: c.CertResource, - SdsConfig: &envoy_core_v3.ConfigSource{ - ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_ApiConfigSource{ - ApiConfigSource: &envoy_core_v3.ApiConfigSource{ - ApiType: envoy_core_v3.ApiConfigSource_GRPC, - TransportApiVersion: envoy_core_v3.ApiVersion_V3, - // Note ClusterNames can't be set here - that's only for REST type - // we need a full GRPC config instead. - GrpcServices: []*envoy_core_v3.GrpcService{ - { - TargetSpecifier: &envoy_core_v3.GrpcService_EnvoyGrpc_{ - EnvoyGrpc: &envoy_core_v3.GrpcService_EnvoyGrpc{ - ClusterName: c.ClusterName, - }, - }, - Timeout: &durationpb.Duration{Seconds: 5}, - }, - }, - }, - }, - ResourceApiVersion: envoy_core_v3.ApiVersion_V3, - }, - }, - } - } - - return nil -} - -func makeTransportSocket(name string, config proto.Message) (*envoy_core_v3.TransportSocket, error) { - any, err := anypb.New(config) - if err != nil { - return nil, err - } - return &envoy_core_v3.TransportSocket{ - Name: name, - ConfigType: &envoy_core_v3.TransportSocket_TypedConfig{ - TypedConfig: any, - }, - }, nil -} - -func makeEnvoyListenerFilter(c pbproxystate.Capability) (*envoy_listener_v3.ListenerFilter, error) { - var lf proto.Message - var name string - - switch c { - case pbproxystate.Capability_CAPABILITY_TRANSPARENT: - lf = &envoy_original_dst_v3.OriginalDst{} - name = envoyOriginalDestinationListenerFilterName - case pbproxystate.Capability_CAPABILITY_L4_TLS_INSPECTION: - name = envoyTLSInspectorListenerFilterName - lf = &envoy_tls_inspector_v3.TlsInspector{} - case pbproxystate.Capability_CAPABILITY_L7_PROTOCOL_INSPECTION: - name = envoyHttpInspectorListenerFilterName - lf = &envoy_extensions_filters_listener_http_inspector_v3.HttpInspector{} - default: - return nil, fmt.Errorf("unsupported listener captability: %s", c) - } - lfAsAny, err := anypb.New(lf) - if err != nil { - return nil, err - } - - return &envoy_listener_v3.ListenerFilter{ - Name: name, - ConfigType: &envoy_listener_v3.ListenerFilter_TypedConfig{TypedConfig: lfAsAny}, - }, nil -} - -func makeEnvoyFilter(name string, cfg proto.Message) (*envoy_listener_v3.Filter, error) { - any, err := anypb.New(cfg) - if err != nil { - return nil, err - } - - return &envoy_listener_v3.Filter{ - Name: name, - ConfigType: &envoy_listener_v3.Filter_TypedConfig{TypedConfig: any}, - }, nil -} - -func makeEnvoyHTTPFilter(name string, cfg proto.Message) (*envoy_http_v3.HttpFilter, error) { - any, err := anypb.New(cfg) - if err != nil { - return nil, err - } - - return &envoy_http_v3.HttpFilter{ - Name: name, - ConfigType: &envoy_http_v3.HttpFilter_TypedConfig{TypedConfig: any}, - }, nil -} - -func RootPEMsAsString(rootPEMs []string) string { - var rootPEMsString string - for _, root := range rootPEMs { - rootPEMsString += lib.EnsureTrailingNewline(root) - } - return rootPEMsString -} - -func marshalEnvoyTLSCipherSuiteStrings(cipherSuites []pbproxystate.TLSCipherSuite) []string { - envoyTLSCipherSuiteStrings := map[pbproxystate.TLSCipherSuite]string{ - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256: "ECDHE-ECDSA-AES128-GCM-SHA256", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305: "ECDHE-ECDSA-CHACHA20-POLY1305", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256: "ECDHE-RSA-AES128-GCM-SHA256", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305: "ECDHE-RSA-CHACHA20-POLY1305", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA: "ECDHE-ECDSA-AES128-SHA", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA: "ECDHE-RSA-AES128-SHA", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_AES128_GCM_SHA256: "AES128-GCM-SHA256", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_AES128_SHA: "AES128-SHA", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384: "ECDHE-ECDSA-AES256-GCM-SHA384", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384: "ECDHE-RSA-AES256-GCM-SHA384", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA: "ECDHE-ECDSA-AES256-SHA", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA: "ECDHE-RSA-AES256-SHA", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_AES256_GCM_SHA384: "AES256-GCM-SHA384", - pbproxystate.TLSCipherSuite_TLS_CIPHER_SUITE_AES256_SHA: "AES256-SHA", - } - - var cipherSuiteStrings []string - - for _, c := range cipherSuites { - if s, ok := envoyTLSCipherSuiteStrings[c]; ok { - cipherSuiteStrings = append(cipherSuiteStrings, s) - } - } - - return cipherSuiteStrings -} - -var envoyTLSVersions = map[pbproxystate.TLSVersion]envoy_tls_v3.TlsParameters_TlsProtocol{ - pbproxystate.TLSVersion_TLS_VERSION_AUTO: envoy_tls_v3.TlsParameters_TLS_AUTO, - pbproxystate.TLSVersion_TLS_VERSION_1_0: envoy_tls_v3.TlsParameters_TLSv1_0, - pbproxystate.TLSVersion_TLS_VERSION_1_1: envoy_tls_v3.TlsParameters_TLSv1_1, - pbproxystate.TLSVersion_TLS_VERSION_1_2: envoy_tls_v3.TlsParameters_TLSv1_2, - pbproxystate.TLSVersion_TLS_VERSION_1_3: envoy_tls_v3.TlsParameters_TLSv1_3, -} - -var envoyXFCCPolicy = map[pbproxystate.XFCCPolicy]envoy_http_v3.HttpConnectionManager_ForwardClientCertDetails{ - pbproxystate.XFCCPolicy_XFCC_POLICY_SANITIZE: envoy_http_v3.HttpConnectionManager_SANITIZE, - pbproxystate.XFCCPolicy_XFCC_POLICY_FORWARD_ONLY: envoy_http_v3.HttpConnectionManager_FORWARD_ONLY, - pbproxystate.XFCCPolicy_XFCC_POLICY_APPEND_FORWARD: envoy_http_v3.HttpConnectionManager_APPEND_FORWARD, - pbproxystate.XFCCPolicy_XFCC_POLICY_SANITIZE_SET: envoy_http_v3.HttpConnectionManager_SANITIZE_SET, - pbproxystate.XFCCPolicy_XFCC_POLICY_ALWAYS_FORWARD_ONLY: envoy_http_v3.HttpConnectionManager_ALWAYS_FORWARD_ONLY, -} - -// Sort the trust domains so that the output is stable. -// This benefits tests but also prevents Envoy from mistakenly thinking the listener -// changed and needs to be drained only because this ordering is different. -func sortTrustDomains(trustDomains []*envoy_tls_v3.SPIFFECertValidatorConfig_TrustDomain) { - sort.Slice(trustDomains, func(i int, j int) bool { - return trustDomains[i].Name < trustDomains[j].Name - }) -} - -// sortRouters stable sorts routers with a Match to avoid draining if the list is provided out of order. -// xdsv1 used to sort the filter chains on outbound listeners, so this adds that functionality by sorting routers with matches. -func sortRouters(routers []*pbproxystate.Router) { - if routers == nil { - return - } - sort.SliceStable(routers, func(i, j int) bool { - si := "" - sj := "" - if routers[i].Match != nil { - if len(routers[i].Match.PrefixRanges) > 0 { - si += routers[i].Match.PrefixRanges[0].AddressPrefix + - "/" + routers[i].Match.PrefixRanges[0].PrefixLen.String() + - ":" + routers[i].Match.DestinationPort.String() - } - if len(routers[i].Match.ServerNames) > 0 { - si += routers[i].Match.ServerNames[0] + - ":" + routers[i].Match.DestinationPort.String() - } else { - si += routers[i].Match.DestinationPort.String() - } - } - - if routers[j].Match != nil { - if len(routers[j].Match.PrefixRanges) > 0 { - sj += routers[j].Match.PrefixRanges[0].AddressPrefix + - "/" + routers[j].Match.PrefixRanges[0].PrefixLen.String() + - ":" + routers[j].Match.DestinationPort.String() - } - if len(routers[j].Match.ServerNames) > 0 { - sj += routers[j].Match.ServerNames[0] + - ":" + routers[j].Match.DestinationPort.String() - } else { - sj += routers[j].Match.DestinationPort.String() - } - } - - return si < sj - }) -} - -func sortPrefixRanges(prefixRanges []*pbproxystate.CidrRange) { - if prefixRanges == nil { - return - } - sort.SliceStable(prefixRanges, func(i, j int) bool { - return prefixRanges[i].AddressPrefix < prefixRanges[j].AddressPrefix - }) -} - -const ( - anyPath = `[^/]+` - trustDomain = anyPath + "." + anyPath -) - -// downstreamServiceIdentityMatcher needs to match XFCC headers in two cases: -// 1. Requests to cluster peered services through a mesh gateway. In this case, the XFCC header looks like the following (I added a new line after each ; for readability) -// By=spiffe://950df996-caef-ddef-ec5f-8d18a153b7b2.consul/gateway/mesh/dc/alpha; -// Hash=...; -// Cert=...; -// Chain=...; -// Subject=""; -// URI=spiffe://c7e1d24a-eed8-10a3-286a-52bdb6b6a6fd.consul/ns/default/dc/primary/svc/s1,By=spiffe://950df996-caef-ddef-ec5f-8d18a153b7b2.consul/ns/default/dc/alpha/svc/s2; -// Hash=...; -// Cert=...; -// Chain=...; -// Subject=""; -// URI=spiffe://950df996-caef-ddef-ec5f-8d18a153b7b2.consul/gateway/mesh/dc/alpha -// -// 2. Requests directly to another service -// By=spiffe://ae9dbea8-c1dd-7356-b211-c564f7917100.consul/ns/default/dc/primary/svc/s2; -// Hash=396218588ebc1655d32a49b68cedd6b66b9de7b3d69d0c0451bc5818132377d0; -// Cert=...; -// Chain=...; -// Subject=""; -// URI=spiffe://ae9dbea8-c1dd-7356-b211-c564f7917100.consul/ns/default/dc/primary/svc/s1 -// -// In either case, the regex matches the downstream service's spiffe id because mesh gateways use a different spiffe id format. -// Envoy requires us to include the trailing and leading .* to properly extract the properly submatch. -const downstreamServiceIdentityMatcher = ".*URI=spiffe://(" + trustDomain + - ")(?:/ap/(" + anyPath + - "))?/ns/(" + anyPath + - ")/dc/(" + anyPath + - ")/svc/([^/;,]+).*" - -func parseXFCCToDynamicMetaHTTPFilter() (*envoy_http_v3.HttpFilter, error) { - var rules []*envoy_http_header_to_meta_v3.Config_Rule - - fields := []struct { - name string - sub string - }{ - { - name: "trust-domain", - sub: `\1`, - }, - { - name: "partition", - sub: `\2`, - }, - { - name: "namespace", - sub: `\3`, - }, - { - name: "datacenter", - sub: `\4`, - }, - { - name: "service", - sub: `\5`, - }, - } - - for _, f := range fields { - rules = append(rules, &envoy_http_header_to_meta_v3.Config_Rule{ - Header: "x-forwarded-client-cert", - OnHeaderPresent: &envoy_http_header_to_meta_v3.Config_KeyValuePair{ - MetadataNamespace: "consul", - Key: f.name, - RegexValueRewrite: &envoy_matcher_v3.RegexMatchAndSubstitute{ - Pattern: &envoy_matcher_v3.RegexMatcher{ - Regex: downstreamServiceIdentityMatcher, - EngineType: &envoy_matcher_v3.RegexMatcher_GoogleRe2{ - GoogleRe2: &envoy_matcher_v3.RegexMatcher_GoogleRE2{}, - }, - }, - Substitution: f.sub, - }, - }, - }) - } - - cfg := &envoy_http_header_to_meta_v3.Config{RequestRules: rules} - - return makeEnvoyHTTPFilter("envoy.filters.http.header_to_metadata", cfg) -} diff --git a/agent/xdsv2/rbac_resources.go b/agent/xdsv2/rbac_resources.go deleted file mode 100644 index df670782ce430..0000000000000 --- a/agent/xdsv2/rbac_resources.go +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xdsv2 - -import ( - "fmt" - - envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" - envoy_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" - envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" - envoy_http_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3" - envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" - envoy_network_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/rbac/v3" - envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" - - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -const ( - baseL4PermissionKey = "consul-intentions-layer4" -) - -// MakeL4RBAC returns the envoy deny and allow rules from the traffic permissions. After calling this function these -// rules can be put into a network rbac filter or http rbac filter depending on the local app port protocol. -func MakeL4RBAC(trafficPermissions *pbproxystate.TrafficPermissions) (deny *envoy_rbac_v3.RBAC, allow *envoy_rbac_v3.RBAC, err error) { - var denyRBAC *envoy_rbac_v3.RBAC - var allowRBAC *envoy_rbac_v3.RBAC - - if trafficPermissions == nil { - return nil, nil, nil - } - - if len(trafficPermissions.DenyPermissions) > 0 { - denyRBAC = &envoy_rbac_v3.RBAC{ - Action: envoy_rbac_v3.RBAC_DENY, - Policies: make(map[string]*envoy_rbac_v3.Policy), - } - denyRBAC.Policies = makeRBACPolicies(trafficPermissions.DenyPermissions) - } - - // Only include the allow RBAC when Consul is in default deny. - if !trafficPermissions.DefaultAllow { - allowRBAC = &envoy_rbac_v3.RBAC{ - Action: envoy_rbac_v3.RBAC_ALLOW, - Policies: make(map[string]*envoy_rbac_v3.Policy), - } - - allowRBAC.Policies = makeRBACPolicies(trafficPermissions.AllowPermissions) - } - - return denyRBAC, allowRBAC, nil -} - -// MakeRBACNetworkFilters calls MakeL4RBAC and wraps the result in envoy network filters meant for L4 protocols. -func MakeRBACNetworkFilters(trafficPermissions *pbproxystate.TrafficPermissions) ([]*envoy_listener_v3.Filter, error) { - var filters []*envoy_listener_v3.Filter - - deny, allow, err := MakeL4RBAC(trafficPermissions) - if err != nil { - return nil, err - } - - if deny != nil { - filter, err := makeRBACFilter(deny) - if err != nil { - return nil, err - } - filters = append(filters, filter) - } - - if allow != nil { - filter, err := makeRBACFilter(allow) - if err != nil { - return nil, err - } - filters = append(filters, filter) - - } - - return filters, nil -} - -// MakeRBACHTTPFilters calls MakeL4RBAC and wraps the result in envoy http filters meant for L7 protocols. Eventually -// this will need to also accumulate any L7 traffic permissions when that is implemented. -func MakeRBACHTTPFilters(trafficPermissions *pbproxystate.TrafficPermissions) ([]*envoy_http_v3.HttpFilter, error) { - var httpFilters []*envoy_http_v3.HttpFilter - - deny, allow, err := MakeL4RBAC(trafficPermissions) - if err != nil { - return nil, err - } - - if deny != nil { - filter, err := makeRBACHTTPFilter(deny) - if err != nil { - return nil, err - } - httpFilters = append(httpFilters, filter) - } - - if allow != nil { - filter, err := makeRBACHTTPFilter(allow) - if err != nil { - return nil, err - } - httpFilters = append(httpFilters, filter) - - } - - return httpFilters, nil -} - -const ( - envoyNetworkRBACFilterKey = "envoy.filters.network.rbac" - envoyHTTPRBACFilterKey = "envoy.filters.http.rbac" -) - -func makeRBACFilter(rbac *envoy_rbac_v3.RBAC) (*envoy_listener_v3.Filter, error) { - cfg := &envoy_network_rbac_v3.RBAC{ - StatPrefix: "connect_authz", - Rules: rbac, - } - return makeEnvoyFilter(envoyNetworkRBACFilterKey, cfg) -} - -func makeRBACHTTPFilter(rbac *envoy_rbac_v3.RBAC) (*envoy_http_v3.HttpFilter, error) { - cfg := &envoy_http_rbac_v3.RBAC{ - Rules: rbac, - } - return makeEnvoyHTTPFilter(envoyHTTPRBACFilterKey, cfg) -} - -func makeRBACPolicies(l4Permissions []*pbproxystate.Permission) map[string]*envoy_rbac_v3.Policy { - policyLabel := func(i int) string { - if len(l4Permissions) == 1 { - return baseL4PermissionKey - } - return fmt.Sprintf("%s-%d", baseL4PermissionKey, i) - } - - policies := make(map[string]*envoy_rbac_v3.Policy, len(l4Permissions)) - - for i, permission := range l4Permissions { - policy := makeRBACPolicy(permission) - if policy != nil { - policies[policyLabel(i)] = policy - } - } - - return policies -} - -func makeRBACPolicy(p *pbproxystate.Permission) *envoy_rbac_v3.Policy { - if len(p.Principals) == 0 { - return nil - } - - var principals []*envoy_rbac_v3.Principal - - for _, p := range p.Principals { - principals = append(principals, toEnvoyPrincipal(p)) - } - - return &envoy_rbac_v3.Policy{ - Principals: principals, - Permissions: []*envoy_rbac_v3.Permission{anyPermission()}, - } -} - -func toEnvoyPrincipal(p *pbproxystate.Principal) *envoy_rbac_v3.Principal { - includePrincipal := principal(p.Spiffe) - - if len(p.ExcludeSpiffes) == 0 { - return includePrincipal - } - - principals := make([]*envoy_rbac_v3.Principal, 0, len(p.ExcludeSpiffes)+1) - principals = append(principals, includePrincipal) - for _, s := range p.ExcludeSpiffes { - principals = append(principals, negatePrincipal(principal(s))) - } - return andPrincipals(principals) -} - -func principal(spiffe *pbproxystate.Spiffe) *envoy_rbac_v3.Principal { - var andIDs []*envoy_rbac_v3.Principal - andIDs = append(andIDs, idPrincipal(spiffe.Regex)) - - if len(spiffe.XfccRegex) > 0 { - andIDs = append(andIDs, xfccPrincipal(spiffe.XfccRegex)) - } - - return andPrincipals(andIDs) -} - -func negatePrincipal(p *envoy_rbac_v3.Principal) *envoy_rbac_v3.Principal { - return &envoy_rbac_v3.Principal{ - Identifier: &envoy_rbac_v3.Principal_NotId{ - NotId: p, - }, - } -} - -func idPrincipal(spiffeID string) *envoy_rbac_v3.Principal { - return &envoy_rbac_v3.Principal{ - Identifier: &envoy_rbac_v3.Principal_Authenticated_{ - Authenticated: &envoy_rbac_v3.Principal_Authenticated{ - PrincipalName: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(spiffeID), - }, - }, - }, - }, - } -} - -func andPrincipals(ids []*envoy_rbac_v3.Principal) *envoy_rbac_v3.Principal { - switch len(ids) { - case 1: - return ids[0] - default: - return &envoy_rbac_v3.Principal{ - Identifier: &envoy_rbac_v3.Principal_AndIds{ - AndIds: &envoy_rbac_v3.Principal_Set{ - Ids: ids, - }, - }, - } - } -} - -func xfccPrincipal(spiffeID string) *envoy_rbac_v3.Principal { - return &envoy_rbac_v3.Principal{ - Identifier: &envoy_rbac_v3.Principal_Header{ - Header: &envoy_route_v3.HeaderMatcher{ - Name: "x-forwarded-client-cert", - HeaderMatchSpecifier: &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(spiffeID), - }, - }, - }, - }, - }, - } -} - -func anyPermission() *envoy_rbac_v3.Permission { - return &envoy_rbac_v3.Permission{ - Rule: &envoy_rbac_v3.Permission_Any{Any: true}, - } -} diff --git a/agent/xdsv2/resources.go b/agent/xdsv2/resources.go deleted file mode 100644 index fa5f7179e6a5d..0000000000000 --- a/agent/xdsv2/resources.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xdsv2 - -import ( - "fmt" - - "github.com/hashicorp/go-hclog" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/envoyextensions/xdscommon" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" -) - -// ResourceGenerator is associated with a single gRPC stream and creates xDS -// resources for a single client. -type ResourceGenerator struct { - Logger hclog.Logger - ProxyFeatures xdscommon.SupportedProxyFeatures -} - -func NewResourceGenerator( - logger hclog.Logger, -) *ResourceGenerator { - return &ResourceGenerator{ - Logger: logger, - } -} - -type ProxyResources struct { - proxyState *proxytracker.ProxyState - envoyResources map[string][]proto.Message -} - -func (g *ResourceGenerator) AllResourcesFromIR(proxyState *proxytracker.ProxyState) (map[string][]proto.Message, error) { - pr := &ProxyResources{ - proxyState: proxyState, - envoyResources: make(map[string][]proto.Message), - } - err := pr.generateXDSResources() - if err != nil { - return nil, fmt.Errorf("failed to generate xDS resources for ProxyState: %v", err) - } - return pr.envoyResources, nil -} - -func (pr *ProxyResources) generateXDSResources() error { - listeners, err := pr.makeXDSListeners() - if err != nil { - return err - } - - pr.envoyResources[xdscommon.ListenerType] = listeners - - clusters, err := pr.makeXDSClusters() - if err != nil { - return err - } - pr.envoyResources[xdscommon.ClusterType] = clusters - - endpoints, err := pr.makeXDSEndpoints() - if err != nil { - return err - } - pr.envoyResources[xdscommon.EndpointType] = endpoints - - routes, err := pr.makeXDSRoutes() - if err != nil { - return err - } - pr.envoyResources[xdscommon.RouteType] = routes - - return nil -} diff --git a/agent/xdsv2/resources_test.go b/agent/xdsv2/resources_test.go deleted file mode 100644 index 433295f9c8970..0000000000000 --- a/agent/xdsv2/resources_test.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xdsv2 - -import ( - "fmt" - envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" - envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" - envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" - "github.com/hashicorp/consul/internal/testing/golden" - "sort" - "testing" - - envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" - envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" - - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" - meshv2beta1 "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/sdk/testutil" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" -) - -var testTypeUrlToPrettyName = map[string]string{ - xdscommon.ListenerType: "listeners", - xdscommon.RouteType: "routes", - xdscommon.ClusterType: "clusters", - xdscommon.EndpointType: "endpoints", - xdscommon.SecretType: "secrets", -} - -// TestAllResourcesFromIR_XDSGoldenFileInputs tests the AllResourcesFromIR() by -// using the golden test output/expected files from the XDS controller tests as -// inputs to the XDSV2 resources generation. -func TestAllResourcesFromIR_XDSGoldenFileInputs(t *testing.T) { - inputPath := "../../internal/mesh/internal/controllers/xds" - - cases := []string{ - // destinations - please add in alphabetical order - "destination/l4-single-destination-ip-port-bind-address", - "destination/l4-single-destination-unix-socket-bind-address", - "destination/l4-single-implicit-destination-tproxy", - "destination/l4-multi-destination", - "destination/l4-multiple-implicit-destinations-tproxy", - "destination/l4-implicit-and-explicit-destinations-tproxy", - "destination/mixed-multi-destination", - "destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy", - "destination/multiport-l4-and-l7-single-implicit-destination-tproxy", - "destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy", - - //sources - please add in alphabetical order - "source/l4-multiple-workload-addresses-with-specific-ports", - "source/l4-multiple-workload-addresses-without-ports", - "source/l4-single-workload-address-without-ports", - "source/l7-expose-paths", - "source/local-and-inbound-connections", - "source/multiport-l4-multiple-workload-addresses-with-specific-ports", - "source/multiport-l4-multiple-workload-addresses-without-ports", - "source/multiport-l4-workload-with-only-mesh-port", - "source/multiport-l7-multiple-workload-addresses-with-specific-ports", - "source/multiport-l7-multiple-workload-addresses-without-ports", - } - - for _, name := range cases { - t.Run(name, func(t *testing.T) { - // Arrange - paths to input and output golden files. - testFile := fmt.Sprintf("%s.golden", name) - inputFilePath := fmt.Sprintf("%s/testdata/%s", inputPath, testFile) - inputValueInput := golden.GetBytesAtFilePath(t, inputFilePath) - - // Act. - ps := jsonToProxyState(t, inputValueInput) - generator := NewResourceGenerator(testutil.Logger(t)) - resources, err := generator.AllResourcesFromIR(&proxytracker.ProxyState{ProxyState: ps}) - require.NoError(t, err) - - // Assert. - // Assert all resources were generated. - typeUrls := []string{ - xdscommon.ListenerType, - xdscommon.RouteType, - xdscommon.ClusterType, - xdscommon.EndpointType, - // TODO(proxystate): add in future - //xdscommon.SecretType, - } - require.Len(t, resources, len(typeUrls)) - - // Assert each resource type has actual XDS matching expected XDS. - for _, typeUrl := range typeUrls { - prettyName := testTypeUrlToPrettyName[typeUrl] - t.Run(prettyName, func(t *testing.T) { - items, ok := resources[typeUrl] - require.True(t, ok) - - // sort resources so they don't show up as flakey tests as - // ordering in JSON is not guaranteed. - sort.Slice(items, func(i, j int) bool { - switch typeUrl { - case xdscommon.ListenerType: - return items[i].(*envoy_listener_v3.Listener).Name < items[j].(*envoy_listener_v3.Listener).Name - case xdscommon.RouteType: - return items[i].(*envoy_route_v3.RouteConfiguration).Name < items[j].(*envoy_route_v3.RouteConfiguration).Name - case xdscommon.ClusterType: - return items[i].(*envoy_cluster_v3.Cluster).Name < items[j].(*envoy_cluster_v3.Cluster).Name - case xdscommon.EndpointType: - return items[i].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName < items[j].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName - case xdscommon.SecretType: - return items[i].(*envoy_tls_v3.Secret).Name < items[j].(*envoy_tls_v3.Secret).Name - default: - panic("not possible") - } - }) - - // Compare actual to expected. - resp, err := response.CreateResponse(typeUrl, "00000001", "00000001", items) - require.NoError(t, err) - gotJSON := protoToJSON(t, resp) - - expectedJSON := golden.Get(t, gotJSON, fmt.Sprintf("%s/%s", prettyName, testFile)) - require.JSONEq(t, expectedJSON, gotJSON) - }) - } - }) - } -} - -func protoToJSON(t *testing.T, pb proto.Message) string { - t.Helper() - m := protojson.MarshalOptions{ - Indent: " ", - } - gotJSON, err := m.Marshal(pb) - require.NoError(t, err) - return string(gotJSON) -} - -func jsonToProxyState(t *testing.T, json []byte) *meshv2beta1.ProxyState { - t.Helper() - um := protojson.UnmarshalOptions{} - ps := &meshv2beta1.ProxyState{} - err := um.Unmarshal(json, ps) - require.NoError(t, err) - return ps -} diff --git a/agent/xdsv2/route_resources.go b/agent/xdsv2/route_resources.go deleted file mode 100644 index af06c174484f8..0000000000000 --- a/agent/xdsv2/route_resources.go +++ /dev/null @@ -1,544 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xdsv2 - -import ( - "fmt" - "strings" - - envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/agent/xds/response" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - - envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" - "google.golang.org/protobuf/proto" -) - -func (pr *ProxyResources) makeXDSRoutes() ([]proto.Message, error) { - routes := make([]proto.Message, 0) - - for name, r := range pr.proxyState.Routes { - protoRoute := pr.makeEnvoyRouteConfigFromProxystateRoute(name, r) - // TODO: aggregate errors for routes and still return any properly formed routes. - routes = append(routes, protoRoute) - } - - return routes, nil -} - -func (pr *ProxyResources) makeEnvoyRoute(name string) (*envoy_route_v3.RouteConfiguration, error) { - var route *envoy_route_v3.RouteConfiguration - // TODO(proxystate): This will make routes in the future. This function should distinguish between static routes - // inlined into listeners and non-static routes that should be added as top level Envoy resources. - _, ok := pr.proxyState.Routes[name] - if !ok { - // This should not happen with a valid proxy state. - return nil, fmt.Errorf("could not find route in ProxyState: %s", name) - } - return route, nil -} - -// makeEnvoyRouteConfigFromProxystateRoute converts the proxystate representation of a Route into Envoy proto message -// form. We don't throw any errors here, since the proxystate has already been validated. -func (pr *ProxyResources) makeEnvoyRouteConfigFromProxystateRoute(name string, psRoute *pbproxystate.Route) *envoy_route_v3.RouteConfiguration { - envoyRouteConfig := &envoy_route_v3.RouteConfiguration{ - Name: name, - // ValidateClusters defaults to true when defined statically and false - // when done via RDS. Re-set the reasonable value of true to prevent - // null-routing traffic. - ValidateClusters: response.MakeBoolValue(true), - } - - for _, vh := range psRoute.GetVirtualHosts() { - envoyRouteConfig.VirtualHosts = append(envoyRouteConfig.VirtualHosts, pr.makeEnvoyVHFromProxystateVH(vh)) - } - - return envoyRouteConfig -} - -func (pr *ProxyResources) makeEnvoyVHFromProxystateVH(psVirtualHost *pbproxystate.VirtualHost) *envoy_route_v3.VirtualHost { - envoyVirtualHost := &envoy_route_v3.VirtualHost{ - Name: psVirtualHost.Name, - Domains: psVirtualHost.GetDomains(), - } - - for _, rr := range psVirtualHost.GetRouteRules() { - envoyVirtualHost.Routes = append(envoyVirtualHost.Routes, pr.makeEnvoyRouteFromProxystateRouteRule(rr)) - } - - for _, hm := range psVirtualHost.GetHeaderMutations() { - injectEnvoyVirtualHostWithProxystateHeaderMutation(envoyVirtualHost, hm) - } - - return envoyVirtualHost -} - -func (pr *ProxyResources) makeEnvoyRouteFromProxystateRouteRule(psRouteRule *pbproxystate.RouteRule) *envoy_route_v3.Route { - envoyRouteRule := &envoy_route_v3.Route{ - Match: makeEnvoyRouteMatchFromProxystateRouteMatch(psRouteRule.GetMatch()), - Action: pr.makeEnvoyRouteActionFromProxystateRouteDestination(psRouteRule.GetDestination()), - } - - for _, hm := range psRouteRule.GetHeaderMutations() { - injectEnvoyRouteRuleWithProxystateHeaderMutation(envoyRouteRule, hm) - } - - return envoyRouteRule -} - -func makeEnvoyRouteMatchFromProxystateRouteMatch(psRouteMatch *pbproxystate.RouteMatch) *envoy_route_v3.RouteMatch { - envoyRouteMatch := &envoy_route_v3.RouteMatch{} - - switch psRouteMatch.PathMatch.GetPathMatch().(type) { - case *pbproxystate.PathMatch_Exact: - envoyRouteMatch.PathSpecifier = &envoy_route_v3.RouteMatch_Path{ - Path: psRouteMatch.PathMatch.GetExact(), - } - case *pbproxystate.PathMatch_Prefix: - envoyRouteMatch.PathSpecifier = &envoy_route_v3.RouteMatch_Prefix{ - Prefix: psRouteMatch.PathMatch.GetPrefix(), - } - case *pbproxystate.PathMatch_Regex: - envoyRouteMatch.PathSpecifier = &envoy_route_v3.RouteMatch_SafeRegex{ - SafeRegex: makeEnvoyRegexMatch(psRouteMatch.PathMatch.GetRegex()), - } - default: - // This shouldn't be possible considering the types of PathMatch - return nil - } - - if len(psRouteMatch.GetHeaderMatches()) > 0 { - envoyRouteMatch.Headers = make([]*envoy_route_v3.HeaderMatcher, 0, len(psRouteMatch.GetHeaderMatches())) - } - for _, psHM := range psRouteMatch.GetHeaderMatches() { - envoyRouteMatch.Headers = append(envoyRouteMatch.Headers, makeEnvoyHeaderMatcherFromProxystateHeaderMatch(psHM)) - } - - if len(psRouteMatch.MethodMatches) > 0 { - methodHeaderRegex := strings.Join(psRouteMatch.MethodMatches, "|") - - eh := &envoy_route_v3.HeaderMatcher{ - Name: ":method", - HeaderMatchSpecifier: &envoy_route_v3.HeaderMatcher_SafeRegexMatch{ - SafeRegexMatch: makeEnvoyRegexMatch(methodHeaderRegex), - }, - } - - envoyRouteMatch.Headers = append(envoyRouteMatch.Headers, eh) - } - - if len(psRouteMatch.GetQueryParameterMatches()) > 0 { - envoyRouteMatch.QueryParameters = make([]*envoy_route_v3.QueryParameterMatcher, 0, len(psRouteMatch.GetQueryParameterMatches())) - } - for _, psQM := range psRouteMatch.GetQueryParameterMatches() { - envoyRouteMatch.QueryParameters = append(envoyRouteMatch.QueryParameters, makeEnvoyQueryParamFromProxystateQueryMatch(psQM)) - } - - return envoyRouteMatch -} - -func makeEnvoyRegexMatch(pattern string) *envoy_matcher_v3.RegexMatcher { - return &envoy_matcher_v3.RegexMatcher{ - EngineType: &envoy_matcher_v3.RegexMatcher_GoogleRe2{ - GoogleRe2: &envoy_matcher_v3.RegexMatcher_GoogleRE2{}, - }, - Regex: pattern, - } -} - -func makeEnvoyHeaderMatcherFromProxystateHeaderMatch(psMatch *pbproxystate.HeaderMatch) *envoy_route_v3.HeaderMatcher { - envoyHeaderMatcher := &envoy_route_v3.HeaderMatcher{ - Name: psMatch.Name, - } - - switch psMatch.Match.(type) { - case *pbproxystate.HeaderMatch_Exact: - envoyHeaderMatcher.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ - Exact: psMatch.GetExact(), - }, - IgnoreCase: false, - }, - } - - case *pbproxystate.HeaderMatch_Regex: - envoyHeaderMatcher.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: response.MakeEnvoyRegexMatch(psMatch.GetRegex()), - }, - IgnoreCase: false, - }, - } - - case *pbproxystate.HeaderMatch_Prefix: - envoyHeaderMatcher.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Prefix{ - Prefix: psMatch.GetPrefix(), - }, - IgnoreCase: false, - }, - } - case *pbproxystate.HeaderMatch_Suffix: - envoyHeaderMatcher.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Suffix{ - Suffix: psMatch.GetSuffix(), - }, - IgnoreCase: false, - }, - } - - case *pbproxystate.HeaderMatch_Present: - envoyHeaderMatcher.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_PresentMatch{ - PresentMatch: true, - } - default: - // This shouldn't be possible considering the types of HeaderMatch - return nil - } - - if psMatch.GetInvertMatch() { - envoyHeaderMatcher.InvertMatch = true - } - - return envoyHeaderMatcher -} - -func makeEnvoyQueryParamFromProxystateQueryMatch(psMatch *pbproxystate.QueryParameterMatch) *envoy_route_v3.QueryParameterMatcher { - envoyQueryParamMatcher := &envoy_route_v3.QueryParameterMatcher{ - Name: psMatch.Name, - } - - switch psMatch.Match.(type) { - case *pbproxystate.QueryParameterMatch_Exact: - envoyQueryParamMatcher.QueryParameterMatchSpecifier = &envoy_route_v3.QueryParameterMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ - Exact: psMatch.GetExact(), - }, - }, - } - - case *pbproxystate.QueryParameterMatch_Regex: - envoyQueryParamMatcher.QueryParameterMatchSpecifier = &envoy_route_v3.QueryParameterMatcher_StringMatch{ - StringMatch: &envoy_matcher_v3.StringMatcher{ - MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ - SafeRegex: makeEnvoyRegexMatch(psMatch.GetRegex()), - }, - }, - } - case *pbproxystate.QueryParameterMatch_Present: - envoyQueryParamMatcher.QueryParameterMatchSpecifier = &envoy_route_v3.QueryParameterMatcher_PresentMatch{ - PresentMatch: true, - } - default: - // This shouldn't be possible considering the types of QueryMatch - return nil - } - - return envoyQueryParamMatcher -} - -// TODO (dans): Will this always be envoy_route_v3.Route_Route? -// Definitely for connect proxies this is the only option. -func (pr *ProxyResources) makeEnvoyRouteActionFromProxystateRouteDestination(psRouteDestination *pbproxystate.RouteDestination) *envoy_route_v3.Route_Route { - envoyRouteRoute := &envoy_route_v3.Route_Route{ - Route: &envoy_route_v3.RouteAction{}, - } - - switch psRouteDestination.Destination.(type) { - case *pbproxystate.RouteDestination_Cluster: - psCluster := psRouteDestination.GetCluster() - envoyRouteRoute.Route.ClusterSpecifier = &envoy_route_v3.RouteAction_Cluster{ - Cluster: psCluster.GetName(), - } - clusters, _ := pr.makeClusters(psCluster.Name) - pr.envoyResources[xdscommon.ClusterType] = append(pr.envoyResources[xdscommon.ClusterType], clusters...) - - case *pbproxystate.RouteDestination_WeightedClusters: - psWeightedClusters := psRouteDestination.GetWeightedClusters() - envoyClusters := make([]*envoy_route_v3.WeightedCluster_ClusterWeight, 0, len(psWeightedClusters.GetClusters())) - totalWeight := 0 - for _, psCluster := range psWeightedClusters.GetClusters() { - clusters, _ := pr.makeClusters(psCluster.Name) - pr.envoyResources[xdscommon.ClusterType] = append(pr.envoyResources[xdscommon.ClusterType], clusters...) - totalWeight += int(psCluster.Weight.GetValue()) - envoyClusters = append(envoyClusters, makeEnvoyClusterWeightFromProxystateWeightedCluster(psCluster)) - } - var envoyWeightScale *wrapperspb.UInt32Value - if totalWeight == 10000 { - envoyWeightScale = response.MakeUint32Value(10000) - } - - envoyRouteRoute.Route.ClusterSpecifier = &envoy_route_v3.RouteAction_WeightedClusters{ - WeightedClusters: &envoy_route_v3.WeightedCluster{ - Clusters: envoyClusters, - TotalWeight: envoyWeightScale, - }, - } - default: - // This shouldn't be possible considering the types of Destination - return nil - } - - injectEnvoyRouteActionWithProxystateDestinationConfig(envoyRouteRoute.Route, psRouteDestination.GetDestinationConfiguration()) - - if psRouteDestination.GetDestinationConfiguration() != nil { - config := psRouteDestination.GetDestinationConfiguration() - action := envoyRouteRoute.Route - - action.PrefixRewrite = config.GetPrefixRewrite() - - if config.GetTimeoutConfig().GetTimeout() != nil { - action.Timeout = config.GetTimeoutConfig().GetTimeout() - } - - if config.GetTimeoutConfig().GetTimeout() != nil { - action.Timeout = config.GetTimeoutConfig().GetTimeout() - } - - if config.GetTimeoutConfig().GetIdleTimeout() != nil { - action.IdleTimeout = config.GetTimeoutConfig().GetIdleTimeout() - } - - if config.GetRetryPolicy() != nil { - action.RetryPolicy = makeEnvoyRetryPolicyFromProxystateRetryPolicy(config.GetRetryPolicy()) - } - } - - return envoyRouteRoute -} - -func makeEnvoyClusterWeightFromProxystateWeightedCluster(cluster *pbproxystate.L7WeightedDestinationCluster) *envoy_route_v3.WeightedCluster_ClusterWeight { - envoyClusterWeight := &envoy_route_v3.WeightedCluster_ClusterWeight{ - Name: cluster.GetName(), - Weight: cluster.GetWeight(), - } - - for _, hm := range cluster.GetHeaderMutations() { - injectEnvoyClusterWeightWithProxystateHeaderMutation(envoyClusterWeight, hm) - } - - return envoyClusterWeight -} - -func injectEnvoyClusterWeightWithProxystateHeaderMutation(envoyClusterWeight *envoy_route_v3.WeightedCluster_ClusterWeight, mutation *pbproxystate.HeaderMutation) { - mutation.GetAction() - switch mutation.GetAction().(type) { - case *pbproxystate.HeaderMutation_RequestHeaderAdd: - action := mutation.GetRequestHeaderAdd() - header := action.GetHeader() - app := action.GetAppendAction() == pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD - - hvo := &envoy_core_v3.HeaderValueOption{ - Header: &envoy_core_v3.HeaderValue{ - Key: header.GetKey(), - Value: header.GetValue(), - }, - Append: response.MakeBoolValue(app), - } - envoyClusterWeight.RequestHeadersToAdd = append(envoyClusterWeight.RequestHeadersToAdd, hvo) - - case *pbproxystate.HeaderMutation_RequestHeaderRemove: - action := mutation.GetRequestHeaderRemove() - envoyClusterWeight.RequestHeadersToRemove = append(envoyClusterWeight.RequestHeadersToRemove, action.GetHeaderKeys()...) - - case *pbproxystate.HeaderMutation_ResponseHeaderAdd: - action := mutation.GetResponseHeaderAdd() - header := action.GetHeader() - app := action.GetAppendAction() == pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD - - hvo := &envoy_core_v3.HeaderValueOption{ - Header: &envoy_core_v3.HeaderValue{ - Key: header.GetKey(), - Value: header.GetValue(), - }, - Append: response.MakeBoolValue(app), - } - envoyClusterWeight.ResponseHeadersToAdd = append(envoyClusterWeight.ResponseHeadersToAdd, hvo) - - case *pbproxystate.HeaderMutation_ResponseHeaderRemove: - action := mutation.GetResponseHeaderRemove() - envoyClusterWeight.ResponseHeadersToRemove = append(envoyClusterWeight.ResponseHeadersToRemove, action.GetHeaderKeys()...) - - default: - // This shouldn't be possible considering the types of Destination - return - } -} - -func injectEnvoyRouteActionWithProxystateDestinationConfig(envoyAction *envoy_route_v3.RouteAction, config *pbproxystate.DestinationConfiguration) { - if config == nil { - return - } - - if len(config.GetHashPolicies()) > 0 { - envoyAction.HashPolicy = make([]*envoy_route_v3.RouteAction_HashPolicy, 0, len(config.GetHashPolicies())) - } - for _, policy := range config.GetHashPolicies() { - envoyPolicy := makeEnvoyHashPolicyFromProxystateLBHashPolicy(policy) - envoyAction.HashPolicy = append(envoyAction.HashPolicy, envoyPolicy) - } - - if config.AutoHostRewrite != nil { - envoyAction.HostRewriteSpecifier = &envoy_route_v3.RouteAction_AutoHostRewrite{ - AutoHostRewrite: config.AutoHostRewrite, - } - } -} - -func makeEnvoyHashPolicyFromProxystateLBHashPolicy(psPolicy *pbproxystate.LoadBalancerHashPolicy) *envoy_route_v3.RouteAction_HashPolicy { - switch psPolicy.GetPolicy().(type) { - case *pbproxystate.LoadBalancerHashPolicy_ConnectionProperties: - return &envoy_route_v3.RouteAction_HashPolicy{ - PolicySpecifier: &envoy_route_v3.RouteAction_HashPolicy_ConnectionProperties_{ - ConnectionProperties: &envoy_route_v3.RouteAction_HashPolicy_ConnectionProperties{ - SourceIp: true, // always true - }, - }, - Terminal: psPolicy.GetConnectionProperties().GetTerminal(), - } - - case *pbproxystate.LoadBalancerHashPolicy_Header: - return &envoy_route_v3.RouteAction_HashPolicy{ - PolicySpecifier: &envoy_route_v3.RouteAction_HashPolicy_Header_{ - Header: &envoy_route_v3.RouteAction_HashPolicy_Header{ - HeaderName: psPolicy.GetHeader().GetName(), - }, - }, - Terminal: psPolicy.GetHeader().GetTerminal(), - } - - case *pbproxystate.LoadBalancerHashPolicy_Cookie: - cookie := &envoy_route_v3.RouteAction_HashPolicy_Cookie{ - Name: psPolicy.GetCookie().GetName(), - Path: psPolicy.GetCookie().GetPath(), - Ttl: psPolicy.GetCookie().GetTtl(), - } - - return &envoy_route_v3.RouteAction_HashPolicy{ - PolicySpecifier: &envoy_route_v3.RouteAction_HashPolicy_Cookie_{ - Cookie: cookie, - }, - Terminal: psPolicy.GetCookie().GetTerminal(), - } - - case *pbproxystate.LoadBalancerHashPolicy_QueryParameter: - return &envoy_route_v3.RouteAction_HashPolicy{ - PolicySpecifier: &envoy_route_v3.RouteAction_HashPolicy_QueryParameter_{ - QueryParameter: &envoy_route_v3.RouteAction_HashPolicy_QueryParameter{ - Name: psPolicy.GetQueryParameter().GetName(), - }, - }, - Terminal: psPolicy.GetQueryParameter().GetTerminal(), - } - } - // This shouldn't be possible considering the types of LoadBalancerPolicy - return nil -} - -func makeEnvoyRetryPolicyFromProxystateRetryPolicy(psRetryPolicy *pbproxystate.RetryPolicy) *envoy_route_v3.RetryPolicy { - return &envoy_route_v3.RetryPolicy{ - NumRetries: psRetryPolicy.GetNumRetries(), - RetriableStatusCodes: psRetryPolicy.GetRetriableStatusCodes(), - RetryOn: psRetryPolicy.GetRetryOn(), - } -} - -func injectEnvoyRouteRuleWithProxystateHeaderMutation(envoyRouteRule *envoy_route_v3.Route, mutation *pbproxystate.HeaderMutation) { - mutation.GetAction() - switch mutation.GetAction().(type) { - case *pbproxystate.HeaderMutation_RequestHeaderAdd: - action := mutation.GetRequestHeaderAdd() - header := action.GetHeader() - app := action.GetAppendAction() == pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD - - hvo := &envoy_core_v3.HeaderValueOption{ - Header: &envoy_core_v3.HeaderValue{ - Key: header.GetKey(), - Value: header.GetValue(), - }, - Append: response.MakeBoolValue(app), - } - envoyRouteRule.RequestHeadersToAdd = append(envoyRouteRule.RequestHeadersToAdd, hvo) - - case *pbproxystate.HeaderMutation_RequestHeaderRemove: - action := mutation.GetRequestHeaderRemove() - envoyRouteRule.RequestHeadersToRemove = append(envoyRouteRule.RequestHeadersToRemove, action.GetHeaderKeys()...) - - case *pbproxystate.HeaderMutation_ResponseHeaderAdd: - action := mutation.GetResponseHeaderAdd() - header := action.GetHeader() - app := action.GetAppendAction() == pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD - - hvo := &envoy_core_v3.HeaderValueOption{ - Header: &envoy_core_v3.HeaderValue{ - Key: header.GetKey(), - Value: header.GetValue(), - }, - Append: response.MakeBoolValue(app), - } - envoyRouteRule.ResponseHeadersToAdd = append(envoyRouteRule.ResponseHeadersToAdd, hvo) - - case *pbproxystate.HeaderMutation_ResponseHeaderRemove: - action := mutation.GetResponseHeaderRemove() - envoyRouteRule.ResponseHeadersToRemove = append(envoyRouteRule.ResponseHeadersToRemove, action.GetHeaderKeys()...) - - default: - // This shouldn't be possible considering the types of Destination - return - } -} - -func injectEnvoyVirtualHostWithProxystateHeaderMutation(envoyVirtualHost *envoy_route_v3.VirtualHost, mutation *pbproxystate.HeaderMutation) { - mutation.GetAction() - switch mutation.GetAction().(type) { - case *pbproxystate.HeaderMutation_RequestHeaderAdd: - action := mutation.GetRequestHeaderAdd() - header := action.GetHeader() - app := action.GetAppendAction() == pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD - - hvo := &envoy_core_v3.HeaderValueOption{ - Header: &envoy_core_v3.HeaderValue{ - Key: header.GetKey(), - Value: header.GetValue(), - }, - Append: response.MakeBoolValue(app), - } - envoyVirtualHost.RequestHeadersToAdd = append(envoyVirtualHost.RequestHeadersToAdd, hvo) - - case *pbproxystate.HeaderMutation_RequestHeaderRemove: - action := mutation.GetRequestHeaderRemove() - envoyVirtualHost.RequestHeadersToRemove = append(envoyVirtualHost.RequestHeadersToRemove, action.GetHeaderKeys()...) - - case *pbproxystate.HeaderMutation_ResponseHeaderAdd: - action := mutation.GetResponseHeaderAdd() - header := action.GetHeader() - app := action.GetAppendAction() == pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD - - hvo := &envoy_core_v3.HeaderValueOption{ - Header: &envoy_core_v3.HeaderValue{ - Key: header.GetKey(), - Value: header.GetValue(), - }, - Append: response.MakeBoolValue(app), - } - envoyVirtualHost.ResponseHeadersToAdd = append(envoyVirtualHost.ResponseHeadersToAdd, hvo) - - case *pbproxystate.HeaderMutation_ResponseHeaderRemove: - action := mutation.GetResponseHeaderRemove() - envoyVirtualHost.ResponseHeadersToRemove = append(envoyVirtualHost.ResponseHeadersToRemove, action.GetHeaderKeys()...) - - default: - // This shouldn't be possible considering the types of Destination - return - } -} diff --git a/agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy.golden deleted file mode 100644 index 089bfb7c20034..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy.golden +++ /dev/null @@ -1,110 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "original-destination", - "type": "ORIGINAL_DST", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-1.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-multi-destination.golden b/agent/xdsv2/testdata/clusters/destination/l4-multi-destination.golden deleted file mode 100644 index c88d7770d85fe..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/l4-multi-destination.golden +++ /dev/null @@ -1,205 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "null_route_cluster", - "type": "STATIC", - "connectTimeout": "10s" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-1.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp2.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp2" - ] - }, - "sni": "api-1.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp2.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp2" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index 089bfb7c20034..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,110 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "original-destination", - "type": "ORIGINAL_DST", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-1.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address.golden b/agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address.golden deleted file mode 100644 index 293416e3737f7..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address.golden +++ /dev/null @@ -1,109 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "null_route_cluster", - "type": "STATIC", - "connectTimeout": "10s" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-1.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address.golden b/agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address.golden deleted file mode 100644 index 742dbd0ea8388..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address.golden +++ /dev/null @@ -1,55 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy.golden deleted file mode 100644 index 0c86051ad7df4..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,62 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "original-destination", - "type": "ORIGINAL_DST", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-1.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden deleted file mode 100644 index 280f42b8581f5..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden +++ /dev/null @@ -1,157 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "http.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~http" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "null_route_cluster", - "type": "STATIC", - "connectTimeout": "10s" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-1.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index ec39ef35787fe..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,302 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "http.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~http" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "http.api-app2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~http" - ] - }, - "sni": "api-app2.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "original-destination", - "type": "ORIGINAL_DST", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-app2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-app2.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp2" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp2.api-app2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp2" - ] - }, - "sni": "api-app2.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden deleted file mode 100644 index d8cad46e7904c..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,158 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "http.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~http" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "original-destination", - "type": "ORIGINAL_DST", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp2" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden deleted file mode 100644 index d8cad46e7904c..0000000000000 --- a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ /dev/null @@ -1,158 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "http.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~http" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "original-destination", - "type": "ORIGINAL_DST", - "connectTimeout": "5s", - "lbPolicy": "CLUSTER_PROVIDED" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - } - ] - }, - "alpnProtocols": [ - "consul~tcp2" - ] - }, - "sni": "api-app.default.dc1.internal.foo.consul" - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index ce9870c06cd9d..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,31 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:port1", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index ce9870c06cd9d..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,31 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:port1", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/l4-single-workload-address-without-ports.golden b/agent/xdsv2/testdata/clusters/source/l4-single-workload-address-without-ports.golden deleted file mode 100644 index ce9870c06cd9d..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/l4-single-workload-address-without-ports.golden +++ /dev/null @@ -1,31 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:port1", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/l7-expose-paths.golden b/agent/xdsv2/testdata/clusters/source/l7-expose-paths.golden deleted file mode 100644 index a83751b4b502b..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/l7-expose-paths.golden +++ /dev/null @@ -1,87 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "exposed_cluster_9090", - "type": "STATIC", - "loadAssignment": { - "clusterName": "exposed_cluster_9090", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "exposed_cluster_9091", - "type": "STATIC", - "loadAssignment": { - "clusterName": "exposed_cluster_9091", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9091 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:port1", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/local-and-inbound-connections.golden b/agent/xdsv2/testdata/clusters/source/local-and-inbound-connections.golden deleted file mode 100644 index d4e6fd1d64ce1..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/local-and-inbound-connections.golden +++ /dev/null @@ -1,127 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "exposed_cluster_9090", - "type": "STATIC", - "loadAssignment": { - "clusterName": "exposed_cluster_9090", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "exposed_cluster_9091", - "type": "STATIC", - "loadAssignment": { - "clusterName": "exposed_cluster_9091", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9091 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:port1", - "type": "STATIC", - "connectTimeout": "6s", - "loadAssignment": { - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - "circuitBreakers": { - "thresholds": [ - { - "maxConnections": 123 - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:port3", - "type": "STATIC", - "connectTimeout": "8s", - "loadAssignment": { - "clusterName": "local_app:port3", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8081 - } - } - } - } - ] - } - ] - }, - "circuitBreakers": { - "thresholds": [ - { - "maxConnections": 123 - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 045470a3e5720..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,55 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:admin-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:admin-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:api-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:api-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 045470a3e5720..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,55 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:admin-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:admin-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:api-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:api-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port.golden b/agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port.golden deleted file mode 100644 index 460d515fe5893..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port.golden +++ /dev/null @@ -1,12 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "black-hole-cluster", - "type": "STATIC" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 339faaae6b0da..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,63 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:admin-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:admin-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:api-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:api-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 6246f19733b82..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,95 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:admin-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:admin-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:api-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:api-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:grpc-port", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:grpc-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9091 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy.golden deleted file mode 100644 index f7d569dc2266f..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy.golden +++ /dev/null @@ -1,49 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-multi-destination.golden b/agent/xdsv2/testdata/endpoints/destination/l4-multi-destination.golden deleted file mode 100644 index f8bca7ea32122..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/l4-multi-destination.golden +++ /dev/null @@ -1,91 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp2.api-1.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp2.api-2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index f7d569dc2266f..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,49 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address.golden b/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address.golden deleted file mode 100644 index f7d569dc2266f..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address.golden +++ /dev/null @@ -1,49 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address.golden b/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address.golden deleted file mode 100644 index 8075b842d96c7..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address.golden +++ /dev/null @@ -1,28 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy.golden deleted file mode 100644 index 333765ea0cb27..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,28 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination.golden deleted file mode 100644 index e22812cafe4bb..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination.golden +++ /dev/null @@ -1,91 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "http.api-1.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "http.api-2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index 56ff9fb5884bc..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,133 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "http.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "http.api-app2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-app2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp2.api-app2.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden deleted file mode 100644 index 52f227f9d4b81..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,70 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "http.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden deleted file mode 100644 index 52f227f9d4b81..0000000000000 --- a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ /dev/null @@ -1,70 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "http.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.1.1.1", - "portValue": 20000 - } - } - }, - "healthStatus": "HEALTHY" - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index b0c31e6e79c77..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,27 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index b0c31e6e79c77..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,27 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/l4-single-workload-address-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/l4-single-workload-address-without-ports.golden deleted file mode 100644 index b0c31e6e79c77..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/l4-single-workload-address-without-ports.golden +++ /dev/null @@ -1,27 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/l7-expose-paths.golden b/agent/xdsv2/testdata/endpoints/source/l7-expose-paths.golden deleted file mode 100644 index 1ccb234c89dbc..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/l7-expose-paths.golden +++ /dev/null @@ -1,67 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "exposed_cluster_9090", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "exposed_cluster_9091", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9091 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections.golden b/agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections.golden deleted file mode 100644 index c9e8727f031d4..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections.golden +++ /dev/null @@ -1,87 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "exposed_cluster_9090", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "exposed_cluster_9091", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9091 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:port1", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:port3", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8081 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 916fbc26ceab7..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,47 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:admin-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:api-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port.golden deleted file mode 100644 index 47b46bca225bf..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 916fbc26ceab7..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,47 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:admin-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:api-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index e3c67d2c90ae8..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,67 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:admin-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:api-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9090 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:grpc-port", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9091 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy.golden deleted file mode 100644 index 35304ea0d7f5a..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy.golden +++ /dev/null @@ -1,90 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "address": { - "socketAddress": { - "address": "1.1.1.1", - "portValue": 1234 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "cluster": "tcp.api-1.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "outbound_listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 15001 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-2.default.default.dc1", - "cluster": "tcp.api-2.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.original-destination", - "cluster": "original-destination" - } - } - ] - }, - "listenerFilters": [ - { - "name": "envoy.filters.listener.original_dst", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" - } - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-multi-destination.golden b/agent/xdsv2/testdata/listeners/destination/l4-multi-destination.golden deleted file mode 100644 index 105b508ef52c6..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/l4-multi-destination.golden +++ /dev/null @@ -1,137 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-1:tcp2:1.1.1.1:2345", - "address": { - "socketAddress": { - "address": "1.1.1.1", - "portValue": 2345 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp2.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp2.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp2.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "address": { - "socketAddress": { - "address": "1.1.1.1", - "portValue": 1234 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-2:tcp2:/path/to/socket", - "address": { - "pipe": { - "path": "/path/to/socket", - "mode": 438 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp2.api-2.default.default.dc1", - "cluster": "tcp2.api-2.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "address": { - "pipe": { - "path": "/path/to/socket", - "mode": 438 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-2.default.default.dc1", - "cluster": "tcp.api-2.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index 7901233ae959f..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,86 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "outbound_listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 15001 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "cluster": "tcp.api-1.default.dc1.internal.foo.consul" - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-2.default.default.dc1", - "cluster": "tcp.api-2.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.original-destination", - "cluster": "original-destination" - } - } - ] - }, - "listenerFilters": [ - { - "name": "envoy.filters.listener.original_dst", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" - } - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address.golden b/agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address.golden deleted file mode 100644 index 5f78003e3fd84..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address.golden +++ /dev/null @@ -1,47 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "address": { - "socketAddress": { - "address": "1.1.1.1", - "portValue": 1234 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address.golden b/agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address.golden deleted file mode 100644 index cf468d7fbbcf7..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address.golden +++ /dev/null @@ -1,32 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "address": { - "pipe": { - "path": "/path/to/socket", - "mode": 438 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-2.default.default.dc1", - "cluster": "tcp.api-2.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy.golden deleted file mode 100644 index ce759b6b02114..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,61 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "outbound_listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 15001 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "cluster": "tcp.api-1.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.original-destination", - "cluster": "original-destination" - } - } - ] - }, - "listenerFilters": [ - { - "name": "envoy.filters.listener.original_dst", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" - } - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden deleted file mode 100644 index 23dd5e4c6475c..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden +++ /dev/null @@ -1,119 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-1:http:1.1.1.1:1234", - "address": { - "socketAddress": { - "address": "1.1.1.1", - "portValue": 1234 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.", - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "default/local/default/api-1:http:1.1.1.1:1234" - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "address": { - "socketAddress": { - "address": "1.1.1.1", - "portValue": 1234 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "address": { - "pipe": { - "path": "/path/to/socket", - "mode": 438 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-2.default.default.dc1", - "cluster": "tcp.api-2.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index 9cd146e6ef0d5..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,222 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "outbound_listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 15001 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-app.default.default.dc1", - "cluster": "tcp.api-app.default.dc1.internal.foo.consul" - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.", - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "default/local/default/api-app:http" - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp2.api-app.default.default.dc1", - "cluster": "tcp2.api-app.default.dc1.internal.foo.consul" - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-app2.default.default.dc1", - "cluster": "tcp.api-app2.default.dc1.internal.foo.consul" - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.", - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "default/local/default/api-app2:http" - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp2.api-app2.default.default.dc1", - "cluster": "tcp2.api-app2.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.original-destination", - "cluster": "original-destination" - } - } - ] - }, - "listenerFilters": [ - { - "name": "envoy.filters.listener.original_dst", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" - } - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden deleted file mode 100644 index 71dec1b4db466..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,125 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "outbound_listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 15001 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-app.default.default.dc1", - "cluster": "tcp.api-app.default.dc1.internal.foo.consul" - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.", - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "default/local/default/api-app:http" - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp2.api-app.default.default.dc1", - "cluster": "tcp2.api-app.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.original-destination", - "cluster": "original-destination" - } - } - ] - }, - "listenerFilters": [ - { - "name": "envoy.filters.listener.original_dst", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" - } - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden deleted file mode 100644 index 71dec1b4db466..0000000000000 --- a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ /dev/null @@ -1,125 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "outbound_listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 15001 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp.api-app.default.default.dc1", - "cluster": "tcp.api-app.default.dc1.internal.foo.consul" - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.", - "rds": { - "configSource": { - "ads": {}, - "resourceApiVersion": "V3" - }, - "routeConfigName": "default/local/default/api-app:http" - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - }, - { - "filterChainMatch": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - }, - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.tcp2.api-app.default.default.dc1", - "cluster": "tcp2.api-app.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "upstream.original-destination", - "cluster": "original-destination" - } - } - ] - }, - "listenerFilters": [ - { - "name": "envoy.filters.listener.original_dst", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" - } - } - ], - "trafficDirection": "OUTBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 644769d8423fc..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,100 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.2", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~port1" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": { - "policies": { - "consul-intentions-layer4": { - "permissions": [ - { - "any": true - } - ], - "principals": [ - { - "authenticated": { - "principalName": { - "safeRegex": { - "googleRe2": {}, - "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" - } - } - } - } - ] - } - } - }, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:port1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 82581d5762489..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,78 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~port1" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:port1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/l4-single-workload-address-without-ports.golden b/agent/xdsv2/testdata/listeners/source/l4-single-workload-address-without-ports.golden deleted file mode 100644 index 82581d5762489..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/l4-single-workload-address-without-ports.golden +++ /dev/null @@ -1,78 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~port1" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:port1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/l7-expose-paths.golden b/agent/xdsv2/testdata/listeners/source/l7-expose-paths.golden deleted file mode 100644 index 973c825a6c632..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/l7-expose-paths.golden +++ /dev/null @@ -1,201 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "exposed_path_GetHealth1235", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 1235 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "exposed_path_route_GetHealth1235", - "routeConfig": { - "name": "exposed_path_route_GetHealth1235", - "virtualHosts": [ - { - "name": "exposed_path_route_GetHealth1235", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "path": "GetHealth" - }, - "route": { - "cluster": "exposed_cluster_9091" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "trafficDirection": "INBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "exposed_path_health1234", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 1234 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "exposed_path_route_health1234", - "routeConfig": { - "name": "exposed_path_route_health1234", - "virtualHosts": [ - { - "name": "exposed_path_route_health1234", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "path": "/health" - }, - "route": { - "cluster": "exposed_cluster_9090" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "trafficDirection": "INBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~port1" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:port1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/local-and-inbound-connections.golden b/agent/xdsv2/testdata/listeners/source/local-and-inbound-connections.golden deleted file mode 100644 index 916961daaf9fe..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/local-and-inbound-connections.golden +++ /dev/null @@ -1,309 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "exposed_path_GetHealth1235", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 1235 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "exposed_path_route_GetHealth1235", - "routeConfig": { - "name": "exposed_path_route_GetHealth1235", - "virtualHosts": [ - { - "name": "exposed_path_route_GetHealth1235", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "path": "GetHealth" - }, - "route": { - "cluster": "exposed_cluster_9091" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "trafficDirection": "INBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "exposed_path_health1234", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 1234 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "exposed_path_route_health1234", - "routeConfig": { - "name": "exposed_path_route_health1234", - "virtualHosts": [ - { - "name": "exposed_path_route_health1234", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "path": "/health" - }, - "route": { - "cluster": "exposed_cluster_9090" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ] - } - ], - "trafficDirection": "INBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~port1" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.connection_limit", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit", - "statPrefix": "inbound_connection_limit", - "maxConnections": "123" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:port1" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~port3" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.connection_limit", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit", - "statPrefix": "inbound_connection_limit", - "maxConnections": "123" - } - }, - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:port3", - "virtualHosts": [ - { - "name": "public_listener:port3", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:port3", - "timeout": "9s" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND", - "connectionBalanceConfig": { - "exactBalance": {} - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 10fcbb9c9b6c8..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,128 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.3", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~admin-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:admin-port" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~api-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:api-port" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index ba8670185485a..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,128 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~admin-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:admin-port" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~api-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:api-port" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port.golden b/agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port.golden deleted file mode 100644 index 15d019e69ca5a..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port.golden +++ /dev/null @@ -1,40 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "black-hole-cluster" - } - } - ] - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 1f0d971a99055..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,206 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.3", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~admin-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:admin-port", - "virtualHosts": [ - { - "name": "public_listener:admin-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:admin-port" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~api-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:api-port", - "virtualHosts": [ - { - "name": "public_listener:api-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:api-port" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 594d47c96c55b..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,309 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~admin-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:admin-port", - "virtualHosts": [ - { - "name": "public_listener:admin-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:admin-port" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~api-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:api-port", - "virtualHosts": [ - { - "name": "public_listener:api-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:api-port" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~grpc-port" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:grpc-port", - "virtualHosts": [ - { - "name": "public_listener:grpc-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:grpc-port" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.grpc_stats", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig", - "statsForAllMethods": true - } - }, - { - "name": "envoy.filters.http.grpc_http1_bridge", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_http1_bridge.v3.Config" - } - }, - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-multi-destination.golden b/agent/xdsv2/testdata/routes/destination/l4-multi-destination.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/l4-multi-destination.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address.golden b/agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address.golden b/agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination.golden deleted file mode 100644 index 28f9669ee3711..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination.golden +++ /dev/null @@ -1,67 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "default/local/default/api-1:http:1.1.1.1:1234", - "virtualHosts": [ - { - "name": "default/local/default/api-1:http:1.1.1.1:1234", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/split" - }, - "route": { - "weightedClusters": { - "clusters": [ - { - "name": "http.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "http.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - }, - "timeout": "77s" - } - }, - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "http.api-1.default.dc1.internal.foo.consul", - "timeout": "606s", - "retryPolicy": { - "retryOn": "connect-failure", - "numRetries": 4 - } - } - }, - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "null_route_cluster" - } - } - ] - } - ], - "validateClusters": true - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index c34c2a0602d27..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,53 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "default/local/default/api-app2:http", - "virtualHosts": [ - { - "name": "default/local/default/api-app2:http", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "http.api-app2.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "validateClusters": true - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "default/local/default/api-app:http", - "virtualHosts": [ - { - "name": "default/local/default/api-app:http", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "http.api-app.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "validateClusters": true - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden deleted file mode 100644 index caa0f6deb0000..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,30 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "default/local/default/api-app:http", - "virtualHosts": [ - { - "name": "default/local/default/api-app:http", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "http.api-app.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "validateClusters": true - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden deleted file mode 100644 index caa0f6deb0000..0000000000000 --- a/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ /dev/null @@ -1,30 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "default/local/default/api-app:http", - "virtualHosts": [ - { - "name": "default/local/default/api-app:http", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "http.api-app.default.dc1.internal.foo.consul" - } - } - ] - } - ], - "validateClusters": true - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/l4-single-workload-address-without-ports.golden b/agent/xdsv2/testdata/routes/source/l4-single-workload-address-without-ports.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/source/l4-single-workload-address-without-ports.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden b/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden deleted file mode 100644 index 68b5239aec9ed..0000000000000 --- a/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden +++ /dev/null @@ -1,53 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "exposed_path_route_GetHealth1235", - "virtualHosts": [ - { - "name": "exposed_path_route_GetHealth1235", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "path": "GetHealth" - }, - "route": { - "cluster": "exposed_cluster_9091" - } - } - ] - } - ], - "validateClusters": true - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "exposed_path_route_health1234", - "virtualHosts": [ - { - "name": "exposed_path_route_health1234", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "path": "/health" - }, - "route": { - "cluster": "exposed_cluster_9090" - } - } - ] - } - ], - "validateClusters": true - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden b/agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden deleted file mode 100644 index 97c96f44bb629..0000000000000 --- a/agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden +++ /dev/null @@ -1,77 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "exposed_path_route_GetHealth1235", - "virtualHosts": [ - { - "name": "exposed_path_route_GetHealth1235", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "path": "GetHealth" - }, - "route": { - "cluster": "exposed_cluster_9091" - } - } - ] - } - ], - "validateClusters": true - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "exposed_path_route_health1234", - "virtualHosts": [ - { - "name": "exposed_path_route_health1234", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "path": "/health" - }, - "route": { - "cluster": "exposed_cluster_9090" - } - } - ] - } - ], - "validateClusters": true - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "public_listener:port3", - "virtualHosts": [ - { - "name": "public_listener:port3", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:port3", - "timeout": "9s" - } - } - ] - } - ], - "validateClusters": true - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port.golden b/agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port.golden deleted file mode 100644 index 306f5220e7b9c..0000000000000 --- a/agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "versionInfo": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 3b1a61403ba7d..0000000000000 --- a/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,53 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "public_listener:admin-port", - "virtualHosts": [ - { - "name": "public_listener:admin-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:admin-port" - } - } - ] - } - ], - "validateClusters": true - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "public_listener:api-port", - "virtualHosts": [ - { - "name": "public_listener:api-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:api-port" - } - } - ] - } - ], - "validateClusters": true - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 7f976890c64b0..0000000000000 --- a/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,76 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "public_listener:admin-port", - "virtualHosts": [ - { - "name": "public_listener:admin-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:admin-port" - } - } - ] - } - ], - "validateClusters": true - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "public_listener:api-port", - "virtualHosts": [ - { - "name": "public_listener:api-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:api-port" - } - } - ] - } - ], - "validateClusters": true - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "public_listener:grpc-port", - "virtualHosts": [ - { - "name": "public_listener:grpc-port", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:grpc-port" - } - } - ] - } - ], - "validateClusters": true - } - ], - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "nonce": "00000001" -} \ No newline at end of file diff --git a/api/.copywrite.hcl b/api/.copywrite.hcl deleted file mode 100644 index 34d99ba25e12e..0000000000000 --- a/api/.copywrite.hcl +++ /dev/null @@ -1,8 +0,0 @@ -schema_version = 1 - -project { - license = "MPL-2.0" - copyright_year = 2023 - - header_ignore = [] -} diff --git a/api/LICENSE b/api/LICENSE deleted file mode 100644 index 7c5baa45e1c29..0000000000000 --- a/api/LICENSE +++ /dev/null @@ -1,365 +0,0 @@ -Copyright (c) 2020 HashiCorp, Inc. - -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/api/acl.go b/api/acl.go index 47b38eb6ca625..48d2e66ee97fe 100644 --- a/api/acl.go +++ b/api/acl.go @@ -19,13 +19,6 @@ 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 { @@ -47,7 +40,6 @@ 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"` @@ -96,7 +88,6 @@ 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"` @@ -157,27 +148,6 @@ 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 @@ -226,7 +196,6 @@ 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 @@ -249,12 +218,6 @@ 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 { @@ -264,7 +227,6 @@ type ACLBindingRule struct { Selector string BindType BindingRuleBindType BindName string - BindVars *ACLTemplatedPolicyVariables `json:",omitempty"` CreateIndex uint64 ModifyIndex uint64 @@ -1661,78 +1623,3 @@ 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/api/agent.go b/api/agent.go index 24e2c50d6499c..6775edf4257ad 100644 --- a/api/agent.go +++ b/api/agent.go @@ -307,10 +307,6 @@ 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 @@ -839,9 +835,6 @@ 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 @@ -998,14 +991,7 @@ 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 { @@ -1393,10 +1379,6 @@ 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/api/agent_test.go b/api/agent_test.go index 511d51607deca..dce525ebc322c 100644 --- a/api/agent_test.go +++ b/api/agent_test.go @@ -165,21 +165,6 @@ func TestAPI_AgentMembersOpts(t *testing.T) { } require.Equal(t, 1, len(members)) - - members, err = agent.MembersOpts(MembersOpts{ - WAN: true, - Filter: `Tags["dc"] == "not-Exist"`, - }) - if err != nil { - t.Fatalf("err: %v", err) - } - require.Equal(t, 0, len(members)) - - _, err = agent.MembersOpts(MembersOpts{ - WAN: true, - Filter: `Tags["dc"] == invalid-bexpr-value`, - }) - require.ErrorContains(t, err, "Failed to create boolean expression evaluator") } func TestAPI_AgentMembers(t *testing.T) { @@ -297,21 +282,6 @@ func TestAgent_ServiceRegisterOpts_WithContextTimeout(t *testing.T) { require.True(t, errors.Is(err, context.DeadlineExceeded), "expected timeout") } -func TestAgent_ServiceRegisterOpts_Token(t *testing.T) { - c, s := makeACLClient(t) - defer s.Stop() - - reg := &AgentServiceRegistration{Name: "example"} - opts := &ServiceRegisterOpts{} - opts.Token = "invalid" - err := c.Agent().ServiceRegisterOpts(reg, *opts) - require.EqualError(t, err, "Unexpected response code: 403 (ACL not found)") - - opts.Token = "root" - err = c.Agent().ServiceRegisterOpts(reg, *opts) - require.NoError(t, err) -} - func TestAPI_NewClient_TokenFileCLIFirstPriority(t *testing.T) { os.Setenv("CONSUL_HTTP_TOKEN_FILE", "httpTokenFile.txt") os.Setenv("CONSUL_HTTP_TOKEN", "httpToken") @@ -1073,7 +1043,7 @@ func TestAPI_AgentChecks(t *testing.T) { Name: "foo", } reg.TTL = "15s" - if err := agent.CheckRegisterOpts(reg, nil); err != nil { + if err := agent.CheckRegister(reg); err != nil { t.Fatalf("err: %v", err) } @@ -1097,19 +1067,6 @@ func TestAPI_AgentChecks(t *testing.T) { } } -func TestAgent_AgentChecksRegisterOpts_WithContextTimeout(t *testing.T) { - c, err := NewClient(DefaultConfig()) - require.NoError(t, err) - - ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond) - t.Cleanup(cancel) - - opts := &QueryOptions{} - opts = opts.WithContext(ctx) - err = c.Agent().CheckRegisterOpts(&AgentCheckRegistration{}, opts) - require.True(t, errors.Is(err, context.DeadlineExceeded), "expected timeout") -} - func TestAPI_AgentChecksWithFilterOpts(t *testing.T) { t.Parallel() c, s := makeClient(t) @@ -1663,10 +1620,6 @@ func TestAPI_AgentUpdateToken(t *testing.T) { t.Fatalf("err: %v", err) } - if _, err := agent.UpdateDNSToken("root", nil); err != nil { - t.Fatalf("err: %v", err) - } - }) t.Run("new with fallback", func(t *testing.T) { @@ -1755,9 +1708,6 @@ func TestAPI_AgentUpdateToken(t *testing.T) { _, err = agent.UpdateConfigFileRegistrationToken("root", nil) require.Error(t, err) - - _, err = agent.UpdateDNSToken("root", nil) - require.Error(t, err) }) } diff --git a/api/ce_test.go b/api/ce_test.go index 91dd973b683ca..c608970428c14 100644 --- a/api/ce_test.go +++ b/api/ce_test.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package api diff --git a/api/config_entry.go b/api/config_entry.go index ffc18a85ed5c9..405e92ef2741e 100644 --- a/api/config_entry.go +++ b/api/config_entry.go @@ -39,12 +39,11 @@ const ( ) const ( - BuiltinAWSLambdaExtension string = "builtin/aws/lambda" - BuiltinExtAuthzExtension string = "builtin/ext-authz" - BuiltinLuaExtension string = "builtin/lua" - BuiltinOTELAccessLoggingExtension string = "builtin/otel-access-logging" - BuiltinPropertyOverrideExtension string = "builtin/property-override" - BuiltinWasmExtension string = "builtin/wasm" + BuiltinAWSLambdaExtension string = "builtin/aws/lambda" + BuiltinExtAuthzExtension string = "builtin/ext-authz" + BuiltinLuaExtension string = "builtin/lua" + 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. @@ -315,48 +314,6 @@ 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. - // For a given request, the first matching route will be applied, if any - // Overrides any top-level configuration. - Routes []InstanceLevelRouteRateLimits -} - -// InstanceLevelRouteRateLimits represents rate limit configuration -// applied to a route matching one of PathExact/PathPrefix/PathRegex. -type InstanceLevelRouteRateLimits struct { - PathExact string `alias:"path_exact"` - PathPrefix string `alias:"path_prefix"` - PathRegex string `alias:"path_regex"` - - RequestsPerSecond int `alias:"requests_per_second"` - RequestsMaxBurst int `alias:"requests_max_burst"` -} - type ServiceConfigEntry struct { Kind string Name string @@ -375,7 +332,6 @@ 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 diff --git a/api/config_entry_gateways.go b/api/config_entry_gateways.go index baf274e2da027..b59f1c0621ff6 100644 --- a/api/config_entry_gateways.go +++ b/api/config_entry_gateways.go @@ -284,10 +284,6 @@ 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 @@ -306,39 +302,3 @@ 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/api/config_entry_gateways_test.go b/api/config_entry_gateways_test.go index 7383b0ae68038..25b0a2d515c26 100644 --- a/api/config_entry_gateways_test.go +++ b/api/config_entry_gateways_test.go @@ -348,150 +348,3 @@ func TestAPI_ConfigEntries_TerminatingGateway(t *testing.T) { _, _, err = configEntries.Get(TerminatingGateway, "foo", nil) require.Error(t, err) } - -func TestAPI_ConfigEntries_APIGateway(t *testing.T) { - t.Parallel() - c, s := makeClient(t) - defer s.Stop() - - configEntries := c.ConfigEntries() - listener1 := APIGatewayListener{ - Name: "listener1", - Hostname: "host.com", - Port: 3360, - Protocol: "http", - } - - listener2 := APIGatewayListener{ - Name: "listener2", - Hostname: "host2.com", - Port: 3362, - Protocol: "http", - } - - apigw1 := &APIGatewayConfigEntry{ - Kind: APIGateway, - Name: "foo", - Meta: map[string]string{ - "foo": "bar", - "gir": "zim", - }, - Listeners: []APIGatewayListener{listener1}, - } - - apigw2 := &APIGatewayConfigEntry{ - Kind: APIGateway, - Name: "bar", - Listeners: []APIGatewayListener{listener2}, - } - - // set it - _, wm, err := configEntries.Set(apigw1, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - // also set the second one - _, wm, err = configEntries.Set(apigw2, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - // get it - entry, qm, err := configEntries.Get(APIGateway, "foo", nil) - require.NoError(t, err) - require.NotNil(t, qm) - require.NotEqual(t, 0, qm.RequestTime) - - // verify it - readGW, ok := entry.(*APIGatewayConfigEntry) - require.True(t, ok) - require.Equal(t, apigw1.Kind, readGW.Kind) - require.Equal(t, apigw1.Name, readGW.Name) - require.Equal(t, apigw1.Meta, readGW.Meta) - require.Equal(t, apigw1.Meta, readGW.GetMeta()) - - // update it - apigw1.Listeners = []APIGatewayListener{ - listener1, - { - Name: "listener3", - Hostname: "host3.com", - Port: 3363, - Protocol: "http", - }, - } - - // CAS fail - written, _, err := configEntries.CAS(apigw1, 0, nil) - require.NoError(t, err) - require.False(t, written) - - // CAS success - written, wm, err = configEntries.CAS(apigw1, readGW.ModifyIndex, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - require.True(t, written) - - // re-setting should not yield an error - _, wm, err = configEntries.Set(apigw1, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - apigw2.Listeners = []APIGatewayListener{ - listener2, - { - Name: "listener4", - Hostname: "host4.com", - Port: 3364, - Protocol: "http", - }, - } - - _, wm, err = configEntries.Set(apigw2, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - // list them - entries, qm, err := configEntries.List(APIGateway, nil) - require.NoError(t, err) - require.NotNil(t, qm) - require.NotEqual(t, 0, qm.RequestTime) - require.Len(t, entries, 2) - - for _, entry = range entries { - switch entry.GetName() { - case "foo": - // this also verifies that the update value was persisted and - // the updated values are seen - readGW, ok = entry.(*APIGatewayConfigEntry) - require.True(t, ok) - require.Equal(t, apigw1.Kind, readGW.Kind) - require.Equal(t, apigw1.Name, readGW.Name) - require.Len(t, readGW.Listeners, 2) - - require.Equal(t, apigw1.Listeners, readGW.Listeners) - case "bar": - readGW, ok = entry.(*APIGatewayConfigEntry) - require.True(t, ok) - require.Equal(t, apigw2.Kind, readGW.Kind) - require.Equal(t, apigw2.Name, readGW.Name) - require.Len(t, readGW.Listeners, 2) - - require.Equal(t, apigw2.Listeners, readGW.Listeners) - } - } - - // delete it - wm, err = configEntries.Delete(APIGateway, "foo", nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - // verify deletion - _, _, err = configEntries.Get(APIGateway, "foo", nil) - require.Error(t, err) -} diff --git a/api/config_entry_routes.go b/api/config_entry_routes.go index bbaa032d50f66..cfea394535dbb 100644 --- a/api/config_entry_routes.go +++ b/api/config_entry_routes.go @@ -3,8 +3,6 @@ package api -import "time" - // TCPRouteConfigEntry -- TODO stub type TCPRouteConfigEntry struct { // Kind of the config entry. This should be set to api.TCPRoute. @@ -197,17 +195,8 @@ 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 - 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 + Headers []HTTPHeaderFilter + URLRewrite *URLRewrite } // HTTPHeaderFilter specifies how HTTP headers should be modified. @@ -221,32 +210,12 @@ 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. @@ -262,15 +231,10 @@ 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/api/config_entry_routes_test.go b/api/config_entry_routes_test.go deleted file mode 100644 index 0a4f8e38b1b8d..0000000000000 --- a/api/config_entry_routes_test.go +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package api - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestAPI_ConfigEntries_HTTPRoute(t *testing.T) { - t.Parallel() - c, s := makeClient(t) - defer s.Stop() - - configEntries := c.ConfigEntries() - route1 := &HTTPRouteConfigEntry{ - Kind: HTTPRoute, - Name: "route1", - } - - route2 := &HTTPRouteConfigEntry{ - Kind: HTTPRoute, - Name: "route2", - } - - // set it - _, wm, err := configEntries.Set(route1, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - // also set the second one - _, wm, err = configEntries.Set(route2, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - // get it - entry, qm, err := configEntries.Get(HTTPRoute, "route1", nil) - require.NoError(t, err) - require.NotNil(t, qm) - require.NotEqual(t, 0, qm.RequestTime) - - // verify it - readRoute, ok := entry.(*HTTPRouteConfigEntry) - require.True(t, ok) - require.Equal(t, route1.Kind, readRoute.Kind) - require.Equal(t, route1.Name, readRoute.Name) - require.Equal(t, route1.Meta, readRoute.Meta) - require.Equal(t, route1.Meta, readRoute.GetMeta()) - - // update it - route1.Rules = []HTTPRouteRule{ - { - Filters: HTTPFilters{ - URLRewrite: &URLRewrite{ - Path: "abc", - }, - }, - }, - } - - // CAS fail - written, _, err := configEntries.CAS(route1, 0, nil) - require.NoError(t, err) - require.False(t, written) - - // CAS success - written, wm, err = configEntries.CAS(route1, readRoute.ModifyIndex, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - require.True(t, written) - - // re-setting should not yield an error - _, wm, err = configEntries.Set(route1, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - route2.Rules = []HTTPRouteRule{ - { - Filters: HTTPFilters{ - URLRewrite: &URLRewrite{ - Path: "def", - }, - }, - }, - } - - _, wm, err = configEntries.Set(route2, nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - // list them - entries, qm, err := configEntries.List(HTTPRoute, nil) - require.NoError(t, err) - require.NotNil(t, qm) - require.NotEqual(t, 0, qm.RequestTime) - require.Len(t, entries, 2) - - for _, entry = range entries { - switch entry.GetName() { - case "route1": - // this also verifies that the update value was persisted and - // the updated values are seen - readRoute, ok = entry.(*HTTPRouteConfigEntry) - require.True(t, ok) - require.Equal(t, route1.Kind, readRoute.Kind) - require.Equal(t, route1.Name, readRoute.Name) - require.Len(t, readRoute.Rules, 1) - - require.Equal(t, route1.Rules, readRoute.Rules) - case "route2": - readRoute, ok = entry.(*HTTPRouteConfigEntry) - require.True(t, ok) - require.Equal(t, route2.Kind, readRoute.Kind) - require.Equal(t, route2.Name, readRoute.Name) - require.Len(t, readRoute.Rules, 1) - - require.Equal(t, route2.Rules, readRoute.Rules) - } - } - - // delete it - wm, err = configEntries.Delete(HTTPRoute, "route1", nil) - require.NoError(t, err) - require.NotNil(t, wm) - require.NotEqual(t, 0, wm.RequestTime) - - // verify deletion - _, _, err = configEntries.Get(HTTPRoute, "route1", nil) - require.Error(t, err) -} diff --git a/api/config_entry_status.go b/api/config_entry_status.go index 997066f24fe9d..2d16ea0fc4e56 100644 --- a/api/config_entry_status.go +++ b/api/config_entry_status.go @@ -106,10 +106,6 @@ const ( // 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 @@ -167,14 +163,6 @@ const ( // 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{ @@ -184,7 +172,6 @@ var validGatewayConditionReasonsMapping = map[GatewayConditionType]map[Condition }, ConditionStatusFalse: { GatewayReasonInvalidCertificates, - GatewayReasonInvalidJWTProviders, }, ConditionStatusUnknown: {}, }, @@ -203,7 +190,6 @@ var validGatewayConditionReasonsMapping = map[GatewayConditionType]map[Condition }, ConditionStatusFalse: { GatewayListenerReasonInvalidCertificateRef, - GatewayListenerReasonInvalidJWTProviderRef, }, ConditionStatusUnknown: {}, }, @@ -296,10 +282,6 @@ const ( // 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{ @@ -320,7 +302,6 @@ var validRouteConditionReasonsMapping = map[RouteConditionType]map[ConditionStat ConditionStatusFalse: { RouteReasonGatewayNotFound, RouteReasonFailedToBind, - RouteReasonJWTProvidersNotFound, }, ConditionStatusUnknown: {}, }, diff --git a/api/config_entry_status_test.go b/api/config_entry_status_test.go index ec64c87164070..9c6eaf034c321 100644 --- a/api/config_entry_status_test.go +++ b/api/config_entry_status_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - package api import "testing" diff --git a/api/go.mod b/api/go.mod index 33f77a1d250fe..49665f73d93cb 100644 --- a/api/go.mod +++ b/api/go.mod @@ -15,7 +15,7 @@ require ( github.com/hashicorp/serf v0.10.1 github.com/mitchellh/mapstructure v1.5.0 github.com/stretchr/testify v1.8.3 - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 ) require ( diff --git a/api/go.sum b/api/go.sum index bfc3fb8a11fbc..a2e26551c4ec5 100644 --- a/api/go.sum +++ b/api/go.sum @@ -173,8 +173,8 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -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/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= diff --git a/api/internal.go b/api/internal.go index b5f400f4b19be..dee161a65eb24 100644 --- a/api/internal.go +++ b/api/internal.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - package api import "context" diff --git a/api/internal_test.go b/api/internal_test.go index ce773d7360f92..ce088f1787d1c 100644 --- a/api/internal_test.go +++ b/api/internal_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - package api import ( diff --git a/api/namespace_test.go b/api/namespace_test.go index 8eb52c0dcfc9e..3a956ffbd4bd0 100644 --- a/api/namespace_test.go +++ b/api/namespace_test.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build consulent +// +build consulent package api diff --git a/api/operator_raft.go b/api/operator_raft.go index f0f5794aa5af0..d72c00c97b93a 100644 --- a/api/operator_raft.go +++ b/api/operator_raft.go @@ -68,14 +68,9 @@ func (op *Operator) RaftGetConfiguration(q *QueryOptions) (*RaftConfiguration, e } // RaftLeaderTransfer is used to transfer the current raft leader to another node -// Optionally accepts a non-empty id of another node to transfer leadership to. -func (op *Operator) RaftLeaderTransfer(id string, q *QueryOptions) (*TransferLeaderResponse, error) { +func (op *Operator) RaftLeaderTransfer(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/api/operator_raft_test.go b/api/operator_raft_test.go index eefffec0775d5..6e3b7fc0e3102 100644 --- a/api/operator_raft_test.go +++ b/api/operator_raft_test.go @@ -4,9 +4,8 @@ package api import ( + "strings" "testing" - - "github.com/hashicorp/consul/sdk/testutil" ) func TestAPI_OperatorRaftGetConfiguration(t *testing.T) { @@ -28,181 +27,33 @@ func TestAPI_OperatorRaftGetConfiguration(t *testing.T) { func TestAPI_OperatorRaftRemovePeerByAddress(t *testing.T) { t.Parallel() - c1, s1 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { - if conf.Autopilot == nil { - conf.Autopilot = &testutil.TestAutopilotConfig{} - } - conf.Autopilot.ServerStabilizationTime = "1ms" - }) - defer s1.Stop() - - _, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { - conf.Server = true - conf.Bootstrap = false - conf.RetryJoin = []string{s1.LANAddr} - if conf.Autopilot == nil { - conf.Autopilot = &testutil.TestAutopilotConfig{} - } - conf.Autopilot.ServerStabilizationTime = "1ms" - }) - defer s2.Stop() - s2.WaitForVoting(t) - - operator := c1.Operator() - err := operator.RaftRemovePeerByAddress(s2.ServerAddr, nil) - if err != nil { - t.Fatalf("err: %v", err) - } - - cfg, err := c1.Operator().RaftGetConfiguration(nil) - if err != nil { - t.Fatalf("err: %v", err) - } - if len(cfg.Servers) != 1 { - t.Fatalf("more than 1 server left: %+v", cfg.Servers) - } -} - -func TestAPI_OperatorRaftRemovePeerByID(t *testing.T) { - t.Parallel() - c1, s1 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { - if conf.Autopilot == nil { - conf.Autopilot = &testutil.TestAutopilotConfig{} - } - conf.Autopilot.ServerStabilizationTime = "1ms" - }) - defer s1.Stop() - - _, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { - conf.Server = true - conf.Bootstrap = false - conf.RetryJoin = []string{s1.LANAddr} - if conf.Autopilot == nil { - conf.Autopilot = &testutil.TestAutopilotConfig{} - } - conf.Autopilot.ServerStabilizationTime = "1ms" - }) - defer s2.Stop() - s2.WaitForVoting(t) - - operator := c1.Operator() - err := operator.RaftRemovePeerByID(s2.Config.NodeID, nil) - if err != nil { - t.Fatalf("err: %v", err) - } + c, s := makeClient(t) + defer s.Stop() - cfg, err := c1.Operator().RaftGetConfiguration(nil) - if err != nil { + // If we get this error, it proves we sent the address all the way + // through. + operator := c.Operator() + err := operator.RaftRemovePeerByAddress("nope", nil) + if err == nil || !strings.Contains(err.Error(), + "address \"nope\" was not found in the Raft configuration") { t.Fatalf("err: %v", err) } - if len(cfg.Servers) != 1 { - t.Fatalf("more than 1 server left: %+v", cfg.Servers) - } } func TestAPI_OperatorRaftLeaderTransfer(t *testing.T) { t.Parallel() - c1, s1 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { - if conf.Autopilot == nil { - conf.Autopilot = &testutil.TestAutopilotConfig{} - } - conf.Autopilot.ServerStabilizationTime = "1ms" - }) - defer s1.Stop() - - _, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { - conf.Server = true - conf.Bootstrap = false - conf.RetryJoin = []string{s1.LANAddr} - if conf.Autopilot == nil { - conf.Autopilot = &testutil.TestAutopilotConfig{} - } - conf.Autopilot.ServerStabilizationTime = "1ms" - }) - defer s2.Stop() - s2.WaitForVoting(t) - - cfg, err := c1.Operator().RaftGetConfiguration(nil) - if err != nil { - t.Fatalf("err: %v", err) - } - if len(cfg.Servers) != 2 { - t.Fatalf("not 2 servers: %#v", cfg.Servers) - } - var leaderID string - for _, srv := range cfg.Servers { - if srv.Leader { - leaderID = srv.ID - } - } - if leaderID == "" { - t.Fatalf("no leader: %+v", cfg.Servers) - } - - transfer, err := c1.Operator().RaftLeaderTransfer("", nil) - if err != nil { - t.Fatalf("err: %v", err) - } - if !transfer.Success { - t.Fatal("unsuccessful transfer") - } - - s2.WaitForLeader(t) - - cfg, err = c1.Operator().RaftGetConfiguration(nil) - if err != nil { - t.Fatalf("err: %v", err) - } - var newLeaderID string - for _, srv := range cfg.Servers { - if srv.Leader { - newLeaderID = srv.ID - } - } - if newLeaderID == "" { - t.Fatalf("no leader: %#v", cfg.Servers) - } - if newLeaderID == leaderID { - t.Fatalf("leader did not change: %v == %v", newLeaderID, leaderID) - } - - _, s3 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { - conf.Server = true - conf.Bootstrap = false - conf.RetryJoin = []string{s1.LANAddr, s2.LANAddr} - if conf.Autopilot == nil { - conf.Autopilot = &testutil.TestAutopilotConfig{} - } - conf.Autopilot.ServerStabilizationTime = "1ms" - }) - defer s3.Stop() - s3.WaitForVoting(t) - - // Transfer it to another member - transfer, err = c1.Operator().RaftLeaderTransfer(s3.Config.NodeID, nil) - if err != nil { - t.Fatalf("err: %v", err) - } - if !transfer.Success { - t.Fatal("unsuccessful transfer") - } - - s3.WaitForLeader(t) + c, s := makeClient(t) + defer s.Stop() - cfg, err = c1.Operator().RaftGetConfiguration(nil) - if err != nil { + // If we get this error, it proves we sent the address all the way + // through. + operator := c.Operator() + transfer, err := operator.RaftLeaderTransfer(nil) + if err == nil || !strings.Contains(err.Error(), + "cannot find peer") { t.Fatalf("err: %v", err) } - newLeaderID = "" - for _, srv := range cfg.Servers { - if srv.Leader { - newLeaderID = srv.ID - } - } - if newLeaderID == "" { - t.Fatalf("no leader: %#v", cfg.Servers) - } - if newLeaderID != s3.Config.NodeID { - t.Fatalf("leader is not s3: %v != %v", newLeaderID, s3.Config.NodeID) + if transfer != nil { + t.Fatalf("err:%v", transfer) } } diff --git a/api/watch/funcs_test.go b/api/watch/funcs_test.go index 4bd79a59c14f9..91318009ceac9 100644 --- a/api/watch/funcs_test.go +++ b/api/watch/funcs_test.go @@ -1196,110 +1196,6 @@ func TestChecksWatch_Filter(t *testing.T) { } } -func TestChecksWatch_Filter_by_ServiceNameStatus(t *testing.T) { - t.Parallel() - c, s := makeClient(t) - defer s.Stop() - - s.WaitForSerfCheck(t) - - var ( - wakeups [][]*api.HealthCheck - notifyCh = make(chan struct{}) - ) - - plan := mustParse(t, `{"type":"checks", "filter":"ServiceName == bar and Status == critical"}`) - plan.Handler = func(idx uint64, raw interface{}) { - if raw == nil { - return // ignore - } - v, ok := raw.([]*api.HealthCheck) - if !ok { - return // ignore - } - wakeups = append(wakeups, v) - notifyCh <- struct{}{} - } - - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - if err := plan.Run(s.HTTPAddr); err != nil { - t.Errorf("err: %v", err) - } - }() - defer plan.Stop() - - // Wait for first wakeup. - <-notifyCh - { - catalog := c.Catalog() - - // we don't want to find this one - reg := &api.CatalogRegistration{ - Node: "foo", - Address: "1.1.1.1", - Datacenter: "dc1", - Service: &api.AgentService{ - ID: "foo", - Service: "foo", - Tags: []string{"a"}, - }, - Check: &api.AgentCheck{ - Node: "foo", - CheckID: "foo", - Name: "foo", - Status: api.HealthPassing, - ServiceID: "foo", - }, - } - if _, err := catalog.Register(reg, nil); err != nil { - t.Fatalf("err: %v", err) - } - - // we want to find this one - reg = &api.CatalogRegistration{ - Node: "bar", - Address: "2.2.2.2", - Datacenter: "dc1", - Service: &api.AgentService{ - ID: "bar", - Service: "bar", - Tags: []string{"a", "b"}, - }, - Check: &api.AgentCheck{ - Node: "bar", - CheckID: "bar", - Name: "bar", - Status: api.HealthCritical, - ServiceID: "bar", - }, - } - if _, err := catalog.Register(reg, nil); err != nil { - t.Fatalf("err: %v", err) - } - } - - // Wait for second wakeup. - <-notifyCh - - plan.Stop() - wg.Wait() - - require.Len(t, wakeups, 2) - - { - v := wakeups[0] - require.Len(t, v, 0) - } - { - v := wakeups[1] - require.Len(t, v, 1) - require.Equal(t, "bar", v[0].CheckID) - } -} - func TestEventWatch(t *testing.T) { t.Parallel() c, s := makeClient(t) diff --git a/buf.work.yaml b/buf.work.yaml index 5fab419b164bf..f89f53a2bd8a2 100644 --- a/buf.work.yaml +++ b/buf.work.yaml @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 version: v1 directories: diff --git a/build-support/docker/Build-Go.dockerfile b/build-support/docker/Build-Go.dockerfile index 884bc4894af3e..8f6748e1059d0 100644 --- a/build-support/docker/Build-Go.dockerfile +++ b/build-support/docker/Build-Go.dockerfile @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 ARG GOLANG_VERSION=1.20.10 FROM golang:${GOLANG_VERSION} diff --git a/build-support/docker/Build-UI.dockerfile b/build-support/docker/Build-UI.dockerfile index 01e8c8254b084..6682458137dce 100644 --- a/build-support/docker/Build-UI.dockerfile +++ b/build-support/docker/Build-UI.dockerfile @@ -1,11 +1,10 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 -FROM docker.mirror.hashicorp.services/node:18-alpine +FROM docker.mirror.hashicorp.services/circleci/node:16-browsers USER root -RUN apk update && apk add make RUN mkdir /consul-src WORKDIR /consul-src CMD make dist-docker diff --git a/build-support/docker/Consul-Dev-Dbg.dockerfile b/build-support/docker/Consul-Dev-Dbg.dockerfile index 488fb053264ed..cf1ae388d1f71 100644 --- a/build-support/docker/Consul-Dev-Dbg.dockerfile +++ b/build-support/docker/Consul-Dev-Dbg.dockerfile @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 FROM consul:local EXPOSE 4000 diff --git a/build-support/docker/Consul-Dev-Multiarch.dockerfile b/build-support/docker/Consul-Dev-Multiarch.dockerfile index e35a98d5f8902..265a1804cf11a 100644 --- a/build-support/docker/Consul-Dev-Multiarch.dockerfile +++ b/build-support/docker/Consul-Dev-Multiarch.dockerfile @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 ARG CONSUL_IMAGE_VERSION=latest FROM hashicorp/consul:${CONSUL_IMAGE_VERSION} diff --git a/build-support/docker/Consul-Dev.dockerfile b/build-support/docker/Consul-Dev.dockerfile index 12f014969ab51..122bc3192a7f5 100644 --- a/build-support/docker/Consul-Dev.dockerfile +++ b/build-support/docker/Consul-Dev.dockerfile @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 ARG CONSUL_IMAGE_VERSION=latest FROM hashicorp/consul:${CONSUL_IMAGE_VERSION} diff --git a/build-support/functions/00-vars.sh b/build-support/functions/00-vars.sh index ef8433c34ebb5..2f16f8ce74cab 100644 --- a/build-support/functions/00-vars.sh +++ b/build-support/functions/00-vars.sh @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # GPG Key ID to use for publically released builds HASHICORP_GPG_KEY="348FFC4C" diff --git a/build-support/functions/10-util.sh b/build-support/functions/10-util.sh index 4bb9f35a9f381..9a47ea3722dcb 100644 --- a/build-support/functions/10-util.sh +++ b/build-support/functions/10-util.sh @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 function err { if test "${COLORIZE}" -eq 1 diff --git a/build-support/functions/20-build.sh b/build-support/functions/20-build.sh index c49ff0c592986..a2e5830196b6c 100644 --- a/build-support/functions/20-build.sh +++ b/build-support/functions/20-build.sh @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 function supported_osarch { # Arguments: diff --git a/build-support/functions/30-release.sh b/build-support/functions/30-release.sh index 26f7c1048995e..d83d9f4155039 100644 --- a/build-support/functions/30-release.sh +++ b/build-support/functions/30-release.sh @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 function tag_release { # Arguments: diff --git a/build-support/scripts/build-date.sh b/build-support/scripts/build-date.sh index 49f3851bef47c..5b52bffa26473 100755 --- a/build-support/scripts/build-date.sh +++ b/build-support/scripts/build-date.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" readonly SCRIPT_DIR="$(dirname ${BASH_SOURCE[0]})" diff --git a/build-support/scripts/build-docker.sh b/build-support/scripts/build-docker.sh index d36196e66bfd0..2b72aa5fb0616 100755 --- a/build-support/scripts/build-docker.sh +++ b/build-support/scripts/build-docker.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" diff --git a/build-support/scripts/check-allowed-imports.sh b/build-support/scripts/check-allowed-imports.sh deleted file mode 100755 index 02cd8ffdee8ba..0000000000000 --- a/build-support/scripts/check-allowed-imports.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - - -readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" -readonly SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" -readonly SOURCE_DIR="$(dirname "$(dirname "${SCRIPT_DIR}")")" -readonly FN_DIR="$(dirname "${SCRIPT_DIR}")/functions" - -source "${SCRIPT_DIR}/functions.sh" - - -set -uo pipefail - -usage() { -cat <<-EOF -Usage: ${SCRIPT_NAME} [...] - -Description: - Verifies that only the specified packages may be imported from the given module - -Options: - -h | --help Print this help text. -EOF -} - -function err_usage { - err "$1" - err "" - err "$(usage)" -} - -function main { - local module_root="" - declare -a allowed_packages=() - while test $# -gt 0 - do - case "$1" in - -h | --help ) - usage - return 0 - ;; - * ) - if test -z "$module_root" - then - module_root="$1" - else - allowed_packages+=("$1") - fi - shift - esac - done - - # If we could guarantee this ran with bash 4.2+ then the final argument could - # be just ${allowed_packages[@]}. However that with older versions of bash - # in combination with set -u causes bash to emit errors about using unbound - # variables when no allowed packages have been specified (i.e. the module should - # generally be disallowed with no exceptions). This syntax is very strange - # but seems to be the prescribed workaround I found. - check_imports "$module_root" ${allowed_packages[@]+"${allowed_packages[@]}"} - return $? -} - -function check_imports { - local module_root="$1" - shift - local allowed_packages="$@" - - module_imports=$( go list -test -f '{{join .TestImports "\n"}}' ./... | grep "$module_root" | sort | uniq) - module_test_imports=$( go list -test -f '{{join .TestImports "\n"}}' ./... | grep "$module_root" | sort | uniq) - - any_error=0 - - for imp in $module_imports - do - is_import_allowed "$imp" "$module_root" $allowed_packages - allowed=$? - - if test $any_error -ne 1 - then - any_error=$allowed - fi - done - - if test $any_error -eq 1 - then - echo "Only the following direct imports are allowed from module $module_root:" - for pkg in $allowed_packages - do - echo " * $pkg" - done - fi - - return $any_error -} - -function is_import_allowed { - local pkg_import=$1 - shift - local module_root=$1 - shift - local allowed_packages="$@" - - # check if the import path is a part of the module we are restricting imports for - if test "$( go list -f '{{.Module.Path}}' $pkg_import)" != "$module_root" - then - return 0 - fi - - for pkg in $allowed_packages - do - if test "${module_root}/$pkg" == "$pkg_import" - then - return 0 - fi - done - - err "Import of package $pkg_import is not allowed" - return 1 -} - -main "$@" -exit $? \ No newline at end of file diff --git a/build-support/scripts/copywrite-exceptions.sh b/build-support/scripts/copywrite-exceptions.sh deleted file mode 100755 index f6ca45626cf23..0000000000000 --- a/build-support/scripts/copywrite-exceptions.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -# Used as a stopgap for copywrite bot in MPL-licensed subdirs, detects BUSL licensed -# headers and deletes them, then runs the copywrite bot to utilize local subdir config -# to inject correct headers. - -find . -type f -name '*.go' | while read line; do - if grep "SPDX-License-Identifier: BUSL-1.1" $line; then - sed -i '/SPDX-License-Identifier: BUSL-1.1/d' $line - sed -i '/Copyright (c) HashiCorp, Inc./d' $line - fi -done - -copywrite headers diff --git a/build-support/scripts/devtools.sh b/build-support/scripts/devtools.sh index b4cf687460d23..82cf316cb3340 100755 --- a/build-support/scripts/devtools.sh +++ b/build-support/scripts/devtools.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" @@ -124,13 +124,7 @@ function proto_tools_install { "${mog_version}" \ 'github.com/hashicorp/mog' - install_local_protoc_generator "${SOURCE_DIR}/internal/tools/protoc-gen-consul-rate-limit" - - install_local_protoc_generator "${SOURCE_DIR}/internal/resource/protoc-gen-resource-types" - - install_local_protoc_generator "${SOURCE_DIR}/internal/resource/protoc-gen-json-shim" - - install_local_protoc_generator "${SOURCE_DIR}/internal/resource/protoc-gen-deepcopy" + install_protoc_gen_consul_rate_limit return 0 } @@ -155,30 +149,14 @@ function lint_install { } function codegen_install { - deepcopy_install - copywrite_install -} - -function deepcopy_install { - local deep_copy_version - deep_copy_version="$(make --no-print-directory print-DEEP_COPY_VERSION)" - - install_versioned_tool \ - 'deep-copy' \ - 'github.com/globusdigital/deep-copy' \ - "${deep_copy_version}" \ - 'github.com/globusdigital/deep-copy' -} - -function copywrite_install { - local copywrite_version - copywrite_version="$(make --no-print-directory print-COPYWRITE_TOOL_VERSION)" + local deep_copy_version + deep_copy_version="$(make --no-print-directory print-DEEP_COPY_VERSION)" install_versioned_tool \ - 'copywrite' \ - 'github.com/hashicorp/copywrite' \ - "${copywrite_version}" \ - 'github.com/hashicorp/copywrite' + 'deep-copy' \ + 'github.com/globusdigital/deep-copy' \ + "${deep_copy_version}" \ + 'github.com/globusdigital/deep-copy' } function tools_install { @@ -186,7 +164,6 @@ function tools_install { lint_install proto_tools_install codegen_install - copywrite_install return 0 } @@ -271,10 +248,9 @@ function install_versioned_tool { return 0 } -function install_local_protoc_generator { - local src=$1 - echo "installing tool $(basename $src) from local source" - pushd -- "$src" > /dev/null +function install_protoc_gen_consul_rate_limit { + echo "installing tool protoc-gen-consul-rate-limit from local source" + pushd -- "${SOURCE_DIR}/internal/tools/protoc-gen-consul-rate-limit" > /dev/null go install popd > /dev/null } diff --git a/build-support/scripts/envoy-library-references.sh b/build-support/scripts/envoy-library-references.sh index bca15806c7e47..7f5413bbf78f8 100644 --- a/build-support/scripts/envoy-library-references.sh +++ b/build-support/scripts/envoy-library-references.sh @@ -23,7 +23,7 @@ unset CDPATH cd "$(dirname "$0")" # build-support/scripts cd ../.. # -if [[ ! -f Makefile ]] || [[ ! -f go.mod ]]; then +if [[ ! -f GNUmakefile ]] || [[ ! -f go.mod ]]; then echo "not in root consul checkout: ${PWD}" >&2 exit 1 fi diff --git a/build-support/scripts/functions.sh b/build-support/scripts/functions.sh index 4db767f13c559..42fe385c012ed 100755 --- a/build-support/scripts/functions.sh +++ b/build-support/scripts/functions.sh @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # # NOTE: This file is meant to be sourced from other bash scripts/shells diff --git a/build-support/scripts/protobuf.sh b/build-support/scripts/protobuf.sh index 20d06c807763b..420d66d6a11bd 100755 --- a/build-support/scripts/protobuf.sh +++ b/build-support/scripts/protobuf.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" @@ -72,10 +72,6 @@ function main { status "Generated gRPC rate limit mapping file" - generate_protoset_file - - status "Generated protoset file" - return 0 } @@ -156,11 +152,5 @@ function generate_rate_limit_mappings { } } -function generate_protoset_file { - local pkg_dir="${SOURCE_DIR}/pkg" - mkdir -p "$pkg_dir" - print_run buf build -o "${pkg_dir}/consul.protoset" -} - main "$@" exit $? diff --git a/build-support/scripts/release.sh b/build-support/scripts/release.sh index fa7e7c066d458..a8fbe84d89117 100755 --- a/build-support/scripts/release.sh +++ b/build-support/scripts/release.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" diff --git a/build-support/scripts/version.sh b/build-support/scripts/version.sh index 2bc9998813ed1..46630636bbfca 100755 --- a/build-support/scripts/version.sh +++ b/build-support/scripts/version.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" diff --git a/build-support/windows/Dockerfile-consul-dev-windows b/build-support/windows/Dockerfile-consul-dev-windows deleted file mode 100644 index 4e35ccb6e5eba..0000000000000 --- a/build-support/windows/Dockerfile-consul-dev-windows +++ /dev/null @@ -1,4 +0,0 @@ -ARG VERSION=1.16.0 - -FROM windows/consul:${VERSION}-local -COPY dist/ C:\\consul diff --git a/build-support/windows/Dockerfile-consul-local-windows b/build-support/windows/Dockerfile-consul-local-windows deleted file mode 100644 index 992c48c286a27..0000000000000 --- a/build-support/windows/Dockerfile-consul-local-windows +++ /dev/null @@ -1,52 +0,0 @@ -ARG VERSION=1.13.3 - -FROM windows/test-sds-server as test-sds-server -FROM docker.mirror.hashicorp.services/windows/openzipkin as openzipkin -FROM windows/consul:${VERSION} - -# Fortio binary downloaded -RUN mkdir fortio -ENV FORTIO_URL=https://github.com/fortio/fortio/releases/download/v1.33.0/fortio_win_1.33.0.zip -RUN curl %FORTIO_URL% -L -o fortio.zip -RUN tar -xf fortio.zip -C fortio - -RUN choco install openssl -yf -RUN choco install jq -yf -RUN choco install netcat -yf -RUN choco install openjdk -yf - -# Install Bats -ENV BATS_URL=https://github.com/bats-core/bats-core/archive/refs/tags/v1.7.0.zip -RUN curl %BATS_URL% -L -o bats.zip -RUN mkdir bats-core -RUN tar -xf bats.zip -C bats-core --strip-components=1 -RUN cd "C:\\Program Files\\Git\\bin" && bash.exe -c "/c/bats-core/install.sh /c/bats" - -# Install Jaeger -ENV JAEGER_URL=https://github.com/jaegertracing/jaeger/releases/download/v1.11.0/jaeger-1.11.0-windows-amd64.tar.gz -RUN curl %JAEGER_URL% -L -o jaeger.tar.gz -RUN mkdir jaeger -RUN tar -xf jaeger.tar.gz -C jaeger --strip-components=1 - -# Install Socat -ENV SOCAT_URL=https://github.com/tech128/socat-1.7.3.0-windows/archive/refs/heads/master.zip -RUN curl %SOCAT_URL% -L -o socat.zip -RUN mkdir socat -RUN tar -xf socat.zip -C socat --strip-components=1 - -# Copy test-sds-server binary and certs -COPY --from=test-sds-server ["C:/go/src/", "C:/test-sds-server/"] - -# Copy openzipkin .jar file -COPY --from=openzipkin ["C:/zipkin", "C:/zipkin"] - -EXPOSE 8300 -EXPOSE 8301 8301/udp 8302 8302/udp -EXPOSE 8500 8600 8600/udp -EXPOSE 8502 - -EXPOSE 19000 19001 19002 19003 19004 -EXPOSE 21000 21001 21002 21003 21004 -EXPOSE 5000 1234 2345 - -RUN SETX /M path "%PATH%;C:\consul;C:\fortio;C:\jaeger;C:\Program Files\Git\bin;C:\Program Files\Git\usr\bin;C:\Program Files\OpenSSL-Win64\bin;C:\bats\bin\;C:\ProgramData\chocolatey\lib\jq\tools;C:\socat" diff --git a/build-support/windows/Dockerfile-openzipkin-windows b/build-support/windows/Dockerfile-openzipkin-windows deleted file mode 100644 index b23867f0b22cf..0000000000000 --- a/build-support/windows/Dockerfile-openzipkin-windows +++ /dev/null @@ -1,12 +0,0 @@ -FROM docker.mirror.hashicorp.services/windows/openjdk:1809 - -RUN mkdir zipkin -RUN curl.exe -sSL 'https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec' -o zipkin/zipkin.jar - -EXPOSE 9410/tcp - -EXPOSE 9411/tcp - -WORKDIR /zipkin - -ENTRYPOINT ["java", "-jar", "zipkin.jar"] \ No newline at end of file diff --git a/build-support/windows/build-consul-dev-image.sh b/build-support/windows/build-consul-dev-image.sh deleted file mode 100644 index 198a5c52fceaa..0000000000000 --- a/build-support/windows/build-consul-dev-image.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - - -cd ../../ -VERSION=1.16.0 -docker build -t windows/consul:${VERSION}-dev -f build-support/windows/Dockerfile-consul-dev-windows . --build-arg VERSION=${VERSION} diff --git a/build-support/windows/build-consul-local-images.sh b/build-support/windows/build-consul-local-images.sh deleted file mode 100644 index 4a22b35706c40..0000000000000 --- a/build-support/windows/build-consul-local-images.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - - -readonly HASHICORP_DOCKER_PROXY="docker.mirror.hashicorp.services" - -# Build Consul Version 1.13.3 / 1.12.6 / 1.11.11 -VERSION=${VERSION:-"1.16.0"} -export VERSION - -# Build Windows Envoy Version 1.23.1 / 1.21.5 / 1.20.7 -ENVOY_VERSION=${ENVOY_VERSION:-"1.27.0"} -export ENVOY_VERSION - -echo "Building Images" - - -# Pull Windows Servercore image -echo " " -echo "Pull Windows Servercore image" -docker pull mcr.microsoft.com/windows/servercore:1809 -# Tag Windows Servercore image -echo " " -echo "Tag Windows Servercore image" -docker tag mcr.microsoft.com/windows/servercore:1809 "${HASHICORP_DOCKER_PROXY}/windows/servercore:1809" - - -# Pull Windows Nanoserver image -echo " " -echo "Pull Windows Nanoserver image" -docker pull mcr.microsoft.com/windows/nanoserver:1809 -# Tag Windows Nanoserver image -echo " " -echo "Tag Windows Nanoserver image" -docker tag mcr.microsoft.com/windows/nanoserver:1809 "${HASHICORP_DOCKER_PROXY}/windows/nanoserver:1809" - - -# Pull Windows OpenJDK image -echo " " -echo "Pull Windows OpenJDK image" -docker pull openjdk:windowsservercore-1809 -# Tag Windows OpenJDK image -echo " " -echo "Tag Windows OpenJDK image" -docker tag openjdk:windowsservercore-1809 "${HASHICORP_DOCKER_PROXY}/windows/openjdk:1809" - -# Pull Windows Golang image -echo " " -echo "Pull Windows Golang image" -docker pull golang:1.18.1-nanoserver-1809 -# Tag Windows Golang image -echo " " -echo "Tag Windows Golang image" -docker tag golang:1.18.1-nanoserver-1809 "${HASHICORP_DOCKER_PROXY}/windows/golang:1809" - - -# Pull Kubernetes/pause image -echo " " -echo "Pull Kubernetes/pause image" -docker pull mcr.microsoft.com/oss/kubernetes/pause:3.6 -# Tag Kubernetes/pause image -echo " " -echo "Tag Kubernetes/pause image" -docker tag mcr.microsoft.com/oss/kubernetes/pause:3.6 "${HASHICORP_DOCKER_PROXY}/windows/kubernetes/pause" - -# Pull envoy-windows image -echo " " -echo "Pull envoyproxy/envoy-windows image" -docker pull envoyproxy/envoy-windows:v${ENVOY_VERSION} -# Tag envoy-windows image -echo " " -echo "Tag envoyproxy/envoy-windows image" -docker tag envoyproxy/envoy-windows:v${ENVOY_VERSION} "${HASHICORP_DOCKER_PROXY}/windows/envoy-windows:v${ENVOY_VERSION}" - -# Build Windows Openzipkin Image -docker build -t "${HASHICORP_DOCKER_PROXY}/windows/openzipkin" -f Dockerfile-openzipkin-windows . - - -# Build Windows Test sds server Image -./build-test-sds-server-image.sh - - -# Build windows/consul:${VERSION} Image -echo " " -echo "Build windows/consul:${VERSION} Image" -docker build -t "windows/consul:${VERSION}" -f ../../Dockerfile-windows ../../ --build-arg VERSION=${VERSION} - - -# Build windows/consul:${VERSION}-local Image -echo " " -echo "Build windows/consul:${VERSION}-local Image" -docker build -t windows/consul:${VERSION}-local -f ./Dockerfile-consul-local-windows . --build-arg VERSION=${VERSION} - -echo "Building Complete!" diff --git a/build-support/windows/build-test-sds-server-image.sh b/build-support/windows/build-test-sds-server-image.sh deleted file mode 100644 index 6856c2f4394d6..0000000000000 --- a/build-support/windows/build-test-sds-server-image.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - - -cd ../../test/integration/connect/envoy - -docker build -t windows/test-sds-server -f ./Dockerfile-test-sds-server-windows test-sds-server diff --git a/build-support/windows/windows-test.md b/build-support/windows/windows-test.md deleted file mode 100644 index 5295e40757ef6..0000000000000 --- a/build-support/windows/windows-test.md +++ /dev/null @@ -1,119 +0,0 @@ -# Dockerfiles for Windows Integration Tests - -## Index - -- [About](#about-this-file) -- [Consul Windows](#consul-windows) -- [Consul Windows Local](#consul-windows-local) -- [Consul Windows Dev](#consul-windows-dev) -- [Dockerfile-openzipkin-windows](#dockerfile-openzipkin-windows) - -## About this File - -In this file you will find which Docker images that need to be pre-built to run the Envoy integration tests on Windows, as well as information on how to run each of these files individually for testing purposes. - -## Consul Windows - -The Windows/Consul:_{VERSION}_ image is built from the "Dockerfile-windows" file located at the root of the project. -To do this, the official [windows/servercore image](https://hub.docker.com/_/microsoft-windows-servercore) is used as base image. -To build the image, use the following command: - -```shell -docker build -t windows/consul -f Dockerfile-windows . --build-arg VERSION=${VERSION} -``` - -You can test the built file by running the following command: - -```shell -docker run --rm -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8500:8500 -p 8600:8600 --name consul --hostname "consul-primary-server" --network-alias "consul-primary-server" windows/consul agent -dev -datacenter "primary" -grpc-port -1 -client "0.0.0.0" -bind "0.0.0.0" -``` - -If everything works properly you should openning the browser and check the Consul UI running on: `http://localhost:8500` - -## Consul Windows Local - -The Windows/Consul:_{VERSION}_-local custom image deployed in the "Dockerfile-consul-local-windows" DockerFile is built from the selected by the shell script _build-consul-local-images.sh_. -When executing it, all the tools required to run the Windows Connect Envoy Integration Tests will be added to the image. -It is necessary that the _"windows/consul"_ image has been built first. This script also takes care of that. - -To build this image you need to run the following command on your terminal: - -```shell -./build-consul-local-images.sh -``` - -> [!NOTE] -> Shell script execution may vary depending on your terminal, we recommend using **Git Bash** for Windows. - -```shell -docker run --rm -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8500:8500 -p 8600:8600 --name consul-local --hostname "consul-primary-server" --network-alias "consul-primary-server" windows/consul:_{VERSION}_-local agent -dev -datacenter "primary" -grpc-port -1 -client "0.0.0.0" -bind "0.0.0.0" -``` - -If everything works properly you can use your browser and check the Consul UI running on: `http://localhost:8500` - -## Consul Windows Dev - -The Windows/Consul:_{VERSION}_-dev custom image deployed in the "Dockerfile-consul-dev-windows" DockerFile is generated by the shell script named _build-consul-dev-image.sh_. -When executing it, the compilation of Consul is carried out and it is saved in the _"dist"_ directory, this file is then copied to the _"windows/consul:_{VERSION}_-dev"_ image. -It is necessary that the _"windows/consul_{VERSION}_-local"_ image has been built first. - -To build this image you need to run the following command on your terminal: - -```shell -./build-consul-dev-image.sh -``` - -> [!NOTE] -> Shell script execution may vary depending on your terminal, we recommend using **Git Bash** for Windows. - -You can test the built file by running the following command: - -```shell -docker run --rm -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8500:8500 -p 8600:8600 --name consul-local --hostname "consul-primary-server" --network-alias "consul-primary-server" windows/consul:_{VERSION}_-dev agent -dev -datacenter "primary" -grpc-port -1 -client "0.0.0.0" -bind "0.0.0.0" -``` - -If everything works properly you can use your browser and check the Consul UI running on: `http://localhost:8500` - -## Dockerfile-openzipkin-windows - -Due to the unavailability of an official Openzipkin Docker image for Windows, the [openjdk Windows image](https://hub.docker.com/layers/openjdk/library/openjdk/jdk-windowsservercore-1809/images/sha256-b0cc238d2ec5fb58109a0006ff9e1bcaf66a5301f49bcb8dece9599ac5be6331) was used, where the latest self-contained executable Openzipkin .jar file is downloaded. - -To build this image you need to run the following command on your terminal: - -```shell -docker build -t openzipkin -f Dockerfile-openzipkin-windows . -``` - -You can test the built file by running the following command: - -```shell -docker run --rm --name openzipkin -``` - -If everything works as it should, you will see the zipkin logo being displayed, along with the current version and port configuration: - -```shell -:: version 2.23.18 :: commit 4b71677 :: - -20XX-XX-XX XX:XX:XX.XXX INFO [/] 1252 --- [oss-http-*:9411] c.l.a.s.Server : Serving HTTP at /[0:0:0:0:0:0:0:0]:9411 - http://127.0.0.1:9411/ -``` - -# Testing - -During development, it may be more convenient to check your work-in-progress by running only the tests which you expect to be affected by your changes, as the full test suite can take several minutes to execute. [Go's built-in test tool](https://golang.org/pkg/cmd/go/internal/test/) allows specifying a list of packages to test and the `-run` option to only include test names matching a regular expression. -The `go test -short` flag can also be used to skip slower tests. - -Examples (run from the repository root): - -- `go test -v ./connect` will run all tests in the connect package (see `./connect` folder) -- `go test -v -run TestRetryJoin ./command/agent` will run all tests in the agent package (see `./command/agent` folder) with name substring `TestRetryJoin` - -When a pull request is opened CI will run all tests and lint to verify the change. - -If you want to run the tests on Windows images you must attach the win=true flag. - -Example: - -```shell -go test -v -timeout=30m -tags integration ./test/integration/connect/envoy -run="TestEnvoy/case-badauthz" -win=true -``` diff --git a/command/acl/acl.go b/command/acl/acl.go index 745fa78175d5e..71ef8c9a06171 100644 --- a/command/acl/acl.go +++ b/command/acl/acl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/command/acl/acl_helpers.go b/command/acl/acl_helpers.go index 9dd40e9e0ee62..b0e65d224c756 100644 --- a/command/acl/acl_helpers.go +++ b/command/acl/acl_helpers.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl @@ -10,9 +10,6 @@ import ( "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/command/helpers" - "github.com/hashicorp/hcl" - "github.com/mitchellh/mapstructure" ) func GetTokenAccessorIDFromPartial(client *api.Client, partialAccessorID string) (string, error) { @@ -221,79 +218,6 @@ func ExtractNodeIdentities(nodeIdents []string) ([]*api.ACLNodeIdentity, error) return out, nil } -func ExtractTemplatedPolicies(templatedPolicy string, templatedPolicyFile string, templatedPolicyVariables []string) ([]*api.ACLTemplatedPolicy, error) { - var out []*api.ACLTemplatedPolicy - if templatedPolicy == "" && templatedPolicyFile == "" { - return out, nil - } - - if templatedPolicy != "" { - parsedVariables, err := getTemplatedPolicyVariables(templatedPolicyVariables) - if err != nil { - return nil, err - } - - out = append(out, &api.ACLTemplatedPolicy{ - TemplateName: templatedPolicy, - TemplateVariables: parsedVariables, - }) - } - - if templatedPolicyFile != "" { - fileData, err := helpers.LoadFromFile(templatedPolicyFile) - if err != nil { - return nil, err - } - - var config map[string]map[string][]api.ACLTemplatedPolicyVariables - err = hcl.Decode(&config, fileData) - if err != nil { - return nil, err - } - - for templateName, templateVariables := range config["TemplatedPolicy"] { - for _, tp := range templateVariables { - out = append(out, &api.ACLTemplatedPolicy{ - TemplateName: templateName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{ - Name: tp.Name, - }, - }) - } - } - } - return out, nil -} - -func ExtractBindVars(bindVars map[string]string) (*api.ACLTemplatedPolicyVariables, error) { - if len(bindVars) == 0 { - return nil, nil - } - out := &api.ACLTemplatedPolicyVariables{} - err := mapstructure.Decode(bindVars, out) - return out, err -} - -func getTemplatedPolicyVariables(variables []string) (*api.ACLTemplatedPolicyVariables, error) { - if len(variables) == 0 { - return nil, nil - } - - out := &api.ACLTemplatedPolicyVariables{} - jsonVariables := make(map[string]string) - - for _, variable := range variables { - parts := strings.Split(variable, ":") - if len(parts) != 2 { - return nil, fmt.Errorf("malformed -var argument: %q, expecting VariableName:Value", variable) - } - jsonVariables[parts[0]] = parts[1] - } - - err := mapstructure.Decode(jsonVariables, out) - return out, err -} - // TestKubernetesJWT_A is a valid service account jwt extracted from a minikube setup. // // { diff --git a/command/acl/acl_test.go b/command/acl/acl_test.go index c2a46f18b0423..2095795ff00be 100644 --- a/command/acl/acl_test.go +++ b/command/acl/acl_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package acl diff --git a/command/acl/agenttokens/agent_tokens.go b/command/acl/agenttokens/agent_tokens.go index 8aca79e5d0064..4e4a359ace77d 100644 --- a/command/acl/agenttokens/agent_tokens.go +++ b/command/acl/agenttokens/agent_tokens.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agenttokens @@ -8,10 +8,9 @@ import ( "fmt" "io" - "github.com/mitchellh/cli" - "github.com/hashicorp/consul/command/flags" "github.com/hashicorp/consul/command/helpers" + "github.com/mitchellh/cli" ) func New(ui cli.Ui) *cmd { @@ -64,8 +63,6 @@ func (c *cmd) Run(args []string) int { _, err = client.Agent().UpdateReplicationACLToken(token, nil) case "config_file_service_registration": _, err = client.Agent().UpdateConfigFileRegistrationToken(token, nil) - case "dns": - _, err = client.Agent().UpdateDNSToken(token, nil) default: c.UI.Error(fmt.Sprintf("Unknown token type")) return 1 @@ -143,11 +140,6 @@ Usage: consul acl set-agent-token [options] TYPE TOKEN If a service or check definition contains a 'token' field, then that token is used instead. - dns This is the token that the will be used in place of the default - token when specified for DNS requests and for DNS-specific RPCs. - If not provided the agent will attempt to use the default token - if one is present, then fallback to the anonymous token. - Example: $ consul acl set-agent-token default c4d0f8df-3aba-4ab6-a7a0-35b760dc29a1 diff --git a/command/acl/agenttokens/agent_tokens_test.go b/command/acl/agenttokens/agent_tokens_test.go index 84f7fa3358011..d735b66d83a37 100644 --- a/command/acl/agenttokens/agent_tokens_test.go +++ b/command/acl/agenttokens/agent_tokens_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agenttokens diff --git a/command/acl/authmethod/authmethod.go b/command/acl/authmethod/authmethod.go index 18b9e58c2633a..897498024c84e 100644 --- a/command/acl/authmethod/authmethod.go +++ b/command/acl/authmethod/authmethod.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethod diff --git a/command/acl/authmethod/create/authmethod_create.go b/command/acl/authmethod/create/authmethod_create.go index 17f328d2b8be5..912a647d41155 100644 --- a/command/acl/authmethod/create/authmethod_create.go +++ b/command/acl/authmethod/create/authmethod_create.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethodcreate diff --git a/command/acl/authmethod/create/authmethod_create_ce.go b/command/acl/authmethod/create/authmethod_create_ce.go index a655cf0b3532d..ff2d488897eda 100644 --- a/command/acl/authmethod/create/authmethod_create_ce.go +++ b/command/acl/authmethod/create/authmethod_create_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package authmethodcreate diff --git a/command/acl/authmethod/create/authmethod_create_test.go b/command/acl/authmethod/create/authmethod_create_test.go index b9392544929af..b0d6a8cfe181b 100644 --- a/command/acl/authmethod/create/authmethod_create_test.go +++ b/command/acl/authmethod/create/authmethod_create_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethodcreate diff --git a/command/acl/authmethod/delete/authmethod_delete.go b/command/acl/authmethod/delete/authmethod_delete.go index e3ccd0efdd01e..44548a5983746 100644 --- a/command/acl/authmethod/delete/authmethod_delete.go +++ b/command/acl/authmethod/delete/authmethod_delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethoddelete diff --git a/command/acl/authmethod/delete/authmethod_delete_test.go b/command/acl/authmethod/delete/authmethod_delete_test.go index fc513fde7ebd4..45bd3ac561cd8 100644 --- a/command/acl/authmethod/delete/authmethod_delete_test.go +++ b/command/acl/authmethod/delete/authmethod_delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethoddelete diff --git a/command/acl/authmethod/formatter.go b/command/acl/authmethod/formatter.go index 6a22443d58dd4..3204af910b714 100644 --- a/command/acl/authmethod/formatter.go +++ b/command/acl/authmethod/formatter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethod diff --git a/command/acl/authmethod/list/authmethod_list.go b/command/acl/authmethod/list/authmethod_list.go index cae9916c12b29..1bcf24b75a638 100644 --- a/command/acl/authmethod/list/authmethod_list.go +++ b/command/acl/authmethod/list/authmethod_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethodlist diff --git a/command/acl/authmethod/list/authmethod_list_test.go b/command/acl/authmethod/list/authmethod_list_test.go index cd1aa2ac767b8..9064b252cd447 100644 --- a/command/acl/authmethod/list/authmethod_list_test.go +++ b/command/acl/authmethod/list/authmethod_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethodlist diff --git a/command/acl/authmethod/read/authmethod_read.go b/command/acl/authmethod/read/authmethod_read.go index 72d3a6f181634..b7860ca0660d2 100644 --- a/command/acl/authmethod/read/authmethod_read.go +++ b/command/acl/authmethod/read/authmethod_read.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethodread diff --git a/command/acl/authmethod/read/authmethod_read_test.go b/command/acl/authmethod/read/authmethod_read_test.go index 20a18c76dfdae..a24c1d2e55f21 100644 --- a/command/acl/authmethod/read/authmethod_read_test.go +++ b/command/acl/authmethod/read/authmethod_read_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethodread diff --git a/command/acl/authmethod/update/authmethod_update.go b/command/acl/authmethod/update/authmethod_update.go index 1c5422e88dea2..2798e6e6da8f6 100644 --- a/command/acl/authmethod/update/authmethod_update.go +++ b/command/acl/authmethod/update/authmethod_update.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethodupdate diff --git a/command/acl/authmethod/update/authmethod_update_ce.go b/command/acl/authmethod/update/authmethod_update_ce.go index e0345eb6a78d4..c1ea32042473e 100644 --- a/command/acl/authmethod/update/authmethod_update_ce.go +++ b/command/acl/authmethod/update/authmethod_update_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package authmethodupdate diff --git a/command/acl/authmethod/update/authmethod_update_test.go b/command/acl/authmethod/update/authmethod_update_test.go index 87ddf2f2c0bc4..e85f270cdf699 100644 --- a/command/acl/authmethod/update/authmethod_update_test.go +++ b/command/acl/authmethod/update/authmethod_update_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package authmethodupdate diff --git a/command/acl/bindingrule/bindingrule.go b/command/acl/bindingrule/bindingrule.go index 8d23e3ee37fab..782041e1ac672 100644 --- a/command/acl/bindingrule/bindingrule.go +++ b/command/acl/bindingrule/bindingrule.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingrule diff --git a/command/acl/bindingrule/create/bindingrule_create.go b/command/acl/bindingrule/create/bindingrule_create.go index ab6a16f3ed5c3..d5253c456e79d 100644 --- a/command/acl/bindingrule/create/bindingrule_create.go +++ b/command/acl/bindingrule/create/bindingrule_create.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingrulecreate @@ -9,7 +9,6 @@ import ( "strings" "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/command/acl" "github.com/hashicorp/consul/command/acl/bindingrule" "github.com/hashicorp/consul/command/flags" "github.com/mitchellh/cli" @@ -32,7 +31,6 @@ type cmd struct { selector string bindType string bindName string - bindVars map[string]string showMeta bool format string @@ -73,14 +71,7 @@ func (c *cmd) init() { &c.bindType, "bind-type", string(api.BindingRuleBindTypeService), - "Type of binding to perform (\"service\", \"role\", \"node\" or \"templated-policy\").", - ) - c.flags.Var( - (*flags.FlagMapValue)(&c.bindVars), - "bind-vars", - "Templated policy variables. Can only be used when -bind-type is templated-policy."+ - " May be specified multiple times with different variables. Can use ${var} interpolation."+ - " Format is VariableName=Value", + "Type of binding to perform (\"service\" or \"role\").", ) c.flags.StringVar( &c.bindName, @@ -109,28 +100,15 @@ func (c *cmd) Run(args []string) int { } if c.authMethodName == "" { - c.UI.Error("Missing required '-method' flag") + c.UI.Error(fmt.Sprintf("Missing required '-method' flag")) c.UI.Error(c.Help()) return 1 } else if c.bindType == "" { - c.UI.Error("Missing required '-bind-type' flag") + c.UI.Error(fmt.Sprintf("Missing required '-bind-type' flag")) c.UI.Error(c.Help()) return 1 } else if c.bindName == "" { - c.UI.Error("Missing required '-bind-name' flag") - c.UI.Error(c.Help()) - return 1 - } - - if api.BindingRuleBindType(c.bindType) != api.BindingRuleBindTypeTemplatedPolicy && len(c.bindVars) > 0 { - c.UI.Error("Cannot specify -bind-vars when -bind-type is not templated-policy") - c.UI.Error(c.Help()) - return 1 - } - - processBindVars, err := acl.ExtractBindVars(c.bindVars) - if err != nil { - c.UI.Error("Failed to decode '-bind-vars'") + c.UI.Error(fmt.Sprintf("Missing required '-bind-name' flag")) c.UI.Error(c.Help()) return 1 } @@ -140,7 +118,6 @@ func (c *cmd) Run(args []string) int { AuthMethod: c.authMethodName, BindType: api.BindingRuleBindType(c.bindType), BindName: c.bindName, - BindVars: processBindVars, Selector: c.selector, } diff --git a/command/acl/bindingrule/create/bindingrule_create_test.go b/command/acl/bindingrule/create/bindingrule_create_test.go index 07a92851a2e5f..43189f784c128 100644 --- a/command/acl/bindingrule/create/bindingrule_create_test.go +++ b/command/acl/bindingrule/create/bindingrule_create_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingrulecreate @@ -106,24 +106,6 @@ func TestBindingRuleCreateCommand(t *testing.T) { require.Contains(t, ui.ErrorWriter.String(), "Missing required '-bind-name' flag") }) - t.Run("bind vars specified when by bindtype is not templated-policy", func(t *testing.T) { - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-method=test", - "-bind-name=web", - "-bind-type=service", - "-bind-vars", "name=test", - } - - ui := cli.NewMockUi() - cmd := New(ui) - - code := cmd.Run(args) - require.Equal(t, code, 1) - require.Contains(t, ui.ErrorWriter.String(), "Cannot specify -bind-vars when -bind-type is not templated-policy") - }) - t.Run("must use roughly valid selector", func(t *testing.T) { args := []string{ "-http-addr=" + a.HTTPAddr(), @@ -194,41 +176,6 @@ func TestBindingRuleCreateCommand(t *testing.T) { require.Equal(t, code, 0) require.Empty(t, ui.ErrorWriter.String()) }) - - t.Run("create it with type templated policy", func(t *testing.T) { - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-method=test", - "-bind-type=templated-policy", - "-bind-name=builtin/service", - "-bind-vars", "name=api", - } - - ui := cli.NewMockUi() - cmd := New(ui) - - code := cmd.Run(args) - require.Equal(t, code, 0) - require.Empty(t, ui.ErrorWriter.String()) - }) - - t.Run("cannot create when missing bind-vars", func(t *testing.T) { - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-method=test", - "-bind-type=templated-policy", - "-bind-name=builtin/service", - } - - ui := cli.NewMockUi() - cmd := New(ui) - - code := cmd.Run(args) - require.Equal(t, code, 1) - require.Contains(t, ui.ErrorWriter.String(), "templated policy failed validation") - }) } func TestBindingRuleCreateCommand_JSON(t *testing.T) { diff --git a/command/acl/bindingrule/delete/bindingrule_delete.go b/command/acl/bindingrule/delete/bindingrule_delete.go index 3fc02d788b4b6..ffb22fc73d357 100644 --- a/command/acl/bindingrule/delete/bindingrule_delete.go +++ b/command/acl/bindingrule/delete/bindingrule_delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingruledelete diff --git a/command/acl/bindingrule/delete/bindingrule_delete_test.go b/command/acl/bindingrule/delete/bindingrule_delete_test.go index 9655fbb101a4c..abd10f8add5d7 100644 --- a/command/acl/bindingrule/delete/bindingrule_delete_test.go +++ b/command/acl/bindingrule/delete/bindingrule_delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingruledelete diff --git a/command/acl/bindingrule/formatter.go b/command/acl/bindingrule/formatter.go index 7bf01d9a3db6b..1fb1feeafcc1c 100644 --- a/command/acl/bindingrule/formatter.go +++ b/command/acl/bindingrule/formatter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingrule @@ -63,10 +63,6 @@ func (f *prettyFormatter) FormatBindingRule(rule *api.ACLBindingRule) (string, e buffer.WriteString(fmt.Sprintf("Description: %s\n", rule.Description)) buffer.WriteString(fmt.Sprintf("BindType: %s\n", rule.BindType)) buffer.WriteString(fmt.Sprintf("BindName: %s\n", rule.BindName)) - if rule.BindVars != nil && rule.BindVars.Name != "" { - buffer.WriteString(fmt.Sprintf("BindVars: \n - Name: %s\n", rule.BindVars.Name)) - } - buffer.WriteString(fmt.Sprintf("Selector: %s\n", rule.Selector)) if f.showMeta { buffer.WriteString(fmt.Sprintf("Create Index: %d\n", rule.CreateIndex)) @@ -100,9 +96,6 @@ func (f *prettyFormatter) formatBindingRuleListEntry(rule *api.ACLBindingRule) s buffer.WriteString(fmt.Sprintf(" Description: %s\n", rule.Description)) buffer.WriteString(fmt.Sprintf(" BindType: %s\n", rule.BindType)) buffer.WriteString(fmt.Sprintf(" BindName: %s\n", rule.BindName)) - if rule.BindVars != nil && rule.BindVars.Name != "" { - buffer.WriteString(fmt.Sprintf(" BindVars: \n - Name: %s\n", rule.BindVars.Name)) - } buffer.WriteString(fmt.Sprintf(" Selector: %s\n", rule.Selector)) if f.showMeta { buffer.WriteString(fmt.Sprintf(" Create Index: %d\n", rule.CreateIndex)) diff --git a/command/acl/bindingrule/list/bindingrule_list.go b/command/acl/bindingrule/list/bindingrule_list.go index 15f395afdf2f6..2f6529af5d08d 100644 --- a/command/acl/bindingrule/list/bindingrule_list.go +++ b/command/acl/bindingrule/list/bindingrule_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingrulelist diff --git a/command/acl/bindingrule/list/bindingrule_list_test.go b/command/acl/bindingrule/list/bindingrule_list_test.go index 22035341e4248..bbb1188f8a0f4 100644 --- a/command/acl/bindingrule/list/bindingrule_list_test.go +++ b/command/acl/bindingrule/list/bindingrule_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingrulelist diff --git a/command/acl/bindingrule/read/bindingrule_read.go b/command/acl/bindingrule/read/bindingrule_read.go index 0ff55bd4ac2b8..25858d64851f1 100644 --- a/command/acl/bindingrule/read/bindingrule_read.go +++ b/command/acl/bindingrule/read/bindingrule_read.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingruleread diff --git a/command/acl/bindingrule/read/bindingrule_read_test.go b/command/acl/bindingrule/read/bindingrule_read_test.go index 4a324edf23174..9e1615e003b95 100644 --- a/command/acl/bindingrule/read/bindingrule_read_test.go +++ b/command/acl/bindingrule/read/bindingrule_read_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingruleread diff --git a/command/acl/bindingrule/update/bindingrule_update.go b/command/acl/bindingrule/update/bindingrule_update.go index ce7006748728d..59998059f476d 100644 --- a/command/acl/bindingrule/update/bindingrule_update.go +++ b/command/acl/bindingrule/update/bindingrule_update.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingruleupdate @@ -34,7 +34,6 @@ type cmd struct { selector string bindType string bindName string - bindVars map[string]string noMerge bool showMeta bool @@ -103,14 +102,6 @@ func (c *cmd) init() { fmt.Sprintf("Output format {%s}", strings.Join(bindingrule.GetSupportedFormats(), "|")), ) - c.flags.Var( - (*flags.FlagMapValue)(&c.bindVars), - "bind-vars", - "Templated policy variables. Can only be used when -bind-type is templated-policy."+ - " May be specified multiple times with different variables. Can use ${var} interpolation."+ - " Format is VariableName=Value", - ) - c.http = &flags.HTTPFlags{} flags.Merge(c.flags, c.http.ClientFlags()) flags.Merge(c.flags, c.http.ServerFlags()) @@ -124,7 +115,7 @@ func (c *cmd) Run(args []string) int { } if c.ruleID == "" { - c.UI.Error("Cannot update a binding rule without specifying the -id parameter") + c.UI.Error(fmt.Sprintf("Cannot update a binding rule without specifying the -id parameter")) return 1 } @@ -150,25 +141,14 @@ func (c *cmd) Run(args []string) int { return 1 } - processBindVars, err := acl.ExtractBindVars(c.bindVars) - if err != nil { - c.UI.Error("Failed to decode '-bind-vars'") - c.UI.Error(c.Help()) - return 1 - } - var rule *api.ACLBindingRule if c.noMerge { if c.bindType == "" { - c.UI.Error("Missing required '-bind-type' flag") + c.UI.Error(fmt.Sprintf("Missing required '-bind-type' flag")) c.UI.Error(c.Help()) return 1 } else if c.bindName == "" { - c.UI.Error("Missing required '-bind-name' flag") - c.UI.Error(c.Help()) - return 1 - } else if len(c.bindVars) > 0 && api.BindingRuleBindType(c.bindType) != api.BindingRuleBindTypeTemplatedPolicy { - c.UI.Error("-bind-vars cannot be specified when -bind-type is not templated-policy") + c.UI.Error(fmt.Sprintf("Missing required '-bind-name' flag")) c.UI.Error(c.Help()) return 1 } @@ -178,7 +158,6 @@ func (c *cmd) Run(args []string) int { AuthMethod: currentRule.AuthMethod, // immutable Description: c.description, BindType: api.BindingRuleBindType(c.bindType), - BindVars: processBindVars, BindName: c.bindName, Selector: c.selector, } @@ -195,14 +174,6 @@ func (c *cmd) Run(args []string) int { if c.bindName != "" { rule.BindName = c.bindName } - if len(c.bindVars) > 0 { - rule.BindVars = processBindVars - } - // remove bind vars for non templated-policy binding rules types - if api.BindingRuleBindType(c.bindType) != api.BindingRuleBindTypeTemplatedPolicy { - rule.BindVars = nil - } - if isFlagSet(c.flags, "selector") { rule.Selector = c.selector // empty is valid } diff --git a/command/acl/bindingrule/update/bindingrule_update_test.go b/command/acl/bindingrule/update/bindingrule_update_test.go index 1bbcd35cc25d9..2f7437edcd333 100644 --- a/command/acl/bindingrule/update/bindingrule_update_test.go +++ b/command/acl/bindingrule/update/bindingrule_update_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bindingruleupdate @@ -127,24 +127,15 @@ func TestBindingRuleUpdateCommand(t *testing.T) { require.Contains(t, ui.ErrorWriter.String(), "Binding rule not found with ID") }) - createRule := func(t *testing.T, isTemplatedPolicy bool) string { - bindingRule := &api.ACLBindingRule{ - AuthMethod: "test", - Description: "test rule", - BindType: api.BindingRuleBindTypeService, - BindName: "test-${serviceaccount.name}", - Selector: "serviceaccount.namespace==default", - } - if isTemplatedPolicy { - bindingRule.BindType = api.BindingRuleBindTypeTemplatedPolicy - bindingRule.BindName = api.ACLTemplatedPolicyServiceName - bindingRule.BindVars = &api.ACLTemplatedPolicyVariables{ - Name: "test-${serviceaccount.name}", - } - } - + createRule := func(t *testing.T) string { rule, _, err := client.ACL().BindingRuleCreate( - bindingRule, + &api.ACLBindingRule{ + AuthMethod: "test", + Description: "test rule", + BindType: api.BindingRuleBindTypeService, + BindName: "test-${serviceaccount.name}", + Selector: "serviceaccount.namespace==default", + }, &api.WriteOptions{Token: "root"}, ) require.NoError(t, err) @@ -170,7 +161,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { m[c] = struct{}{} } - _ = createRule(t, false) + _ = createRule(t) } } @@ -192,7 +183,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { }) t.Run("must use roughly valid selector", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) args := []string{ "-http-addr=" + a.HTTPAddr(), @@ -210,7 +201,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { }) t.Run("update all fields", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -242,79 +233,10 @@ func TestBindingRuleUpdateCommand(t *testing.T) { require.Equal(t, "serviceaccount.namespace==alt and serviceaccount.name==demo", rule.Selector) }) - t.Run("update all fields with templated policy", func(t *testing.T) { - id := createRule(t, false) - - ui := cli.NewMockUi() - cmd := New(ui) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-id", id, - "-description=test rule edited", - "-bind-type", "templated-policy", - "-bind-name=builtin/service", - "-bind-vars", "name=api", - "-selector=serviceaccount.namespace==alt and serviceaccount.name==demo", - } - - code := cmd.Run(args) - require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) - require.Empty(t, ui.ErrorWriter.String()) - - rule, _, err := client.ACL().BindingRuleRead( - id, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, rule) - - require.Equal(t, "test rule edited", rule.Description) - require.Equal(t, api.ACLTemplatedPolicyServiceName, rule.BindName) - require.Equal(t, api.BindingRuleBindTypeTemplatedPolicy, rule.BindType) - require.Equal(t, &api.ACLTemplatedPolicyVariables{Name: "api"}, rule.BindVars) - require.Equal(t, "serviceaccount.namespace==alt and serviceaccount.name==demo", rule.Selector) - }) - - t.Run("update bind type to something other than templated-policy unsets bindvars", func(t *testing.T) { - id := createRule(t, true) - - ui := cli.NewMockUi() - cmd := New(ui) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-id", id, - "-description=test rule edited", - "-bind-type", "role", - "-bind-name=role-updated", - "-selector=serviceaccount.namespace==alt and serviceaccount.name==demo", - } - - code := cmd.Run(args) - require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) - require.Empty(t, ui.ErrorWriter.String()) - - rule, _, err := client.ACL().BindingRuleRead( - id, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, rule) - - require.Equal(t, "test rule edited", rule.Description) - require.Equal(t, "role-updated", rule.BindName) - require.Equal(t, api.BindingRuleBindTypeRole, rule.BindType) - require.Empty(t, rule.BindVars) - require.Equal(t, "serviceaccount.namespace==alt and serviceaccount.name==demo", rule.Selector) - }) - t.Run("update all fields - partial", func(t *testing.T) { deleteRules(t) // reset since we created a bunch that might be dupes - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -347,7 +269,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { }) t.Run("update all fields but description", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -379,7 +301,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { }) t.Run("update all fields but bind name", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -411,7 +333,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { }) t.Run("update all fields but must exist", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -443,7 +365,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { }) t.Run("update all fields but selector", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -475,7 +397,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { }) t.Run("update all fields clear selector", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -508,7 +430,7 @@ func TestBindingRuleUpdateCommand(t *testing.T) { }) t.Run("update all fields json formatted", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -649,25 +571,15 @@ func TestBindingRuleUpdateCommand_noMerge(t *testing.T) { require.Contains(t, ui.ErrorWriter.String(), "Binding rule not found with ID") }) - createRule := func(t *testing.T, isTemplatedPolicy bool) string { - bindingRule := &api.ACLBindingRule{ - AuthMethod: "test", - Description: "test rule", - BindType: api.BindingRuleBindTypeRole, - BindName: "test-${serviceaccount.name}", - Selector: "serviceaccount.namespace==default", - } - - if isTemplatedPolicy { - bindingRule.BindType = api.BindingRuleBindTypeTemplatedPolicy - bindingRule.BindName = "builtin/service" - bindingRule.BindVars = &api.ACLTemplatedPolicyVariables{ - Name: "test-${serviceaccount.name}", - } - } - + createRule := func(t *testing.T) string { rule, _, err := client.ACL().BindingRuleCreate( - bindingRule, + &api.ACLBindingRule{ + AuthMethod: "test", + Description: "test rule", + BindType: api.BindingRuleBindTypeRole, + BindName: "test-${serviceaccount.name}", + Selector: "serviceaccount.namespace==default", + }, &api.WriteOptions{Token: "root"}, ) require.NoError(t, err) @@ -693,7 +605,7 @@ func TestBindingRuleUpdateCommand_noMerge(t *testing.T) { m[c] = struct{}{} } - _ = createRule(t, false) + _ = createRule(t) } } @@ -716,7 +628,7 @@ func TestBindingRuleUpdateCommand_noMerge(t *testing.T) { }) t.Run("must use roughly valid selector", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -738,41 +650,7 @@ func TestBindingRuleUpdateCommand_noMerge(t *testing.T) { }) t.Run("update all fields", func(t *testing.T) { - id := createRule(t, false) - - ui := cli.NewMockUi() - cmd := New(ui) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-no-merge", - "-id", id, - "-description=test rule edited", - "-bind-type", "service", - "-bind-name=role-updated", - "-selector=serviceaccount.namespace==alt and serviceaccount.name==demo", - } - - code := cmd.Run(args) - require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) - require.Empty(t, ui.ErrorWriter.String()) - - rule, _, err := client.ACL().BindingRuleRead( - id, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, rule) - - require.Equal(t, "test rule edited", rule.Description) - require.Equal(t, api.BindingRuleBindTypeService, rule.BindType) - require.Equal(t, "role-updated", rule.BindName) - require.Equal(t, "serviceaccount.namespace==alt and serviceaccount.name==demo", rule.Selector) - }) - - t.Run("update all fields after initial binding rule is templated-policy", func(t *testing.T) { - id := createRule(t, true) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -801,51 +679,14 @@ func TestBindingRuleUpdateCommand_noMerge(t *testing.T) { require.Equal(t, "test rule edited", rule.Description) require.Equal(t, api.BindingRuleBindTypeService, rule.BindType) - require.Empty(t, rule.BindVars) require.Equal(t, "role-updated", rule.BindName) require.Equal(t, "serviceaccount.namespace==alt and serviceaccount.name==demo", rule.Selector) }) - t.Run("update all fields with templated-policy bind type", func(t *testing.T) { - id := createRule(t, false) - - ui := cli.NewMockUi() - cmd := New(ui) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-no-merge", - "-id", id, - "-description=test rule edited", - "-bind-type=templated-policy", - "-bind-name=builtin/service", - "-bind-vars", "name=api", - "-selector=serviceaccount.namespace==alt and serviceaccount.name==demo", - } - - code := cmd.Run(args) - require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) - require.Empty(t, ui.ErrorWriter.String()) - - rule, _, err := client.ACL().BindingRuleRead( - id, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, rule) - - require.Equal(t, "test rule edited", rule.Description) - require.Equal(t, api.BindingRuleBindTypeTemplatedPolicy, rule.BindType) - require.Equal(t, api.ACLTemplatedPolicyServiceName, rule.BindName) - require.Equal(t, &api.ACLTemplatedPolicyVariables{Name: "api"}, rule.BindVars) - require.Equal(t, "serviceaccount.namespace==alt and serviceaccount.name==demo", rule.Selector) - }) - t.Run("update all fields - partial", func(t *testing.T) { deleteRules(t) // reset since we created a bunch that might be dupes - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -879,7 +720,7 @@ func TestBindingRuleUpdateCommand_noMerge(t *testing.T) { }) t.Run("update all fields but description", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -912,7 +753,7 @@ func TestBindingRuleUpdateCommand_noMerge(t *testing.T) { }) t.Run("missing bind name", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) @@ -932,7 +773,7 @@ func TestBindingRuleUpdateCommand_noMerge(t *testing.T) { }) t.Run("update all fields but selector", func(t *testing.T) { - id := createRule(t, false) + id := createRule(t) ui := cli.NewMockUi() cmd := New(ui) diff --git a/command/acl/bootstrap/bootstrap.go b/command/acl/bootstrap/bootstrap.go index 2a2bfd3716d32..2f608bbdab347 100644 --- a/command/acl/bootstrap/bootstrap.go +++ b/command/acl/bootstrap/bootstrap.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bootstrap diff --git a/command/acl/bootstrap/bootstrap_test.go b/command/acl/bootstrap/bootstrap_test.go index e9a0e8cebee2a..ef5fcf41dc7aa 100644 --- a/command/acl/bootstrap/bootstrap_test.go +++ b/command/acl/bootstrap/bootstrap_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package bootstrap diff --git a/command/acl/policy/create/policy_create.go b/command/acl/policy/create/policy_create.go index a172b17fbb1ac..131d096b1cf25 100644 --- a/command/acl/policy/create/policy_create.go +++ b/command/acl/policy/create/policy_create.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policycreate @@ -71,7 +71,7 @@ func (c *cmd) Run(args []string) int { } if c.name == "" { - c.UI.Error(fmt.Sprintf("Missing required '-name' flag")) + c.UI.Error(fmt.Sprintf("Missing require '-name' flag")) c.UI.Error(c.Help()) return 1 } diff --git a/command/acl/policy/create/policy_create_test.go b/command/acl/policy/create/policy_create_test.go index 953dd978ed964..94ef7ac95f53d 100644 --- a/command/acl/policy/create/policy_create_test.go +++ b/command/acl/policy/create/policy_create_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policycreate diff --git a/command/acl/policy/delete/policy_delete.go b/command/acl/policy/delete/policy_delete.go index 63c02a47ddd2b..eb1fbfc83bccf 100644 --- a/command/acl/policy/delete/policy_delete.go +++ b/command/acl/policy/delete/policy_delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policydelete diff --git a/command/acl/policy/delete/policy_delete_test.go b/command/acl/policy/delete/policy_delete_test.go index 33f121db981fa..4e0b8ffbf6278 100644 --- a/command/acl/policy/delete/policy_delete_test.go +++ b/command/acl/policy/delete/policy_delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policydelete diff --git a/command/acl/policy/formatter.go b/command/acl/policy/formatter.go index dce79c3907160..1e78976412079 100644 --- a/command/acl/policy/formatter.go +++ b/command/acl/policy/formatter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policy diff --git a/command/acl/policy/list/policy_list.go b/command/acl/policy/list/policy_list.go index 44be10d6843d9..d88f57595030f 100644 --- a/command/acl/policy/list/policy_list.go +++ b/command/acl/policy/list/policy_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policylist diff --git a/command/acl/policy/list/policy_list_test.go b/command/acl/policy/list/policy_list_test.go index b0cc05b2a5cf7..d9df5cc879a54 100644 --- a/command/acl/policy/list/policy_list_test.go +++ b/command/acl/policy/list/policy_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policylist diff --git a/command/acl/policy/policy.go b/command/acl/policy/policy.go index 565c672706468..7a7b80cba8ffc 100644 --- a/command/acl/policy/policy.go +++ b/command/acl/policy/policy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policy diff --git a/command/acl/policy/read/policy_read.go b/command/acl/policy/read/policy_read.go index 36f1e65340794..e1b6b923df094 100644 --- a/command/acl/policy/read/policy_read.go +++ b/command/acl/policy/read/policy_read.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policyread diff --git a/command/acl/policy/read/policy_read_test.go b/command/acl/policy/read/policy_read_test.go index 70036457cebb9..08fe5d1ce96ce 100644 --- a/command/acl/policy/read/policy_read_test.go +++ b/command/acl/policy/read/policy_read_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policyread diff --git a/command/acl/policy/update/policy_update.go b/command/acl/policy/update/policy_update.go index 60b6340736137..ec0577ebb9a22 100644 --- a/command/acl/policy/update/policy_update.go +++ b/command/acl/policy/update/policy_update.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policyupdate diff --git a/command/acl/policy/update/policy_update_test.go b/command/acl/policy/update/policy_update_test.go index 4d77191d64332..22fa8b4c89aa4 100644 --- a/command/acl/policy/update/policy_update_test.go +++ b/command/acl/policy/update/policy_update_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package policyupdate diff --git a/command/acl/role/create/role_create.go b/command/acl/role/create/role_create.go index c6bc7330a9157..588b3a0cb6590 100644 --- a/command/acl/role/create/role_create.go +++ b/command/acl/role/create/role_create.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rolecreate @@ -28,15 +28,12 @@ type cmd struct { http *flags.HTTPFlags help string - name string - description string - policyIDs []string - policyNames []string - serviceIdents []string - nodeIdents []string - templatedPolicy string - templatedPolicyFile string - templatedPolicyVariables []string + name string + description string + policyIDs []string + policyNames []string + serviceIdents []string + nodeIdents []string showMeta bool format string @@ -58,12 +55,6 @@ func (c *cmd) init() { c.flags.Var((*flags.AppendSliceValue)(&c.nodeIdents), "node-identity", "Name of a "+ "node identity to use for this role. May be specified multiple times. Format is "+ "NODENAME:DATACENTER") - c.flags.Var((*flags.AppendSliceValue)(&c.templatedPolicyVariables), "var", "Templated policy variables."+ - " Must be used in combination with -templated-policy flag to specify required variables."+ - " May be specified multiple times with different variables."+ - " Format is VariableName:Value") - c.flags.StringVar(&c.templatedPolicy, "templated-policy", "", "The templated policy name. Use -var flag to specify variables when required.") - c.flags.StringVar(&c.templatedPolicyFile, "templated-policy-file", "", "Path to a file containing templated policy names and variables.") c.flags.StringVar( &c.format, "format", @@ -83,21 +74,13 @@ func (c *cmd) Run(args []string) int { } if c.name == "" { - c.UI.Error("Missing required '-name' flag") + c.UI.Error(fmt.Sprintf("Missing require '-name' flag")) c.UI.Error(c.Help()) return 1 } - if len(c.policyNames) == 0 && len(c.policyIDs) == 0 && len(c.serviceIdents) == 0 && len(c.nodeIdents) == 0 && - len(c.templatedPolicy) == 0 && len(c.templatedPolicyFile) == 0 { - c.UI.Error("Cannot create a role without specifying -policy-name, -policy-id, -service-identity, -node-identity, -templated-policy-file or -templated-policy at least once") - return 1 - } - - if len(c.templatedPolicyFile) != 0 && len(c.templatedPolicy) != 0 { - c.UI.Error("Cannot combine the use of templated-policy flag with templated-policy-file. " + - "To create a role with a single templated policy and simple use case, use -templated-policy. " + - "For multiple templated policies and more complicated use cases, use -templated-policy-file") + if len(c.policyNames) == 0 && len(c.policyIDs) == 0 && len(c.serviceIdents) == 0 && len(c.nodeIdents) == 0 { + c.UI.Error(fmt.Sprintf("Cannot create a role without specifying -policy-name, -policy-id, -service-identity, or -node-identity at least once")) return 1 } @@ -141,13 +124,6 @@ func (c *cmd) Run(args []string) int { } newRole.NodeIdentities = parsedNodeIdents - parsedTemplatedPolicies, err := acl.ExtractTemplatedPolicies(c.templatedPolicy, c.templatedPolicyFile, c.templatedPolicyVariables) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - newRole.TemplatedPolicies = parsedTemplatedPolicies - r, _, err := client.ACL().RoleCreate(newRole, nil) if err != nil { c.UI.Error(fmt.Sprintf("Failed to create new role: %v", err)) @@ -191,7 +167,5 @@ Usage: consul acl role create -name NAME [options] -policy-id b52fc3de-5 \ -policy-name "acl-replication" \ -service-identity "web" \ - -service-identity "db:east,west" \ - -templated-policy "builtin/service" \ - -var "name:api" + -service-identity "db:east,west" ` diff --git a/command/acl/role/create/role_create_test.go b/command/acl/role/create/role_create_test.go index 55aebc13fac2c..40f15433a7bf5 100644 --- a/command/acl/role/create/role_create_test.go +++ b/command/acl/role/create/role_create_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rolecreate @@ -115,22 +115,6 @@ func TestRoleCreateCommand_Pretty(t *testing.T) { require.Len(t, role.NodeIdentities, 1) }) - - t.Run("prevent templated-policy and templated-policy-file simultaneous use", func(t *testing.T) { - ui := cli.NewMockUi() - cmd := New(ui) - - code := cmd.Run([]string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-name=role-with-node-identity", - "-templated-policy=builtin/node", - "-var=name:" + a.Config.NodeName, - "-templated-policy-file=test.hcl", - }) - require.Equal(t, 1, code) - require.Contains(t, ui.ErrorWriter.String(), "Cannot combine the use of templated-policy flag with templated-policy-file.") - }) } func TestRoleCreateCommand_JSON(t *testing.T) { diff --git a/command/acl/role/delete/role_delete.go b/command/acl/role/delete/role_delete.go index aaac306f01b2b..21dc7c0d1b45f 100644 --- a/command/acl/role/delete/role_delete.go +++ b/command/acl/role/delete/role_delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package roledelete diff --git a/command/acl/role/delete/role_delete_test.go b/command/acl/role/delete/role_delete_test.go index 61897ca245575..8a38cf2cfc3bc 100644 --- a/command/acl/role/delete/role_delete_test.go +++ b/command/acl/role/delete/role_delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package roledelete diff --git a/command/acl/role/formatter.go b/command/acl/role/formatter.go index 9ead147582c9f..5df6085e46ac6 100644 --- a/command/acl/role/formatter.go +++ b/command/acl/role/formatter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package role @@ -89,20 +89,6 @@ func (f *prettyFormatter) FormatRole(role *api.ACLRole) (string, error) { buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter)) } } - if len(role.TemplatedPolicies) > 0 { - buffer.WriteString(fmt.Sprintln("Templated Policies:")) - for _, templatedPolicy := range role.TemplatedPolicies { - buffer.WriteString(fmt.Sprintf(" %s\n", templatedPolicy.TemplateName)) - if templatedPolicy.TemplateVariables != nil && templatedPolicy.TemplateVariables.Name != "" { - buffer.WriteString(fmt.Sprintf(" Name: %s\n", templatedPolicy.TemplateVariables.Name)) - } - if len(templatedPolicy.Datacenters) > 0 { - buffer.WriteString(fmt.Sprintf(" Datacenters: %s\n", strings.Join(templatedPolicy.Datacenters, ", "))) - } else { - buffer.WriteString(" Datacenters: all\n") - } - } - } return buffer.String(), nil } @@ -158,21 +144,6 @@ func (f *prettyFormatter) formatRoleListEntry(role *api.ACLRole) string { } } - if len(role.TemplatedPolicies) > 0 { - buffer.WriteString(fmt.Sprintln(" Templated Policies:")) - for _, templatedPolicy := range role.TemplatedPolicies { - buffer.WriteString(fmt.Sprintf(" %s\n", templatedPolicy.TemplateName)) - if templatedPolicy.TemplateVariables != nil && templatedPolicy.TemplateVariables.Name != "" { - buffer.WriteString(fmt.Sprintf(" Name: %s\n", templatedPolicy.TemplateVariables.Name)) - } - if len(templatedPolicy.Datacenters) > 0 { - buffer.WriteString(fmt.Sprintf(" Datacenters: %s\n", strings.Join(templatedPolicy.Datacenters, ", "))) - } else { - buffer.WriteString(" Datacenters: all\n") - } - } - } - return buffer.String() } diff --git a/command/acl/role/formatter_test.go b/command/acl/role/formatter_test.go index 3c1ecaeddc704..cd1ba90fe9a1f 100644 --- a/command/acl/role/formatter_test.go +++ b/command/acl/role/formatter_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package role @@ -83,14 +83,6 @@ func TestFormatRole(t *testing.T) { Datacenter: "middleearth-northwest", }, }, - TemplatedPolicies: []*api.ACLTemplatedPolicy{ - { - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "gardener"}, - Datacenters: []string{"middleearth-northwest", "somewhere-east"}, - }, - {TemplateName: api.ACLTemplatedPolicyNodeName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "bagend"}}, - }, }, }, } @@ -122,7 +114,7 @@ func TestFormatRole(t *testing.T) { } } -func TestFormatRoleList(t *testing.T) { +func TestFormatTokenList(t *testing.T) { type testCase struct { roles []*api.ACLRole overrideGoldenName string @@ -173,10 +165,6 @@ func TestFormatRoleList(t *testing.T) { Datacenter: "middleearth-northwest", }, }, - TemplatedPolicies: []*api.ACLTemplatedPolicy{ - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "gardener"}}, - {TemplateName: api.ACLTemplatedPolicyNodeName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "bagend"}}, - }, }, }, }, diff --git a/command/acl/role/list/role_list.go b/command/acl/role/list/role_list.go index 558419e07067a..3582f9da63c20 100644 --- a/command/acl/role/list/role_list.go +++ b/command/acl/role/list/role_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rolelist diff --git a/command/acl/role/list/role_list_test.go b/command/acl/role/list/role_list_test.go index 0a94d11a109da..651ab120278c9 100644 --- a/command/acl/role/list/role_list_test.go +++ b/command/acl/role/list/role_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rolelist diff --git a/command/acl/role/read/role_read.go b/command/acl/role/read/role_read.go index 027aaa80019f9..d6d06997ad13f 100644 --- a/command/acl/role/read/role_read.go +++ b/command/acl/role/read/role_read.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package roleread diff --git a/command/acl/role/read/role_read_test.go b/command/acl/role/read/role_read_test.go index bef1fab260164..c7be4cb4c0375 100644 --- a/command/acl/role/read/role_read_test.go +++ b/command/acl/role/read/role_read_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package roleread diff --git a/command/acl/role/role.go b/command/acl/role/role.go index c1da51d86401e..2ea085f763311 100644 --- a/command/acl/role/role.go +++ b/command/acl/role/role.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package role diff --git a/command/acl/role/testdata/FormatRole/complex.json.golden b/command/acl/role/testdata/FormatRole/complex.json.golden index 8b22fcb3b7c39..b8d9b64950c0e 100644 --- a/command/acl/role/testdata/FormatRole/complex.json.golden +++ b/command/acl/role/testdata/FormatRole/complex.json.golden @@ -26,24 +26,6 @@ "Datacenter": "middleearth-northwest" } ], - "TemplatedPolicies": [ - { - "TemplateName": "builtin/service", - "TemplateVariables": { - "Name": "gardener" - }, - "Datacenters": [ - "middleearth-northwest", - "somewhere-east" - ] - }, - { - "TemplateName": "builtin/node", - "TemplateVariables": { - "Name": "bagend" - } - } - ], "Hash": "YWJjZGVmZ2g=", "CreateIndex": 5, "ModifyIndex": 10, diff --git a/command/acl/role/testdata/FormatRole/complex.pretty-meta.golden b/command/acl/role/testdata/FormatRole/complex.pretty-meta.golden index 174d3eb2b8aaa..56e61f7780fe5 100644 --- a/command/acl/role/testdata/FormatRole/complex.pretty-meta.golden +++ b/command/acl/role/testdata/FormatRole/complex.pretty-meta.golden @@ -12,10 +12,3 @@ Service Identities: gardener (Datacenters: middleearth-northwest) Node Identities: bagend (Datacenter: middleearth-northwest) -Templated Policies: - builtin/service - Name: gardener - Datacenters: middleearth-northwest, somewhere-east - builtin/node - Name: bagend - Datacenters: all diff --git a/command/acl/role/testdata/FormatRole/complex.pretty.golden b/command/acl/role/testdata/FormatRole/complex.pretty.golden index 54402c34e453f..b3d347ed00ccb 100644 --- a/command/acl/role/testdata/FormatRole/complex.pretty.golden +++ b/command/acl/role/testdata/FormatRole/complex.pretty.golden @@ -9,10 +9,3 @@ Service Identities: gardener (Datacenters: middleearth-northwest) Node Identities: bagend (Datacenter: middleearth-northwest) -Templated Policies: - builtin/service - Name: gardener - Datacenters: middleearth-northwest, somewhere-east - builtin/node - Name: bagend - Datacenters: all diff --git a/command/acl/role/testdata/FormatRoleList/complex.json.golden b/command/acl/role/testdata/FormatRoleList/complex.json.golden index 2d448667a59b5..58c6d850b85d0 100644 --- a/command/acl/role/testdata/FormatRoleList/complex.json.golden +++ b/command/acl/role/testdata/FormatRoleList/complex.json.golden @@ -27,20 +27,6 @@ "Datacenter": "middleearth-northwest" } ], - "TemplatedPolicies": [ - { - "TemplateName": "builtin/service", - "TemplateVariables": { - "Name": "gardener" - } - }, - { - "TemplateName": "builtin/node", - "TemplateVariables": { - "Name": "bagend" - } - } - ], "Hash": "YWJjZGVmZ2g=", "CreateIndex": 5, "ModifyIndex": 10, diff --git a/command/acl/role/testdata/FormatRoleList/complex.pretty-meta.golden b/command/acl/role/testdata/FormatRoleList/complex.pretty-meta.golden index 842482b4e2f93..76355e91dddca 100644 --- a/command/acl/role/testdata/FormatRoleList/complex.pretty-meta.golden +++ b/command/acl/role/testdata/FormatRoleList/complex.pretty-meta.golden @@ -12,10 +12,3 @@ complex: gardener (Datacenters: middleearth-northwest) Node Identities: bagend (Datacenter: middleearth-northwest) - Templated Policies: - builtin/service - Name: gardener - Datacenters: all - builtin/node - Name: bagend - Datacenters: all diff --git a/command/acl/role/testdata/FormatRoleList/complex.pretty.golden b/command/acl/role/testdata/FormatRoleList/complex.pretty.golden index a3907e4d97759..ab2b0c87f8fee 100644 --- a/command/acl/role/testdata/FormatRoleList/complex.pretty.golden +++ b/command/acl/role/testdata/FormatRoleList/complex.pretty.golden @@ -9,10 +9,3 @@ complex: gardener (Datacenters: middleearth-northwest) Node Identities: bagend (Datacenter: middleearth-northwest) - Templated Policies: - builtin/service - Name: gardener - Datacenters: all - builtin/node - Name: bagend - Datacenters: all diff --git a/command/acl/role/update/role_update.go b/command/acl/role/update/role_update.go index fa1ac4176fa36..c42ab7ce9e616 100644 --- a/command/acl/role/update/role_update.go +++ b/command/acl/role/update/role_update.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package roleupdate @@ -28,18 +28,13 @@ type cmd struct { http *flags.HTTPFlags help string - roleID string - name string - description string - policyIDs []string - policyNames []string - serviceIdents []string - nodeIdents []string - appendTemplatedPolicy string - replaceTemplatedPolicy string - appendTemplatedPolicyFile string - replaceTemplatedPolicyFile string - templatedPolicyVariables []string + roleID string + name string + description string + policyIDs []string + policyNames []string + serviceIdents []string + nodeIdents []string noMerge bool showMeta bool @@ -74,16 +69,6 @@ func (c *cmd) init() { role.PrettyFormat, fmt.Sprintf("Output format {%s}", strings.Join(role.GetSupportedFormats(), "|")), ) - c.flags.Var((*flags.AppendSliceValue)(&c.templatedPolicyVariables), "var", "Templated policy variables."+ - " Must be used in combination with -append-templated-policy or -replace-templated-policy flags to specify required variables."+ - " May be specified multiple times with different variables."+ - " Format is VariableName:Value") - c.flags.StringVar(&c.appendTemplatedPolicy, "append-templated-policy", "", "The templated policy name to attach to the role's existing templated policies list. Use -var flag to specify variables when required."+ - " The role retains existing templated policies.") - c.flags.StringVar(&c.replaceTemplatedPolicy, "replace-templated-policy", "", "The templated policy name to replace the existing templated policies list with. Use -var flag to specify variables when required."+ - " Overwrites the role's existing templated policies.") - c.flags.StringVar(&c.appendTemplatedPolicyFile, "append-templated-policy-file", "", "Path to a file containing templated policies and variables. Works like `-append-templated-policy`. The role retains existing templated policies.") - c.flags.StringVar(&c.replaceTemplatedPolicyFile, "replace-templated-policy-file", "", "Path to a file containing templated policies and variables. Works like `-replace-templated-policy`. Overwrites the role's existing templated policies.") c.http = &flags.HTTPFlags{} flags.Merge(c.flags, c.http.ClientFlags()) @@ -126,24 +111,6 @@ func (c *cmd) Run(args []string) int { return 1 } - hasAppendTemplatedPolicies := len(c.appendTemplatedPolicy) > 0 || len(c.appendTemplatedPolicyFile) > 0 - hasReplaceTemplatedPolicies := len(c.replaceTemplatedPolicy) > 0 || len(c.replaceTemplatedPolicyFile) > 0 - - if hasReplaceTemplatedPolicies && hasAppendTemplatedPolicies { - c.UI.Error("Cannot combine the use of append-templated-policy flags with replace-templated-policy. " + - "To set or overwrite existing templated policies, use -replace-templated-policy or -replace-templated-policy-file. " + - "To append to existing templated policies, use -append-templated-policy or -append-templated-policy-file.") - return 1 - } - parsedTemplatedPolicies, err := acl.ExtractTemplatedPolicies(c.replaceTemplatedPolicy, c.replaceTemplatedPolicyFile, c.templatedPolicyVariables) - if hasAppendTemplatedPolicies { - parsedTemplatedPolicies, err = acl.ExtractTemplatedPolicies(c.appendTemplatedPolicy, c.appendTemplatedPolicyFile, c.templatedPolicyVariables) - } - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - // Read the current role in both cases so we can fail better if not found. currentRole, _, err := client.ACL().RoleRead(roleID, nil) if err != nil { @@ -162,7 +129,6 @@ func (c *cmd) Run(args []string) int { Description: c.description, ServiceIdentities: parsedServiceIdents, NodeIdentities: parsedNodeIdents, - TemplatedPolicies: parsedTemplatedPolicies, } for _, policyName := range c.policyNames { @@ -255,12 +221,6 @@ func (c *cmd) Run(args []string) int { r.NodeIdentities = append(r.NodeIdentities, nodeid) } } - - if hasReplaceTemplatedPolicies { - r.TemplatedPolicies = parsedTemplatedPolicies - } else { - r.TemplatedPolicies = append(r.TemplatedPolicies, parsedTemplatedPolicies...) - } } r, _, err = client.ACL().RoleUpdate(r, nil) @@ -313,8 +273,6 @@ Usage: consul acl role update [options] -name "better-name" \ -description "replication" \ -policy-name "token-replication" \ - -service-identity "web" \ - -templated-policy "builtin/service" \ - -var "name:api" + -service-identity "web" ` ) diff --git a/command/acl/role/update/role_update_test.go b/command/acl/role/update/role_update_test.go index e9868f8c20ed2..18d6110996884 100644 --- a/command/acl/role/update/role_update_test.go +++ b/command/acl/role/update/role_update_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package roleupdate @@ -68,9 +68,6 @@ func TestRoleUpdateCommand(t *testing.T) { ServiceName: "fake", }, }, - TemplatedPolicies: []*api.ACLTemplatedPolicy{ - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "fake"}}, - }, }, &api.WriteOptions{Token: "root"}, ) @@ -125,7 +122,6 @@ func TestRoleUpdateCommand(t *testing.T) { require.Equal(t, "test role edited", role.Description) require.Len(t, role.Policies, 1) require.Len(t, role.ServiceIdentities, 1) - require.Len(t, role.TemplatedPolicies, 1) }) t.Run("update with policy by id", func(t *testing.T) { @@ -202,47 +198,6 @@ func TestRoleUpdateCommand(t *testing.T) { require.Len(t, role.ServiceIdentities, 3) require.Len(t, role.NodeIdentities, 1) }) - t.Run("update with append templated policies", func(t *testing.T) { - _ = run(t, []string{ - "-id=" + role.ID, - "-token=root", - "-append-templated-policy=builtin/service", - "-var=name:api", - }) - - role, _, err := client.ACL().RoleRead( - role.ID, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, role) - require.Equal(t, "test role edited", role.Description) - require.Len(t, role.Policies, 2) - require.Len(t, role.ServiceIdentities, 3) - require.Len(t, role.NodeIdentities, 1) - require.Len(t, role.TemplatedPolicies, 2) - }) - - t.Run("update with replace templated policies", func(t *testing.T) { - _ = run(t, []string{ - "-id=" + role.ID, - "-token=root", - "-replace-templated-policy=builtin/service", - "-var=name:api", - }) - - role, _, err := client.ACL().RoleRead( - role.ID, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, role) - require.Equal(t, "test role edited", role.Description) - require.Len(t, role.Policies, 2) - require.Len(t, role.ServiceIdentities, 3) - require.Len(t, role.NodeIdentities, 1) - require.Len(t, role.TemplatedPolicies, 1) - }) } func TestRoleUpdateCommand_JSON(t *testing.T) { @@ -380,9 +335,6 @@ func TestRoleUpdateCommand_noMerge(t *testing.T) { ServiceName: "fake", }, }, - TemplatedPolicies: []*api.ACLTemplatedPolicy{ - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "fake"}}, - }, Policies: []*api.ACLRolePolicyLink{ { ID: policy3.ID, @@ -530,64 +482,4 @@ func TestRoleUpdateCommand_noMerge(t *testing.T) { require.Len(t, role.Policies, 0) require.Len(t, role.ServiceIdentities, 1) }) - - t.Run("update with templated policy append", func(t *testing.T) { - role := createRole(t) - - ui := cli.NewMockUi() - cmd := New(ui) - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-id=" + role.ID, - "-name=" + role.Name, - "-token=root", - "-no-merge", - "-append-templated-policy=builtin/service", - "-var=name:api", - } - - code := cmd.Run(args) - require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) - require.Empty(t, ui.ErrorWriter.String()) - - role, _, err := client.ACL().RoleRead( - role.ID, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, role) - require.Equal(t, "", role.Description) - require.Len(t, role.Policies, 0) - require.Len(t, role.TemplatedPolicies, 1) - }) - - t.Run("update with replace templated policy", func(t *testing.T) { - role := createRole(t) - - ui := cli.NewMockUi() - cmd := New(ui) - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-id=" + role.ID, - "-name=" + role.Name, - "-token=root", - "-no-merge", - "-replace-templated-policy=builtin/service", - "-var=name:api", - } - - code := cmd.Run(args) - require.Equal(t, code, 0, "err: %s", ui.ErrorWriter.String()) - require.Empty(t, ui.ErrorWriter.String()) - - role, _, err := client.ACL().RoleRead( - role.ID, - &api.QueryOptions{Token: "root"}, - ) - require.NoError(t, err) - require.NotNil(t, role) - require.Equal(t, "", role.Description) - require.Len(t, role.Policies, 0) - require.Len(t, role.TemplatedPolicies, 1) - }) } diff --git a/command/acl/templatedpolicy/formatter.go b/command/acl/templatedpolicy/formatter.go deleted file mode 100644 index dec8378bcc5fd..0000000000000 --- a/command/acl/templatedpolicy/formatter.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicy - -import ( - "bytes" - "encoding/json" - "fmt" - "sort" - - "github.com/hashicorp/consul/api" -) - -const ( - PrettyFormat string = "pretty" - JSONFormat string = "json" - WhitespaceIndent = "\t" -) - -// Formatter defines methods provided by templated-policy command output formatter -type Formatter interface { - FormatTemplatedPolicy(policy api.ACLTemplatedPolicyResponse) (string, error) - FormatTemplatedPolicyList(policies map[string]api.ACLTemplatedPolicyResponse) (string, error) -} - -// GetSupportedFormats returns supported formats -func GetSupportedFormats() []string { - return []string{PrettyFormat, JSONFormat} -} - -// NewFormatter returns Formatter implementation -func NewFormatter(format string, showMeta bool) (formatter Formatter, err error) { - switch format { - case PrettyFormat: - formatter = newPrettyFormatter(showMeta) - case JSONFormat: - formatter = newJSONFormatter(showMeta) - default: - err = fmt.Errorf("unknown format: %q", format) - } - - return formatter, err -} - -func newPrettyFormatter(showMeta bool) Formatter { - return &prettyFormatter{showMeta} -} - -func newJSONFormatter(showMeta bool) Formatter { - return &jsonFormatter{showMeta} -} - -type prettyFormatter struct { - showMeta bool -} - -// FormatTemplatedPolicy displays template name, input variables and example usages. When -// showMeta is true, we display raw template code and schema. -// This implementation is a conscious choice as we know builtin variables we know every required/optional input variables -// so we can just hardcode this. -// In the future, when we implement user defined templated policies, we will move this to some sort of schema parsing. -// This implementation allows us to move forward without limiting ourselves when implementing user defined templated policies. -func (f *prettyFormatter) FormatTemplatedPolicy(templatedPolicy api.ACLTemplatedPolicyResponse) (string, error) { - var buffer bytes.Buffer - - buffer.WriteString(fmt.Sprintf("Name: %s\n", templatedPolicy.TemplateName)) - - buffer.WriteString("Input variables:") - switch templatedPolicy.TemplateName { - case api.ACLTemplatedPolicyServiceName: - buffer.WriteString(fmt.Sprintf("\n%sName: String - Required - The name of the service.\n", WhitespaceIndent)) - buffer.WriteString("Example usage:\n") - buffer.WriteString(WhitespaceIndent + "consul acl token create -templated-policy builtin/service -var name:api\n") - case api.ACLTemplatedPolicyNodeName: - buffer.WriteString(fmt.Sprintf("\n%sName: String - Required - The node name.\n", WhitespaceIndent)) - buffer.WriteString("Example usage:\n") - buffer.WriteString(fmt.Sprintf("%sconsul acl token create -templated-policy builtin/node -var name:node-1\n", WhitespaceIndent)) - case api.ACLTemplatedPolicyDNSName, api.ACLTemplatedPolicyNomadServerName: - noRequiredVariablesOutput(&buffer, templatedPolicy.TemplateName) - default: - buffer.WriteString(" None\n") - } - - if f.showMeta { - if templatedPolicy.Schema != "" { - buffer.WriteString(fmt.Sprintf("Schema:\n%s\n\n", templatedPolicy.Schema)) - } - buffer.WriteString(fmt.Sprintf("Raw Template:\n%s\n", templatedPolicy.Template)) - } - - return buffer.String(), nil -} - -func noRequiredVariablesOutput(buffer *bytes.Buffer, templateName string) { - buffer.WriteString(" None\n") - buffer.WriteString("Example usage:\n") - buffer.WriteString(fmt.Sprintf("%sconsul acl token create -templated-policy %s\n", WhitespaceIndent, templateName)) -} - -func (f *prettyFormatter) FormatTemplatedPolicyList(policies map[string]api.ACLTemplatedPolicyResponse) (string, error) { - var buffer bytes.Buffer - - templateNames := make([]string, 0, len(policies)) - for _, templatedPolicy := range policies { - templateNames = append(templateNames, templatedPolicy.TemplateName) - } - - //ensure the list is consistently sorted by strings - sort.Strings(templateNames) - for _, name := range templateNames { - buffer.WriteString(fmt.Sprintf("%s\n", name)) - } - - return buffer.String(), nil -} - -type jsonFormatter struct { - showMeta bool -} - -func (f *jsonFormatter) FormatTemplatedPolicy(templatedPolicy api.ACLTemplatedPolicyResponse) (string, error) { - b, err := json.MarshalIndent(templatedPolicy, "", " ") - if err != nil { - return "", fmt.Errorf("failed to marshal templated policy: %v", err) - } - return string(b), nil -} - -func (f *jsonFormatter) FormatTemplatedPolicyList(templatedPolicies map[string]api.ACLTemplatedPolicyResponse) (string, error) { - b, err := json.MarshalIndent(templatedPolicies, "", " ") - if err != nil { - return "", fmt.Errorf("failed to marshal templated policies: %v", err) - } - return string(b), nil -} diff --git a/command/acl/templatedpolicy/formatter_ce_test.go b/command/acl/templatedpolicy/formatter_ce_test.go deleted file mode 100644 index 1333b9557256c..0000000000000 --- a/command/acl/templatedpolicy/formatter_ce_test.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package templatedpolicy - -import "testing" - -func TestFormatTemplatedPolicy(t *testing.T) { - testFormatTemplatedPolicy(t, "FormatTemplatedPolicy/ce") -} - -func TestFormatTemplatedPolicyList(t *testing.T) { - testFormatTemplatedPolicyList(t, "FormatTemplatedPolicyList/ce") -} diff --git a/command/acl/templatedpolicy/formatter_test.go b/command/acl/templatedpolicy/formatter_test.go deleted file mode 100644 index aa00854980b45..0000000000000 --- a/command/acl/templatedpolicy/formatter_test.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicy - -import ( - "fmt" - "os" - "path" - "path/filepath" - "testing" - - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/api" - "github.com/stretchr/testify/require" -) - -// golden reads from the golden file returning the contents as a string. -func golden(t *testing.T, name string) string { - t.Helper() - - golden := filepath.Join("testdata", name+".golden") - expected, err := os.ReadFile(golden) - require.NoError(t, err) - - return string(expected) -} - -func testFormatTemplatedPolicy(t *testing.T, dirPath string) { - type testCase struct { - templatedPolicy api.ACLTemplatedPolicyResponse - } - - cases := map[string]testCase{ - "node-templated-policy": { - templatedPolicy: api.ACLTemplatedPolicyResponse{ - TemplateName: api.ACLTemplatedPolicyNodeName, - Schema: structs.ACLTemplatedPolicyNodeSchema, - Template: structs.ACLTemplatedPolicyNode, - }, - }, - "dns-templated-policy": { - templatedPolicy: api.ACLTemplatedPolicyResponse{ - TemplateName: api.ACLTemplatedPolicyDNSName, - Schema: structs.ACLTemplatedPolicyNoRequiredVariablesSchema, - Template: structs.ACLTemplatedPolicyDNS, - }, - }, - "service-templated-policy": { - templatedPolicy: api.ACLTemplatedPolicyResponse{ - TemplateName: api.ACLTemplatedPolicyServiceName, - Schema: structs.ACLTemplatedPolicyServiceSchema, - Template: structs.ACLTemplatedPolicyService, - }, - }, - "nomad-server-templated-policy": { - templatedPolicy: api.ACLTemplatedPolicyResponse{ - TemplateName: api.ACLTemplatedPolicyNomadServerName, - Schema: structs.ACLTemplatedPolicyNoRequiredVariablesSchema, - Template: structs.ACLTemplatedPolicyNomadServer, - }, - }, - } - - formatters := map[string]Formatter{ - "pretty": newPrettyFormatter(false), - "pretty-meta": newPrettyFormatter(true), - // the JSON formatter ignores the showMeta - "json": newJSONFormatter(false), - } - - for name, tcase := range cases { - t.Run(name, func(t *testing.T) { - for fmtName, formatter := range formatters { - t.Run(fmtName, func(t *testing.T) { - actual, err := formatter.FormatTemplatedPolicy(tcase.templatedPolicy) - require.NoError(t, err) - - gName := fmt.Sprintf("%s.%s", name, fmtName) - - expected := golden(t, path.Join(dirPath, gName)) - require.Equal(t, expected, actual) - }) - } - }) - } -} - -func testFormatTemplatedPolicyList(t *testing.T, dirPath string) { - // we don't consider the showMeta field for policy list - formatters := map[string]Formatter{ - "pretty": newPrettyFormatter(false), - "json": newJSONFormatter(false), - } - - policies := map[string]api.ACLTemplatedPolicyResponse{ - "builtin/node": { - TemplateName: api.ACLTemplatedPolicyNodeName, - Schema: structs.ACLTemplatedPolicyNodeSchema, - Template: structs.ACLTemplatedPolicyNode, - }, - "builtin/dns": { - TemplateName: api.ACLTemplatedPolicyDNSName, - Schema: structs.ACLTemplatedPolicyNoRequiredVariablesSchema, - Template: structs.ACLTemplatedPolicyDNS, - }, - "builtin/service": { - TemplateName: api.ACLTemplatedPolicyServiceName, - Schema: structs.ACLTemplatedPolicyServiceSchema, - Template: structs.ACLTemplatedPolicyService, - }, - } - - for fmtName, formatter := range formatters { - t.Run(fmtName, func(t *testing.T) { - actual, err := formatter.FormatTemplatedPolicyList(policies) - require.NoError(t, err) - - gName := fmt.Sprintf("list.%s", fmtName) - - expected := golden(t, path.Join(dirPath, gName)) - require.Equal(t, expected, actual) - }) - } -} diff --git a/command/acl/templatedpolicy/list/templated_policy_list.go b/command/acl/templatedpolicy/list/templated_policy_list.go deleted file mode 100644 index 3e5e30570f122..0000000000000 --- a/command/acl/templatedpolicy/list/templated_policy_list.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicylist - -import ( - "flag" - "fmt" - "strings" - - "github.com/mitchellh/cli" - - "github.com/hashicorp/consul/command/acl/templatedpolicy" - "github.com/hashicorp/consul/command/flags" -) - -func New(ui cli.Ui) *cmd { - c := &cmd{UI: ui} - c.init() - return c -} - -type cmd struct { - UI cli.Ui - flags *flag.FlagSet - http *flags.HTTPFlags - help string - - format string -} - -func (c *cmd) init() { - c.flags = flag.NewFlagSet("", flag.ContinueOnError) - c.flags.StringVar( - &c.format, - "format", - templatedpolicy.PrettyFormat, - fmt.Sprintf("Output format {%s}", strings.Join(templatedpolicy.GetSupportedFormats(), "|")), - ) - - c.http = &flags.HTTPFlags{} - flags.Merge(c.flags, c.http.ClientFlags()) - flags.Merge(c.flags, c.http.ServerFlags()) - flags.Merge(c.flags, c.http.MultiTenancyFlags()) - c.help = flags.Usage(help, c.flags) -} - -func (c *cmd) Run(args []string) int { - if err := c.flags.Parse(args); err != nil { - return 1 - } - - client, err := c.http.APIClient() - if err != nil { - c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) - return 1 - } - - tps, _, err := client.ACL().TemplatedPolicyList(nil) - if err != nil { - c.UI.Error(fmt.Sprintf("Failed to retrieve the templated policies list: %v", err)) - return 1 - } - - formatter, err := templatedpolicy.NewFormatter(c.format, false) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - out, err := formatter.FormatTemplatedPolicyList(tps) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - if out != "" { - c.UI.Info(out) - } - - return 0 -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(c.help, nil) -} - -const ( - synopsis = "Lists ACL templated policies" - help = ` -Usage: consul acl templated-policy list [options] - - Lists all the ACL templated policies. - - Example: - - $ consul acl templated-policy list -` -) diff --git a/command/acl/templatedpolicy/list/templated_policy_list_test.go b/command/acl/templatedpolicy/list/templated_policy_list_test.go deleted file mode 100644 index 5f548918e7af3..0000000000000 --- a/command/acl/templatedpolicy/list/templated_policy_list_test.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicylist - -import ( - "encoding/json" - "strings" - "testing" - - "github.com/hashicorp/consul/agent" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/testrpc" - "github.com/mitchellh/cli" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestTemplatedPolicyListCommand_noTabs(t *testing.T) { - t.Parallel() - - if strings.ContainsRune(New(cli.NewMockUi()).Help(), '\t') { - t.Fatal("help has tabs") - } -} - -func TestTemplatedPolicyListCommand(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - a := agent.NewTestAgent(t, ` - primary_datacenter = "dc1" - acl { - enabled = true - tokens { - initial_management = "root" - } - }`) - - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1", testrpc.WithToken("root")) - - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 0) - assert.Empty(t, ui.ErrorWriter.String()) - - output := ui.OutputWriter.String() - require.Contains(t, output, api.ACLTemplatedPolicyServiceName) - require.Contains(t, output, api.ACLTemplatedPolicyDNSName) -} - -func TestTemplatedPolicyListCommand_JSON(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - a := agent.NewTestAgent(t, ` - primary_datacenter = "dc1" - acl { - enabled = true - tokens { - initial_management = "root" - } - }`) - - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1", testrpc.WithToken("root")) - - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-format=json", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 0) - assert.Empty(t, ui.ErrorWriter.String()) - output := ui.OutputWriter.String() - require.Contains(t, output, api.ACLTemplatedPolicyServiceName) - require.Contains(t, output, api.ACLTemplatedPolicyDNSName) - - var jsonOutput map[string]api.ACLTemplatedPolicyResponse - err := json.Unmarshal([]byte(output), &jsonOutput) - assert.NoError(t, err) - outputTemplate := jsonOutput[api.ACLTemplatedPolicyDNSName] - assert.Equal(t, structs.ACLTemplatedPolicyNoRequiredVariablesSchema, outputTemplate.Schema) -} diff --git a/command/acl/templatedpolicy/preview/templated_policy_preview.go b/command/acl/templatedpolicy/preview/templated_policy_preview.go deleted file mode 100644 index c2dc706f90074..0000000000000 --- a/command/acl/templatedpolicy/preview/templated_policy_preview.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicylist - -import ( - "flag" - "fmt" - "strings" - - "github.com/mitchellh/cli" - - "github.com/hashicorp/consul/command/acl" - "github.com/hashicorp/consul/command/acl/policy" - "github.com/hashicorp/consul/command/acl/templatedpolicy" - "github.com/hashicorp/consul/command/flags" -) - -func New(ui cli.Ui) *cmd { - c := &cmd{UI: ui} - c.init() - return c -} - -type cmd struct { - UI cli.Ui - flags *flag.FlagSet - http *flags.HTTPFlags - help string - - templatedPolicyName string - templatedPolicyFile string - templatedPolicyVariables []string - format string -} - -func (c *cmd) init() { - c.flags = flag.NewFlagSet("", flag.ContinueOnError) - c.flags.StringVar( - &c.format, - "format", - templatedpolicy.PrettyFormat, - fmt.Sprintf("Output format {%s}", strings.Join(templatedpolicy.GetSupportedFormats(), "|")), - ) - c.flags.Var((*flags.AppendSliceValue)(&c.templatedPolicyVariables), "var", "Templated policy variables."+ - " Must be used in combination with -name flag to specify required variables."+ - " May be specified multiple times with different variables."+ - " Format is VariableName:Value") - c.flags.StringVar(&c.templatedPolicyName, "name", "", "The templated policy name. Use -var flag to specify variables when required.") - c.flags.StringVar(&c.templatedPolicyFile, "file", "", "Path to a file containing templated policies and variables.") - - c.http = &flags.HTTPFlags{} - flags.Merge(c.flags, c.http.ClientFlags()) - flags.Merge(c.flags, c.http.ServerFlags()) - flags.Merge(c.flags, c.http.MultiTenancyFlags()) - c.help = flags.Usage(help, c.flags) -} - -func (c *cmd) Run(args []string) int { - if err := c.flags.Parse(args); err != nil { - return 1 - } - - if len(c.templatedPolicyName) == 0 && len(c.templatedPolicyFile) == 0 { - c.UI.Error("Cannot preview a templated policy without specifying -name or -file") - return 1 - } - - client, err := c.http.APIClient() - if err != nil { - c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) - return 1 - } - - parsedTemplatedPolicies, err := acl.ExtractTemplatedPolicies(c.templatedPolicyName, c.templatedPolicyFile, c.templatedPolicyVariables) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - - if !(len(parsedTemplatedPolicies) == 1) { - c.UI.Error("Can only preview a single templated policy at a time.") - return 1 - } - - syntheticPolicy, _, err := client.ACL().TemplatedPolicyPreview(parsedTemplatedPolicies[0], nil) - if err != nil { - c.UI.Error(fmt.Sprintf("Failed to generate the templated policy preview: %v", err)) - return 1 - } - - formatter, err := policy.NewFormatter(c.format, false) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - out, err := formatter.FormatPolicy(syntheticPolicy) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - if out != "" { - c.UI.Info(out) - } - - return 0 -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(c.help, nil) -} - -const ( - synopsis = "Preview the policy rendered by the ACL templated policy" - help = ` -Usage: consul acl templated-policy preview [options] - - Preview the policy rendered by the ACL templated policy. - - Example: - - $ consul acl templated-policy preview -name "builtin/service" -var "name:api" - - Preview a templated policy using a file. - - Example: - - $ consul acl templated-policy preview -file templated-policy-file.hcl -` -) diff --git a/command/acl/templatedpolicy/preview/templated_policy_preview_test.go b/command/acl/templatedpolicy/preview/templated_policy_preview_test.go deleted file mode 100644 index 706e1d270f164..0000000000000 --- a/command/acl/templatedpolicy/preview/templated_policy_preview_test.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicylist - -import ( - "encoding/json" - "os" - "strings" - "testing" - - "github.com/hashicorp/consul/agent" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/testrpc" - "github.com/mitchellh/cli" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestTemplatedPolicyPreviewCommand_noTabs(t *testing.T) { - t.Parallel() - - if strings.ContainsRune(New(cli.NewMockUi()).Help(), '\t') { - t.Fatal("help has tabs") - } -} - -func TestTemplatedPolicyPreviewCommand(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - testDir := testutil.TempDir(t, "acl") - - a := agent.NewTestAgent(t, ` - primary_datacenter = "dc1" - acl { - enabled = true - tokens { - initial_management = "root" - } - }`) - - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1", testrpc.WithToken("root")) - - t.Run("missing name and file flags", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 1) - assert.Contains(t, ui.ErrorWriter.String(), "Cannot preview a templated policy without specifying -name or -file") - }) - - t.Run("missing required template variables", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-name=builtin/node", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 1) - assert.Contains(t, ui.ErrorWriter.String(), "Failed to generate the templated policy preview") - }) - - t.Run("correct input", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-name=builtin/node", - "-var=name:api", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 0) - assert.Empty(t, ui.ErrorWriter.String()) - output := ui.OutputWriter.String() - require.Contains(t, output, "synthetic policy generated from templated policy: builtin/node") - }) - - t.Run("correct input with file", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-file=" + testDir + "/templated-policy.hcl", - } - - templatedPolicy := []byte("TemplatedPolicy \"builtin/service\" { Name = \"web\"}") - err := os.WriteFile(testDir+"/templated-policy.hcl", templatedPolicy, 0644) - require.NoError(t, err) - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 0) - assert.Empty(t, ui.ErrorWriter.String()) - output := ui.OutputWriter.String() - require.Contains(t, output, "synthetic policy generated from templated policy: builtin/service") - }) - - t.Run("multiple templated policies input in file", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-file=" + testDir + "/templated-policy.hcl", - } - - templatedPolicy := []byte(` - TemplatedPolicy "builtin/service" { Name = "web"} - TemplatedPolicy "builtin/node" { Name = "api"} - `) - err := os.WriteFile(testDir+"/templated-policy.hcl", templatedPolicy, 0644) - require.NoError(t, err) - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 1) - assert.Contains(t, ui.ErrorWriter.String(), "Can only preview a single templated policy at a time.") - }) -} - -func TestTemplatedPolicyPreviewCommand_JSON(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - a := agent.NewTestAgent(t, ` - primary_datacenter = "dc1" - acl { - enabled = true - tokens { - initial_management = "root" - } - }`) - - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1", testrpc.WithToken("root")) - - t.Run("missing templated-policy flags", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-format=json", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 1) - assert.Contains(t, ui.ErrorWriter.String(), "Cannot preview a templated policy without specifying -name or -file") - }) - - t.Run("missing required template variables", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-name=builtin/node", - "-format=json", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 1) - assert.Contains(t, ui.ErrorWriter.String(), "Failed to generate the templated policy preview") - }) - - t.Run("correct input", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-name=builtin/node", - "-var=name:api", - "-format=json", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 0) - assert.Empty(t, ui.ErrorWriter.String()) - output := ui.OutputWriter.String() - require.Contains(t, output, "synthetic policy generated from templated policy: builtin/node") - - // ensure valid json - var jsonOutput json.RawMessage - err := json.Unmarshal([]byte(output), &jsonOutput) - assert.NoError(t, err) - }) -} diff --git a/command/acl/templatedpolicy/read/templated_policy_read.go b/command/acl/templatedpolicy/read/templated_policy_read.go deleted file mode 100644 index 0d3955fb004a0..0000000000000 --- a/command/acl/templatedpolicy/read/templated_policy_read.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicyread - -import ( - "flag" - "fmt" - "strings" - - "github.com/mitchellh/cli" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/command/acl/templatedpolicy" - "github.com/hashicorp/consul/command/flags" -) - -const ( - PrettyFormat string = "pretty" - JSONFormat string = "json" - synopsis = "Read an ACL Templated Policy" - help = ` -Usage: consul acl templated-policy read [options] TEMPLATED_POLICY - - This command will retrieve and print out the details of a single templated policy. - - Example: - - $ consul acl templated-policy read -name templated-policy-name -` -) - -func New(ui cli.Ui) *cmd { - c := &cmd{UI: ui} - c.init() - return c -} - -type cmd struct { - UI cli.Ui - flags *flag.FlagSet - http *flags.HTTPFlags - help string - - templateName string - format string - showMeta bool -} - -func (c *cmd) init() { - c.flags = flag.NewFlagSet("", flag.ContinueOnError) - c.flags.StringVar(&c.templateName, "name", "", "The name of the templated policy to read.") - c.flags.StringVar( - &c.format, - "format", - templatedpolicy.PrettyFormat, - fmt.Sprintf("Output format {%s}", strings.Join(templatedpolicy.GetSupportedFormats(), "|")), - ) - c.flags.BoolVar(&c.showMeta, "meta", false, "Indicates that templated policy metadata such "+ - "as the schema and template code should be shown for each entry.") - c.http = &flags.HTTPFlags{} - flags.Merge(c.flags, c.http.ClientFlags()) - flags.Merge(c.flags, c.http.ServerFlags()) - flags.Merge(c.flags, c.http.MultiTenancyFlags()) - c.help = flags.Usage(help, c.flags) -} - -func (c *cmd) Run(args []string) int { - if err := c.flags.Parse(args); err != nil { - return 1 - } - - if c.templateName == "" { - c.UI.Error("Must specify the -name parameter") - return 1 - } - - client, err := c.http.APIClient() - if err != nil { - c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) - return 1 - } - - var tp *api.ACLTemplatedPolicyResponse - - tp, _, err = client.ACL().TemplatedPolicyReadByName(c.templateName, nil) - if err != nil { - c.UI.Error(fmt.Sprintf("Error reading templated policy %q: %v", c.templateName, err)) - return 1 - } else if tp == nil { - c.UI.Error(fmt.Sprintf("Templated policy not found with name %q", c.templateName)) - return 1 - } - - formatter, err := templatedpolicy.NewFormatter(c.format, c.showMeta) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - out, err := formatter.FormatTemplatedPolicy(*tp) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - - if out != "" { - c.UI.Info(out) - } - - return 0 -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(c.help, nil) -} diff --git a/command/acl/templatedpolicy/read/templated_policy_read_test.go b/command/acl/templatedpolicy/read/templated_policy_read_test.go deleted file mode 100644 index 99ee66efc9281..0000000000000 --- a/command/acl/templatedpolicy/read/templated_policy_read_test.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicyread - -import ( - "encoding/json" - "strings" - "testing" - - "github.com/hashicorp/consul/agent" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/testrpc" - "github.com/mitchellh/cli" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestTemplatedPolicyReadCommand_noTabs(t *testing.T) { - t.Parallel() - - if strings.ContainsRune(New(cli.NewMockUi()).Help(), '\t') { - t.Fatal("help has tabs") - } -} - -func TestTemplatedPolicyReadCommand(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - a := agent.NewTestAgent(t, ` - primary_datacenter = "dc1" - acl { - enabled = true - tokens { - initial_management = "root" - } - }`) - - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1", testrpc.WithToken("root")) - - t.Run("missing name flag", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 1) - assert.Contains(t, ui.ErrorWriter.String(), "Must specify the -name parameter") - }) - - t.Run("correct input", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-name=" + api.ACLTemplatedPolicyNodeName, - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 0) - assert.Empty(t, ui.ErrorWriter.String()) - - output := ui.OutputWriter.String() - require.Contains(t, output, "Name: String - Required - The node name.") - require.Contains(t, output, "consul acl token create -templated-policy builtin/node -var name:node-1") - }) -} - -func TestTemplatedPolicyReadCommand_JSON(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - a := agent.NewTestAgent(t, ` - primary_datacenter = "dc1" - acl { - enabled = true - tokens { - initial_management = "root" - } - }`) - - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1", testrpc.WithToken("root")) - - t.Run("missing name flag", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-format=json", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 1) - assert.Contains(t, ui.ErrorWriter.String(), "Must specify the -name parameter") - }) - - t.Run("correct input", func(t *testing.T) { - ui := cli.NewMockUi() - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-name=" + api.ACLTemplatedPolicyNodeName, - "-format=json", - } - - cmd := New(ui) - code := cmd.Run(args) - assert.Equal(t, code, 0) - assert.Empty(t, ui.ErrorWriter.String()) - - output := ui.OutputWriter.String() - var templatedPolicy api.ACLTemplatedPolicyResponse - err := json.Unmarshal([]byte(output), &templatedPolicy) - - assert.NoError(t, err) - assert.Equal(t, structs.ACLTemplatedPolicyNodeSchema, templatedPolicy.Schema) - assert.Equal(t, api.ACLTemplatedPolicyNodeName, templatedPolicy.TemplateName) - }) -} diff --git a/command/acl/templatedpolicy/templated_policy.go b/command/acl/templatedpolicy/templated_policy.go deleted file mode 100644 index b6951a075c9ba..0000000000000 --- a/command/acl/templatedpolicy/templated_policy.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package templatedpolicy - -import ( - "github.com/hashicorp/consul/command/flags" - "github.com/mitchellh/cli" -) - -func New() *cmd { - return &cmd{} -} - -type cmd struct{} - -func (c *cmd) Run(args []string) int { - return cli.RunResultHelp -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(help, nil) -} - -const synopsis = "Manage Consul's ACL templated policies" -const help = ` -Usage: consul acl templated-policy [options] [args] - - This command has subcommands for managing Consul ACL templated policies. - Here are some simple examples, and more detailed examples are available - in the subcommands or the documentation. - - List all templated policies: - - $ consul acl templated-policy list - - Preview the policy rendered by the ACL templated policy: - - $ consul acl templated-policy preview -name "builtin/service" -var "name:api" - - Read a templated policy with name: - - $ consul acl templated-policy read -name "builtin/service" - - For more examples, ask for subcommand help or view the documentation. -` diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.json.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.json.golden deleted file mode 100644 index 36682729f1cb5..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.json.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "TemplateName": "builtin/dns", - "Schema": "", - "Template": "\nnode_prefix \"\" {\n\tpolicy = \"read\"\n}\nservice_prefix \"\" {\n\tpolicy = \"read\"\n}\nquery_prefix \"\" {\n\tpolicy = \"read\"\n}" -} \ No newline at end of file diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.pretty-meta.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.pretty-meta.golden deleted file mode 100644 index a30a0c5355470..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.pretty-meta.golden +++ /dev/null @@ -1,15 +0,0 @@ -Name: builtin/dns -Input variables: None -Example usage: - consul acl token create -templated-policy builtin/dns -Raw Template: - -node_prefix "" { - policy = "read" -} -service_prefix "" { - policy = "read" -} -query_prefix "" { - policy = "read" -} diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.pretty.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.pretty.golden deleted file mode 100644 index f52cfdfe1dfcf..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/dns-templated-policy.pretty.golden +++ /dev/null @@ -1,4 +0,0 @@ -Name: builtin/dns -Input variables: None -Example usage: - consul acl token create -templated-policy builtin/dns diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.json.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.json.golden deleted file mode 100644 index 22981af04666d..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.json.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "TemplateName": "builtin/node", - "Schema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"name\": { \"type\": \"string\", \"$ref\": \"#/definitions/min-length-one\" }\n\t},\n\t\"required\": [\"name\"],\n\t\"definitions\": {\n\t\t\"min-length-one\": {\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"minLength\": 1\n\t\t}\n\t}\n}", - "Template": "\nnode \"{{.Name}}\" {\n\tpolicy = \"write\"\n}\nservice_prefix \"\" {\n\tpolicy = \"read\"\n}" -} \ No newline at end of file diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.pretty-meta.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.pretty-meta.golden deleted file mode 100644 index fda0d9559e37d..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.pretty-meta.golden +++ /dev/null @@ -1,28 +0,0 @@ -Name: builtin/node -Input variables: - Name: String - Required - The node name. -Example usage: - consul acl token create -templated-policy builtin/node -var name:node-1 -Schema: -{ - "type": "object", - "properties": { - "name": { "type": "string", "$ref": "#/definitions/min-length-one" } - }, - "required": ["name"], - "definitions": { - "min-length-one": { - "type": "string", - "minLength": 1 - } - } -} - -Raw Template: - -node "{{.Name}}" { - policy = "write" -} -service_prefix "" { - policy = "read" -} diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.pretty.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.pretty.golden deleted file mode 100644 index a923087028c01..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/node-templated-policy.pretty.golden +++ /dev/null @@ -1,5 +0,0 @@ -Name: builtin/node -Input variables: - Name: String - Required - The node name. -Example usage: - consul acl token create -templated-policy builtin/node -var name:node-1 diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.json.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.json.golden deleted file mode 100644 index 7c9981e7f8c95..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.json.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "TemplateName": "builtin/nomad-server", - "Schema": "", - "Template": "\nacl = \"write\"\nagent_prefix \"\" {\n policy = \"read\"\n}\nnode_prefix \"\" {\n policy = \"read\"\n}\nservice_prefix \"\" {\n policy = \"write\"\n}" -} \ No newline at end of file diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.pretty-meta.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.pretty-meta.golden deleted file mode 100644 index be000cce1d5c4..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.pretty-meta.golden +++ /dev/null @@ -1,16 +0,0 @@ -Name: builtin/nomad-server -Input variables: None -Example usage: - consul acl token create -templated-policy builtin/nomad-server -Raw Template: - -acl = "write" -agent_prefix "" { - policy = "read" -} -node_prefix "" { - policy = "read" -} -service_prefix "" { - policy = "write" -} diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.pretty.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.pretty.golden deleted file mode 100644 index d4943665e78b2..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/nomad-server-templated-policy.pretty.golden +++ /dev/null @@ -1,4 +0,0 @@ -Name: builtin/nomad-server -Input variables: None -Example usage: - consul acl token create -templated-policy builtin/nomad-server diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.json.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.json.golden deleted file mode 100644 index e4b71de9b8407..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.json.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "TemplateName": "builtin/service", - "Schema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"name\": { \"type\": \"string\", \"$ref\": \"#/definitions/min-length-one\" }\n\t},\n\t\"required\": [\"name\"],\n\t\"definitions\": {\n\t\t\"min-length-one\": {\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"minLength\": 1\n\t\t}\n\t}\n}", - "Template": "\nservice \"{{.Name}}\" {\n\tpolicy = \"write\"\n}\nservice \"{{.Name}}-sidecar-proxy\" {\n\tpolicy = \"write\"\n}\nservice_prefix \"\" {\n\tpolicy = \"read\"\n}\nnode_prefix \"\" {\n\tpolicy = \"read\"\n}" -} \ No newline at end of file diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.pretty-meta.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.pretty-meta.golden deleted file mode 100644 index f3ae5c6d7be2c..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.pretty-meta.golden +++ /dev/null @@ -1,34 +0,0 @@ -Name: builtin/service -Input variables: - Name: String - Required - The name of the service. -Example usage: - consul acl token create -templated-policy builtin/service -var name:api -Schema: -{ - "type": "object", - "properties": { - "name": { "type": "string", "$ref": "#/definitions/min-length-one" } - }, - "required": ["name"], - "definitions": { - "min-length-one": { - "type": "string", - "minLength": 1 - } - } -} - -Raw Template: - -service "{{.Name}}" { - policy = "write" -} -service "{{.Name}}-sidecar-proxy" { - policy = "write" -} -service_prefix "" { - policy = "read" -} -node_prefix "" { - policy = "read" -} diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.pretty.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.pretty.golden deleted file mode 100644 index bc3ffcfd25e0f..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicy/ce/service-templated-policy.pretty.golden +++ /dev/null @@ -1,5 +0,0 @@ -Name: builtin/service -Input variables: - Name: String - Required - The name of the service. -Example usage: - consul acl token create -templated-policy builtin/service -var name:api diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicyList/ce/list.json.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicyList/ce/list.json.golden deleted file mode 100644 index b634ddc9d8f46..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicyList/ce/list.json.golden +++ /dev/null @@ -1,17 +0,0 @@ -{ - "builtin/dns": { - "TemplateName": "builtin/dns", - "Schema": "", - "Template": "\nnode_prefix \"\" {\n\tpolicy = \"read\"\n}\nservice_prefix \"\" {\n\tpolicy = \"read\"\n}\nquery_prefix \"\" {\n\tpolicy = \"read\"\n}" - }, - "builtin/node": { - "TemplateName": "builtin/node", - "Schema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"name\": { \"type\": \"string\", \"$ref\": \"#/definitions/min-length-one\" }\n\t},\n\t\"required\": [\"name\"],\n\t\"definitions\": {\n\t\t\"min-length-one\": {\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"minLength\": 1\n\t\t}\n\t}\n}", - "Template": "\nnode \"{{.Name}}\" {\n\tpolicy = \"write\"\n}\nservice_prefix \"\" {\n\tpolicy = \"read\"\n}" - }, - "builtin/service": { - "TemplateName": "builtin/service", - "Schema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"name\": { \"type\": \"string\", \"$ref\": \"#/definitions/min-length-one\" }\n\t},\n\t\"required\": [\"name\"],\n\t\"definitions\": {\n\t\t\"min-length-one\": {\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"minLength\": 1\n\t\t}\n\t}\n}", - "Template": "\nservice \"{{.Name}}\" {\n\tpolicy = \"write\"\n}\nservice \"{{.Name}}-sidecar-proxy\" {\n\tpolicy = \"write\"\n}\nservice_prefix \"\" {\n\tpolicy = \"read\"\n}\nnode_prefix \"\" {\n\tpolicy = \"read\"\n}" - } -} \ No newline at end of file diff --git a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicyList/ce/list.pretty.golden b/command/acl/templatedpolicy/testdata/FormatTemplatedPolicyList/ce/list.pretty.golden deleted file mode 100644 index e6080847d424f..0000000000000 --- a/command/acl/templatedpolicy/testdata/FormatTemplatedPolicyList/ce/list.pretty.golden +++ /dev/null @@ -1,3 +0,0 @@ -builtin/dns -builtin/node -builtin/service diff --git a/command/acl/token/clone/token_clone.go b/command/acl/token/clone/token_clone.go index 127fca78762cd..0f4ed2473a976 100644 --- a/command/acl/token/clone/token_clone.go +++ b/command/acl/token/clone/token_clone.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokenclone diff --git a/command/acl/token/clone/token_clone_test.go b/command/acl/token/clone/token_clone_test.go index 8fb729e40c62a..0142db7437957 100644 --- a/command/acl/token/clone/token_clone_test.go +++ b/command/acl/token/clone/token_clone_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokenclone @@ -165,7 +165,6 @@ func TestTokenCloneCommand_Pretty(t *testing.T) { require.Equal(t, cloned.Description, apiToken.Description) require.Equal(t, cloned.Local, apiToken.Local) require.Equal(t, cloned.Policies, apiToken.Policies) - require.Equal(t, cloned.TemplatedPolicies, apiToken.TemplatedPolicies) }) } @@ -199,13 +198,7 @@ func TestTokenCloneCommand_JSON(t *testing.T) { // create a token token, _, err := client.ACL().TokenCreate( - &api.ACLToken{ - Description: "test", - Policies: []*api.ACLTokenPolicyLink{{Name: "test-policy"}}, - TemplatedPolicies: []*api.ACLTemplatedPolicy{ - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "web"}}, - }, - }, + &api.ACLToken{Description: "test", Policies: []*api.ACLTokenPolicyLink{{Name: "test-policy"}}}, &api.WriteOptions{Token: "root"}, ) require.NoError(t, err) diff --git a/command/acl/token/create/token_create.go b/command/acl/token/create/token_create.go index b7a7b9eefa679..4f33562908e8f 100644 --- a/command/acl/token/create/token_create.go +++ b/command/acl/token/create/token_create.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokencreate @@ -29,22 +29,19 @@ type cmd struct { http *flags.HTTPFlags help string - accessor string - secret string - policyIDs []string - policyNames []string - description string - roleIDs []string - roleNames []string - serviceIdents []string - nodeIdents []string - templatedPolicy string - templatedPolicyFile string - templatedPolicyVariables []string - expirationTTL time.Duration - local bool - showMeta bool - format string + accessor string + secret string + policyIDs []string + policyNames []string + description string + roleIDs []string + roleNames []string + serviceIdents []string + nodeIdents []string + expirationTTL time.Duration + local bool + showMeta bool + format string } func (c *cmd) init() { @@ -79,12 +76,6 @@ func (c *cmd) init() { token.PrettyFormat, fmt.Sprintf("Output format {%s}", strings.Join(token.GetSupportedFormats(), "|")), ) - c.flags.Var((*flags.AppendSliceValue)(&c.templatedPolicyVariables), "var", "Templated policy variables."+ - " Must be used in combination with -templated-policy flag to specify required variables."+ - " May be specified multiple times with different variables."+ - " Format is VariableName:Value") - c.flags.StringVar(&c.templatedPolicy, "templated-policy", "", "The templated policy name. Use -var flag to specify variables when required.") - c.flags.StringVar(&c.templatedPolicyFile, "templated-policy-file", "", "Path to a file containing templated policies and variables.") c.http = &flags.HTTPFlags{} flags.Merge(c.flags, c.http.ClientFlags()) flags.Merge(c.flags, c.http.ServerFlags()) @@ -99,16 +90,8 @@ func (c *cmd) Run(args []string) int { if len(c.policyNames) == 0 && len(c.policyIDs) == 0 && len(c.roleNames) == 0 && len(c.roleIDs) == 0 && - len(c.serviceIdents) == 0 && len(c.nodeIdents) == 0 && - len(c.templatedPolicy) == 0 && len(c.templatedPolicyFile) == 0 { - c.UI.Error("Cannot create a token without specifying -policy-name, -policy-id, -role-name, -role-id, -service-identity, -node-identity, -templated-policy, or -templated-policy-file at least once") - return 1 - } - - if len(c.templatedPolicyFile) != 0 && len(c.templatedPolicy) != 0 { - c.UI.Error("Cannot combine the use of templated-policy flag with templated-policy-file. " + - "To create a token with a single templated policy and simple use case, use -templated-policy. " + - "For multiple templated policies and more complicated use cases, use -templated-policy-file") + len(c.serviceIdents) == 0 && len(c.nodeIdents) == 0 { + c.UI.Error(fmt.Sprintf("Cannot create a token without specifying -policy-name, -policy-id, -role-name, -role-id, -service-identity, or -node-identity at least once")) return 1 } @@ -142,13 +125,6 @@ func (c *cmd) Run(args []string) int { } newToken.NodeIdentities = parsedNodeIdents - parsedTemplatedPolicies, err := acl.ExtractTemplatedPolicies(c.templatedPolicy, c.templatedPolicyFile, c.templatedPolicyVariables) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - newToken.TemplatedPolicies = parsedTemplatedPolicies - for _, policyName := range c.policyNames { // We could resolve names to IDs here but there isn't any reason why its would be better // than allowing the agent to do it. @@ -227,8 +203,6 @@ Usage: consul acl token create [options] -role-id c630d4ef-6 \ -role-name "db-updater" \ -service-identity "web" \ - -service-identity "db:east,west" \ - -templated-policy "builtin/service" \ - -var "name:web" + -service-identity "db:east,west" ` ) diff --git a/command/acl/token/create/token_create_test.go b/command/acl/token/create/token_create_test.go index 55ced9a3d17ee..747d9415171d9 100644 --- a/command/acl/token/create/token_create_test.go +++ b/command/acl/token/create/token_create_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokencreate @@ -107,42 +107,6 @@ func TestTokenCreateCommand_Pretty(t *testing.T) { require.Equal(t, a.Config.NodeName, nodes[0].Node) }) - // templated policy - t.Run("templated-policy", func(t *testing.T) { - token := run(t, []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-templated-policy=builtin/node", - "-var=name:" + a.Config.NodeName, - }) - - conf := api.DefaultConfig() - conf.Address = a.HTTPAddr() - conf.Token = token.SecretID - client, err := api.NewClient(conf) - require.NoError(t, err) - - nodes, _, err := client.Catalog().Nodes(nil) - require.NoError(t, err) - require.Len(t, nodes, 1) - require.Equal(t, a.Config.NodeName, nodes[0].Node) - }) - - t.Run("prevent templated-policy and templated-policy-file simultaneous use", func(t *testing.T) { - ui := cli.NewMockUi() - cmd := New(ui) - - code := cmd.Run(append([]string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-templated-policy=builtin/node", - "-var=name:" + a.Config.NodeName, - "-templated-policy-file=test.hcl", - }, "-format=json")) - require.Equal(t, 1, code) - require.Contains(t, ui.ErrorWriter.String(), "Cannot combine the use of templated-policy flag with templated-policy-file.") - }) - // create with accessor and secret t.Run("predefined-ids", func(t *testing.T) { token := run(t, []string{ diff --git a/command/acl/token/delete/token_delete.go b/command/acl/token/delete/token_delete.go index aa9f79903bb72..378c399115367 100644 --- a/command/acl/token/delete/token_delete.go +++ b/command/acl/token/delete/token_delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokendelete diff --git a/command/acl/token/delete/token_delete_test.go b/command/acl/token/delete/token_delete_test.go index 29c1fe292d605..988e4afe24dc2 100644 --- a/command/acl/token/delete/token_delete_test.go +++ b/command/acl/token/delete/token_delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokendelete diff --git a/command/acl/token/formatter.go b/command/acl/token/formatter.go index 5325d285dbbba..dbe1a939fcec1 100644 --- a/command/acl/token/formatter.go +++ b/command/acl/token/formatter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package token @@ -109,20 +109,6 @@ func (f *prettyFormatter) FormatToken(token *api.ACLToken) (string, error) { buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter)) } } - if len(token.TemplatedPolicies) > 0 { - buffer.WriteString(fmt.Sprintln("Templated Policies:")) - for _, templatedPolicy := range token.TemplatedPolicies { - buffer.WriteString(fmt.Sprintf(" %s\n", templatedPolicy.TemplateName)) - if templatedPolicy.TemplateVariables != nil && templatedPolicy.TemplateVariables.Name != "" { - buffer.WriteString(fmt.Sprintf(" Name: %s\n", templatedPolicy.TemplateVariables.Name)) - } - if len(templatedPolicy.Datacenters) > 0 { - buffer.WriteString(fmt.Sprintf(" Datacenters: %s\n", strings.Join(templatedPolicy.Datacenters, ", "))) - } else { - buffer.WriteString(" Datacenters: all\n") - } - } - } return buffer.String(), nil } @@ -188,7 +174,10 @@ func (f *prettyFormatter) FormatTokenExpanded(token *api.ACLTokenExpanded) (stri } identity := structs.ACLServiceIdentity{ServiceName: svcIdentity.ServiceName, Datacenters: svcIdentity.Datacenters} policy := identity.SyntheticPolicy(&entMeta) - displaySyntheticPolicy(policy, &buffer, indent) + buffer.WriteString(fmt.Sprintf(indent+WHITESPACE_2+"Description: %s\n", policy.Description)) + buffer.WriteString(indent + WHITESPACE_2 + "Rules:") + buffer.WriteString(strings.ReplaceAll(policy.Rules, "\n", "\n"+indent+WHITESPACE_4)) + buffer.WriteString("\n\n") } if len(token.ACLToken.ServiceIdentities) > 0 { buffer.WriteString("Service Identities:\n") @@ -201,7 +190,10 @@ func (f *prettyFormatter) FormatTokenExpanded(token *api.ACLTokenExpanded) (stri buffer.WriteString(fmt.Sprintf(indent+"Name: %s (Datacenter: %s)\n", nodeIdentity.NodeName, nodeIdentity.Datacenter)) identity := structs.ACLNodeIdentity{NodeName: nodeIdentity.NodeName, Datacenter: nodeIdentity.Datacenter} policy := identity.SyntheticPolicy(&entMeta) - displaySyntheticPolicy(policy, &buffer, indent) + buffer.WriteString(fmt.Sprintf(indent+WHITESPACE_2+"Description: %s\n", policy.Description)) + buffer.WriteString(indent + WHITESPACE_2 + "Rules:") + buffer.WriteString(strings.ReplaceAll(policy.Rules, "\n", "\n"+indent+WHITESPACE_4)) + buffer.WriteString("\n\n") } if len(token.ACLToken.NodeIdentities) > 0 { buffer.WriteString("Node Identities:\n") @@ -210,34 +202,6 @@ func (f *prettyFormatter) FormatTokenExpanded(token *api.ACLTokenExpanded) (stri } } - formatTemplatedPolicy := func(templatedPolicy *api.ACLTemplatedPolicy, indent string) { - buffer.WriteString(fmt.Sprintf(indent+"%s\n", templatedPolicy.TemplateName)) - tp := structs.ACLTemplatedPolicy{ - TemplateName: templatedPolicy.TemplateName, - Datacenters: templatedPolicy.Datacenters, - } - if templatedPolicy.TemplateVariables != nil && templatedPolicy.TemplateVariables.Name != "" { - tp.TemplateVariables = &structs.ACLTemplatedPolicyVariables{ - Name: templatedPolicy.TemplateVariables.Name, - } - buffer.WriteString(fmt.Sprintf(indent+WHITESPACE_2+"Name: %s\n", templatedPolicy.TemplateVariables.Name)) - } - if len(templatedPolicy.Datacenters) > 0 { - buffer.WriteString(fmt.Sprintf(indent+WHITESPACE_2+"Datacenters: %s\n", strings.Join(templatedPolicy.Datacenters, ", "))) - } else { - buffer.WriteString(fmt.Sprintf(indent + WHITESPACE_2 + "Datacenters: all\n")) - } - policy, _ := tp.SyntheticPolicy(&entMeta) - displaySyntheticPolicy(policy, &buffer, indent) - } - if len(token.ACLToken.TemplatedPolicies) > 0 { - buffer.WriteString("Templated Policies:\n") - - for _, templatedPolicy := range token.ACLToken.TemplatedPolicies { - formatTemplatedPolicy(templatedPolicy, WHITESPACE_2) - } - } - formatRole := func(role api.ACLRole, indent string) { buffer.WriteString(fmt.Sprintf(indent+"Role Name: %s\n", role.Name)) buffer.WriteString(fmt.Sprintf(indent+WHITESPACE_2+"ID: %s\n", role.ID)) @@ -302,13 +266,6 @@ func (f *prettyFormatter) FormatTokenExpanded(token *api.ACLTokenExpanded) (stri return buffer.String(), nil } -func displaySyntheticPolicy(policy *structs.ACLPolicy, buffer *bytes.Buffer, indent string) { - buffer.WriteString(fmt.Sprintf(indent+WHITESPACE_2+"Description: %s\n", policy.Description)) - buffer.WriteString(indent + WHITESPACE_2 + "Rules:") - buffer.WriteString(strings.ReplaceAll(policy.Rules, "\n", "\n"+indent+WHITESPACE_4)) - buffer.WriteString("\n\n") -} - func (f *prettyFormatter) FormatTokenList(tokens []*api.ACLTokenListEntry) (string, error) { var buffer bytes.Buffer @@ -378,21 +335,6 @@ func (f *prettyFormatter) formatTokenListEntry(token *api.ACLTokenListEntry) str buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter)) } } - - if len(token.TemplatedPolicies) > 0 { - buffer.WriteString(fmt.Sprintln("Templated Policies:")) - for _, templatedPolicy := range token.TemplatedPolicies { - buffer.WriteString(fmt.Sprintf(" %s\n", templatedPolicy.TemplateName)) - if templatedPolicy.TemplateVariables != nil && templatedPolicy.TemplateVariables.Name != "" { - buffer.WriteString(fmt.Sprintf(" Name: %s\n", templatedPolicy.TemplateVariables.Name)) - } - if len(templatedPolicy.Datacenters) > 0 { - buffer.WriteString(fmt.Sprintf(" Datacenters: %s\n", strings.Join(templatedPolicy.Datacenters, ", "))) - } else { - buffer.WriteString(" Datacenters: all\n") - } - } - } return buffer.String() } diff --git a/command/acl/token/formatter_ce_test.go b/command/acl/token/formatter_ce_test.go index 9ea382fafcfcc..9faa6f4b736be 100644 --- a/command/acl/token/formatter_ce_test.go +++ b/command/acl/token/formatter_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package token diff --git a/command/acl/token/formatter_test.go b/command/acl/token/formatter_test.go index 65be4dfae98fc..2a5e5414d754d 100644 --- a/command/acl/token/formatter_test.go +++ b/command/acl/token/formatter_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package token @@ -106,21 +106,6 @@ func TestFormatToken(t *testing.T) { Datacenter: "middleearth-northwest", }, }, - TemplatedPolicies: []*api.ACLTemplatedPolicy{ - { - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{ - Name: "web", - }, - Datacenters: []string{"middleearth-northwest", "somewhere-east"}, - }, - { - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - }, }, }, } @@ -224,21 +209,6 @@ func TestFormatTokenList(t *testing.T) { Datacenter: "middleearth-northwest", }, }, - TemplatedPolicies: []*api.ACLTemplatedPolicy{ - { - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{ - Name: "web", - }, - Datacenters: []string{"middleearth-northwest"}, - }, - { - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - }, }, }, }, @@ -474,21 +444,6 @@ var expandedTokenTestCases = map[string]testCase{ Datacenter: "middleearth-northwest", }, }, - TemplatedPolicies: []*api.ACLTemplatedPolicy{ - { - TemplateName: api.ACLTemplatedPolicyServiceName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{ - Name: "web", - }, - Datacenters: []string{"middleearth-northwest"}, - }, - { - TemplateName: api.ACLTemplatedPolicyNodeName, - TemplateVariables: &api.ACLTemplatedPolicyVariables{ - Name: "api", - }, - }, - }, }, }, }, diff --git a/command/acl/token/list/token_list.go b/command/acl/token/list/token_list.go index 7f500426f3369..4d7177dddf645 100644 --- a/command/acl/token/list/token_list.go +++ b/command/acl/token/list/token_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokenlist diff --git a/command/acl/token/list/token_list_test.go b/command/acl/token/list/token_list_test.go index c8586bde6b80b..0a4441c47a562 100644 --- a/command/acl/token/list/token_list_test.go +++ b/command/acl/token/list/token_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokenlist diff --git a/command/acl/token/read/token_read.go b/command/acl/token/read/token_read.go index 23496135bf725..c5798a8b9b31a 100644 --- a/command/acl/token/read/token_read.go +++ b/command/acl/token/read/token_read.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokenread diff --git a/command/acl/token/read/token_read_test.go b/command/acl/token/read/token_read_test.go index 69df72e72917b..ea2317b79fd63 100644 --- a/command/acl/token/read/token_read_test.go +++ b/command/acl/token/read/token_read_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokenread diff --git a/command/acl/token/testdata/FormatToken/complex.json.golden b/command/acl/token/testdata/FormatToken/complex.json.golden index f3e3baef557d2..26e2b0144c767 100644 --- a/command/acl/token/testdata/FormatToken/complex.json.golden +++ b/command/acl/token/testdata/FormatToken/complex.json.golden @@ -38,24 +38,6 @@ "Datacenter": "middleearth-northwest" } ], - "TemplatedPolicies": [ - { - "TemplateName": "builtin/service", - "TemplateVariables": { - "Name": "web" - }, - "Datacenters": [ - "middleearth-northwest", - "somewhere-east" - ] - }, - { - "TemplateName": "builtin/node", - "TemplateVariables": { - "Name": "api" - } - } - ], "Local": false, "AuthMethod": "bar", "ExpirationTime": "2020-05-22T19:52:31Z", diff --git a/command/acl/token/testdata/FormatToken/complex.pretty-meta.golden b/command/acl/token/testdata/FormatToken/complex.pretty-meta.golden index 1644a72a66ef7..b5b33dadc5f20 100644 --- a/command/acl/token/testdata/FormatToken/complex.pretty-meta.golden +++ b/command/acl/token/testdata/FormatToken/complex.pretty-meta.golden @@ -19,10 +19,3 @@ Service Identities: gardener (Datacenters: middleearth-northwest) Node Identities: bagend (Datacenter: middleearth-northwest) -Templated Policies: - builtin/service - Name: web - Datacenters: middleearth-northwest, somewhere-east - builtin/node - Name: api - Datacenters: all diff --git a/command/acl/token/testdata/FormatToken/complex.pretty.golden b/command/acl/token/testdata/FormatToken/complex.pretty.golden index 6d25b40ea097d..5d649f35a83bc 100644 --- a/command/acl/token/testdata/FormatToken/complex.pretty.golden +++ b/command/acl/token/testdata/FormatToken/complex.pretty.golden @@ -16,10 +16,3 @@ Service Identities: gardener (Datacenters: middleearth-northwest) Node Identities: bagend (Datacenter: middleearth-northwest) -Templated Policies: - builtin/service - Name: web - Datacenters: middleearth-northwest, somewhere-east - builtin/node - Name: api - Datacenters: all diff --git a/command/acl/token/testdata/FormatTokenExpanded/ce/complex.json.golden b/command/acl/token/testdata/FormatTokenExpanded/ce/complex.json.golden index 3eddfdc5dfbc4..b0ed45c0d3007 100644 --- a/command/acl/token/testdata/FormatTokenExpanded/ce/complex.json.golden +++ b/command/acl/token/testdata/FormatTokenExpanded/ce/complex.json.golden @@ -181,23 +181,6 @@ "Datacenter": "middleearth-northwest" } ], - "TemplatedPolicies": [ - { - "TemplateName": "builtin/service", - "TemplateVariables": { - "Name": "web" - }, - "Datacenters": [ - "middleearth-northwest" - ] - }, - { - "TemplateName": "builtin/node", - "TemplateVariables": { - "Name": "api" - } - } - ], "Local": false, "AuthMethod": "bar", "ExpirationTime": "2020-05-22T19:52:31Z", diff --git a/command/acl/token/testdata/FormatTokenExpanded/ce/complex.pretty-meta.golden b/command/acl/token/testdata/FormatTokenExpanded/ce/complex.pretty-meta.golden index d8e668cf4a749..bc8033edf9de4 100644 --- a/command/acl/token/testdata/FormatTokenExpanded/ce/complex.pretty-meta.golden +++ b/command/acl/token/testdata/FormatTokenExpanded/ce/complex.pretty-meta.golden @@ -26,7 +26,7 @@ Policies: Service Identities: Name: gardener (Datacenters: middleearth-northwest) - Description: synthetic policy generated from templated policy: builtin/service + Description: synthetic policy for service identity "gardener" Rules: service "gardener" { policy = "write" @@ -43,7 +43,7 @@ Service Identities: Node Identities: Name: bagend (Datacenter: middleearth-northwest) - Description: synthetic policy generated from templated policy: builtin/node + Description: synthetic policy for node identity "bagend" Rules: node "bagend" { policy = "write" @@ -52,37 +52,6 @@ Node Identities: policy = "read" } -Templated Policies: - builtin/service - Name: web - Datacenters: middleearth-northwest - Description: synthetic policy generated from templated policy: builtin/service - Rules: - service "web" { - policy = "write" - } - service "web-sidecar-proxy" { - policy = "write" - } - service_prefix "" { - policy = "read" - } - node_prefix "" { - policy = "read" - } - - builtin/node - Name: api - Datacenters: all - Description: synthetic policy generated from templated policy: builtin/node - Rules: - node "api" { - policy = "write" - } - service_prefix "" { - policy = "read" - } - Roles: Role Name: shire ID: 3b0a78fe-b9c3-40de-b8ea-7d4d6674b366 @@ -96,7 +65,7 @@ Roles: Service Identities: Name: foo (Datacenters: middleearth-southwest) - Description: synthetic policy generated from templated policy: builtin/service + Description: synthetic policy for service identity "foo" Rules: service "foo" { policy = "write" @@ -125,7 +94,7 @@ Roles: Node Identities: Name: bar (Datacenter: middleearth-southwest) - Description: synthetic policy generated from templated policy: builtin/node + Description: synthetic policy for node identity "bar" Rules: node "bar" { policy = "write" @@ -158,7 +127,7 @@ Namespace Role Defaults: Service Identities: Name: web (Datacenters: middleearth-northeast) - Description: synthetic policy generated from templated policy: builtin/service + Description: synthetic policy for service identity "web" Rules: service "web" { policy = "write" @@ -175,7 +144,7 @@ Namespace Role Defaults: Node Identities: Name: db (Datacenter: middleearth-northwest) - Description: synthetic policy generated from templated policy: builtin/node + Description: synthetic policy for node identity "db" Rules: node "db" { policy = "write" diff --git a/command/acl/token/testdata/FormatTokenExpanded/ce/complex.pretty.golden b/command/acl/token/testdata/FormatTokenExpanded/ce/complex.pretty.golden index f1b31d45193de..215cf8b7a037f 100644 --- a/command/acl/token/testdata/FormatTokenExpanded/ce/complex.pretty.golden +++ b/command/acl/token/testdata/FormatTokenExpanded/ce/complex.pretty.golden @@ -23,7 +23,7 @@ Policies: Service Identities: Name: gardener (Datacenters: middleearth-northwest) - Description: synthetic policy generated from templated policy: builtin/service + Description: synthetic policy for service identity "gardener" Rules: service "gardener" { policy = "write" @@ -40,7 +40,7 @@ Service Identities: Node Identities: Name: bagend (Datacenter: middleearth-northwest) - Description: synthetic policy generated from templated policy: builtin/node + Description: synthetic policy for node identity "bagend" Rules: node "bagend" { policy = "write" @@ -49,37 +49,6 @@ Node Identities: policy = "read" } -Templated Policies: - builtin/service - Name: web - Datacenters: middleearth-northwest - Description: synthetic policy generated from templated policy: builtin/service - Rules: - service "web" { - policy = "write" - } - service "web-sidecar-proxy" { - policy = "write" - } - service_prefix "" { - policy = "read" - } - node_prefix "" { - policy = "read" - } - - builtin/node - Name: api - Datacenters: all - Description: synthetic policy generated from templated policy: builtin/node - Rules: - node "api" { - policy = "write" - } - service_prefix "" { - policy = "read" - } - Roles: Role Name: shire ID: 3b0a78fe-b9c3-40de-b8ea-7d4d6674b366 @@ -93,7 +62,7 @@ Roles: Service Identities: Name: foo (Datacenters: middleearth-southwest) - Description: synthetic policy generated from templated policy: builtin/service + Description: synthetic policy for service identity "foo" Rules: service "foo" { policy = "write" @@ -122,7 +91,7 @@ Roles: Node Identities: Name: bar (Datacenter: middleearth-southwest) - Description: synthetic policy generated from templated policy: builtin/node + Description: synthetic policy for node identity "bar" Rules: node "bar" { policy = "write" @@ -155,7 +124,7 @@ Namespace Role Defaults: Service Identities: Name: web (Datacenters: middleearth-northeast) - Description: synthetic policy generated from templated policy: builtin/service + Description: synthetic policy for service identity "web" Rules: service "web" { policy = "write" @@ -172,7 +141,7 @@ Namespace Role Defaults: Node Identities: Name: db (Datacenter: middleearth-northwest) - Description: synthetic policy generated from templated policy: builtin/node + Description: synthetic policy for node identity "db" Rules: node "db" { policy = "write" diff --git a/command/acl/token/testdata/FormatTokenList/complex.json.golden b/command/acl/token/testdata/FormatTokenList/complex.json.golden index 9e06b6c8ff3a4..8bddb0f133897 100644 --- a/command/acl/token/testdata/FormatTokenList/complex.json.golden +++ b/command/acl/token/testdata/FormatTokenList/complex.json.golden @@ -39,23 +39,6 @@ "Datacenter": "middleearth-northwest" } ], - "TemplatedPolicies": [ - { - "TemplateName": "builtin/service", - "TemplateVariables": { - "Name": "web" - }, - "Datacenters": [ - "middleearth-northwest" - ] - }, - { - "TemplateName": "builtin/node", - "TemplateVariables": { - "Name": "api" - } - } - ], "Local": false, "AuthMethod": "bar", "ExpirationTime": "2020-05-22T19:52:31Z", diff --git a/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden b/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden index db4f2a8ce72df..c14bd7058037c 100644 --- a/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden +++ b/command/acl/token/testdata/FormatTokenList/complex.pretty-meta.golden @@ -19,10 +19,3 @@ Service Identities: gardener (Datacenters: middleearth-northwest) Node Identities: bagend (Datacenter: middleearth-northwest) -Templated Policies: - builtin/service - Name: web - Datacenters: middleearth-northwest - builtin/node - Name: api - Datacenters: all diff --git a/command/acl/token/testdata/FormatTokenList/complex.pretty.golden b/command/acl/token/testdata/FormatTokenList/complex.pretty.golden index dd6fcf3ac293a..4a3c011743f75 100644 --- a/command/acl/token/testdata/FormatTokenList/complex.pretty.golden +++ b/command/acl/token/testdata/FormatTokenList/complex.pretty.golden @@ -16,10 +16,3 @@ Service Identities: gardener (Datacenters: middleearth-northwest) Node Identities: bagend (Datacenter: middleearth-northwest) -Templated Policies: - builtin/service - Name: web - Datacenters: middleearth-northwest - builtin/node - Name: api - Datacenters: all diff --git a/command/acl/token/token.go b/command/acl/token/token.go index db3771926ccc0..e8bb0cd420b61 100644 --- a/command/acl/token/token.go +++ b/command/acl/token/token.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package token diff --git a/command/acl/token/update/token_update.go b/command/acl/token/update/token_update.go index dec85c59b9717..915c358d48ad1 100644 --- a/command/acl/token/update/token_update.go +++ b/command/acl/token/update/token_update.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokenupdate @@ -28,27 +28,22 @@ type cmd struct { http *flags.HTTPFlags help string - tokenAccessorID string - policyIDs []string - appendPolicyIDs []string - policyNames []string - appendPolicyNames []string - roleIDs []string - appendRoleIDs []string - roleNames []string - appendRoleNames []string - serviceIdents []string - nodeIdents []string - appendNodeIdents []string - appendServiceIdents []string - appendTemplatedPolicy string - replaceTemplatedPolicy string - appendTemplatedPolicyFile string - replaceTemplatedPolicyFile string - templatedPolicyVariables []string - description string - showMeta bool - format string + tokenAccessorID string + policyIDs []string + appendPolicyIDs []string + policyNames []string + appendPolicyNames []string + roleIDs []string + appendRoleIDs []string + roleNames []string + appendRoleNames []string + serviceIdents []string + nodeIdents []string + appendNodeIdents []string + appendServiceIdents []string + description string + showMeta bool + format string // DEPRECATED mergeServiceIdents bool @@ -94,19 +89,6 @@ func (c *cmd) init() { c.flags.Var((*flags.AppendSliceValue)(&c.appendNodeIdents), "append-node-identity", "Name of a "+ "node identity to use for this token. This token retains existing node identities. May be "+ "specified multiple times. Format is NODENAME:DATACENTER") - c.flags.Var((*flags.AppendSliceValue)(&c.templatedPolicyVariables), "var", "Templated policy variables."+ - " Must be used in combination with -replace-templated-policy or -append-templated-policy flags to specify required variables."+ - " May be specified multiple times with different variables."+ - " Format is VariableName:Value") - c.flags.StringVar(&c.appendTemplatedPolicy, "append-templated-policy", "", "The templated policy name to attach to the token's existing templated policies."+ - "Use -var flag to specify variables when required. Token retains existing templated policies.") - c.flags.StringVar(&c.replaceTemplatedPolicy, "replace-templated-policy", "", "The templated policy name to use replace token's existing templated policies."+ - " Use -var flag to specify variables when required. Overwrites token's existing templated policies.") - c.flags.StringVar(&c.appendTemplatedPolicyFile, "append-templated-policy-file", "", "Path to a file containing templated policy names and variables."+ - " Works similarly to `-append-templated-policy`. The token retains existing templated policies.") - c.flags.StringVar(&c.replaceTemplatedPolicyFile, "replace-templated-policy-file", "", "Path to a file containing templated policy names and variables."+ - " Works similarly to `-replace-templated-policy`. Overwrites the token's existing templated policies.") - c.flags.StringVar( &c.format, "format", @@ -213,24 +195,6 @@ func (c *cmd) Run(args []string) int { return 1 } - hasAppendTemplatedPolicies := len(c.appendTemplatedPolicy) > 0 || len(c.appendTemplatedPolicyFile) > 0 - hasReplaceTemplatedPolicies := len(c.replaceTemplatedPolicy) > 0 || len(c.replaceTemplatedPolicyFile) > 0 - - if hasReplaceTemplatedPolicies && hasAppendTemplatedPolicies { - c.UI.Error("Cannot combine the use of -append-templated-policy flags with replace-templated-policy. " + - "To set or overwrite existing templated policies, use -replace-templated-policy or -replace-templated-policy-file. " + - "To append to existing templated policies, use -append-templated-policy or -append-templated-policy-file.") - return 1 - } - parsedTemplatedPolicies, err := acl.ExtractTemplatedPolicies(c.replaceTemplatedPolicy, c.replaceTemplatedPolicyFile, c.templatedPolicyVariables) - if hasAppendTemplatedPolicies { - parsedTemplatedPolicies, err = acl.ExtractTemplatedPolicies(c.appendTemplatedPolicy, c.appendTemplatedPolicyFile, c.templatedPolicyVariables) - } - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - if c.mergePolicies { c.UI.Warn("merge-policies is deprecated and will be removed in a future Consul version. " + "Use `append-policy-name` or `append-policy-id` instead.") @@ -420,12 +384,6 @@ func (c *cmd) Run(args []string) int { t.NodeIdentities = parsedNodeIdents } - if hasReplaceTemplatedPolicies { - t.TemplatedPolicies = parsedTemplatedPolicies - } else { - t.TemplatedPolicies = append(t.TemplatedPolicies, parsedTemplatedPolicies...) - } - t, _, err = client.ACL().TokenUpdate(t, nil) if err != nil { c.UI.Error(fmt.Sprintf("Failed to update token %s: %v", tok, err)) @@ -474,8 +432,6 @@ Usage: consul acl token update [options] $ consul acl token update -accessor-id abcd \ -description "replication" \ -policy-name "token-replication" \ - -role-name "db-updater" \ - -templated-policy "builtin/service" \ - -var "name:web" + -role-name "db-updater" ` ) diff --git a/command/acl/token/update/token_update_test.go b/command/acl/token/update/token_update_test.go index 91f630e8d2f23..ac764cbea5754 100644 --- a/command/acl/token/update/token_update_test.go +++ b/command/acl/token/update/token_update_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tokenupdate @@ -120,51 +120,6 @@ func TestTokenUpdateCommand(t *testing.T) { require.ElementsMatch(t, expected, responseToken.NodeIdentities) }) - t.Run("replace-templated-policy", func(t *testing.T) { - token := create_token( - t, - client, &api.ACLToken{Description: "test", TemplatedPolicies: []*api.ACLTemplatedPolicy{ - {TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "api"}}, - }}, - &api.WriteOptions{Token: "root"}, - ) - - responseToken := run(t, []string{ - "-http-addr=" + a.HTTPAddr(), - "-accessor-id=" + token.AccessorID, - "-token=root", - "-replace-templated-policy=builtin/node", - "-description=test token", - "-var=name:web", - }) - - require.Len(t, responseToken.TemplatedPolicies, 1) - require.Equal(t, api.ACLTemplatedPolicyNodeName, responseToken.TemplatedPolicies[0].TemplateName) - require.Equal(t, "web", responseToken.TemplatedPolicies[0].TemplateVariables.Name) - }) - t.Run("append-templated-policy", func(t *testing.T) { - templatedPolicy := &api.ACLTemplatedPolicy{TemplateName: api.ACLTemplatedPolicyServiceName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "api"}} - token := create_token( - t, - client, &api.ACLToken{Description: "test", TemplatedPolicies: []*api.ACLTemplatedPolicy{ - templatedPolicy, - }}, - &api.WriteOptions{Token: "root"}, - ) - - responseToken := run(t, []string{ - "-http-addr=" + a.HTTPAddr(), - "-accessor-id=" + token.AccessorID, - "-token=root", - "-append-templated-policy=builtin/node", - "-description=test token", - "-var=name:web", - }) - - require.Len(t, responseToken.TemplatedPolicies, 2) - require.ElementsMatch(t, responseToken.TemplatedPolicies, - []*api.ACLTemplatedPolicy{templatedPolicy, {TemplateName: api.ACLTemplatedPolicyNodeName, TemplateVariables: &api.ACLTemplatedPolicyVariables{Name: "web"}}}) - }) // update with policy by name t.Run("policy-name", func(t *testing.T) { token := create_token(t, client, &api.ACLToken{Description: "test"}, &api.WriteOptions{Token: "root"}) diff --git a/command/agent/agent.go b/command/agent/agent.go index 84515f2c94bd5..c241fa2b7bc8a 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/command/agent/agent_test.go b/command/agent/agent_test.go index 3fa5d1e1a31a5..a197c6ed44798 100644 --- a/command/agent/agent_test.go +++ b/command/agent/agent_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/command/agent/startup_logger.go b/command/agent/startup_logger.go index f324ac6c55c85..baa016a2a7b09 100644 --- a/command/agent/startup_logger.go +++ b/command/agent/startup_logger.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package agent diff --git a/command/catalog/catalog.go b/command/catalog/catalog.go index f685512060076..dbc229eb35224 100644 --- a/command/catalog/catalog.go +++ b/command/catalog/catalog.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package catalog diff --git a/command/catalog/catalog_test.go b/command/catalog/catalog_test.go index 308da9452edfe..5ff5ac40e2e3c 100644 --- a/command/catalog/catalog_test.go +++ b/command/catalog/catalog_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package catalog diff --git a/command/catalog/helpers.go b/command/catalog/helpers.go index f457d8f792ab5..1d9ad1964d3d1 100644 --- a/command/catalog/helpers.go +++ b/command/catalog/helpers.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package catalog diff --git a/command/catalog/helpers_ce.go b/command/catalog/helpers_ce.go index 9898d5a5a2174..5f60fd9b13122 100644 --- a/command/catalog/helpers_ce.go +++ b/command/catalog/helpers_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package catalog diff --git a/command/catalog/list/dc/catalog_list_datacenters.go b/command/catalog/list/dc/catalog_list_datacenters.go index c7531c9164342..7df18e7a8b70d 100644 --- a/command/catalog/list/dc/catalog_list_datacenters.go +++ b/command/catalog/list/dc/catalog_list_datacenters.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dc diff --git a/command/catalog/list/dc/catalog_list_datacenters_test.go b/command/catalog/list/dc/catalog_list_datacenters_test.go index 68a8a8bc50552..6052db994117e 100644 --- a/command/catalog/list/dc/catalog_list_datacenters_test.go +++ b/command/catalog/list/dc/catalog_list_datacenters_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package dc diff --git a/command/catalog/list/nodes/catalog_list_nodes.go b/command/catalog/list/nodes/catalog_list_nodes.go index 1d1f3912f2255..44760182cd1be 100644 --- a/command/catalog/list/nodes/catalog_list_nodes.go +++ b/command/catalog/list/nodes/catalog_list_nodes.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package nodes diff --git a/command/catalog/list/nodes/catalog_list_nodes_test.go b/command/catalog/list/nodes/catalog_list_nodes_test.go index 59db1c666bb67..0bef492b7b779 100644 --- a/command/catalog/list/nodes/catalog_list_nodes_test.go +++ b/command/catalog/list/nodes/catalog_list_nodes_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package nodes diff --git a/command/catalog/list/services/catalog_list_services.go b/command/catalog/list/services/catalog_list_services.go index 4bbcce6532957..029c8bae94f44 100644 --- a/command/catalog/list/services/catalog_list_services.go +++ b/command/catalog/list/services/catalog_list_services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package services diff --git a/command/catalog/list/services/catalog_list_services_test.go b/command/catalog/list/services/catalog_list_services_test.go index 905729410d95e..28c7c0652e894 100644 --- a/command/catalog/list/services/catalog_list_services_test.go +++ b/command/catalog/list/services/catalog_list_services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package services diff --git a/command/cli/cli.go b/command/cli/cli.go index a0bb5d78ddf7b..4afaeb279f665 100644 --- a/command/cli/cli.go +++ b/command/cli/cli.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cli diff --git a/command/cli/formatting.go b/command/cli/formatting.go index fec86797b057c..11ca247e900b6 100644 --- a/command/cli/formatting.go +++ b/command/cli/formatting.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cli diff --git a/command/config/config.go b/command/config/config.go index ed54954cbeb96..e5fbe803a8dc6 100644 --- a/command/config/config.go +++ b/command/config/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package config diff --git a/command/config/delete/config_delete.go b/command/config/delete/config_delete.go index baec168b172aa..e9a9f97c7d83f 100644 --- a/command/config/delete/config_delete.go +++ b/command/config/delete/config_delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package delete diff --git a/command/config/delete/config_delete_test.go b/command/config/delete/config_delete_test.go index d7d6d9226054c..66b5a47a71a22 100644 --- a/command/config/delete/config_delete_test.go +++ b/command/config/delete/config_delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package delete diff --git a/command/config/list/config_list.go b/command/config/list/config_list.go index 4dd469590cffd..978804a191991 100644 --- a/command/config/list/config_list.go +++ b/command/config/list/config_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package list diff --git a/command/config/list/config_list_test.go b/command/config/list/config_list_test.go index 3e528a062fbb3..bf188f51bd963 100644 --- a/command/config/list/config_list_test.go +++ b/command/config/list/config_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package list diff --git a/command/config/read/config_read.go b/command/config/read/config_read.go index d3e3828817b52..348d893738853 100644 --- a/command/config/read/config_read.go +++ b/command/config/read/config_read.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package read diff --git a/command/config/read/config_read_test.go b/command/config/read/config_read_test.go index 5fbf37885d0b6..074c0ee30d3b8 100644 --- a/command/config/read/config_read_test.go +++ b/command/config/read/config_read_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package read diff --git a/command/config/write/config_write.go b/command/config/write/config_write.go index 4edfbed3bf0ce..d6a0c188b8fa1 100644 --- a/command/config/write/config_write.go +++ b/command/config/write/config_write.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package write @@ -7,12 +7,17 @@ import ( "flag" "fmt" "io" + "time" + "github.com/hashicorp/go-multierror" "github.com/mitchellh/cli" + "github.com/mitchellh/mapstructure" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/command/config" "github.com/hashicorp/consul/command/flags" "github.com/hashicorp/consul/command/helpers" + "github.com/hashicorp/consul/lib/decode" ) func New(ui cli.Ui) *cmd { @@ -104,6 +109,67 @@ func (c *cmd) Run(args []string) int { return 0 } +// There is a 'structs' variation of this in +// agent/structs/config_entry.go:DecodeConfigEntry +func newDecodeConfigEntry(raw map[string]interface{}) (api.ConfigEntry, error) { + var entry api.ConfigEntry + + kindVal, ok := raw["Kind"] + if !ok { + kindVal, ok = raw["kind"] + } + if !ok { + return nil, fmt.Errorf("Payload does not contain a kind/Kind key at the top level") + } + + if kindStr, ok := kindVal.(string); ok { + newEntry, err := api.MakeConfigEntry(kindStr, "") + if err != nil { + return nil, err + } + entry = newEntry + } else { + return nil, fmt.Errorf("Kind value in payload is not a string") + } + + var md mapstructure.Metadata + decodeConf := &mapstructure.DecoderConfig{ + DecodeHook: mapstructure.ComposeDecodeHookFunc( + decode.HookWeakDecodeFromSlice, + decode.HookTranslateKeys, + mapstructure.StringToTimeDurationHookFunc(), + mapstructure.StringToTimeHookFunc(time.RFC3339), + ), + Metadata: &md, + Result: &entry, + WeaklyTypedInput: true, + } + + decoder, err := mapstructure.NewDecoder(decodeConf) + if err != nil { + return nil, err + } + + if err := decoder.Decode(raw); err != nil { + return nil, err + } + + for _, k := range md.Unused { + switch k { + case "kind", "Kind": + // The kind field is used to determine the target, but doesn't need + // to exist on the target. + continue + } + err = multierror.Append(err, fmt.Errorf("invalid config key %q", k)) + } + if err != nil { + return nil, err + } + + return entry, nil +} + func (c *cmd) Synopsis() string { return synopsis } diff --git a/command/config/write/config_write_test.go b/command/config/write/config_write_test.go index 15e7a47465323..3319084f4f210 100644 --- a/command/config/write/config_write_test.go +++ b/command/config/write/config_write_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package write diff --git a/command/connect/ca/ca.go b/command/connect/ca/ca.go index a5edd43dbc2e9..f85ae17d6b8af 100644 --- a/command/connect/ca/ca.go +++ b/command/connect/ca/ca.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/command/connect/ca/ca_test.go b/command/connect/ca/ca_test.go index 84ebe2873dd37..eb20f57c220db 100644 --- a/command/connect/ca/ca_test.go +++ b/command/connect/ca/ca_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/command/connect/ca/get/connect_ca_get.go b/command/connect/ca/get/connect_ca_get.go index 40b9b556a4bbf..a2a7c6cb8b48b 100644 --- a/command/connect/ca/get/connect_ca_get.go +++ b/command/connect/ca/get/connect_ca_get.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package get diff --git a/command/connect/ca/get/connect_ca_get_test.go b/command/connect/ca/get/connect_ca_get_test.go index 0e5545152c34b..7d628fb2940db 100644 --- a/command/connect/ca/get/connect_ca_get_test.go +++ b/command/connect/ca/get/connect_ca_get_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package get diff --git a/command/connect/ca/set/connect_ca_set.go b/command/connect/ca/set/connect_ca_set.go index 2c9af4ec6ea9c..ca17f3e2129a7 100644 --- a/command/connect/ca/set/connect_ca_set.go +++ b/command/connect/ca/set/connect_ca_set.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package set diff --git a/command/connect/ca/set/connect_ca_set_test.go b/command/connect/ca/set/connect_ca_set_test.go index 4193d718f0dd9..1928a7dbd43f0 100644 --- a/command/connect/ca/set/connect_ca_set_test.go +++ b/command/connect/ca/set/connect_ca_set_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package set diff --git a/command/connect/connect.go b/command/connect/connect.go index c92481a723ab0..675017291692b 100644 --- a/command/connect/connect.go +++ b/command/connect/connect.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/command/connect/connect_test.go b/command/connect/connect_test.go index 3098962dc4ef8..452207a96b656 100644 --- a/command/connect/connect_test.go +++ b/command/connect/connect_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/command/connect/envoy/bootstrap_config.go b/command/connect/envoy/bootstrap_config.go index 452d3679d6f2f..2a0e21c4d25dd 100644 --- a/command/connect/envoy/bootstrap_config.go +++ b/command/connect/envoy/bootstrap_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoy diff --git a/command/connect/envoy/bootstrap_config_test.go b/command/connect/envoy/bootstrap_config_test.go index ef05786347142..86566ed80cae2 100644 --- a/command/connect/envoy/bootstrap_config_test.go +++ b/command/connect/envoy/bootstrap_config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoy diff --git a/command/connect/envoy/bootstrap_tpl.go b/command/connect/envoy/bootstrap_tpl.go index 4b4bbc8db77f4..26b8e2118b1ef 100644 --- a/command/connect/envoy/bootstrap_tpl.go +++ b/command/connect/envoy/bootstrap_tpl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoy @@ -8,7 +8,7 @@ package envoy type BootstrapTplArgs struct { GRPC - // ProxyCluster is the cluster name for the Envoy `node` specification and + // ProxyCluster is the cluster name for the the Envoy `node` specification and // is typically the same as the ProxyID. ProxyCluster string diff --git a/command/connect/envoy/envoy.go b/command/connect/envoy/envoy.go index 3489f1017a658..256f6fc33c1a8 100644 --- a/command/connect/envoy/envoy.go +++ b/command/connect/envoy/envoy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoy @@ -38,7 +38,7 @@ func New(ui cli.Ui) *cmd { return c } -const DefaultAdminAccessLogPath = os.DevNull +const DefaultAdminAccessLogPath = "/dev/null" type cmd struct { UI cli.Ui diff --git a/command/connect/envoy/envoy_ce_test.go b/command/connect/envoy/envoy_ce_test.go index 84bfb969f7497..89e3fd303efe9 100644 --- a/command/connect/envoy/envoy_ce_test.go +++ b/command/connect/envoy/envoy_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package envoy diff --git a/command/connect/envoy/envoy_test.go b/command/connect/envoy/envoy_test.go index 0e61eea1865ab..517108e0330c8 100644 --- a/command/connect/envoy/envoy_test.go +++ b/command/connect/envoy/envoy_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoy diff --git a/command/connect/envoy/exec.go b/command/connect/envoy/exec.go index 71f903c106437..ffece038f71b8 100644 --- a/command/connect/envoy/exec.go +++ b/command/connect/envoy/exec.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoy diff --git a/command/connect/envoy/exec_supported.go b/command/connect/envoy/exec_supported.go deleted file mode 100644 index 6eba0672eba6a..0000000000000 --- a/command/connect/envoy/exec_supported.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build linux || darwin || windows - -package envoy - -import ( - "fmt" - "os" - "strings" -) - -func isHotRestartOption(s string) bool { - restartOpts := []string{ - "--restart-epoch", - "--hot-restart-version", - "--drain-time-s", - "--parent-shutdown-time-s", - } - for _, opt := range restartOpts { - if s == opt { - return true - } - if strings.HasPrefix(s, opt+"=") { - return true - } - } - return false -} - -func hasHotRestartOption(argSets ...[]string) bool { - for _, args := range argSets { - for _, opt := range args { - if isHotRestartOption(opt) { - return true - } - } - } - return false -} - -// execArgs returns the command and args used to execute a binary. By default it -// will return a command of os.Executable with the args unmodified. This is a shim -// for testing, and can be overridden to execute using 'go run' instead. -var execArgs = func(args ...string) (string, []string, error) { - execPath, err := os.Executable() - if err != nil { - return "", nil, err - } - - if strings.HasSuffix(execPath, "/envoy.test") { - return "", nil, fmt.Errorf("set execArgs to use 'go run' instead of doing a self-exec") - } - - return execPath, args, nil -} diff --git a/command/connect/envoy/exec_test.go b/command/connect/envoy/exec_test.go index e949019e8235e..3ffc89e2f24d8 100644 --- a/command/connect/envoy/exec_test.go +++ b/command/connect/envoy/exec_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build linux || darwin +// +build linux darwin package envoy diff --git a/command/connect/envoy/exec_unix.go b/command/connect/envoy/exec_unix.go index 4c20acdf957eb..d3eb0765a9f9d 100644 --- a/command/connect/envoy/exec_unix.go +++ b/command/connect/envoy/exec_unix.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build linux || darwin +// +build linux darwin package envoy @@ -11,12 +12,63 @@ import ( "os" "os/exec" "path/filepath" + "strings" "syscall" "time" "golang.org/x/sys/unix" ) +// testSelfExecOverride is a way for the tests to no fork-bomb themselves by +// self-executing the whole test suite for each case recursively. It's gross but +// the least gross option I could think of. +var testSelfExecOverride string + +func isHotRestartOption(s string) bool { + restartOpts := []string{ + "--restart-epoch", + "--hot-restart-version", + "--drain-time-s", + "--parent-shutdown-time-s", + } + for _, opt := range restartOpts { + if s == opt { + return true + } + if strings.HasPrefix(s, opt+"=") { + return true + } + } + return false +} + +func hasHotRestartOption(argSets ...[]string) bool { + for _, args := range argSets { + for _, opt := range args { + if isHotRestartOption(opt) { + return true + } + } + } + return false +} + +// execArgs returns the command and args used to execute a binary. By default it +// will return a command of os.Executable with the args unmodified. This is a shim +// for testing, and can be overridden to execute using 'go run' instead. +var execArgs = func(args ...string) (string, []string, error) { + execPath, err := os.Executable() + if err != nil { + return "", nil, err + } + + if strings.HasSuffix(execPath, "/envoy.test") { + return "", nil, fmt.Errorf("set execArgs to use 'go run' instead of doing a self-exec") + } + + return execPath, args, nil +} + func makeBootstrapPipe(bootstrapJSON []byte) (string, error) { pipeFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) diff --git a/command/connect/envoy/exec_unsupported.go b/command/connect/envoy/exec_unsupported.go index c5c95ce4c5382..c9686098983e9 100644 --- a/command/connect/envoy/exec_unsupported.go +++ b/command/connect/envoy/exec_unsupported.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 -//go:build !linux && !darwin && !windows +//go:build !linux && !darwin +// +build !linux,!darwin package envoy diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go deleted file mode 100644 index fe5f2ae9a3b90..0000000000000 --- a/command/connect/envoy/exec_windows.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 -//go:build windows && !fips - -package envoy - -import ( - "errors" - "fmt" - "github.com/natefinch/npipe" - "os" - "os/exec" - "path/filepath" - "time" -) - -func makeBootstrapPipe(bootstrapJSON []byte) (string, error) { - pipeFile := filepath.Join(os.TempDir(), - fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) - - binary, args, err := execArgs("connect", "envoy", "pipe-bootstrap", pipeFile) - if err != nil { - return pipeFile, err - } - - // Dial the named pipe - pipeConn, err := npipe.Dial(pipeFile) - if err != nil { - return pipeFile, err - } - defer pipeConn.Close() - - // Start the command to connect to the named pipe - cmd := exec.Command(binary, args...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = pipeConn - - // Start the command - err = cmd.Start() - if err != nil { - return pipeFile, err - } - - // Write the config - n, err := pipeConn.Write(bootstrapJSON) - if err != nil { - return pipeFile, err - } - - if n < len(bootstrapJSON) { - return pipeFile, fmt.Errorf("failed writing boostrap to child STDIN: %s", err) - } - - // We can't wait for the process since we need to exec into Envoy before it - // will be able to complete so it will be remain as a zombie until Envoy is - // killed then will be reaped by the init process (pid 0). This is all a bit - // gross but the cleanest workaround I can think of for Envoy 1.10 not - // supporting /dev/fd/ config paths any more. So we are done and leaving - // the child to run it's course without reaping it. - return pipeFile, nil -} - -func startProc(binary string, args []string) (p *os.Process, err error) { - if binary, err = exec.LookPath(binary); err == nil { - var procAttr os.ProcAttr - procAttr.Files = []*os.File{os.Stdin, - os.Stdout, os.Stderr} - p, err := os.StartProcess(binary, args, &procAttr) - if err == nil { - return p, nil - } - } - return nil, err -} - -func execEnvoy(binary string, prefixArgs, suffixArgs []string, bootstrapJSON []byte) error { - tempFile, err := makeBootstrapPipe(bootstrapJSON) - if err != nil { - os.RemoveAll(tempFile) - return err - } - // We don't defer a cleanup since we are about to Exec into Envoy which means - // defer will never fire. The child process cleans up for us in the happy - // path. - - // We default to disabling hot restart because it makes it easier to run - // multiple envoys locally for testing without them trying to share memory and - // unix sockets and complain about being different IDs. But if user is - // actually configuring hot-restart explicitly with the --restart-epoch option - // then don't disable it! - disableHotRestart := !hasHotRestartOption(prefixArgs, suffixArgs) - - // First argument needs to be the executable name. - envoyArgs := []string{} - envoyArgs = append(envoyArgs, prefixArgs...) - if disableHotRestart { - envoyArgs = append(envoyArgs, "--disable-hot-restart") - } - envoyArgs = append(envoyArgs, suffixArgs...) - envoyArgs = append(envoyArgs, "--config-path", tempFile) - - // Exec - if proc, err := startProc(binary, envoyArgs); err == nil { - proc.Wait() - } else if err != nil { - return errors.New("Failed to exec envoy: " + err.Error()) - } - - return nil -} diff --git a/command/connect/envoy/flags.go b/command/connect/envoy/flags.go index 4d7994ccd45da..eed9698c72fa0 100644 --- a/command/connect/envoy/flags.go +++ b/command/connect/envoy/flags.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoy diff --git a/command/connect/envoy/flags_test.go b/command/connect/envoy/flags_test.go index 596c0fa1a22fb..617f852691254 100644 --- a/command/connect/envoy/flags_test.go +++ b/command/connect/envoy/flags_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoy diff --git a/command/connect/envoy/pipe-bootstrap/connect_envoy_pipe-bootstrap.go b/command/connect/envoy/pipe-bootstrap/connect_envoy_pipe-bootstrap.go index e6dbc33db1eb7..48cec90b8145c 100644 --- a/command/connect/envoy/pipe-bootstrap/connect_envoy_pipe-bootstrap.go +++ b/command/connect/envoy/pipe-bootstrap/connect_envoy_pipe-bootstrap.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pipebootstrap diff --git a/command/connect/envoy/pipe-bootstrap/connect_envoy_pipe-bootstrap_test.go b/command/connect/envoy/pipe-bootstrap/connect_envoy_pipe-bootstrap_test.go index 4f271b6e74039..8e8b982f61f85 100644 --- a/command/connect/envoy/pipe-bootstrap/connect_envoy_pipe-bootstrap_test.go +++ b/command/connect/envoy/pipe-bootstrap/connect_envoy_pipe-bootstrap_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pipebootstrap diff --git a/command/connect/expose/expose.go b/command/connect/expose/expose.go index 569ab46bab4a7..0fe3e3de74a67 100644 --- a/command/connect/expose/expose.go +++ b/command/connect/expose/expose.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package expose diff --git a/command/connect/expose/expose_test.go b/command/connect/expose/expose_test.go index 511a495640fb8..9db76a765e822 100644 --- a/command/connect/expose/expose_test.go +++ b/command/connect/expose/expose_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package expose diff --git a/command/connect/proxy/flag_upstreams.go b/command/connect/proxy/flag_upstreams.go index 47bbb730ae86a..21a70c9b3c6bb 100644 --- a/command/connect/proxy/flag_upstreams.go +++ b/command/connect/proxy/flag_upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/command/connect/proxy/flag_upstreams_test.go b/command/connect/proxy/flag_upstreams_test.go index 7e47a9ad7950a..42647c98396d3 100644 --- a/command/connect/proxy/flag_upstreams_test.go +++ b/command/connect/proxy/flag_upstreams_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/command/connect/proxy/proxy.go b/command/connect/proxy/proxy.go index 9b352dab5d0ce..3585d798abeec 100644 --- a/command/connect/proxy/proxy.go +++ b/command/connect/proxy/proxy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/command/connect/proxy/proxy_test.go b/command/connect/proxy/proxy_test.go index f17b04f5f8e88..fc55eadcc9b40 100644 --- a/command/connect/proxy/proxy_test.go +++ b/command/connect/proxy/proxy_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/command/connect/proxy/register.go b/command/connect/proxy/register.go index 87d6dbb9a2d32..c3051e0f9dd1c 100644 --- a/command/connect/proxy/register.go +++ b/command/connect/proxy/register.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/command/connect/proxy/register_test.go b/command/connect/proxy/register_test.go index 823b11d23c1b2..c1845ac6256ed 100644 --- a/command/connect/proxy/register_test.go +++ b/command/connect/proxy/register_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/command/connect/redirecttraffic/redirect_traffic.go b/command/connect/redirecttraffic/redirect_traffic.go index 8a597696b7f08..5e92193f0b004 100644 --- a/command/connect/redirecttraffic/redirect_traffic.go +++ b/command/connect/redirecttraffic/redirect_traffic.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package redirecttraffic diff --git a/command/connect/redirecttraffic/redirect_traffic_test.go b/command/connect/redirecttraffic/redirect_traffic_test.go index de9b362416c2d..209cfcc35d8a2 100644 --- a/command/connect/redirecttraffic/redirect_traffic_test.go +++ b/command/connect/redirecttraffic/redirect_traffic_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package redirecttraffic diff --git a/command/debug/debug.go b/command/debug/debug.go index 9fe18280b8206..e5d02383d85fa 100644 --- a/command/debug/debug.go +++ b/command/debug/debug.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package debug diff --git a/command/debug/debug_test.go b/command/debug/debug_test.go index c05d115873f06..d8982b9e20fdb 100644 --- a/command/debug/debug_test.go +++ b/command/debug/debug_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package debug diff --git a/command/event/event.go b/command/event/event.go index 73c19b6c5f776..5882b6005f680 100644 --- a/command/event/event.go +++ b/command/event/event.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package event diff --git a/command/event/event_test.go b/command/event/event_test.go index 349cb0daa8167..b267e8920a754 100644 --- a/command/event/event_test.go +++ b/command/event/event_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package event diff --git a/command/exec/exec.go b/command/exec/exec.go index 53026a6f8c877..140cdea300eb6 100644 --- a/command/exec/exec.go +++ b/command/exec/exec.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package exec diff --git a/command/exec/exec_test.go b/command/exec/exec_test.go index d8335160f28a4..74f446d11ca71 100644 --- a/command/exec/exec_test.go +++ b/command/exec/exec_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package exec diff --git a/command/flags/config.go b/command/flags/config.go index 39c615554d676..162ffea5a22ca 100644 --- a/command/flags/config.go +++ b/command/flags/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/flags/config_test.go b/command/flags/config_test.go index 1a6d69ca4b574..bc718f1dc5b91 100644 --- a/command/flags/config_test.go +++ b/command/flags/config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/flags/flag_map_value.go b/command/flags/flag_map_value.go index af5fec436dd57..58afc9f5c365b 100644 --- a/command/flags/flag_map_value.go +++ b/command/flags/flag_map_value.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/flags/flag_map_value_test.go b/command/flags/flag_map_value_test.go index d04342a01b34d..4177f452afac1 100644 --- a/command/flags/flag_map_value_test.go +++ b/command/flags/flag_map_value_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/flags/flag_slice_value.go b/command/flags/flag_slice_value.go index 58428e58ce9cc..b965b76546796 100644 --- a/command/flags/flag_slice_value.go +++ b/command/flags/flag_slice_value.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/flags/flag_slice_value_test.go b/command/flags/flag_slice_value_test.go index 24187f3f41835..84421f0f958af 100644 --- a/command/flags/flag_slice_value_test.go +++ b/command/flags/flag_slice_value_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/flags/http.go b/command/flags/http.go index 009c26629c1d9..82e59431ae71d 100644 --- a/command/flags/http.go +++ b/command/flags/http.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags @@ -29,7 +29,6 @@ type HTTPFlags struct { // multi-tenancy flags namespace StringValue partition StringValue - peer StringValue } func (f *HTTPFlags) ClientFlags() *flag.FlagSet { @@ -110,10 +109,6 @@ func (f *HTTPFlags) Partition() string { return f.partition.String() } -func (f *HTTPFlags) PeerName() string { - return f.peer.String() -} - func (f *HTTPFlags) Stale() bool { if f.stale.v == nil { return false @@ -179,9 +174,3 @@ func (f *HTTPFlags) AddPartitionFlag(fs *flag.FlagSet) { "from the request's ACL token, or will default to the `default` admin partition. "+ "Admin Partitions are a Consul Enterprise feature.") } - -func (f *HTTPFlags) AddPeerName() *flag.FlagSet { - fs := flag.NewFlagSet("", flag.ContinueOnError) - fs.Var(&f.peer, "peer", "Specifies the name of peer to query. By default, it is `local`.") - return fs -} diff --git a/command/flags/http_test.go b/command/flags/http_test.go index f8b48f80cbabc..baf4ac231c8dd 100644 --- a/command/flags/http_test.go +++ b/command/flags/http_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/flags/merge.go b/command/flags/merge.go index 251698e320fcf..c7a475b4b1d5e 100644 --- a/command/flags/merge.go +++ b/command/flags/merge.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/flags/usage.go b/command/flags/usage.go index 3583620bd9f65..245cfd67c0187 100644 --- a/command/flags/usage.go +++ b/command/flags/usage.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package flags diff --git a/command/forceleave/forceleave.go b/command/forceleave/forceleave.go index 2c9e2ceb1def8..1b3aac559f171 100644 --- a/command/forceleave/forceleave.go +++ b/command/forceleave/forceleave.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package forceleave diff --git a/command/forceleave/forceleave_test.go b/command/forceleave/forceleave_test.go index 05d490777575c..c29d2996b8124 100644 --- a/command/forceleave/forceleave_test.go +++ b/command/forceleave/forceleave_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package forceleave diff --git a/command/helpers/decode_shim.go b/command/helpers/decode_shim.go index d2a73895a57fb..20ca1faeaaa80 100644 --- a/command/helpers/decode_shim.go +++ b/command/helpers/decode_shim.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package helpers diff --git a/command/helpers/helpers.go b/command/helpers/helpers.go index e4b95fff37e82..3720439df3874 100644 --- a/command/helpers/helpers.go +++ b/command/helpers/helpers.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package helpers @@ -8,17 +8,15 @@ import ( "fmt" "io" "os" - "strings" "time" - "github.com/mitchellh/mapstructure" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib/decode" "github.com/hashicorp/go-multierror" + "github.com/mitchellh/mapstructure" ) -func LoadFromFile(path string) (string, error) { +func loadFromFile(path string) (string, error) { data, err := os.ReadFile(path) if err != nil { return "", fmt.Errorf("Failed to read file: %v", err) @@ -47,7 +45,7 @@ func LoadDataSource(data string, testStdin io.Reader) (string, error) { switch data[0] { case '@': - return LoadFromFile(data[1:]) + return loadFromFile(data[1:]) case '-': if len(data) > 1 { return data, nil @@ -67,7 +65,7 @@ func LoadDataSourceNoRaw(data string, testStdin io.Reader) (string, error) { return loadFromStdin(testStdin) } - return LoadFromFile(data) + return loadFromFile(data) } func ParseConfigEntry(data string) (api.ConfigEntry, error) { @@ -126,19 +124,13 @@ func newDecodeConfigEntry(raw map[string]interface{}) (api.ConfigEntry, error) { } for _, k := range md.Unused { - switch { - case strings.ToLower(k) == "kind": + switch k { + case "kind", "Kind": // The kind field is used to determine the target, but doesn't need // to exist on the target. continue - - case strings.HasSuffix(strings.ToLower(k), "namespace"): - err = multierror.Append(err, fmt.Errorf("invalid config key %q, namespaces are a consul enterprise feature", k)) - case strings.Contains(strings.ToLower(k), "jwt"): - err = multierror.Append(err, fmt.Errorf("invalid config key %q, api-gateway jwt validation is a consul enterprise feature", k)) - default: - err = multierror.Append(err, fmt.Errorf("invalid config key %q", k)) } + err = multierror.Append(err, fmt.Errorf("invalid config key %q", k)) } if err != nil { return nil, err diff --git a/command/helpers/helpers_test.go b/command/helpers/helpers_test.go index 6479386747bac..8d8b2164f7e7c 100644 --- a/command/helpers/helpers_test.go +++ b/command/helpers/helpers_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package helpers diff --git a/command/info/info.go b/command/info/info.go index 5bbad23eabbed..de17a53dd0d51 100644 --- a/command/info/info.go +++ b/command/info/info.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package info diff --git a/command/info/info_test.go b/command/info/info_test.go index 0faac3acc660e..5e046df8c484e 100644 --- a/command/info/info_test.go +++ b/command/info/info_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package info diff --git a/command/intention/check/check.go b/command/intention/check/check.go index dce63c75bc068..ed8119170f476 100644 --- a/command/intention/check/check.go +++ b/command/intention/check/check.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package check diff --git a/command/intention/check/check_test.go b/command/intention/check/check_test.go index 666d44d80c552..7ecac4a92f537 100644 --- a/command/intention/check/check_test.go +++ b/command/intention/check/check_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package check diff --git a/command/intention/create/create.go b/command/intention/create/create.go index df92dfe302a2e..c1eab7b0f12ca 100644 --- a/command/intention/create/create.go +++ b/command/intention/create/create.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package create diff --git a/command/intention/create/create_test.go b/command/intention/create/create_test.go index 90250368ef2b8..e74c87c2bb674 100644 --- a/command/intention/create/create_test.go +++ b/command/intention/create/create_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package create diff --git a/command/intention/delete/delete.go b/command/intention/delete/delete.go index a58ee163e6875..b63029d91d866 100644 --- a/command/intention/delete/delete.go +++ b/command/intention/delete/delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package delete diff --git a/command/intention/delete/delete_test.go b/command/intention/delete/delete_test.go index 51e59c8b52db1..dedcf8ff2e7d2 100644 --- a/command/intention/delete/delete_test.go +++ b/command/intention/delete/delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package delete diff --git a/command/intention/format.go b/command/intention/format.go index bd202cfa5081c..8683063207585 100644 --- a/command/intention/format.go +++ b/command/intention/format.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package intention diff --git a/command/intention/get/get.go b/command/intention/get/get.go index 64dd2c8441c4d..1c2437962627c 100644 --- a/command/intention/get/get.go +++ b/command/intention/get/get.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package get diff --git a/command/intention/get/get_test.go b/command/intention/get/get_test.go index 7559a3611849d..6f6f31ee9e8bc 100644 --- a/command/intention/get/get_test.go +++ b/command/intention/get/get_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package get diff --git a/command/intention/helpers.go b/command/intention/helpers.go index abc7c21e73a14..60774da85c9f1 100644 --- a/command/intention/helpers.go +++ b/command/intention/helpers.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package intention diff --git a/command/intention/helpers_test.go b/command/intention/helpers_test.go index cd2db64c69113..11dff93b108b0 100644 --- a/command/intention/helpers_test.go +++ b/command/intention/helpers_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package intention diff --git a/command/intention/intention.go b/command/intention/intention.go index 77ba5e2f5eae8..450ec630a49e1 100644 --- a/command/intention/intention.go +++ b/command/intention/intention.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package intention diff --git a/command/intention/intention_test.go b/command/intention/intention_test.go index 3a728fc028f9d..098fecfa938e6 100644 --- a/command/intention/intention_test.go +++ b/command/intention/intention_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package intention diff --git a/command/intention/list/intention_list.go b/command/intention/list/intention_list.go index 408f9d8dcd09d..f79f454dc79cb 100644 --- a/command/intention/list/intention_list.go +++ b/command/intention/list/intention_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package list diff --git a/command/intention/list/intention_list_test.go b/command/intention/list/intention_list_test.go index ccd6faefe3c10..2227c1c508e35 100644 --- a/command/intention/list/intention_list_test.go +++ b/command/intention/list/intention_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package list diff --git a/command/intention/match/match.go b/command/intention/match/match.go index ee115a7b1ad86..b6f00d1a0e88f 100644 --- a/command/intention/match/match.go +++ b/command/intention/match/match.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package match diff --git a/command/intention/match/match_test.go b/command/intention/match/match_test.go index 6715c7eba8d3a..d2a69ceada58c 100644 --- a/command/intention/match/match_test.go +++ b/command/intention/match/match_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package match diff --git a/command/join/join.go b/command/join/join.go index f5d041ed4b4d9..074813993d6ab 100644 --- a/command/join/join.go +++ b/command/join/join.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package join diff --git a/command/join/join_test.go b/command/join/join_test.go index 828cb46b6e318..e5d43c7cdea9f 100644 --- a/command/join/join_test.go +++ b/command/join/join_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package join diff --git a/command/keygen/keygen.go b/command/keygen/keygen.go index e2907bda0c0d2..c7ab5337c02c4 100644 --- a/command/keygen/keygen.go +++ b/command/keygen/keygen.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package keygen diff --git a/command/keygen/keygen_test.go b/command/keygen/keygen_test.go index 59edb12896bd6..a78a07cfedf74 100644 --- a/command/keygen/keygen_test.go +++ b/command/keygen/keygen_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package keygen diff --git a/command/keyring/keyring.go b/command/keyring/keyring.go index 0e4756f6191f7..2f9d96f0e266f 100644 --- a/command/keyring/keyring.go +++ b/command/keyring/keyring.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package keyring diff --git a/command/keyring/keyring_test.go b/command/keyring/keyring_test.go index 68c5e7f982196..5ee1b1a8752f8 100644 --- a/command/keyring/keyring_test.go +++ b/command/keyring/keyring_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package keyring diff --git a/command/kv/del/kv_delete.go b/command/kv/del/kv_delete.go index e58e4a229661f..89bdde4508c04 100644 --- a/command/kv/del/kv_delete.go +++ b/command/kv/del/kv_delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package del diff --git a/command/kv/del/kv_delete_test.go b/command/kv/del/kv_delete_test.go index 254fb4aa5097e..29d9b7bb98c4b 100644 --- a/command/kv/del/kv_delete_test.go +++ b/command/kv/del/kv_delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package del diff --git a/command/kv/exp/kv_export.go b/command/kv/exp/kv_export.go index 2f2e835bd42d7..c14acd4424d47 100644 --- a/command/kv/exp/kv_export.go +++ b/command/kv/exp/kv_export.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package exp diff --git a/command/kv/exp/kv_export_test.go b/command/kv/exp/kv_export_test.go index 76da13dcd4e6d..96e1d469113f6 100644 --- a/command/kv/exp/kv_export_test.go +++ b/command/kv/exp/kv_export_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package exp diff --git a/command/kv/get/kv_get.go b/command/kv/get/kv_get.go index 4abf0251751e4..b53173c048633 100644 --- a/command/kv/get/kv_get.go +++ b/command/kv/get/kv_get.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package get diff --git a/command/kv/get/kv_get_test.go b/command/kv/get/kv_get_test.go index 56318586de439..92b6675b80a5b 100644 --- a/command/kv/get/kv_get_test.go +++ b/command/kv/get/kv_get_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package get diff --git a/command/kv/imp/kv_import.go b/command/kv/imp/kv_import.go index 1d91d281df846..b1e6841060e60 100644 --- a/command/kv/imp/kv_import.go +++ b/command/kv/imp/kv_import.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package imp diff --git a/command/kv/imp/kv_import_test.go b/command/kv/imp/kv_import_test.go index 6bed5684cebdf..3528c2119abb2 100644 --- a/command/kv/imp/kv_import_test.go +++ b/command/kv/imp/kv_import_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package imp diff --git a/command/kv/impexp/kvimpexp.go b/command/kv/impexp/kvimpexp.go index 0dc4b394e0687..3235439ee5394 100644 --- a/command/kv/impexp/kvimpexp.go +++ b/command/kv/impexp/kvimpexp.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package impexp diff --git a/command/kv/kv.go b/command/kv/kv.go index 86d8c258e058a..3d98b63bdba3a 100644 --- a/command/kv/kv.go +++ b/command/kv/kv.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package kv diff --git a/command/kv/kv_test.go b/command/kv/kv_test.go index 85195ee9acbac..56ee94fa7e2da 100644 --- a/command/kv/kv_test.go +++ b/command/kv/kv_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package kv diff --git a/command/kv/put/kv_put.go b/command/kv/put/kv_put.go index 5f0580ce1431c..13e6ee4b9e8e4 100644 --- a/command/kv/put/kv_put.go +++ b/command/kv/put/kv_put.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package put diff --git a/command/kv/put/kv_put_test.go b/command/kv/put/kv_put_test.go index 1f0245c8e0f21..bd07f5aab38f6 100644 --- a/command/kv/put/kv_put_test.go +++ b/command/kv/put/kv_put_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package put diff --git a/command/leave/leave.go b/command/leave/leave.go index 8d997fb83c8dd..d822b5fedc540 100644 --- a/command/leave/leave.go +++ b/command/leave/leave.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package leave diff --git a/command/leave/leave_test.go b/command/leave/leave_test.go index 317a6862b91ec..67f16fefb74a9 100644 --- a/command/leave/leave_test.go +++ b/command/leave/leave_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package leave diff --git a/command/lock/lock.go b/command/lock/lock.go index a662babe041ff..f1acfd4f90937 100644 --- a/command/lock/lock.go +++ b/command/lock/lock.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lock diff --git a/command/lock/lock_test.go b/command/lock/lock_test.go index f32de5bc5e463..d90a7c0826c9e 100644 --- a/command/lock/lock_test.go +++ b/command/lock/lock_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lock diff --git a/command/lock/util_unix.go b/command/lock/util_unix.go index de864f0b358aa..3c754560b4e12 100644 --- a/command/lock/util_unix.go +++ b/command/lock/util_unix.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !windows +// +build !windows package lock diff --git a/command/lock/util_windows.go b/command/lock/util_windows.go index 33a531c3618d4..9a271af66d1d2 100644 --- a/command/lock/util_windows.go +++ b/command/lock/util_windows.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build windows +// +build windows package lock diff --git a/command/login/aws.go b/command/login/aws.go index e7fb6af58eeff..99230679c13d5 100644 --- a/command/login/aws.go +++ b/command/login/aws.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package login diff --git a/command/login/login.go b/command/login/login.go index 0ab5237852929..18f2762c99543 100644 --- a/command/login/login.go +++ b/command/login/login.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package login diff --git a/command/login/login_ce.go b/command/login/login_ce.go index 1ae2455a488a3..365d89dfd5dee 100644 --- a/command/login/login_ce.go +++ b/command/login/login_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package login diff --git a/command/login/login_test.go b/command/login/login_test.go index c3bf117676178..918e1fcbff2fd 100644 --- a/command/login/login_test.go +++ b/command/login/login_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package login diff --git a/command/logout/logout.go b/command/logout/logout.go index 35365f4469547..8ff8fb6778926 100644 --- a/command/logout/logout.go +++ b/command/logout/logout.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logout diff --git a/command/logout/logout_test.go b/command/logout/logout_test.go index 7228def746b88..1e3890bb8acb9 100644 --- a/command/logout/logout_test.go +++ b/command/logout/logout_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logout diff --git a/command/maint/maint.go b/command/maint/maint.go index 252aa1de46a73..e9d189157b1f2 100644 --- a/command/maint/maint.go +++ b/command/maint/maint.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package maint diff --git a/command/maint/maint_test.go b/command/maint/maint_test.go index eabd173a623f9..c182ecbdf3ab3 100644 --- a/command/maint/maint_test.go +++ b/command/maint/maint_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package maint diff --git a/command/members/members.go b/command/members/members.go index 7b10612643b08..9895837f6484d 100644 --- a/command/members/members.go +++ b/command/members/members.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package members diff --git a/command/members/members_test.go b/command/members/members_test.go index 76e3bbe1260d2..646c51ec6248d 100644 --- a/command/members/members_test.go +++ b/command/members/members_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package members diff --git a/command/monitor/monitor.go b/command/monitor/monitor.go index e1d0e8597d502..0703b34a05120 100644 --- a/command/monitor/monitor.go +++ b/command/monitor/monitor.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package monitor diff --git a/command/monitor/monitor_test.go b/command/monitor/monitor_test.go index e9eacdda4caf6..61abfb6c9bf07 100644 --- a/command/monitor/monitor_test.go +++ b/command/monitor/monitor_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package monitor diff --git a/command/operator/autopilot/get/operator_autopilot_get.go b/command/operator/autopilot/get/operator_autopilot_get.go index 5cc2dc351e34a..d891672782673 100644 --- a/command/operator/autopilot/get/operator_autopilot_get.go +++ b/command/operator/autopilot/get/operator_autopilot_get.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package get diff --git a/command/operator/autopilot/get/operator_autopilot_get_test.go b/command/operator/autopilot/get/operator_autopilot_get_test.go index 264706ea24452..fc5e0f12e1aeb 100644 --- a/command/operator/autopilot/get/operator_autopilot_get_test.go +++ b/command/operator/autopilot/get/operator_autopilot_get_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package get diff --git a/command/operator/autopilot/operator_autopilot.go b/command/operator/autopilot/operator_autopilot.go index d1de582fbecf9..38d51641eb593 100644 --- a/command/operator/autopilot/operator_autopilot.go +++ b/command/operator/autopilot/operator_autopilot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autopilot diff --git a/command/operator/autopilot/operator_autopilot_test.go b/command/operator/autopilot/operator_autopilot_test.go index 9861749b172a4..9fa91f988b2fc 100644 --- a/command/operator/autopilot/operator_autopilot_test.go +++ b/command/operator/autopilot/operator_autopilot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package autopilot diff --git a/command/operator/autopilot/set/operator_autopilot_set.go b/command/operator/autopilot/set/operator_autopilot_set.go index 6a8dd5fec9ae7..c396dd5d966c4 100644 --- a/command/operator/autopilot/set/operator_autopilot_set.go +++ b/command/operator/autopilot/set/operator_autopilot_set.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package set diff --git a/command/operator/autopilot/set/operator_autopilot_set_test.go b/command/operator/autopilot/set/operator_autopilot_set_test.go index b92e7ef4b4fd8..c8d757bdbbc73 100644 --- a/command/operator/autopilot/set/operator_autopilot_set_test.go +++ b/command/operator/autopilot/set/operator_autopilot_set_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package set diff --git a/command/operator/autopilot/state/formatter.go b/command/operator/autopilot/state/formatter.go index 11cec09c6a160..f4e42a6578ed9 100644 --- a/command/operator/autopilot/state/formatter.go +++ b/command/operator/autopilot/state/formatter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/command/operator/autopilot/state/operator_autopilot_state.go b/command/operator/autopilot/state/operator_autopilot_state.go index be85fdb3ccf18..b5fd6d0718862 100644 --- a/command/operator/autopilot/state/operator_autopilot_state.go +++ b/command/operator/autopilot/state/operator_autopilot_state.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/command/operator/autopilot/state/operator_autopilot_state_test.go b/command/operator/autopilot/state/operator_autopilot_state_test.go index adc4b65933b1f..d81abcde44f7f 100644 --- a/command/operator/autopilot/state/operator_autopilot_state_test.go +++ b/command/operator/autopilot/state/operator_autopilot_state_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package state diff --git a/command/operator/operator.go b/command/operator/operator.go index 06c8c7622e487..b66924d3cb715 100644 --- a/command/operator/operator.go +++ b/command/operator/operator.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package operator diff --git a/command/operator/operator_test.go b/command/operator/operator_test.go index d25f4fc4f8d38..822ffc52347d9 100644 --- a/command/operator/operator_test.go +++ b/command/operator/operator_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package operator diff --git a/command/operator/raft/listpeers/operator_raft_list.go b/command/operator/raft/listpeers/operator_raft_list.go index abe682c103715..29643a87cf33b 100644 --- a/command/operator/raft/listpeers/operator_raft_list.go +++ b/command/operator/raft/listpeers/operator_raft_list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package listpeers diff --git a/command/operator/raft/listpeers/operator_raft_list_test.go b/command/operator/raft/listpeers/operator_raft_list_test.go index c29ed9d418e9c..0694e0dd10465 100644 --- a/command/operator/raft/listpeers/operator_raft_list_test.go +++ b/command/operator/raft/listpeers/operator_raft_list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package listpeers diff --git a/command/operator/raft/operator_raft.go b/command/operator/raft/operator_raft.go index 52bcb446f9b10..42b6175e974db 100644 --- a/command/operator/raft/operator_raft.go +++ b/command/operator/raft/operator_raft.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package raft diff --git a/command/operator/raft/operator_raft_test.go b/command/operator/raft/operator_raft_test.go index cac0545fa511e..275606ab5aeca 100644 --- a/command/operator/raft/operator_raft_test.go +++ b/command/operator/raft/operator_raft_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package raft diff --git a/command/operator/raft/removepeer/operator_raft_remove.go b/command/operator/raft/removepeer/operator_raft_remove.go index 12692d4d5225f..eea10a045d9ad 100644 --- a/command/operator/raft/removepeer/operator_raft_remove.go +++ b/command/operator/raft/removepeer/operator_raft_remove.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package removepeer diff --git a/command/operator/raft/removepeer/operator_raft_remove_test.go b/command/operator/raft/removepeer/operator_raft_remove_test.go index e7647712647d8..e81fc1474a386 100644 --- a/command/operator/raft/removepeer/operator_raft_remove_test.go +++ b/command/operator/raft/removepeer/operator_raft_remove_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package removepeer diff --git a/command/operator/raft/transferleader/transfer_leader.go b/command/operator/raft/transferleader/transfer_leader.go index c7694b65a6ed9..9e3630c056015 100644 --- a/command/operator/raft/transferleader/transfer_leader.go +++ b/command/operator/raft/transferleader/transfer_leader.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package transferleader @@ -53,7 +53,7 @@ func (c *cmd) Run(args []string) int { } // Fetch the current configuration. - result, err := raftTransferLeader(client, c.http.Stale(), c.id) + result, err := raftTransferLeader(client, c.http.Stale()) if err != nil { c.UI.Error(fmt.Sprintf("Error transfering leadership: %v", err)) return 1 @@ -63,11 +63,11 @@ func (c *cmd) Run(args []string) int { return 0 } -func raftTransferLeader(client *api.Client, stale bool, id string) (string, error) { +func raftTransferLeader(client *api.Client, stale bool) (string, error) { q := &api.QueryOptions{ AllowStale: stale, } - reply, err := client.Operator().RaftLeaderTransfer(id, q) + reply, err := client.Operator().RaftLeaderTransfer(q) if err != nil { return "", fmt.Errorf("Failed to transfer leadership %w", err) } diff --git a/command/operator/raft/transferleader/transfer_leader_test.go b/command/operator/raft/transferleader/transfer_leader_test.go index 2b56fe1d784f6..7c0fc4115dbc4 100644 --- a/command/operator/raft/transferleader/transfer_leader_test.go +++ b/command/operator/raft/transferleader/transfer_leader_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package transferleader diff --git a/command/operator/usage/instances/usage_instances.go b/command/operator/usage/instances/usage_instances.go index 4926f85ead9c3..1ac90dce8d363 100644 --- a/command/operator/usage/instances/usage_instances.go +++ b/command/operator/usage/instances/usage_instances.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package instances @@ -11,11 +11,9 @@ import ( "strings" "text/tabwriter" - "github.com/mitchellh/cli" - "golang.org/x/exp/maps" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/command/flags" + "github.com/mitchellh/cli" ) func New(ui cli.Ui) *cmd { @@ -137,11 +135,9 @@ func formatNodesCounts(usageStats map[string]api.ServiceUsage) (string, error) { fmt.Fprint(tw, "\t\n") - nodes := maps.Keys(usageStats) - sort.Strings(nodes) - for _, dc := range nodes { - nodesTotal += usageStats[dc].Nodes - fmt.Fprintf(tw, "%s\t%d\n", dc, usageStats[dc].Nodes) + for dc, usage := range usageStats { + nodesTotal += usage.Nodes + fmt.Fprintf(tw, "%s\t%d\n", dc, usage.Nodes) } fmt.Fprint(tw, "\t\n") diff --git a/command/operator/usage/instances/usage_instances_ce.go b/command/operator/usage/instances/usage_instances_ce.go index 149131ecb3c59..dc9511b32ce28 100644 --- a/command/operator/usage/instances/usage_instances_ce.go +++ b/command/operator/usage/instances/usage_instances_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package instances diff --git a/command/operator/usage/instances/usage_instances_ce_test.go b/command/operator/usage/instances/usage_instances_ce_test.go index c7d50568a1a2a..478b9f42118b8 100644 --- a/command/operator/usage/instances/usage_instances_ce_test.go +++ b/command/operator/usage/instances/usage_instances_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package instances diff --git a/command/operator/usage/instances/usage_instances_test.go b/command/operator/usage/instances/usage_instances_test.go index 7dac04dd3e323..8ad38e1b0c53a 100644 --- a/command/operator/usage/instances/usage_instances_test.go +++ b/command/operator/usage/instances/usage_instances_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package instances diff --git a/command/operator/usage/usage.go b/command/operator/usage/usage.go index 6e7cde57e4bf5..3d733f8f36ffb 100644 --- a/command/operator/usage/usage.go +++ b/command/operator/usage/usage.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package usage diff --git a/command/peering/delete/delete.go b/command/peering/delete/delete.go index 039ace5391884..f4399b73ce2f4 100644 --- a/command/peering/delete/delete.go +++ b/command/peering/delete/delete.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package delete diff --git a/command/peering/delete/delete_test.go b/command/peering/delete/delete_test.go index 5aa299b78d52a..56d0d495a897c 100644 --- a/command/peering/delete/delete_test.go +++ b/command/peering/delete/delete_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package delete diff --git a/command/peering/establish/establish.go b/command/peering/establish/establish.go index 42178f149040d..ef5178eecf8aa 100644 --- a/command/peering/establish/establish.go +++ b/command/peering/establish/establish.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package establish diff --git a/command/peering/establish/establish_test.go b/command/peering/establish/establish_test.go index 25abae316bc43..515b727f78b69 100644 --- a/command/peering/establish/establish_test.go +++ b/command/peering/establish/establish_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package establish diff --git a/command/peering/generate/generate.go b/command/peering/generate/generate.go index e2122aa7aa095..26410480f517b 100644 --- a/command/peering/generate/generate.go +++ b/command/peering/generate/generate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package generate diff --git a/command/peering/generate/generate_test.go b/command/peering/generate/generate_test.go index 863b266ed15e2..529f46aacdf6e 100644 --- a/command/peering/generate/generate_test.go +++ b/command/peering/generate/generate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package generate diff --git a/command/peering/list/list.go b/command/peering/list/list.go index 10e85d9b582f4..87fb6bade5998 100644 --- a/command/peering/list/list.go +++ b/command/peering/list/list.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package list diff --git a/command/peering/list/list_test.go b/command/peering/list/list_test.go index 43da9684728e0..f923e6d2b7615 100644 --- a/command/peering/list/list_test.go +++ b/command/peering/list/list_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package list diff --git a/command/peering/peering.go b/command/peering/peering.go index 157dd42c63d71..2a4834e514c23 100644 --- a/command/peering/peering.go +++ b/command/peering/peering.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peering diff --git a/command/peering/read/read.go b/command/peering/read/read.go index 8d15210fcfaa9..ddd44cb4fe8b8 100644 --- a/command/peering/read/read.go +++ b/command/peering/read/read.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package read diff --git a/command/peering/read/read_test.go b/command/peering/read/read_test.go index 90a2ac879244e..42b3544661753 100644 --- a/command/peering/read/read_test.go +++ b/command/peering/read/read_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package read diff --git a/command/registry.go b/command/registry.go index 559189b6f9885..b370f14bc872c 100644 --- a/command/registry.go +++ b/command/registry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package command @@ -36,10 +36,6 @@ import ( aclrlist "github.com/hashicorp/consul/command/acl/role/list" aclrread "github.com/hashicorp/consul/command/acl/role/read" aclrupdate "github.com/hashicorp/consul/command/acl/role/update" - acltp "github.com/hashicorp/consul/command/acl/templatedpolicy" - acltplist "github.com/hashicorp/consul/command/acl/templatedpolicy/list" - acltppreview "github.com/hashicorp/consul/command/acl/templatedpolicy/preview" - acltpread "github.com/hashicorp/consul/command/acl/templatedpolicy/read" acltoken "github.com/hashicorp/consul/command/acl/token" acltclone "github.com/hashicorp/consul/command/acl/token/clone" acltcreate "github.com/hashicorp/consul/command/acl/token/create" @@ -112,11 +108,6 @@ import ( peerlist "github.com/hashicorp/consul/command/peering/list" peerread "github.com/hashicorp/consul/command/peering/read" "github.com/hashicorp/consul/command/reload" - "github.com/hashicorp/consul/command/resource" - resourceapply "github.com/hashicorp/consul/command/resource/apply" - resourcedelete "github.com/hashicorp/consul/command/resource/delete" - resourcelist "github.com/hashicorp/consul/command/resource/list" - resourceread "github.com/hashicorp/consul/command/resource/read" "github.com/hashicorp/consul/command/rtt" "github.com/hashicorp/consul/command/services" svcsderegister "github.com/hashicorp/consul/command/services/deregister" @@ -182,10 +173,6 @@ func RegisteredCommands(ui cli.Ui) map[string]mcli.CommandFactory { entry{"acl binding-rule read", func(ui cli.Ui) (cli.Command, error) { return aclbrread.New(ui), nil }}, entry{"acl binding-rule update", func(ui cli.Ui) (cli.Command, error) { return aclbrupdate.New(ui), nil }}, entry{"acl binding-rule delete", func(ui cli.Ui) (cli.Command, error) { return aclbrdelete.New(ui), nil }}, - entry{"acl templated-policy", func(cli.Ui) (cli.Command, error) { return acltp.New(), nil }}, - entry{"acl templated-policy list", func(ui cli.Ui) (cli.Command, error) { return acltplist.New(ui), nil }}, - entry{"acl templated-policy read", func(ui cli.Ui) (cli.Command, error) { return acltpread.New(ui), nil }}, - entry{"acl templated-policy preview", func(ui cli.Ui) (cli.Command, error) { return acltppreview.New(ui), nil }}, entry{"agent", func(ui cli.Ui) (cli.Command, error) { return agent.New(ui), nil }}, entry{"catalog", func(cli.Ui) (cli.Command, error) { return catalog.New(), nil }}, entry{"catalog datacenters", func(ui cli.Ui) (cli.Command, error) { return catlistdc.New(ui), nil }}, @@ -251,11 +238,6 @@ func RegisteredCommands(ui cli.Ui) map[string]mcli.CommandFactory { entry{"peering list", func(ui cli.Ui) (cli.Command, error) { return peerlist.New(ui), nil }}, entry{"peering read", func(ui cli.Ui) (cli.Command, error) { return peerread.New(ui), nil }}, entry{"reload", func(ui cli.Ui) (cli.Command, error) { return reload.New(ui), nil }}, - entry{"resource", func(cli.Ui) (cli.Command, error) { return resource.New(), nil }}, - entry{"resource read", func(ui cli.Ui) (cli.Command, error) { return resourceread.New(ui), nil }}, - entry{"resource delete", func(ui cli.Ui) (cli.Command, error) { return resourcedelete.New(ui), nil }}, - entry{"resource apply", func(ui cli.Ui) (cli.Command, error) { return resourceapply.New(ui), nil }}, - entry{"resource list", func(ui cli.Ui) (cli.Command, error) { return resourcelist.New(ui), nil }}, entry{"rtt", func(ui cli.Ui) (cli.Command, error) { return rtt.New(ui), nil }}, entry{"services", func(cli.Ui) (cli.Command, error) { return services.New(), nil }}, entry{"services register", func(ui cli.Ui) (cli.Command, error) { return svcsregister.New(ui), nil }}, diff --git a/command/registry_ce.go b/command/registry_ce.go index f797b8f75b496..2a7708221022a 100644 --- a/command/registry_ce.go +++ b/command/registry_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package command diff --git a/command/reload/reload.go b/command/reload/reload.go index 458b90cbf6a89..b0989817fdc07 100644 --- a/command/reload/reload.go +++ b/command/reload/reload.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package reload diff --git a/command/reload/reload_test.go b/command/reload/reload_test.go index 11313fb138418..d75712c539347 100644 --- a/command/reload/reload_test.go +++ b/command/reload/reload_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package reload diff --git a/command/resource/apply/apply.go b/command/resource/apply/apply.go deleted file mode 100644 index df3f136c5028e..0000000000000 --- a/command/resource/apply/apply.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package apply - -import ( - "encoding/json" - "errors" - "flag" - "fmt" - "io" - - "github.com/mitchellh/cli" - "google.golang.org/protobuf/encoding/protojson" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/command/flags" - "github.com/hashicorp/consul/command/resource" - "github.com/hashicorp/consul/command/resource/client" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func New(ui cli.Ui) *cmd { - c := &cmd{UI: ui} - c.init() - return c -} - -type cmd struct { - UI cli.Ui - flags *flag.FlagSet - http *flags.HTTPFlags - help string - - filePath string - - testStdin io.Reader -} - -func (c *cmd) init() { - c.flags = flag.NewFlagSet("", flag.ContinueOnError) - c.flags.StringVar(&c.filePath, "f", "", - "File path with resource definition") - - c.http = &flags.HTTPFlags{} - flags.Merge(c.flags, c.http.ClientFlags()) - c.help = flags.Usage(help, c.flags) -} - -func makeWriteRequest(parsedResource *pbresource.Resource) (payload *resource.WriteRequest, error error) { - // The parsed hcl file has data field in proto message format anypb.Any - // Converting to json format requires us to fisrt marshal it then unmarshal it - data, err := protojson.Marshal(parsedResource.Data) - if err != nil { - return nil, fmt.Errorf("unrecognized hcl format: %s", err) - } - - var resourceData map[string]any - err = json.Unmarshal(data, &resourceData) - if err != nil { - return nil, fmt.Errorf("unrecognized hcl format: %s", err) - } - delete(resourceData, "@type") - - return &resource.WriteRequest{ - Data: resourceData, - Metadata: parsedResource.GetMetadata(), - Owner: parsedResource.GetOwner(), - }, nil -} - -func (c *cmd) Run(args []string) int { - if err := c.flags.Parse(args); err != nil { - if !errors.Is(err, flag.ErrHelp) { - c.UI.Error(fmt.Sprintf("Failed to parse args: %v", err)) - return 1 - } - } - - input := c.filePath - - if input == "" && len(c.flags.Args()) > 0 { - input = c.flags.Arg(0) - } - - var parsedResource *pbresource.Resource - - if input != "" { - data, err := resource.ParseResourceInput(input, c.testStdin) - if err != nil { - c.UI.Error(fmt.Sprintf("Failed to decode resource from input file: %v", err)) - return 1 - } - parsedResource = data - } else { - c.UI.Error("Incorrect argument format: Must provide exactly one positional argument to specify the resource to write") - return 1 - } - - if parsedResource == nil { - c.UI.Error("Unable to parse the file argument") - return 1 - } - - config := api.DefaultConfig() - - c.http.MergeOntoConfig(config) - resourceClient, err := client.NewClient(config) - if err != nil { - c.UI.Error(fmt.Sprintf("Error connect to Consul agent: %s", err)) - return 1 - } - - res := resource.Resource{C: resourceClient} - - opts := &client.QueryOptions{ - Namespace: parsedResource.Id.Tenancy.GetNamespace(), - Partition: parsedResource.Id.Tenancy.GetPartition(), - Peer: parsedResource.Id.Tenancy.GetPeerName(), - Token: c.http.Token(), - } - - gvk := &resource.GVK{ - Group: parsedResource.Id.Type.GetGroup(), - Version: parsedResource.Id.Type.GetGroupVersion(), - Kind: parsedResource.Id.Type.GetKind(), - } - - writeRequest, err := makeWriteRequest(parsedResource) - if err != nil { - c.UI.Error(fmt.Sprintf("Error parsing hcl input: %v", err)) - return 1 - } - - entry, err := res.Apply(gvk, parsedResource.Id.GetName(), opts, writeRequest) - if err != nil { - c.UI.Error(fmt.Sprintf("Error writing resource %s/%s: %v", gvk, parsedResource.Id.GetName(), err)) - return 1 - } - - b, err := json.MarshalIndent(entry, "", " ") - if err != nil { - c.UI.Error("Failed to encode output data") - return 1 - } - - c.UI.Info(fmt.Sprintf("%s.%s.%s '%s' created.", gvk.Group, gvk.Version, gvk.Kind, parsedResource.Id.GetName())) - c.UI.Info(string(b)) - return 0 -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(c.help, nil) -} - -const synopsis = "Writes/updates resource information" - -const help = ` -Usage: consul resource apply [options] - - Write and/or update a resource by providing the definition. The configuration - argument is either a file path or '-' to indicate that the resource - should be read from stdin. The data should be either in HCL or - JSON form. - - Example (with flag): - - $ consul resource apply -f=demo.hcl - - Example (from file): - - $ consul resource apply demo.hcl - - Example (from stdin): - - $ consul resource apply - - - Sample demo.hcl: - - ID { - Type = gvk("group.version.kind") - Name = "resource-name" - Tenancy { - Namespace = "default" - Partition = "default" - PeerName = "local" - } - } - - Data { - Name = "demo" - } - - Metadata = { - "foo" = "bar" - } -` diff --git a/command/resource/apply/apply_test.go b/command/resource/apply/apply_test.go deleted file mode 100644 index 2644e7aaebdde..0000000000000 --- a/command/resource/apply/apply_test.go +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package apply - -import ( - "errors" - "io" - "testing" - - "github.com/mitchellh/cli" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent" - "github.com/hashicorp/consul/command/resource/read" - "github.com/hashicorp/consul/testrpc" -) - -func TestResourceApplyCommand(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - a := agent.NewTestAgent(t, ``) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") - - cases := []struct { - name string - output string - args []string - }{ - { - name: "sample output", - args: []string{"-f=../testdata/demo.hcl"}, - output: "demo.v2.Artist 'korn' created.", - }, - { - name: "nested data format", - args: []string{"-f=../testdata/nested_data.hcl"}, - output: "mesh.v2beta1.Destinations 'api' created.", - }, - { - name: "file path with no flag", - args: []string{"../testdata/nested_data.hcl"}, - output: "mesh.v2beta1.Destinations 'api' created.", - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - ui := cli.NewMockUi() - c := New(ui) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - args = append(args, tc.args...) - - code := c.Run(args) - require.Equal(t, 0, code) - require.Empty(t, ui.ErrorWriter.String()) - require.Contains(t, ui.OutputWriter.String(), tc.output) - }) - } -} - -func readResource(t *testing.T, a *agent.TestAgent, extraArgs []string) string { - readUi := cli.NewMockUi() - readCmd := read.New(readUi) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - args = append(extraArgs, args...) - - code := readCmd.Run(args) - require.Equal(t, 0, code) - require.Empty(t, readUi.ErrorWriter.String()) - return readUi.OutputWriter.String() -} - -func TestResourceApplyCommand_StdIn(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - a := agent.NewTestAgent(t, ``) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") - - t.Run("hcl", func(t *testing.T) { - stdinR, stdinW := io.Pipe() - - ui := cli.NewMockUi() - c := New(ui) - c.testStdin = stdinR - - stdInput := `ID { - Type = gvk("demo.v2.Artist") - Name = "korn" - Tenancy { - Namespace = "default" - Partition = "default" - PeerName = "local" - } - } - - Data { - Name = "Korn" - Genre = "GENRE_METAL" - } - - Metadata = { - "foo" = "bar" - }` - - go func() { - stdinW.Write([]byte(stdInput)) - stdinW.Close() - }() - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-", - } - - code := c.Run(args) - require.Equal(t, 0, code) - require.Empty(t, ui.ErrorWriter.String()) - expected := readResource(t, a, []string{"demo.v2.Artist", "korn"}) - require.Contains(t, ui.OutputWriter.String(), "demo.v2.Artist 'korn' created.") - require.Contains(t, ui.OutputWriter.String(), expected) - }) - - t.Run("json", func(t *testing.T) { - stdinR, stdinW := io.Pipe() - - ui := cli.NewMockUi() - c := New(ui) - c.testStdin = stdinR - - stdInput := `{ - "data": { - "genre": "GENRE_METAL", - "name": "Korn" - }, - "id": { - "name": "korn", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "demo", - "groupVersion": "v2", - "kind": "Artist" - } - }, - "metadata": { - "foo": "bar" - } - }` - - go func() { - stdinW.Write([]byte(stdInput)) - stdinW.Close() - }() - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-", - } - - code := c.Run(args) - require.Equal(t, 0, code) - require.Empty(t, ui.ErrorWriter.String()) - expected := readResource(t, a, []string{"demo.v2.Artist", "korn"}) - require.Contains(t, ui.OutputWriter.String(), "demo.v2.Artist 'korn' created.") - require.Contains(t, ui.OutputWriter.String(), expected) - }) -} - -func TestResourceApplyInvalidArgs(t *testing.T) { - t.Parallel() - - type tc struct { - args []string - expectedCode int - expectedErr error - } - - cases := map[string]tc{ - "no file path": { - args: []string{"-f"}, - expectedCode: 1, - expectedErr: errors.New("Failed to parse args: flag needs an argument: -f"), - }, - "missing required flag": { - args: []string{}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must provide exactly one positional argument to specify the resource to write"), - }, - "file parsing failure": { - args: []string{"-f=../testdata/invalid.hcl"}, - expectedCode: 1, - expectedErr: errors.New("Failed to decode resource from input file"), - }, - "file not found": { - args: []string{"-f=../testdata/test.hcl"}, - expectedCode: 1, - expectedErr: errors.New("Failed to load data: Failed to read file: open ../testdata/test.hcl: no such file or directory"), - }, - } - - for desc, tc := range cases { - t.Run(desc, func(t *testing.T) { - ui := cli.NewMockUi() - c := New(ui) - - code := c.Run(tc.args) - - require.Equal(t, tc.expectedCode, code) - require.Contains(t, ui.ErrorWriter.String(), tc.expectedErr.Error()) - }) - } -} diff --git a/command/resource/client/client.go b/command/resource/client/client.go deleted file mode 100644 index 0d0d59e2df996..0000000000000 --- a/command/resource/client/client.go +++ /dev/null @@ -1,1073 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package client - -import ( - "bytes" - "context" - "crypto/tls" - "encoding/json" - "fmt" - "io" - "net" - "net/http" - "net/url" - "os" - "strconv" - "strings" - "sync" - "time" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/go-cleanhttp" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-rootcerts" -) - -// NOTE: This client is copied from the api module to temporarily facilitate the resource cli commands - -const ( - // HTTPAddrEnvName defines an environment variable name which sets - // the HTTP address if there is no -http-addr specified. - HTTPAddrEnvName = "CONSUL_HTTP_ADDR" - - // HTTPTokenEnvName defines an environment variable name which sets - // the HTTP token. - HTTPTokenEnvName = "CONSUL_HTTP_TOKEN" - - // HTTPTokenFileEnvName defines an environment variable name which sets - // the HTTP token file. - HTTPTokenFileEnvName = "CONSUL_HTTP_TOKEN_FILE" - - // HTTPAuthEnvName defines an environment variable name which sets - // the HTTP authentication header. - HTTPAuthEnvName = "CONSUL_HTTP_AUTH" - - // HTTPSSLEnvName defines an environment variable name which sets - // whether or not to use HTTPS. - HTTPSSLEnvName = "CONSUL_HTTP_SSL" - - // HTTPCAFile defines an environment variable name which sets the - // CA file to use for talking to Consul over TLS. - HTTPCAFile = "CONSUL_CACERT" - - // HTTPCAPath defines an environment variable name which sets the - // path to a directory of CA certs to use for talking to Consul over TLS. - HTTPCAPath = "CONSUL_CAPATH" - - // HTTPClientCert defines an environment variable name which sets the - // client cert file to use for talking to Consul over TLS. - HTTPClientCert = "CONSUL_CLIENT_CERT" - - // HTTPClientKey defines an environment variable name which sets the - // client key file to use for talking to Consul over TLS. - HTTPClientKey = "CONSUL_CLIENT_KEY" - - // HTTPTLSServerName defines an environment variable name which sets the - // server name to use as the SNI host when connecting via TLS - HTTPTLSServerName = "CONSUL_TLS_SERVER_NAME" - - // HTTPSSLVerifyEnvName defines an environment variable name which sets - // whether or not to disable certificate checking. - HTTPSSLVerifyEnvName = "CONSUL_HTTP_SSL_VERIFY" - - // GRPCAddrEnvName defines an environment variable name which sets the gRPC - // address for consul connect envoy. Note this isn't actually used by the api - // client in this package but is defined here for consistency with all the - // other ENV names we use. - GRPCAddrEnvName = "CONSUL_GRPC_ADDR" - - // GRPCCAFileEnvName defines an environment variable name which sets the - // CA file to use for talking to Consul gRPC over TLS. - GRPCCAFileEnvName = "CONSUL_GRPC_CACERT" - - // GRPCCAPathEnvName defines an environment variable name which sets the - // path to a directory of CA certs to use for talking to Consul gRPC over TLS. - GRPCCAPathEnvName = "CONSUL_GRPC_CAPATH" - - // HTTPNamespaceEnvVar defines an environment variable name which sets - // the HTTP Namespace to be used by default. This can still be overridden. - HTTPNamespaceEnvName = "CONSUL_NAMESPACE" - - // HTTPPartitionEnvName defines an environment variable name which sets - // the HTTP Partition to be used by default. This can still be overridden. - HTTPPartitionEnvName = "CONSUL_PARTITION" - - // QueryBackendStreaming Query backend of type streaming - QueryBackendStreaming = "streaming" - - // QueryBackendBlockingQuery Query backend of type blocking query - QueryBackendBlockingQuery = "blocking-query" -) - -type StatusError struct { - Code int - Body string -} - -func (e StatusError) Error() string { - return fmt.Sprintf("Unexpected response code: %d (%s)", e.Code, e.Body) -} - -// QueryOptions are used to parameterize a query -type QueryOptions struct { - // Namespace overrides the `default` namespace - // Note: Namespaces are available only in Consul Enterprise - Namespace string - - // Partition overrides the `default` partition - // Note: Partitions are available only in Consul Enterprise - Partition string - - // Providing a datacenter overwrites the DC provided - // by the Config - Datacenter string - - // Providing a peer name in the query option - Peer string - - // AllowStale allows any Consul server (non-leader) to service - // a read. This allows for lower latency and higher throughput - AllowStale bool - - // RequireConsistent forces the read to be fully consistent. - // This is more expensive but prevents ever performing a stale - // read. - RequireConsistent bool - - // UseCache requests that the agent cache results locally. See - // https://www.consul.io/api/features/caching.html for more details on the - // semantics. - UseCache bool - - // MaxAge limits how old a cached value will be returned if UseCache is true. - // If there is a cached response that is older than the MaxAge, it is treated - // as a cache miss and a new fetch invoked. If the fetch fails, the error is - // returned. Clients that wish to allow for stale results on error can set - // StaleIfError to a longer duration to change this behavior. It is ignored - // if the endpoint supports background refresh caching. See - // https://www.consul.io/api/features/caching.html for more details. - MaxAge time.Duration - - // StaleIfError specifies how stale the client will accept a cached response - // if the servers are unavailable to fetch a fresh one. Only makes sense when - // UseCache is true and MaxAge is set to a lower, non-zero value. It is - // ignored if the endpoint supports background refresh caching. See - // https://www.consul.io/api/features/caching.html for more details. - StaleIfError time.Duration - - // WaitIndex is used to enable a blocking query. Waits - // until the timeout or the next index is reached - WaitIndex uint64 - - // WaitHash is used by some endpoints instead of WaitIndex to perform blocking - // on state based on a hash of the response rather than a monotonic index. - // This is required when the state being blocked on is not stored in Raft, for - // example agent-local proxy configuration. - WaitHash string - - // WaitTime is used to bound the duration of a wait. - // Defaults to that of the Config, but can be overridden. - WaitTime time.Duration - - // Token is used to provide a per-request ACL token - // which overrides the agent's default token. - Token string - - // Near is used to provide a node name that will sort the results - // in ascending order based on the estimated round trip time from - // that node. Setting this to "_agent" will use the agent's node - // for the sort. - Near string - - // NodeMeta is used to filter results by nodes with the given - // metadata key/value pairs. Currently, only one key/value pair can - // be provided for filtering. - NodeMeta map[string]string - - // RelayFactor is used in keyring operations to cause responses to be - // relayed back to the sender through N other random nodes. Must be - // a value from 0 to 5 (inclusive). - RelayFactor uint8 - - // LocalOnly is used in keyring list operation to force the keyring - // query to only hit local servers (no WAN traffic). - LocalOnly bool - - // Connect filters prepared query execution to only include Connect-capable - // services. This currently affects prepared query execution. - Connect bool - - // ctx is an optional context pass through to the underlying HTTP - // request layer. Use Context() and WithContext() to manage this. - ctx context.Context - - // Filter requests filtering data prior to it being returned. The string - // is a go-bexpr compatible expression. - Filter string - - // MergeCentralConfig returns a service definition merged with the - // proxy-defaults/global and service-defaults/:service config entries. - // This can be used to ensure a full service definition is returned in the response - // especially when the service might not be written into the catalog that way. - MergeCentralConfig bool - - // Global is used to request information from all datacenters. Currently only - // used for operator usage requests. - Global bool -} - -func (o *QueryOptions) Context() context.Context { - if o != nil && o.ctx != nil { - return o.ctx - } - return context.Background() -} - -func (o *QueryOptions) WithContext(ctx context.Context) *QueryOptions { - o2 := new(QueryOptions) - if o != nil { - *o2 = *o - } - o2.ctx = ctx - return o2 -} - -// WriteOptions are used to parameterize a write -type WriteOptions struct { - // Namespace overrides the `default` namespace - // Note: Namespaces are available only in Consul Enterprise - Namespace string - - // Partition overrides the `default` partition - // Note: Partitions are available only in Consul Enterprise - Partition string - - // Providing a datacenter overwrites the DC provided - // by the Config - Datacenter string - - // Token is used to provide a per-request ACL token - // which overrides the agent's default token. - Token string - - // RelayFactor is used in keyring operations to cause responses to be - // relayed back to the sender through N other random nodes. Must be - // a value from 0 to 5 (inclusive). - RelayFactor uint8 - - // ctx is an optional context pass through to the underlying HTTP - // request layer. Use Context() and WithContext() to manage this. - ctx context.Context -} - -func (o *WriteOptions) Context() context.Context { - if o != nil && o.ctx != nil { - return o.ctx - } - return context.Background() -} - -func (o *WriteOptions) WithContext(ctx context.Context) *WriteOptions { - o2 := new(WriteOptions) - if o != nil { - *o2 = *o - } - o2.ctx = ctx - return o2 -} - -// QueryMeta is used to return meta data about a query -type QueryMeta struct { - // LastIndex. This can be used as a WaitIndex to perform - // a blocking query - LastIndex uint64 - - // LastContentHash. This can be used as a WaitHash to perform a blocking query - // for endpoints that support hash-based blocking. Endpoints that do not - // support it will return an empty hash. - LastContentHash string - - // Time of last contact from the leader for the - // server servicing the request - LastContact time.Duration - - // Is there a known leader - KnownLeader bool - - // How long did the request take - RequestTime time.Duration - - // Is address translation enabled for HTTP responses on this agent - AddressTranslationEnabled bool - - // CacheHit is true if the result was served from agent-local cache. - CacheHit bool - - // CacheAge is set if request was ?cached and indicates how stale the cached - // response is. - CacheAge time.Duration - - // QueryBackend represent which backend served the request. - QueryBackend string - - // DefaultACLPolicy is used to control the ACL interaction when there is no - // defined policy. This can be "allow" which means ACLs are used to - // deny-list, or "deny" which means ACLs are allow-lists. - DefaultACLPolicy string - - // ResultsFilteredByACLs is true when some of the query's results were - // filtered out by enforcing ACLs. It may be false because nothing was - // removed, or because the endpoint does not yet support this flag. - ResultsFilteredByACLs bool -} - -// WriteMeta is used to return meta data about a write -type WriteMeta struct { - // How long did the request take - RequestTime time.Duration -} - -// HttpBasicAuth is used to authenticate http client with HTTP Basic Authentication -type HttpBasicAuth struct { - // Username to use for HTTP Basic Authentication - Username string - - // Password to use for HTTP Basic Authentication - Password string -} - -// Config is used to configure the creation of a client -type Config struct { - // Address is the address of the Consul server - Address string - - // Scheme is the URI scheme for the Consul server - Scheme string - - // Prefix for URIs for when consul is behind an API gateway (reverse - // proxy). The API gateway must strip off the PathPrefix before - // passing the request onto consul. - PathPrefix string - - // Datacenter to use. If not provided, the default agent datacenter is used. - Datacenter string - - // Transport is the Transport to use for the http client. - Transport *http.Transport - - // HttpClient is the client to use. Default will be - // used if not provided. - HttpClient *http.Client - - // HttpAuth is the auth info to use for http access. - HttpAuth *HttpBasicAuth - - // WaitTime limits how long a Watch will block. If not provided, - // the agent default values will be used. - WaitTime time.Duration - - // Token is used to provide a per-request ACL token - // which overrides the agent's default token. - Token string - - // TokenFile is a file containing the current token to use for this client. - // If provided it is read once at startup and never again. - TokenFile string - - // Namespace is the name of the namespace to send along for the request - // when no other Namespace is present in the QueryOptions - Namespace string - - // Partition is the name of the partition to send along for the request - // when no other Partition is present in the QueryOptions - Partition string - - TLSConfig TLSConfig -} - -// TLSConfig is used to generate a TLSClientConfig that's useful for talking to -// Consul using TLS. -type TLSConfig struct { - // Address is the optional address of the Consul server. The port, if any - // will be removed from here and this will be set to the ServerName of the - // resulting config. - Address string - - // CAFile is the optional path to the CA certificate used for Consul - // communication, defaults to the system bundle if not specified. - CAFile string - - // CAPath is the optional path to a directory of CA certificates to use for - // Consul communication, defaults to the system bundle if not specified. - CAPath string - - // CAPem is the optional PEM-encoded CA certificate used for Consul - // communication, defaults to the system bundle if not specified. - CAPem []byte - - // CertFile is the optional path to the certificate for Consul - // communication. If this is set then you need to also set KeyFile. - CertFile string - - // CertPEM is the optional PEM-encoded certificate for Consul - // communication. If this is set then you need to also set KeyPEM. - CertPEM []byte - - // KeyFile is the optional path to the private key for Consul communication. - // If this is set then you need to also set CertFile. - KeyFile string - - // KeyPEM is the optional PEM-encoded private key for Consul communication. - // If this is set then you need to also set CertPEM. - KeyPEM []byte - - // InsecureSkipVerify if set to true will disable TLS host verification. - InsecureSkipVerify bool -} - -// DefaultConfig returns a default configuration for the client. By default this -// will pool and reuse idle connections to Consul. If you have a long-lived -// client object, this is the desired behavior and should make the most efficient -// use of the connections to Consul. If you don't reuse a client object, which -// is not recommended, then you may notice idle connections building up over -// time. To avoid this, use the DefaultNonPooledConfig() instead. -func DefaultConfig() *Config { - return defaultConfig(nil, cleanhttp.DefaultPooledTransport) -} - -// DefaultConfigWithLogger returns a default configuration for the client. It -// is exactly the same as DefaultConfig, but allows for a pre-configured logger -// object to be passed through. -func DefaultConfigWithLogger(logger hclog.Logger) *Config { - return defaultConfig(logger, cleanhttp.DefaultPooledTransport) -} - -// DefaultNonPooledConfig returns a default configuration for the client which -// does not pool connections. This isn't a recommended configuration because it -// will reconnect to Consul on every request, but this is useful to avoid the -// accumulation of idle connections if you make many client objects during the -// lifetime of your application. -func DefaultNonPooledConfig() *Config { - return defaultConfig(nil, cleanhttp.DefaultTransport) -} - -// defaultConfig returns the default configuration for the client, using the -// given function to make the transport. -func defaultConfig(logger hclog.Logger, transportFn func() *http.Transport) *Config { - if logger == nil { - logger = hclog.New(&hclog.LoggerOptions{ - Name: "consul-api", - }) - } - - config := &Config{ - Address: "127.0.0.1:8500", - Scheme: "http", - Transport: transportFn(), - } - - if addr := os.Getenv(HTTPAddrEnvName); addr != "" { - config.Address = addr - } - - if tokenFile := os.Getenv(HTTPTokenFileEnvName); tokenFile != "" { - config.TokenFile = tokenFile - } - - if token := os.Getenv(HTTPTokenEnvName); token != "" { - config.Token = token - } - - if auth := os.Getenv(HTTPAuthEnvName); auth != "" { - var username, password string - if strings.Contains(auth, ":") { - split := strings.SplitN(auth, ":", 2) - username = split[0] - password = split[1] - } else { - username = auth - } - - config.HttpAuth = &HttpBasicAuth{ - Username: username, - Password: password, - } - } - - if ssl := os.Getenv(HTTPSSLEnvName); ssl != "" { - enabled, err := strconv.ParseBool(ssl) - if err != nil { - logger.Warn(fmt.Sprintf("could not parse %s", HTTPSSLEnvName), "error", err) - } - - if enabled { - config.Scheme = "https" - } - } - - if v := os.Getenv(HTTPTLSServerName); v != "" { - config.TLSConfig.Address = v - } - if v := os.Getenv(HTTPCAFile); v != "" { - config.TLSConfig.CAFile = v - } - if v := os.Getenv(HTTPCAPath); v != "" { - config.TLSConfig.CAPath = v - } - if v := os.Getenv(HTTPClientCert); v != "" { - config.TLSConfig.CertFile = v - } - if v := os.Getenv(HTTPClientKey); v != "" { - config.TLSConfig.KeyFile = v - } - if v := os.Getenv(HTTPSSLVerifyEnvName); v != "" { - doVerify, err := strconv.ParseBool(v) - if err != nil { - logger.Warn(fmt.Sprintf("could not parse %s", HTTPSSLVerifyEnvName), "error", err) - } - if !doVerify { - config.TLSConfig.InsecureSkipVerify = true - } - } - - if v := os.Getenv(HTTPNamespaceEnvName); v != "" { - config.Namespace = v - } - - if v := os.Getenv(HTTPPartitionEnvName); v != "" { - config.Partition = v - } - - return config -} - -// TLSConfig is used to generate a TLSClientConfig that's useful for talking to -// Consul using TLS. -func SetupTLSConfig(tlsConfig *TLSConfig) (*tls.Config, error) { - tlsClientConfig := &tls.Config{ - InsecureSkipVerify: tlsConfig.InsecureSkipVerify, - } - - if tlsConfig.Address != "" { - server := tlsConfig.Address - hasPort := strings.LastIndex(server, ":") > strings.LastIndex(server, "]") - if hasPort { - var err error - server, _, err = net.SplitHostPort(server) - if err != nil { - return nil, err - } - } - tlsClientConfig.ServerName = server - } - - if len(tlsConfig.CertPEM) != 0 && len(tlsConfig.KeyPEM) != 0 { - tlsCert, err := tls.X509KeyPair(tlsConfig.CertPEM, tlsConfig.KeyPEM) - if err != nil { - return nil, err - } - tlsClientConfig.Certificates = []tls.Certificate{tlsCert} - } else if len(tlsConfig.CertPEM) != 0 || len(tlsConfig.KeyPEM) != 0 { - return nil, fmt.Errorf("both client cert and client key must be provided") - } - - if tlsConfig.CertFile != "" && tlsConfig.KeyFile != "" { - tlsCert, err := tls.LoadX509KeyPair(tlsConfig.CertFile, tlsConfig.KeyFile) - if err != nil { - return nil, err - } - tlsClientConfig.Certificates = []tls.Certificate{tlsCert} - } else if tlsConfig.CertFile != "" || tlsConfig.KeyFile != "" { - return nil, fmt.Errorf("both client cert and client key must be provided") - } - - if tlsConfig.CAFile != "" || tlsConfig.CAPath != "" || len(tlsConfig.CAPem) != 0 { - rootConfig := &rootcerts.Config{ - CAFile: tlsConfig.CAFile, - CAPath: tlsConfig.CAPath, - CACertificate: tlsConfig.CAPem, - } - if err := rootcerts.ConfigureTLS(tlsClientConfig, rootConfig); err != nil { - return nil, err - } - } - - return tlsClientConfig, nil -} - -func (c *Config) GenerateEnv() []string { - env := make([]string, 0, 10) - - env = append(env, - fmt.Sprintf("%s=%s", HTTPAddrEnvName, c.Address), - fmt.Sprintf("%s=%s", HTTPTokenEnvName, c.Token), - fmt.Sprintf("%s=%s", HTTPTokenFileEnvName, c.TokenFile), - fmt.Sprintf("%s=%t", HTTPSSLEnvName, c.Scheme == "https"), - fmt.Sprintf("%s=%s", HTTPCAFile, c.TLSConfig.CAFile), - fmt.Sprintf("%s=%s", HTTPCAPath, c.TLSConfig.CAPath), - fmt.Sprintf("%s=%s", HTTPClientCert, c.TLSConfig.CertFile), - fmt.Sprintf("%s=%s", HTTPClientKey, c.TLSConfig.KeyFile), - fmt.Sprintf("%s=%s", HTTPTLSServerName, c.TLSConfig.Address), - fmt.Sprintf("%s=%t", HTTPSSLVerifyEnvName, !c.TLSConfig.InsecureSkipVerify)) - - if c.HttpAuth != nil { - env = append(env, fmt.Sprintf("%s=%s:%s", HTTPAuthEnvName, c.HttpAuth.Username, c.HttpAuth.Password)) - } else { - env = append(env, fmt.Sprintf("%s=", HTTPAuthEnvName)) - } - - return env -} - -// Client provides a client to the Consul API -type Client struct { - modifyLock sync.RWMutex - headers http.Header - - config api.Config -} - -// Headers gets the current set of headers used for requests. This returns a -// copy; to modify it call AddHeader or SetHeaders. -func (c *Client) Headers() http.Header { - c.modifyLock.RLock() - defer c.modifyLock.RUnlock() - - if c.headers == nil { - return nil - } - - ret := make(http.Header) - for k, v := range c.headers { - for _, val := range v { - ret[k] = append(ret[k], val) - } - } - - return ret -} - -// NewClient returns a new client -func NewClient(config *api.Config) (*Client, error) { - // bootstrap the config - defConfig := api.DefaultConfig() - - if config.Address == "" { - config.Address = defConfig.Address - } - - if config.Scheme == "" { - config.Scheme = defConfig.Scheme - } - - if config.Transport == nil { - config.Transport = defConfig.Transport - } - - if config.TLSConfig.Address == "" { - config.TLSConfig.Address = defConfig.TLSConfig.Address - } - - if config.TLSConfig.CAFile == "" { - config.TLSConfig.CAFile = defConfig.TLSConfig.CAFile - } - - if config.TLSConfig.CAPath == "" { - config.TLSConfig.CAPath = defConfig.TLSConfig.CAPath - } - - if config.TLSConfig.CertFile == "" { - config.TLSConfig.CertFile = defConfig.TLSConfig.CertFile - } - - if config.TLSConfig.KeyFile == "" { - config.TLSConfig.KeyFile = defConfig.TLSConfig.KeyFile - } - - if !config.TLSConfig.InsecureSkipVerify { - config.TLSConfig.InsecureSkipVerify = defConfig.TLSConfig.InsecureSkipVerify - } - - if config.HttpClient == nil { - var err error - config.HttpClient, err = NewHttpClient(config.Transport, config.TLSConfig) - if err != nil { - return nil, err - } - } - - if config.Namespace == "" { - config.Namespace = defConfig.Namespace - } - - if config.Partition == "" { - config.Partition = defConfig.Partition - } - - parts := strings.SplitN(config.Address, "://", 2) - if len(parts) == 2 { - switch parts[0] { - case "http": - // Never revert to http if TLS was explicitly requested. - case "https": - config.Scheme = "https" - case "unix": - trans := cleanhttp.DefaultTransport() - trans.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial("unix", parts[1]) - } - httpClient, err := NewHttpClient(trans, config.TLSConfig) - if err != nil { - return nil, err - } - config.HttpClient = httpClient - default: - return nil, fmt.Errorf("Unknown protocol scheme: %s", parts[0]) - } - config.Address = parts[1] - - // separate out a reverse proxy prefix, if it is present. - // NOTE: Rewriting this code to use url.Parse() instead of - // strings.SplitN() breaks existing test cases. - switch parts[0] { - case "http", "https": - parts := strings.SplitN(parts[1], "/", 2) - if len(parts) == 2 { - config.Address = parts[0] - config.PathPrefix = "/" + parts[1] - } - } - } - - // If the TokenFile is set, always use that, even if a Token is configured. - // This is because when TokenFile is set it is read into the Token field. - // We want any derived clients to have to re-read the token file. - // The precedence of ACL token should be: - // 1. -token-file cli option - // 2. -token cli option - // 3. CONSUL_HTTP_TOKEN_FILE environment variable - // 4. CONSUL_HTTP_TOKEN environment variable - if config.TokenFile != "" && config.TokenFile != defConfig.TokenFile { - data, err := os.ReadFile(config.TokenFile) - if err != nil { - return nil, fmt.Errorf("Error loading token file %s : %s", config.TokenFile, err) - } - - if token := strings.TrimSpace(string(data)); token != "" { - config.Token = token - } - } else if config.Token != "" && defConfig.Token != config.Token { - // Fall through - } else if defConfig.TokenFile != "" { - data, err := os.ReadFile(defConfig.TokenFile) - if err != nil { - return nil, fmt.Errorf("Error loading token file %s : %s", defConfig.TokenFile, err) - } - - if token := strings.TrimSpace(string(data)); token != "" { - config.Token = token - config.TokenFile = defConfig.TokenFile - } - } else { - config.Token = defConfig.Token - } - return &Client{config: *config, headers: make(http.Header)}, nil -} - -// NewHttpClient returns an http client configured with the given Transport and TLS -// config. -func NewHttpClient(transport *http.Transport, tlsConf api.TLSConfig) (*http.Client, error) { - client := &http.Client{ - Transport: transport, - } - - // TODO (slackpad) - Once we get some run time on the HTTP/2 support we - // should turn it on by default if TLS is enabled. We would basically - // just need to call http2.ConfigureTransport(transport) here. We also - // don't want to introduce another external dependency on - // golang.org/x/net/http2 at this time. For a complete recipe for how - // to enable HTTP/2 support on a transport suitable for the API client - // library see agent/http_test.go:TestHTTPServer_H2. - - if transport.TLSClientConfig == nil { - tlsClientConfig, err := api.SetupTLSConfig(&tlsConf) - - if err != nil { - return nil, err - } - - transport.TLSClientConfig = tlsClientConfig - } - - return client, nil -} - -// request is used to help build up a request -// defined a custom object that includes use-case specific config -type request struct { - config *api.Config - method string - url *url.URL - params url.Values - body io.Reader - header http.Header - Obj interface{} - ctx context.Context -} - -// setQueryOptions is used to annotate the request with -// additional query options -func (r *request) SetQueryOptions(q *QueryOptions) { - if q == nil { - return - } - if q.Namespace != "" { - // For backwards-compatibility with existing tests, - // use the short-hand query param name "ns" - // rather than the alternative long-hand "namespace" - r.params.Set("ns", q.Namespace) - } - if q.Partition != "" { - // For backwards-compatibility with existing tests, - // use the long-hand query param name "partition" - // rather than the alternative short-hand "ap" - r.params.Set("partition", q.Partition) - } - if q.Datacenter != "" { - // For backwards-compatibility with existing tests, - // use the short-hand query param name "dc" - // rather than the alternative long-hand "datacenter" - r.params.Set("dc", q.Datacenter) - } - if q.Peer != "" { - r.params.Set("peer", q.Peer) - } - if q.AllowStale { - r.params.Set("stale", "") - } - if q.RequireConsistent { - r.params.Set("consistent", "") - } - if q.WaitIndex != 0 { - r.params.Set("index", strconv.FormatUint(q.WaitIndex, 10)) - } - if q.WaitTime != 0 { - r.params.Set("wait", durToMsec(q.WaitTime)) - } - if q.WaitHash != "" { - r.params.Set("hash", q.WaitHash) - } - if q.Token != "" { - r.header.Set("X-Consul-Token", q.Token) - } - if q.Near != "" { - r.params.Set("near", q.Near) - } - if q.Filter != "" { - r.params.Set("filter", q.Filter) - } - if len(q.NodeMeta) > 0 { - for key, value := range q.NodeMeta { - r.params.Add("node-meta", key+":"+value) - } - } - if q.RelayFactor != 0 { - r.params.Set("relay-factor", strconv.Itoa(int(q.RelayFactor))) - } - if q.LocalOnly { - r.params.Set("local-only", fmt.Sprintf("%t", q.LocalOnly)) - } - if q.Connect { - r.params.Set("connect", "true") - } - if q.UseCache && !q.RequireConsistent { - r.params.Set("cached", "") - - cc := []string{} - if q.MaxAge > 0 { - cc = append(cc, fmt.Sprintf("max-age=%.0f", q.MaxAge.Seconds())) - } - if q.StaleIfError > 0 { - cc = append(cc, fmt.Sprintf("stale-if-error=%.0f", q.StaleIfError.Seconds())) - } - if len(cc) > 0 { - r.header.Set("Cache-Control", strings.Join(cc, ", ")) - } - } - if q.MergeCentralConfig { - r.params.Set("merge-central-config", "") - } - if q.Global { - r.params.Set("global", "") - } - - r.ctx = q.ctx -} - -// durToMsec converts a duration to a millisecond specified string. If the -// user selected a positive value that rounds to 0 ms, then we will use 1 ms -// so they get a short delay, otherwise Consul will translate the 0 ms into -// a huge default delay. -func durToMsec(dur time.Duration) string { - ms := dur / time.Millisecond - if dur > 0 && ms == 0 { - ms = 1 - } - return fmt.Sprintf("%dms", ms) -} - -// toHTTP converts the request to an HTTP request -func (r *request) toHTTP() (*http.Request, error) { - // Encode the query parameters - r.url.RawQuery = r.params.Encode() - - // Check if we should encode the body - if r.body == nil && r.Obj != nil { - b, err := encodeBody(r.Obj) - if err != nil { - return nil, err - } - r.body = b - } - - // Create the HTTP request - req, err := http.NewRequest(r.method, r.url.RequestURI(), r.body) - if err != nil { - return nil, err - } - - // validate that socket communications that do not use the host, detect - // slashes in the host name and replace it with local host. - // this is required since go started validating req.host in 1.20.6 and 1.19.11. - // prior to that they would strip out the slashes for you. They removed that - // behavior and added more strict validation as part of a CVE. - // This issue is being tracked by the Go team: - // https://github.com/golang/go/issues/61431 - // If there is a resolution in this issue, we will remove this code. - // In the time being, this is the accepted workaround. - if strings.HasPrefix(r.url.Host, "/") { - r.url.Host = "localhost" - } - - req.URL.Host = r.url.Host - req.URL.Scheme = r.url.Scheme - req.Host = r.url.Host - req.Header = r.header - - // Content-Type must always be set when a body is present - // See https://github.com/hashicorp/consul/issues/10011 - if req.Body != nil && req.Header.Get("Content-Type") == "" { - req.Header.Set("Content-Type", "application/json") - } - - // Setup auth - if r.config.HttpAuth != nil { - req.SetBasicAuth(r.config.HttpAuth.Username, r.config.HttpAuth.Password) - } - if r.ctx != nil { - return req.WithContext(r.ctx), nil - } - - return req, nil -} - -// newRequest is used to create a new request -func (c *Client) NewRequest(method, path string) *request { - r := &request{ - config: &c.config, - method: method, - url: &url.URL{ - Scheme: c.config.Scheme, - Host: c.config.Address, - Path: c.config.PathPrefix + path, - }, - params: make(map[string][]string), - header: c.Headers(), - } - - if c.config.Datacenter != "" { - r.params.Set("dc", c.config.Datacenter) - } - if c.config.Namespace != "" { - r.params.Set("ns", c.config.Namespace) - } - if c.config.Partition != "" { - r.params.Set("partition", c.config.Partition) - } - if c.config.WaitTime != 0 { - r.params.Set("wait", durToMsec(r.config.WaitTime)) - } - if c.config.Token != "" { - r.header.Set("X-Consul-Token", r.config.Token) - } - return r -} - -// doRequest runs a request with our client -func (c *Client) DoRequest(r *request) (time.Duration, *http.Response, error) { - req, err := r.toHTTP() - if err != nil { - return 0, nil, err - } - start := time.Now() - resp, err := c.config.HttpClient.Do(req) - diff := time.Since(start) - return diff, resp, err -} - -// DecodeBody is used to JSON decode a body -func DecodeBody(resp *http.Response, out interface{}) error { - dec := json.NewDecoder(resp.Body) - return dec.Decode(out) -} - -// encodeBody is used to encode a request body -func encodeBody(obj interface{}) (io.Reader, error) { - buf := bytes.NewBuffer(nil) - enc := json.NewEncoder(buf) - if err := enc.Encode(obj); err != nil { - return nil, err - } - return buf, nil -} - -// requireOK is used to wrap doRequest and check for a 200 -func RequireOK(resp *http.Response) error { - return RequireHttpCodes(resp, 200) -} - -// requireHttpCodes checks for the "allowable" http codes for a response -func RequireHttpCodes(resp *http.Response, httpCodes ...int) error { - // if there is an http code that we require, return w no error - for _, httpCode := range httpCodes { - if resp.StatusCode == httpCode { - return nil - } - } - - // if we reached here, then none of the http codes in resp matched any that we expected - // so err out - return generateUnexpectedResponseCodeError(resp) -} - -// closeResponseBody reads resp.Body until EOF, and then closes it. The read -// is necessary to ensure that the http.Client's underlying RoundTripper is able -// to re-use the TCP connection. See godoc on net/http.Client.Do. -func CloseResponseBody(resp *http.Response) error { - _, _ = io.Copy(io.Discard, resp.Body) - return resp.Body.Close() -} - -// generateUnexpectedResponseCodeError consumes the rest of the body, closes -// the body stream and generates an error indicating the status code was -// unexpected. -func generateUnexpectedResponseCodeError(resp *http.Response) error { - var buf bytes.Buffer - io.Copy(&buf, resp.Body) - CloseResponseBody(resp) - - trimmed := strings.TrimSpace(string(buf.Bytes())) - return StatusError{Code: resp.StatusCode, Body: trimmed} -} diff --git a/command/resource/delete/delete.go b/command/resource/delete/delete.go deleted file mode 100644 index 06421d6d1e2d7..0000000000000 --- a/command/resource/delete/delete.go +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package delete - -import ( - "errors" - "flag" - "fmt" - - "github.com/mitchellh/cli" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/command/flags" - "github.com/hashicorp/consul/command/resource" - "github.com/hashicorp/consul/command/resource/client" -) - -func New(ui cli.Ui) *cmd { - c := &cmd{UI: ui} - c.init() - return c -} - -type cmd struct { - UI cli.Ui - flags *flag.FlagSet - http *flags.HTTPFlags - help string - - filePath string -} - -func (c *cmd) init() { - c.flags = flag.NewFlagSet("", flag.ContinueOnError) - c.http = &flags.HTTPFlags{} - c.flags.StringVar(&c.filePath, "f", "", "File path with resource definition") - flags.Merge(c.flags, c.http.ClientFlags()) - flags.Merge(c.flags, c.http.ServerFlags()) - flags.Merge(c.flags, c.http.MultiTenancyFlags()) - flags.Merge(c.flags, c.http.AddPeerName()) - c.help = flags.Usage(help, c.flags) -} - -func (c *cmd) Run(args []string) int { - var gvk *resource.GVK - var resourceName string - var opts *client.QueryOptions - - if err := c.flags.Parse(args); err != nil { - if !errors.Is(err, flag.ErrHelp) { - c.UI.Error(fmt.Sprintf("Failed to parse args: %v", err)) - return 1 - } - } - - if c.flags.Lookup("f").Value.String() != "" { - if c.filePath != "" { - parsedResource, err := resource.ParseResourceFromFile(c.filePath) - if err != nil { - c.UI.Error(fmt.Sprintf("Failed to decode resource from input file: %v", err)) - return 1 - } - - if parsedResource == nil { - c.UI.Error("Unable to parse the file argument") - return 1 - } - - gvk = &resource.GVK{ - Group: parsedResource.Id.Type.GetGroup(), - Version: parsedResource.Id.Type.GetGroupVersion(), - Kind: parsedResource.Id.Type.GetKind(), - } - resourceName = parsedResource.Id.GetName() - opts = &client.QueryOptions{ - Namespace: parsedResource.Id.Tenancy.GetNamespace(), - Partition: parsedResource.Id.Tenancy.GetPartition(), - Peer: parsedResource.Id.Tenancy.GetPeerName(), - Token: c.http.Token(), - } - } else { - c.UI.Error(fmt.Sprintf("Please provide an input file with resource definition")) - return 1 - } - } else { - var err error - gvk, resourceName, err = resource.GetTypeAndResourceName(args) - if err != nil { - c.UI.Error(fmt.Sprintf("Incorrect argument format: %s", err)) - return 1 - } - - inputArgs := args[2:] - err = resource.ParseInputParams(inputArgs, c.flags) - if err != nil { - c.UI.Error(fmt.Sprintf("Error parsing input arguments: %v", err)) - return 1 - } - if c.filePath != "" { - c.UI.Error("Incorrect argument format: File argument is not needed when resource information is provided with the command") - return 1 - } - opts = &client.QueryOptions{ - Namespace: c.http.Namespace(), - Partition: c.http.Partition(), - Peer: c.http.PeerName(), - Token: c.http.Token(), - } - } - - config := api.DefaultConfig() - - c.http.MergeOntoConfig(config) - resourceClient, err := client.NewClient(config) - if err != nil { - c.UI.Error(fmt.Sprintf("Error connect to Consul agent: %s", err)) - return 1 - } - - res := resource.Resource{C: resourceClient} - - if err := res.Delete(gvk, resourceName, opts); err != nil { - c.UI.Error(fmt.Sprintf("Error deleting resource %s.%s.%s/%s: %v", gvk.Group, gvk.Version, gvk.Kind, resourceName, err)) - return 1 - } - - c.UI.Info(fmt.Sprintf("%s.%s.%s/%s deleted", gvk.Group, gvk.Version, gvk.Kind, resourceName)) - return 0 -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(c.help, nil) -} - -const synopsis = "Delete resource information" -const help = ` -Usage: You have two options to delete the resource specified by the given -type, name, partition, namespace and peer and outputs its JSON representation. - -consul resource delete [type] [name] -partition= -namespace= -peer= -consul resource delete -f [resource_file_path] - -But you could only use one of the approaches. - -Example: - -$ consul resource delete catalog.v2beta1.Service card-processor -partition=billing -namespace=payments -peer=eu -$ consul resource delete -f resource.hcl - -In resource.hcl, it could be: -ID { - Type = gvk("catalog.v2beta1.Service") - Name = "card-processor" - Tenancy { - Namespace = "payments" - Partition = "billing" - PeerName = "eu" - } -} -` diff --git a/command/resource/delete/delete_test.go b/command/resource/delete/delete_test.go deleted file mode 100644 index 7454455c941e6..0000000000000 --- a/command/resource/delete/delete_test.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 -package delete - -import ( - "errors" - "testing" - - "github.com/mitchellh/cli" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent" - "github.com/hashicorp/consul/command/resource/apply" - "github.com/hashicorp/consul/testrpc" -) - -func TestResourceDeleteInvalidArgs(t *testing.T) { - t.Parallel() - - type tc struct { - args []string - expectedCode int - expectedErr error - } - - cases := map[string]tc{ - "nil args": { - args: nil, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must specify two arguments: resource type and resource name"), - }, - "empty args": { - args: []string{}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must specify two arguments: resource type and resource name"), - }, - "missing file path": { - args: []string{"-f"}, - expectedCode: 1, - expectedErr: errors.New("Failed to parse args: flag needs an argument: -f"), - }, - "file not found": { - args: []string{"-f=../testdata/test.hcl"}, - expectedCode: 1, - expectedErr: errors.New("Failed to load data: Failed to read file: open ../testdata/test.hcl: no such file or directory"), - }, - "provide type and name": { - args: []string{"a.b.c"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must specify two arguments: resource type and resource name"), - }, - "provide type and name with -f": { - args: []string{"a.b.c", "name", "-f", "test.hcl"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: File argument is not needed when resource information is provided with the command"), - }, - "provide type and name with -f and other flags": { - args: []string{"a.b.c", "name", "-f", "test.hcl", "-namespace", "default"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: File argument is not needed when resource information is provided with the command"), - }, - "does not provide resource name after type": { - args: []string{"a.b.c", "-namespace", "default"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must provide resource name right after type"), - }, - "invalid resource type format": { - args: []string{"a.", "name", "-namespace", "default"}, - expectedCode: 1, - expectedErr: errors.New("Must provide resource type argument with either in group.verion.kind format or its shorthand name"), - }, - } - - for desc, tc := range cases { - t.Run(desc, func(t *testing.T) { - ui := cli.NewMockUi() - c := New(ui) - - code := c.Run(tc.args) - - require.Equal(t, tc.expectedCode, code) - require.Contains(t, ui.ErrorWriter.String(), tc.expectedErr.Error()) - }) - } -} - -func createResource(t *testing.T, a *agent.TestAgent) { - applyUi := cli.NewMockUi() - applyCmd := apply.New(applyUi) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - args = append(args, []string{"-f=../testdata/demo.hcl"}...) - - code := applyCmd.Run(args) - require.Equal(t, 0, code) - require.Empty(t, applyUi.ErrorWriter.String()) -} - -func TestResourceDelete(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - a := agent.NewTestAgent(t, ``) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") - - defaultCmdArgs := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - cases := []struct { - name string - args []string - expectedCode int - createResource bool - }{ - { - name: "delete resource in hcl format", - args: []string{"-f=../testdata/demo.hcl"}, - expectedCode: 0, - createResource: true, - }, - { - name: "delete resource in command line format", - args: []string{"demo.v2.Artist", "korn", "-partition=default", "-namespace=default", "-peer=local"}, - expectedCode: 0, - createResource: true, - }, - { - name: "delete resource that doesn't exist in command line format", - args: []string{"demo.v2.Artist", "korn", "-partition=default", "-namespace=default", "-peer=local"}, - expectedCode: 0, - createResource: false, - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - ui := cli.NewMockUi() - c := New(ui) - cliArgs := append(tc.args, defaultCmdArgs...) - if tc.createResource { - createResource(t, a) - } - code := c.Run(cliArgs) - require.Empty(t, ui.ErrorWriter.String()) - require.Equal(t, tc.expectedCode, code) - require.Contains(t, ui.OutputWriter.String(), "deleted") - }) - } -} diff --git a/command/resource/helper.go b/command/resource/helper.go deleted file mode 100644 index 221a018599a77..0000000000000 --- a/command/resource/helper.go +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "encoding/json" - "errors" - "flag" - "fmt" - "io" - "net/http" - "strings" - "unicode" - "unicode/utf8" - - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/agent/consul" - "github.com/hashicorp/consul/command/helpers" - "github.com/hashicorp/consul/command/resource/client" - "github.com/hashicorp/consul/internal/resourcehcl" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type OuterResource struct { - ID *ID `json:"id"` - Owner *ID `json:"owner"` - Generation string `json:"generation"` - Version string `json:"version"` - Metadata map[string]any `json:"metadata"` - Data map[string]any `json:"data"` -} - -type Tenancy struct { - Namespace string `json:"namespace"` - Partition string `json:"partition"` - PeerName string `json:"peerName"` -} - -type Type struct { - Group string `json:"group"` - GroupVersion string `json:"groupVersion"` - Kind string `json:"kind"` -} - -type ID struct { - Name string `json:"name"` - Tenancy Tenancy `json:"tenancy"` - Type Type `json:"type"` - UID string `json:"uid"` -} - -func parseJson(js string) (*pbresource.Resource, error) { - - parsedResource := new(pbresource.Resource) - - var outerResource OuterResource - - if err := json.Unmarshal([]byte(js), &outerResource); err != nil { - return nil, err - } - - if outerResource.ID == nil { - return nil, fmt.Errorf("\"id\" field need to be provided") - } - - typ := pbresource.Type{ - Kind: outerResource.ID.Type.Kind, - Group: outerResource.ID.Type.Group, - GroupVersion: outerResource.ID.Type.GroupVersion, - } - - reg, ok := consul.NewTypeRegistry().Resolve(&typ) - if !ok { - return nil, fmt.Errorf("invalid type %v", parsedResource) - } - data := reg.Proto.ProtoReflect().New().Interface() - anyProtoMsg, err := anypb.New(data) - if err != nil { - return nil, err - } - - outerResource.Data["@type"] = anyProtoMsg.TypeUrl - - marshal, err := json.Marshal(outerResource) - if err != nil { - return nil, err - } - - if err := protojson.Unmarshal(marshal, parsedResource); err != nil { - return nil, err - } - return parsedResource, nil -} - -func ParseResourceFromFile(filePath string) (*pbresource.Resource, error) { - return ParseResourceInput(filePath, nil) -} - -// this is an inlined variant of hcl.lexMode() -func isHCL(v []byte) bool { - var ( - r rune - w int - offset int - ) - - for { - r, w = utf8.DecodeRune(v[offset:]) - offset += w - if unicode.IsSpace(r) { - continue - } - if r == '{' { - return false - } - break - } - - return true -} - -func ParseResourceInput(filePath string, stdin io.Reader) (*pbresource.Resource, error) { - data, err := helpers.LoadDataSourceNoRaw(filePath, stdin) - - if err != nil { - return nil, fmt.Errorf("Failed to load data: %v", err) - } - var parsedResource *pbresource.Resource - if isHCL([]byte(data)) { - parsedResource, err = resourcehcl.Unmarshal([]byte(data), consul.NewTypeRegistry()) - } else { - parsedResource, err = parseJson(data) - } - if err != nil { - return nil, fmt.Errorf("Failed to decode resource from input: %v", err) - } - - return parsedResource, nil -} - -func ParseInputParams(inputArgs []string, flags *flag.FlagSet) error { - if err := flags.Parse(inputArgs); err != nil { - if !errors.Is(err, flag.ErrHelp) { - return fmt.Errorf("Failed to parse args: %v", err) - } - } - return nil -} - -func GetTypeAndResourceName(args []string) (gvk *GVK, resourceName string, e error) { - if len(args) < 2 { - return nil, "", fmt.Errorf("Must specify two arguments: resource type and resource name") - } - // it has to be resource name after the type - if strings.HasPrefix(args[1], "-") { - return nil, "", fmt.Errorf("Must provide resource name right after type") - } - resourceName = args[1] - - gvk, e = inferGVKFromResourceType(args[0]) - - return -} - -type Resource struct { - C *client.Client -} - -type GVK struct { - Group string - Version string - Kind string -} - -type WriteRequest struct { - Metadata map[string]string `json:"metadata"` - Data map[string]any `json:"data"` - Owner *pbresource.ID `json:"owner"` -} - -type ListResponse struct { - Resources []map[string]interface{} `json:"resources"` -} - -func (resource *Resource) Read(gvk *GVK, resourceName string, q *client.QueryOptions) (map[string]interface{}, error) { - r := resource.C.NewRequest("GET", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName))) - r.SetQueryOptions(q) - _, resp, err := resource.C.DoRequest(r) - if err != nil { - return nil, err - } - defer client.CloseResponseBody(resp) - if err := client.RequireOK(resp); err != nil { - return nil, err - } - - var out map[string]interface{} - if err := client.DecodeBody(resp, &out); err != nil { - return nil, err - } - - return out, nil -} - -func (resource *Resource) Delete(gvk *GVK, resourceName string, q *client.QueryOptions) error { - r := resource.C.NewRequest("DELETE", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName))) - r.SetQueryOptions(q) - _, resp, err := resource.C.DoRequest(r) - if err != nil { - return err - } - defer client.CloseResponseBody(resp) - if err := client.RequireHttpCodes(resp, http.StatusNoContent); err != nil { - return err - } - return nil -} - -func (resource *Resource) Apply(gvk *GVK, resourceName string, q *client.QueryOptions, payload *WriteRequest) (*map[string]interface{}, error) { - url := strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName)) - - r := resource.C.NewRequest("PUT", url) - r.SetQueryOptions(q) - r.Obj = payload - _, resp, err := resource.C.DoRequest(r) - if err != nil { - return nil, err - } - defer client.CloseResponseBody(resp) - if err := client.RequireOK(resp); err != nil { - return nil, err - } - - var out map[string]interface{} - - if err := client.DecodeBody(resp, &out); err != nil { - return nil, err - } - - return &out, nil -} - -func (resource *Resource) List(gvk *GVK, q *client.QueryOptions) (*ListResponse, error) { - r := resource.C.NewRequest("GET", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind))) - r.SetQueryOptions(q) - _, resp, err := resource.C.DoRequest(r) - if err != nil { - return nil, err - } - defer client.CloseResponseBody(resp) - if err := client.RequireOK(resp); err != nil { - return nil, err - } - - var out *ListResponse - if err := client.DecodeBody(resp, &out); err != nil { - return nil, err - } - - return out, nil -} - -func inferGVKFromResourceType(resourceType string) (*GVK, error) { - s := strings.Split(resourceType, ".") - switch length := len(s); { - // only kind is provided - case length == 1: - kindToGVKMap := BuildKindToGVKMap() - kind := strings.ToLower(s[0]) - switch len(kindToGVKMap[kind]) { - // no g.v.k is found - case 0: - return nil, fmt.Errorf("The shorthand name does not map to any existing resource type, please check `consul api-resources`") - // only one is found - case 1: - // infer gvk from resource kind - gvkSplit := strings.Split(kindToGVKMap[kind][0], ".") - return &GVK{ - Group: gvkSplit[0], - Version: gvkSplit[1], - Kind: gvkSplit[2], - }, nil - // it alerts error if any conflict is found - default: - return nil, fmt.Errorf("The shorthand name has conflicts %v, please use the full name", kindToGVKMap[s[0]]) - } - case length == 3: - return &GVK{ - Group: s[0], - Version: s[1], - Kind: s[2], - }, nil - default: - return nil, fmt.Errorf("Must provide resource type argument with either in group.verion.kind format or its shorthand name") - } -} - -func BuildKindToGVKMap() map[string][]string { - // this use the local copy of registration to build map - typeRegistry := consul.NewTypeRegistry() - kindToGVKMap := map[string][]string{} - for _, r := range typeRegistry.Types() { - gvkString := fmt.Sprintf("%s.%s.%s", r.Type.Group, r.Type.GroupVersion, r.Type.Kind) - kindKey := strings.ToLower(r.Type.Kind) - if len(kindToGVKMap[kindKey]) == 0 { - kindToGVKMap[kindKey] = []string{gvkString} - } else { - kindToGVKMap[kindKey] = append(kindToGVKMap[kindKey], gvkString) - } - } - return kindToGVKMap -} diff --git a/command/resource/helper_test.go b/command/resource/helper_test.go deleted file mode 100644 index 003c2b7aa63aa..0000000000000 --- a/command/resource/helper_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "github.com/stretchr/testify/require" - "testing" -) - -func Test_parseJson(t *testing.T) { - tests := []struct { - name string - js string - wantErr bool - }{ - {"valid resource", "{\n \"data\": {\n \"genre\": \"GENRE_METAL\",\n \"name\": \"Korn\"\n },\n \"generation\": \"01HAYWBPV1KMT2KWECJ6CEWDQ0\",\n \"id\": {\n \"name\": \"korn\",\n \"tenancy\": {\n \"namespace\": \"default\",\n \"partition\": \"default\",\n \"peerName\": \"local\"\n },\n \"type\": {\n \"group\": \"demo\",\n \"groupVersion\": \"v2\",\n \"kind\": \"Artist\"\n },\n \"uid\": \"01HAYWBPV1KMT2KWECJ4NW88S1\"\n },\n \"metadata\": {\n \"foo\": \"bar\"\n },\n \"version\": \"18\"\n}", false}, - {"invalid resource", "{\n \"data\": {\n \"genre\": \"GENRE_METAL\",\n \"name\": \"Korn\"\n },\n \"id\": {\n \"name\": \"korn\",\n \"tenancy\": {\n \"namespace\": \"default\",\n \"partition\": \"default\",\n \"peerName\": \"local\"\n },\n \"type\": \"\"\n },\n \"metadata\": {\n \"foo\": \"bar\"\n }\n}\n", true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := parseJson(tt.js) - if tt.wantErr { - require.Error(t, err) - require.Nil(t, got) - } else { - require.NoError(t, err) - require.NotNil(t, got) - } - - }) - } -} diff --git a/command/resource/list/list.go b/command/resource/list/list.go deleted file mode 100644 index d0a5f398a6349..0000000000000 --- a/command/resource/list/list.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package list - -import ( - "encoding/json" - "errors" - "flag" - "fmt" - "strings" - - "github.com/mitchellh/cli" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/command/flags" - "github.com/hashicorp/consul/command/resource" - "github.com/hashicorp/consul/command/resource/client" -) - -func New(ui cli.Ui) *cmd { - c := &cmd{UI: ui} - c.init() - return c -} - -type cmd struct { - UI cli.Ui - flags *flag.FlagSet - http *flags.HTTPFlags - help string - - filePath string -} - -func (c *cmd) init() { - c.flags = flag.NewFlagSet("", flag.ContinueOnError) - c.http = &flags.HTTPFlags{} - c.flags.StringVar(&c.filePath, "f", "", "File path with resource definition") - flags.Merge(c.flags, c.http.ClientFlags()) - flags.Merge(c.flags, c.http.ServerFlags()) - flags.Merge(c.flags, c.http.MultiTenancyFlags()) - flags.Merge(c.flags, c.http.AddPeerName()) - c.help = flags.Usage(help, c.flags) -} - -func (c *cmd) Run(args []string) int { - var gvk *resource.GVK - var opts *client.QueryOptions - - if err := c.flags.Parse(args); err != nil { - if !errors.Is(err, flag.ErrHelp) { - c.UI.Error(fmt.Sprintf("Failed to parse args: %v", err)) - return 1 - } - } - - if c.flags.Lookup("f").Value.String() != "" { - if c.filePath != "" { - parsedResource, err := resource.ParseResourceFromFile(c.filePath) - if err != nil { - c.UI.Error(fmt.Sprintf("Failed to decode resource from input file: %v", err)) - return 1 - } - - if parsedResource == nil { - c.UI.Error("Unable to parse the file argument") - return 1 - } - - gvk = &resource.GVK{ - Group: parsedResource.Id.Type.GetGroup(), - Version: parsedResource.Id.Type.GetGroupVersion(), - Kind: parsedResource.Id.Type.GetKind(), - } - opts = &client.QueryOptions{ - Namespace: parsedResource.Id.Tenancy.GetNamespace(), - Partition: parsedResource.Id.Tenancy.GetPartition(), - Peer: parsedResource.Id.Tenancy.GetPeerName(), - Token: c.http.Token(), - RequireConsistent: !c.http.Stale(), - } - } else { - c.UI.Error(fmt.Sprintf("Please provide an input file with resource definition")) - return 1 - } - } else { - var err error - // extract resource type - gvk, err = getResourceType(c.flags.Args()) - if err != nil { - c.UI.Error(fmt.Sprintf("Incorrect argument format: %v", err)) - return 1 - } - // skip resource type to parse remaining args - inputArgs := c.flags.Args()[1:] - err = resource.ParseInputParams(inputArgs, c.flags) - if err != nil { - c.UI.Error(fmt.Sprintf("Error parsing input arguments: %v", err)) - return 1 - } - if c.filePath != "" { - c.UI.Error("Incorrect argument format: File argument is not needed when resource information is provided with the command") - return 1 - } - - opts = &client.QueryOptions{ - Namespace: c.http.Namespace(), - Partition: c.http.Partition(), - Peer: c.http.PeerName(), - Token: c.http.Token(), - RequireConsistent: !c.http.Stale(), - } - } - - config := api.DefaultConfig() - - c.http.MergeOntoConfig(config) - resourceClient, err := client.NewClient(config) - if err != nil { - c.UI.Error(fmt.Sprintf("Error connect to Consul agent: %s", err)) - return 1 - } - - res := resource.Resource{C: resourceClient} - - entry, err := res.List(gvk, opts) - if err != nil { - c.UI.Error(fmt.Sprintf("Error reading resources for type %s: %v", gvk, err)) - return 1 - } - - b, err := json.MarshalIndent(entry, "", " ") - if err != nil { - c.UI.Error("Failed to encode output data") - return 1 - } - - c.UI.Info(string(b)) - return 0 -} - -func getResourceType(args []string) (gvk *resource.GVK, e error) { - if len(args) < 1 { - return nil, fmt.Errorf("Must include resource type argument") - } - // it should not have resource name - if len(args) > 1 && !strings.HasPrefix(args[1], "-") { - return nil, fmt.Errorf("Must include flag arguments after resource type") - } - - s := strings.Split(args[0], ".") - if len(s) < 3 { - return nil, fmt.Errorf("Must include resource type argument in group.verion.kind format") - } - gvk = &resource.GVK{ - Group: s[0], - Version: s[1], - Kind: s[2], - } - - return -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(c.help, nil) -} - -const synopsis = "Reads all resources by type" -const help = ` -Usage: consul resource list [type] -partition= -namespace= -peer= -or -consul resource list -f [path/to/file.hcl] - -Lists all the resources specified by the type under the given partition, namespace and peer -and outputs in JSON format. - -Example: - -$ consul resource list catalog.v2beta1.Service card-processor -partition=billing -namespace=payments -peer=eu - -$ consul resource list -f=demo.hcl - -Sample demo.hcl: - -ID { - Type = gvk("group.version.kind") - Name = "resource-name" - Tenancy { - Namespace = "default" - Partition = "default" - PeerName = "local" - } - } -` diff --git a/command/resource/list/list_test.go b/command/resource/list/list_test.go deleted file mode 100644 index b8fc12556a144..0000000000000 --- a/command/resource/list/list_test.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package list - -import ( - "errors" - "testing" - - "github.com/hashicorp/consul/agent" - "github.com/hashicorp/consul/testrpc" - "github.com/mitchellh/cli" - - "github.com/stretchr/testify/require" - - apply "github.com/hashicorp/consul/command/resource/apply" -) - -func TestResourceListCommand(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - a := agent.NewTestAgent(t, ``) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") - - applyCli := cli.NewMockUi() - - applyCmd := apply.New(applyCli) - code := applyCmd.Run([]string{ - "-f=../testdata/demo.hcl", - "-http-addr=" + a.HTTPAddr(), - "-token=root", - }) - require.Equal(t, 0, code) - require.Empty(t, applyCli.ErrorWriter.String()) - require.Contains(t, applyCli.OutputWriter.String(), "demo.v2.Artist 'korn' created.") - - cases := []struct { - name string - output string - extraArgs []string - }{ - { - name: "sample output", - output: "\"name\": \"korn\"", - extraArgs: []string{ - "demo.v2.artist", - "-namespace=default", - "-peer=local", - "-partition=default", - }, - }, - { - name: "file input", - output: "\"name\": \"korn\"", - extraArgs: []string{ - "-f=../testdata/demo.hcl", - }, - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - ui := cli.NewMockUi() - c := New(ui) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - args = append(args, tc.extraArgs...) - - actualCode := c.Run(args) - require.Equal(t, 0, actualCode) - require.Empty(t, ui.ErrorWriter.String()) - require.Contains(t, ui.OutputWriter.String(), tc.output) - }) - } -} - -func TestResourceListInvalidArgs(t *testing.T) { - t.Parallel() - - a := agent.NewTestAgent(t, ``) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") - - type tc struct { - args []string - expectedCode int - expectedErr error - } - - cases := map[string]tc{ - "nil args": { - args: nil, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must include resource type argument"), - }, - "minimum args required": { - args: []string{}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must include resource type argument"), - }, - "no file path": { - args: []string{ - "-f", - }, - expectedCode: 1, - expectedErr: errors.New("Failed to parse args: flag needs an argument: -f"), - }, - "file not found": { - args: []string{ - "-f=../testdata/test.hcl", - }, - expectedCode: 1, - expectedErr: errors.New("Failed to load data: Failed to read file: open ../testdata/test.hcl: no such file or directory"), - }, - "file parsing failure": { - args: []string{ - "-f=../testdata/invalid_type.hcl", - }, - expectedCode: 1, - expectedErr: errors.New("Failed to decode resource from input file"), - }, - "file argument with resource type": { - args: []string{ - "demo.v2.artist", - "-namespace=default", - "-peer=local", - "-partition=default", - "-http-addr=" + a.HTTPAddr(), - "-token=root", - "-f=demo.hcl", - }, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: File argument is not needed when resource information is provided with the command"), - }, - "resource type invalid": { - args: []string{ - "test", - "-namespace=default", - "-peer=local", - "-partition=default", - }, - expectedCode: 1, - expectedErr: errors.New("Must include resource type argument in group.verion.kind format"), - }, - "resource name is provided": { - args: []string{ - "demo.v2.artist", - "test", - "-namespace=default", - "-peer=local", - "-partition=default", - }, - expectedCode: 1, - expectedErr: errors.New("Must include flag arguments after resource type"), - }, - } - - for desc, tc := range cases { - t.Run(desc, func(t *testing.T) { - ui := cli.NewMockUi() - c := New(ui) - - code := c.Run(tc.args) - - require.Equal(t, tc.expectedCode, code) - require.Contains(t, ui.ErrorWriter.String(), tc.expectedErr.Error()) - }) - } -} diff --git a/command/resource/read/read.go b/command/resource/read/read.go deleted file mode 100644 index fe35521056ba4..0000000000000 --- a/command/resource/read/read.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package read - -import ( - "encoding/json" - "errors" - "flag" - "fmt" - - "github.com/mitchellh/cli" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/command/flags" - "github.com/hashicorp/consul/command/resource" - "github.com/hashicorp/consul/command/resource/client" -) - -func New(ui cli.Ui) *cmd { - c := &cmd{UI: ui} - c.init() - return c -} - -type cmd struct { - UI cli.Ui - flags *flag.FlagSet - http *flags.HTTPFlags - help string - - filePath string -} - -func (c *cmd) init() { - c.flags = flag.NewFlagSet("", flag.ContinueOnError) - c.http = &flags.HTTPFlags{} - c.flags.StringVar(&c.filePath, "f", "", "File path with resource definition") - flags.Merge(c.flags, c.http.ClientFlags()) - flags.Merge(c.flags, c.http.ServerFlags()) - flags.Merge(c.flags, c.http.MultiTenancyFlags()) - flags.Merge(c.flags, c.http.AddPeerName()) - c.help = flags.Usage(help, c.flags) -} - -func (c *cmd) Run(args []string) int { - var gvk *resource.GVK - var resourceName string - var opts *client.QueryOptions - - if err := c.flags.Parse(args); err != nil { - if !errors.Is(err, flag.ErrHelp) { - c.UI.Error(fmt.Sprintf("Failed to parse args: %v", err)) - return 1 - } - } - - if c.flags.Lookup("f").Value.String() != "" { - if c.filePath != "" { - parsedResource, err := resource.ParseResourceFromFile(c.filePath) - if err != nil { - c.UI.Error(fmt.Sprintf("Failed to decode resource from input file: %v", err)) - return 1 - } - - if parsedResource == nil { - c.UI.Error("Unable to parse the file argument") - return 1 - } - - gvk = &resource.GVK{ - Group: parsedResource.Id.Type.GetGroup(), - Version: parsedResource.Id.Type.GetGroupVersion(), - Kind: parsedResource.Id.Type.GetKind(), - } - resourceName = parsedResource.Id.GetName() - opts = &client.QueryOptions{ - Namespace: parsedResource.Id.Tenancy.GetNamespace(), - Partition: parsedResource.Id.Tenancy.GetPartition(), - Peer: parsedResource.Id.Tenancy.GetPeerName(), - Token: c.http.Token(), - RequireConsistent: !c.http.Stale(), - } - } else { - c.UI.Error(fmt.Sprintf("Please provide an input file with resource definition")) - return 1 - } - } else { - if len(args) < 2 { - c.UI.Error("Incorrect argument format: Must specify two arguments: resource type and resource name") - return 1 - } - var err error - gvk, resourceName, err = resource.GetTypeAndResourceName(args) - if err != nil { - c.UI.Error(fmt.Sprintf("Incorrect argument format: %s", err)) - return 1 - } - - inputArgs := args[2:] - err = resource.ParseInputParams(inputArgs, c.flags) - if err != nil { - c.UI.Error(fmt.Sprintf("Error parsing input arguments: %v", err)) - return 1 - } - if c.filePath != "" { - c.UI.Error("Incorrect argument format: File argument is not needed when resource information is provided with the command") - return 1 - } - opts = &client.QueryOptions{ - Namespace: c.http.Namespace(), - Partition: c.http.Partition(), - Peer: c.http.PeerName(), - Token: c.http.Token(), - RequireConsistent: !c.http.Stale(), - } - } - - config := api.DefaultConfig() - - c.http.MergeOntoConfig(config) - resourceClient, err := client.NewClient(config) - if err != nil { - c.UI.Error(fmt.Sprintf("Error connect to Consul agent: %s", err)) - return 1 - } - - res := resource.Resource{C: resourceClient} - - entry, err := res.Read(gvk, resourceName, opts) - if err != nil { - c.UI.Error(fmt.Sprintf("Error reading resource %s/%s: %v", gvk, resourceName, err)) - return 1 - } - - b, err := json.MarshalIndent(entry, "", " ") - if err != nil { - c.UI.Error("Failed to encode output data") - return 1 - } - - c.UI.Info(string(b)) - return 0 -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(c.help, nil) -} - -const synopsis = "Read resource information" -const help = ` -Usage: You have two options to read the resource specified by the given -type, name, partition, namespace and peer and outputs its JSON representation. - -consul resource read [type] [name] -partition= -namespace= -peer= -consul resource read -f [resource_file_path] - -But you could only use one of the approaches. - -Example: - -$ consul resource read catalog.v2beta1.Service card-processor -partition=billing -namespace=payments -peer=eu -$ consul resource read -f resource.hcl - -In resource.hcl, it could be: -ID { - Type = gvk("catalog.v2beta1.Service") - Name = "card-processor" - Tenancy { - Namespace = "payments" - Partition = "billing" - PeerName = "eu" - } -} -` diff --git a/command/resource/read/read_test.go b/command/resource/read/read_test.go deleted file mode 100644 index a293a9faf5e20..0000000000000 --- a/command/resource/read/read_test.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 -package read - -import ( - "errors" - "testing" - - "github.com/mitchellh/cli" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent" - "github.com/hashicorp/consul/command/resource/apply" - "github.com/hashicorp/consul/testrpc" -) - -func TestResourceReadInvalidArgs(t *testing.T) { - t.Parallel() - - type tc struct { - args []string - expectedCode int - expectedErr error - } - - cases := map[string]tc{ - "nil args": { - args: nil, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must specify two arguments: resource type and resource name"), - }, - "empty args": { - args: []string{}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must specify two arguments: resource type and resource name"), - }, - "missing file path": { - args: []string{"-f"}, - expectedCode: 1, - expectedErr: errors.New("Failed to parse args: flag needs an argument: -f"), - }, - "file not found": { - args: []string{"-f=../testdata/test.hcl"}, - expectedCode: 1, - expectedErr: errors.New("Failed to load data: Failed to read file: open ../testdata/test.hcl: no such file or directory"), - }, - "provide type and name": { - args: []string{"a.b.c"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must specify two arguments: resource type and resource name"), - }, - "provide type and name with -f": { - args: []string{"a.b.c", "name", "-f", "test.hcl"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: File argument is not needed when resource information is provided with the command"), - }, - "provide type and name with -f and other flags": { - args: []string{"a.b.c", "name", "-f", "test.hcl", "-namespace", "default"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: File argument is not needed when resource information is provided with the command"), - }, - "does not provide resource name after type": { - args: []string{"a.b.c", "-namespace", "default"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must provide resource name right after type"), - }, - "invalid resource type format": { - args: []string{"a.", "name", "-namespace", "default"}, - expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must provide resource type argument with either in group.verion.kind format or its shorthand name"), - }, - } - - for desc, tc := range cases { - t.Run(desc, func(t *testing.T) { - ui := cli.NewMockUi() - c := New(ui) - - code := c.Run(tc.args) - - require.Equal(t, tc.expectedCode, code) - require.Contains(t, ui.ErrorWriter.String(), tc.expectedErr.Error()) - }) - } -} - -func createResource(t *testing.T, a *agent.TestAgent) { - applyUi := cli.NewMockUi() - applyCmd := apply.New(applyUi) - - args := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - args = append(args, []string{"-f=../testdata/demo.hcl"}...) - - code := applyCmd.Run(args) - require.Equal(t, 0, code) - require.Empty(t, applyUi.ErrorWriter.String()) -} - -func TestResourceRead(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - a := agent.NewTestAgent(t, ``) - defer a.Shutdown() - testrpc.WaitForTestAgent(t, a.RPC, "dc1") - - defaultCmdArgs := []string{ - "-http-addr=" + a.HTTPAddr(), - "-token=root", - } - - createResource(t, a) - cases := []struct { - name string - args []string - expectedCode int - errMsg string - }{ - { - name: "read resource in hcl format", - args: []string{"-f=../testdata/demo.hcl"}, - expectedCode: 0, - errMsg: "", - }, - { - name: "read resource in command line format", - args: []string{"demo.v2.Artist", "korn", "-partition=default", "-namespace=default", "-peer=local"}, - expectedCode: 0, - errMsg: "", - }, - { - name: "read resource that doesn't exist", - args: []string{"demo.v2.Artist", "fake-korn", "-partition=default", "-namespace=default", "-peer=local"}, - expectedCode: 1, - errMsg: "Error reading resource &{demo v2 Artist}/fake-korn: Unexpected response code: 404 (rpc error: code = NotFound desc = resource not found)\n", - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - ui := cli.NewMockUi() - c := New(ui) - cliArgs := append(tc.args, defaultCmdArgs...) - code := c.Run(cliArgs) - require.Equal(t, ui.ErrorWriter.String(), tc.errMsg) - require.Equal(t, tc.expectedCode, code) - }) - } -} diff --git a/command/resource/resource.go b/command/resource/resource.go deleted file mode 100644 index 709b03e4e49d2..0000000000000 --- a/command/resource/resource.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "github.com/mitchellh/cli" - - "github.com/hashicorp/consul/command/flags" -) - -func New() *cmd { - return &cmd{} -} - -type cmd struct{} - -func (c *cmd) Run(args []string) int { - return cli.RunResultHelp -} - -func (c *cmd) Synopsis() string { - return synopsis -} - -func (c *cmd) Help() string { - return flags.Usage(help, nil) -} - -const synopsis = "Interact with Consul's resources" -const help = ` -Usage: consul resource [options] - -This command has subcommands for interacting with Consul's resources. -Here are some simple examples, and more detailed examples are available -in the subcommands or the documentation. - -Read a resource: - -$ consul resource read [type] [name] -partition= -namespace= -peer= -consistent= -json - -Write/update a resource: - -$ consul resource apply -f= - -List resources by type: - -$ consul resource list [type] -partition= -namespace= -peer= - -Run - -consul resource -h - -for help on that subcommand. -` diff --git a/command/resource/testdata/demo.hcl b/command/resource/testdata/demo.hcl deleted file mode 100644 index 35e72aba31258..0000000000000 --- a/command/resource/testdata/demo.hcl +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -ID { - Type = gvk("demo.v2.Artist") - Name = "korn" - Tenancy { - Namespace = "default" - Partition = "default" - PeerName = "local" - } -} - -Data { - Name = "Korn" - Genre = "GENRE_METAL" -} - -Metadata = { - "foo" = "bar" -} diff --git a/command/resource/testdata/invalid.hcl b/command/resource/testdata/invalid.hcl deleted file mode 100644 index 04c08e9212f21..0000000000000 --- a/command/resource/testdata/invalid.hcl +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -ID { - Type = gvk("demo.v2.Artist") - Name = "korn" - Tenancy { - Namespace = "default" - Partition = "default" - PeerName = "local" - } -} - -D { - Name = "Korn" - Genre = "GENRE_METAL" -} - -Metadata = { - "foo" = "bar" -} diff --git a/command/resource/testdata/invalid_type.hcl b/command/resource/testdata/invalid_type.hcl deleted file mode 100644 index b3b87ae2458b0..0000000000000 --- a/command/resource/testdata/invalid_type.hcl +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -D { - Type = gvk("demo.v2.Artist") - Tenancy { - Namespace = "default" - Partition = "default" - PeerName = "local" - } -} diff --git a/command/resource/testdata/nested_data.hcl b/command/resource/testdata/nested_data.hcl deleted file mode 100644 index b62875c732b42..0000000000000 --- a/command/resource/testdata/nested_data.hcl +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -ID { - Type = gvk("mesh.v2beta1.Destinations") - Name = "api" -} - -Data { - Workloads { - Prefixes = ["api"] - } - - Destinations = [ - { - DestinationRef = { - Type = gvk("catalog.v2beta1.Service") - Name = "db" - } - - DestinationPort = "tcp" - - IpPort = { - Ip = "127.0.0.1" - Port = 1234 - } - } - ] -} diff --git a/command/rtt/rtt.go b/command/rtt/rtt.go index db9e3efd06be2..f7a7414511d60 100644 --- a/command/rtt/rtt.go +++ b/command/rtt/rtt.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rtt diff --git a/command/rtt/rtt_test.go b/command/rtt/rtt_test.go index 4b0621cfe33f8..8534fc1a59bc2 100644 --- a/command/rtt/rtt_test.go +++ b/command/rtt/rtt_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package rtt diff --git a/command/services/config.go b/command/services/config.go index 1a173078d6f04..f881778956d6b 100644 --- a/command/services/config.go +++ b/command/services/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package services diff --git a/command/services/config_test.go b/command/services/config_test.go index b8a2207fb9e86..e8770337d4d9b 100644 --- a/command/services/config_test.go +++ b/command/services/config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package services diff --git a/command/services/deregister/deregister.go b/command/services/deregister/deregister.go index bff2c972704a8..69a4ef9437d74 100644 --- a/command/services/deregister/deregister.go +++ b/command/services/deregister/deregister.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package deregister diff --git a/command/services/deregister/deregister_test.go b/command/services/deregister/deregister_test.go index 2ee9d8de5fab5..15d9ffddb22ba 100644 --- a/command/services/deregister/deregister_test.go +++ b/command/services/deregister/deregister_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package deregister diff --git a/command/services/export/export.go b/command/services/export/export.go index 49a5756602006..637553f93e6c7 100644 --- a/command/services/export/export.go +++ b/command/services/export/export.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package export import ( diff --git a/command/services/export/export_test.go b/command/services/export/export_test.go index aa13aff63c238..6a2dfa9d67b06 100644 --- a/command/services/export/export_test.go +++ b/command/services/export/export_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package export import ( diff --git a/command/services/register/register.go b/command/services/register/register.go index 33599dda01323..6e5f7a0fcfa57 100644 --- a/command/services/register/register.go +++ b/command/services/register/register.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package register diff --git a/command/services/register/register_test.go b/command/services/register/register_test.go index 24d5f4fb87ea1..2004610cf50d0 100644 --- a/command/services/register/register_test.go +++ b/command/services/register/register_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package register diff --git a/command/services/services.go b/command/services/services.go index 521092f063ae5..9c12445def7e1 100644 --- a/command/services/services.go +++ b/command/services/services.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package services diff --git a/command/services/services_test.go b/command/services/services_test.go index a2d4b45262be5..11a31cd16dbe1 100644 --- a/command/services/services_test.go +++ b/command/services/services_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package services diff --git a/command/snapshot/inspect/formatter.go b/command/snapshot/inspect/formatter.go index 53da998b25c8b..2898bf174fb07 100644 --- a/command/snapshot/inspect/formatter.go +++ b/command/snapshot/inspect/formatter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inspect diff --git a/command/snapshot/inspect/formatter_test.go b/command/snapshot/inspect/formatter_test.go index 48b8d1da4d966..b55ea6b972a26 100644 --- a/command/snapshot/inspect/formatter_test.go +++ b/command/snapshot/inspect/formatter_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inspect diff --git a/command/snapshot/inspect/snapshot_inspect.go b/command/snapshot/inspect/snapshot_inspect.go index 483e937eb4810..018d3f3dec348 100644 --- a/command/snapshot/inspect/snapshot_inspect.go +++ b/command/snapshot/inspect/snapshot_inspect.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inspect diff --git a/command/snapshot/inspect/snapshot_inspect_test.go b/command/snapshot/inspect/snapshot_inspect_test.go index 1f7ff69f1bc35..f6a7990783680 100644 --- a/command/snapshot/inspect/snapshot_inspect_test.go +++ b/command/snapshot/inspect/snapshot_inspect_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inspect diff --git a/command/snapshot/restore/snapshot_restore.go b/command/snapshot/restore/snapshot_restore.go index aaa08a162d7a8..170e77685dc2c 100644 --- a/command/snapshot/restore/snapshot_restore.go +++ b/command/snapshot/restore/snapshot_restore.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package restore diff --git a/command/snapshot/restore/snapshot_restore_test.go b/command/snapshot/restore/snapshot_restore_test.go index 61c8b2bed0d67..076df99a6bdd6 100644 --- a/command/snapshot/restore/snapshot_restore_test.go +++ b/command/snapshot/restore/snapshot_restore_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package restore diff --git a/command/snapshot/save/snapshot_save.go b/command/snapshot/save/snapshot_save.go index ac333e8ca3d36..11569d60c519c 100644 --- a/command/snapshot/save/snapshot_save.go +++ b/command/snapshot/save/snapshot_save.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package save diff --git a/command/snapshot/save/snapshot_save_test.go b/command/snapshot/save/snapshot_save_test.go index 44d07aebb882f..15f31784847f0 100644 --- a/command/snapshot/save/snapshot_save_test.go +++ b/command/snapshot/save/snapshot_save_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package save diff --git a/command/snapshot/snapshot_command.go b/command/snapshot/snapshot_command.go index 2e96550e191fd..7378f5449f29d 100644 --- a/command/snapshot/snapshot_command.go +++ b/command/snapshot/snapshot_command.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package snapshot diff --git a/command/snapshot/snapshot_command_test.go b/command/snapshot/snapshot_command_test.go index d38f5cde9271b..99db9533a31d7 100644 --- a/command/snapshot/snapshot_command_test.go +++ b/command/snapshot/snapshot_command_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package snapshot diff --git a/command/tls/ca/create/tls_ca_create.go b/command/tls/ca/create/tls_ca_create.go index 43a9c249f154e..4c25f8aec7a2e 100644 --- a/command/tls/ca/create/tls_ca_create.go +++ b/command/tls/ca/create/tls_ca_create.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package create diff --git a/command/tls/ca/create/tls_ca_create_test.go b/command/tls/ca/create/tls_ca_create_test.go index aee2b69062cff..d9e837e56d7f4 100644 --- a/command/tls/ca/create/tls_ca_create_test.go +++ b/command/tls/ca/create/tls_ca_create_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package create diff --git a/command/tls/ca/tls_ca.go b/command/tls/ca/tls_ca.go index ef943a4fbfe0e..65207c0dc8ba0 100644 --- a/command/tls/ca/tls_ca.go +++ b/command/tls/ca/tls_ca.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/command/tls/ca/tls_ca_test.go b/command/tls/ca/tls_ca_test.go index d24c15665f307..74cd8de37da47 100644 --- a/command/tls/ca/tls_ca_test.go +++ b/command/tls/ca/tls_ca_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ca diff --git a/command/tls/cert/create/tls_cert_create.go b/command/tls/cert/create/tls_cert_create.go index 9e0f92173bd15..7af36bc986cd8 100644 --- a/command/tls/cert/create/tls_cert_create.go +++ b/command/tls/cert/create/tls_cert_create.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package create diff --git a/command/tls/cert/create/tls_cert_create_test.go b/command/tls/cert/create/tls_cert_create_test.go index 6e807d4a4fc71..9f9fa1385a21e 100644 --- a/command/tls/cert/create/tls_cert_create_test.go +++ b/command/tls/cert/create/tls_cert_create_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package create diff --git a/command/tls/cert/tls_cert.go b/command/tls/cert/tls_cert.go index 38551ef6c621d..17795507e4319 100644 --- a/command/tls/cert/tls_cert.go +++ b/command/tls/cert/tls_cert.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cert diff --git a/command/tls/cert/tls_cert_test.go b/command/tls/cert/tls_cert_test.go index 912ff3e58e4b2..ab5144813de61 100644 --- a/command/tls/cert/tls_cert_test.go +++ b/command/tls/cert/tls_cert_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cert diff --git a/command/tls/tls.go b/command/tls/tls.go index a25a313ed02ec..fda3c4a12331a 100644 --- a/command/tls/tls.go +++ b/command/tls/tls.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tls diff --git a/command/tls/tls_test.go b/command/tls/tls_test.go index 7bd99fd4c11c4..dd34df10fd282 100644 --- a/command/tls/tls_test.go +++ b/command/tls/tls_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tls diff --git a/command/troubleshoot/proxy/troubleshoot_proxy.go b/command/troubleshoot/proxy/troubleshoot_proxy.go index 1f513043fb17d..08928b9e5453f 100644 --- a/command/troubleshoot/proxy/troubleshoot_proxy.go +++ b/command/troubleshoot/proxy/troubleshoot_proxy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/command/troubleshoot/troubleshoot.go b/command/troubleshoot/troubleshoot.go index 36c77ff104352..431c671ee732c 100644 --- a/command/troubleshoot/troubleshoot.go +++ b/command/troubleshoot/troubleshoot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/command/troubleshoot/troubleshoot_test.go b/command/troubleshoot/troubleshoot_test.go index a0e3f1c06957f..9ec2f68665a36 100644 --- a/command/troubleshoot/troubleshoot_test.go +++ b/command/troubleshoot/troubleshoot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/command/troubleshoot/upstreams/troubleshoot_upstreams.go b/command/troubleshoot/upstreams/troubleshoot_upstreams.go index 5796dac583764..19737c7353307 100644 --- a/command/troubleshoot/upstreams/troubleshoot_upstreams.go +++ b/command/troubleshoot/upstreams/troubleshoot_upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upstreams diff --git a/command/validate/validate.go b/command/validate/validate.go index 1a9630c65f47e..a44120a89f8be 100644 --- a/command/validate/validate.go +++ b/command/validate/validate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package validate diff --git a/command/validate/validate_test.go b/command/validate/validate_test.go index dc5b519dbe31a..fdd0c7b2f2ff6 100644 --- a/command/validate/validate_test.go +++ b/command/validate/validate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package validate diff --git a/command/version/formatter.go b/command/version/formatter.go index 612c305a7985d..c7c16da4419bf 100644 --- a/command/version/formatter.go +++ b/command/version/formatter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package version diff --git a/command/version/formatter_test.go b/command/version/formatter_test.go index 45e4019dfb5c8..b5c0bd2482b98 100644 --- a/command/version/formatter_test.go +++ b/command/version/formatter_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package version diff --git a/command/version/version.go b/command/version/version.go index da8978c3e72f7..1c2157a8eae8a 100644 --- a/command/version/version.go +++ b/command/version/version.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package version diff --git a/command/version/version_test.go b/command/version/version_test.go index d0af11506e383..45bd4fc6ac4c2 100644 --- a/command/version/version_test.go +++ b/command/version/version_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package version diff --git a/command/watch/watch.go b/command/watch/watch.go index 205ff3fb083d7..b187fa369ab44 100644 --- a/command/watch/watch.go +++ b/command/watch/watch.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package watch diff --git a/command/watch/watch_test.go b/command/watch/watch_test.go index ba29c2731a8c0..ed830a2aa7f3c 100644 --- a/command/watch/watch_test.go +++ b/command/watch/watch_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package watch diff --git a/connect/certgen/certgen.go b/connect/certgen/certgen.go index 509e7f8df4f3b..ced3720cd81b0 100644 --- a/connect/certgen/certgen.go +++ b/connect/certgen/certgen.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // certgen: a tool for generating test certificates on disk for use as // test-fixtures and for end-to-end testing and local development. diff --git a/connect/example_test.go b/connect/example_test.go index 51571bf1818cb..666f2f09db6dd 100644 --- a/connect/example_test.go +++ b/connect/example_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/connect/proxy/config.go b/connect/proxy/config.go index 19476d48d49f5..9d5e85bf4deee 100644 --- a/connect/proxy/config.go +++ b/connect/proxy/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/proxy/config_test.go b/connect/proxy/config_test.go index a196958316816..55bd64e1b18a2 100644 --- a/connect/proxy/config_test.go +++ b/connect/proxy/config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/proxy/conn.go b/connect/proxy/conn.go index acc1a49eb4b77..2c9314642ee26 100644 --- a/connect/proxy/conn.go +++ b/connect/proxy/conn.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/proxy/conn_test.go b/connect/proxy/conn_test.go index b5be7952d0ee5..95836af0d9e4f 100644 --- a/connect/proxy/conn_test.go +++ b/connect/proxy/conn_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/proxy/listener.go b/connect/proxy/listener.go index fc823d2712845..97d607c751f6a 100644 --- a/connect/proxy/listener.go +++ b/connect/proxy/listener.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/proxy/listener_test.go b/connect/proxy/listener_test.go index 5554ecf353a6e..9b4e573a4aa1e 100644 --- a/connect/proxy/listener_test.go +++ b/connect/proxy/listener_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/proxy/proxy.go b/connect/proxy/proxy.go index c365862ad8ec7..f5e7f913460fd 100644 --- a/connect/proxy/proxy.go +++ b/connect/proxy/proxy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/proxy/proxy_test.go b/connect/proxy/proxy_test.go index 20b4cdd55efef..876a91c81a4d0 100644 --- a/connect/proxy/proxy_test.go +++ b/connect/proxy/proxy_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/proxy/testing.go b/connect/proxy/testing.go index 6756f16a2567b..7f8604394af75 100644 --- a/connect/proxy/testing.go +++ b/connect/proxy/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package proxy diff --git a/connect/resolver.go b/connect/resolver.go index fa89bc36d33d8..eb68b1c123358 100644 --- a/connect/resolver.go +++ b/connect/resolver.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/connect/resolver_test.go b/connect/resolver_test.go index 3aece268b5dc3..51bc13ee28d4b 100644 --- a/connect/resolver_test.go +++ b/connect/resolver_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/connect/service.go b/connect/service.go index ea38dd59b2e53..1260b065a068c 100644 --- a/connect/service.go +++ b/connect/service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/connect/service_test.go b/connect/service_test.go index 0f6ed51a8b458..87f522214cee2 100644 --- a/connect/service_test.go +++ b/connect/service_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/connect/testing.go b/connect/testing.go index 1017ee15f5e7d..4fe1a54f6e098 100644 --- a/connect/testing.go +++ b/connect/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/connect/tls.go b/connect/tls.go index 3d29cf48e1c0a..a0e0286bc1afb 100644 --- a/connect/tls.go +++ b/connect/tls.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect @@ -425,7 +425,7 @@ func (cfg *dynamicTLSConfig) Ready() bool { return cfg.VerifyLeafWithRoots() == nil } -// ReadyWait returns a chan that is closed when the Service becomes ready +// ReadyWait returns a chan that is closed when the the Service becomes ready // for use for the first time. Note that if the Service is ready when it is // called it returns a nil chan. Ready means that it has root and leaf // certificates configured but not that the combination is valid nor that diff --git a/connect/tls_test.go b/connect/tls_test.go index 74609b1740e35..5c96371c9443d 100644 --- a/connect/tls_test.go +++ b/connect/tls_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package connect diff --git a/docs/README.md b/docs/README.md index 0d61b30fa5778..d3483710b33bd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -40,8 +40,6 @@ Also see the [FAQ](./faq.md). 1. [Integration Tests](../test/integration/connect/envoy/README.md) 1. [Upgrade Tests](../test/integration/consul-container/test/upgrade/README.md) -1. [Remote Debugging Integration Tests](../test/integration/consul-container/test/debugging.md) -1. [Peering Common Topology Tests](../test-integ/peering_commontopo/README.md) ## Important Directories @@ -56,7 +54,7 @@ contain other important source related to Consul. * [.changelog] contains markdown files that are used by [hashicorp/go-changelog] to produce the [CHANGELOG.md]. * [build-support] contains bash functions and scripts used to automate. - development tasks. Generally these scripts are called from the [Makefile]. + development tasks. Generally these scripts are called from the [GNUmakefile]. * [grafana] contains the source for a [Grafana dashboard] that can be used to monitor Consul. @@ -67,7 +65,7 @@ contain other important source related to Consul. [hashicorp/go-changelog]: https://github.com/hashicorp/go-changelog [CHANGELOG.md]: https://github.com/hashicorp/consul/blob/main/CHANGELOG.md [build-support]: https://github.com/hashicorp/consul/tree/main/build-support -[Makefile]: https://github.com/hashicorp/consul/tree/main/Makefile +[GNUmakefile]: https://github.com/hashicorp/consul/tree/main/GNUmakefile [Grafana dashboard]: https://grafana.com/grafana/dashboards [grafana]: https://github.com/hashicorp/consul/tree/main/grafana diff --git a/docs/resources/guide.md b/docs/resources/guide.md index aaecdecef07df..b3f389c006a6a 100644 --- a/docs/resources/guide.md +++ b/docs/resources/guide.md @@ -17,13 +17,10 @@ $ mkdir proto-public/pbfoo/v1alpha1 syntax = "proto3"; import "pbresource/resource.proto"; -import "pbresource/annotations.proto"; package hashicorp.consul.foo.v1alpha1; message Bar { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - string baz = 1; hashicorp.consul.resource.ID qux = 2; } @@ -50,22 +47,22 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) +var BarV1Alpha1Type = &pbresource.Type{ + Group: "foo", + GroupVersion: "v1alpha1", + Kind: "bar", +} + func RegisterTypes(r resource.Registry) { r.Register(resource.Registration{ - Type: pbv1alpha1.BarType, - Scope: resource.ScopePartition, + Type: BarV1Alpha1Type, Proto: &pbv1alpha1.Bar{}, }) } ``` -Note that Scope reference the scope of the new resource, `resource.ScopePartition` -mean that resource will be at the partition level and have no namespace, while `resource.ScopeNamespace` mean it will have both a namespace -and a partition. -Update the `NewTypeRegistry` method in [`type_registry.go`] to call your -package's type registration method: - -[`type_registry.go`]: ../../agent/consul/type_registry.go +Update the `registerResources` method in [`server.go`] to call your package's +type registration method: ```Go import ( @@ -74,13 +71,15 @@ import ( // … ) -func NewTypeRegistry() resource.Registry { +func (s *Server) registerResources() { // … - foo.RegisterTypes(registry) + foo.RegisterTypes(s.typeRegistry) // … } ``` +[`server.go`]: ../../agent/consul/server.go + That should be all you need to start using your new resource type. Test it out by starting an agent in dev mode: @@ -140,9 +139,8 @@ using a validation hook provided in the type registration: ```Go func RegisterTypes(r resource.Registry) { r.Register(resource.Registration{ - Type: pbv1alpha1.BarType, - Proto: &pbv1alpha1.Bar{}, - Scope: resource.ScopeNamespace, + Type: BarV1Alpha1Type, + Proto: &pbv1alpha1.Bar{}, Validate: validateBar, }) } @@ -173,9 +171,8 @@ a set of ACL hooks: ```Go func RegisterTypes(r resource.Registry) { r.Register(resource.Registration{ - Type: pbv1alpha1.BarType, - Proto: &pbv1alpha1.Bar{}, - Scope: resource.ScopeNamespace, + Type: BarV1Alpha1Type, + Proto: &pbv1alpha1.Bar{}, ACLs: &resource.ACLHooks{, Read: authzReadBar, Write: authzWriteBar, @@ -184,19 +181,19 @@ func RegisterTypes(r resource.Registry) { }) } -func authzReadBar(authz acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { +func authzReadBar(authz acl.Authorizer, id *pbresource.ID) error { return authz.ToAllowAuthorizer(). - BarReadAllowed(id.Name, authzContext) + BarReadAllowed(id.Name, resource.AuthorizerContext(id.Tenancy)) } -func authzWriteBar(authz acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { +func authzWriteBar(authz acl.Authorizer, id *pbresource.ID) error { return authz.ToAllowAuthorizer(). - BarWriteAllowed(res.ID().Name, authzContext) + BarWriteAllowed(id.Name, resource.AuthorizerContext(id.Tenancy)) } -func authzListBar(authz acl.Authorizer, authzContext *acl.AuthorizerContext) error { +func authzListBar(authz acl.Authorizer, ten *pbresource.Tenancy) error { return authz.ToAllowAuthorizer(). - BarListAllowed(authzContext) + BarListAllowed(resource.AuthorizerContext(ten)) } ``` @@ -212,9 +209,8 @@ by providing a mutation hook: ```Go func RegisterTypes(r resource.Registry) { r.Register(resource.Registration{ - Type: pbv1alpha1.BarType, - Proto: &pbv1alpha1.Bar{}, - Scope: resource.ScopeNamespace, + Type: BarV1Alpha1Type, + Proto: &pbv1alpha1.Bar{}, Mutate: mutateBar, }) } @@ -251,7 +247,7 @@ import ( ) func barController() controller.Controller { - return controller.ForType(pbv1alpha1.BarType). + return controller.ForType(BarV1Alpha1Type). WithReconciler(barReconciler{}) } @@ -281,9 +277,7 @@ func (barReconciler) Reconcile(ctx context.Context, rt controller.Runtime, req c Next, register your controller with the controller manager. Another common pattern is to have your package expose a method for registering controllers, -which is called from `registerControllers` in [`server.go`]. - -[`server.go`]: ../../agent/consul/server.go +which is also called from `registerResources` in [`server.go`]. ```Go package foo @@ -296,7 +290,7 @@ func RegisterControllers(mgr *controller.Manager) { ```Go package consul -func (s *Server) registerControllers() { +func (s *Server) registerResources() { // … foo.RegisterControllers(s.controllerManager) // … @@ -387,8 +381,8 @@ controller also watches workloads and services. ```Go func barController() controller.Controller { - return controller.ForType(pbv1alpha1.BarType). - WithWatch(pbv1alpha1.BazType, controller.MapOwner) + return controller.ForType(BarV1Alpha1Type). + WithWatch(BazV1Alpha1Type, controller.MapOwner) WithReconciler(barReconciler{}) } ``` @@ -413,7 +407,7 @@ the controller's placement. ```Go func barController() controller.Controller { - return controller.ForType(pbv1alpha1.BarType). + return controller.ForType(BarV1Alpha1Type). WithPlacement(controller.PlacementEachServer) WithReconciler(barReconciler{}) } diff --git a/envoyextensions/extensioncommon/basic_envoy_extender.go b/envoyextensions/extensioncommon/basic_envoy_extender.go index 86cee8f14a4e8..a99d7439fea83 100644 --- a/envoyextensions/extensioncommon/basic_envoy_extender.go +++ b/envoyextensions/extensioncommon/basic_envoy_extender.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensioncommon diff --git a/envoyextensions/extensioncommon/basic_extension_adapter.go b/envoyextensions/extensioncommon/basic_extension_adapter.go index 39e1e8c8363bf..fbf73f34c2983 100644 --- a/envoyextensions/extensioncommon/basic_extension_adapter.go +++ b/envoyextensions/extensioncommon/basic_extension_adapter.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensioncommon diff --git a/envoyextensions/extensioncommon/envoy_extender.go b/envoyextensions/extensioncommon/envoy_extender.go index 269f01acd6de4..0c8f9141c9258 100644 --- a/envoyextensions/extensioncommon/envoy_extender.go +++ b/envoyextensions/extensioncommon/envoy_extender.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensioncommon @@ -21,7 +21,7 @@ type EnvoyExtender interface { // Extend updates indexed xDS structures to include patches for // built-in extensions. It is responsible for applying extensions to - // the appropriate xDS resources. If any portion of this function fails, + // the the appropriate xDS resources. If any portion of this function fails, // it will attempt continue and return an error. The caller can then determine // if it is better to use a partially applied extension or error out. Extend(*xdscommon.IndexedResources, *RuntimeConfig) (*xdscommon.IndexedResources, error) diff --git a/envoyextensions/extensioncommon/envoy_extender_test.go b/envoyextensions/extensioncommon/envoy_extender_test.go index 9fe6b49aeb33b..48e338ed896f3 100644 --- a/envoyextensions/extensioncommon/envoy_extender_test.go +++ b/envoyextensions/extensioncommon/envoy_extender_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package extensioncommon import ( diff --git a/envoyextensions/extensioncommon/resources.go b/envoyextensions/extensioncommon/resources.go index c5febfb6dd30a..22c6c3ffa9ee1 100644 --- a/envoyextensions/extensioncommon/resources.go +++ b/envoyextensions/extensioncommon/resources.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensioncommon @@ -411,8 +411,8 @@ func getSNI(chain *envoy_listener_v3.FilterChain) string { } // GetHTTPConnectionManager returns the Envoy HttpConnectionManager filter from the list of network filters. -// It also returns the index within the list of filters where the connection manager was found in case the -// caller needs to overwrite the original filter. +// It also returns the index within the list of filters where the connection manager was found in case the caller +// needs this information. // It returns a non-nil error if the HttpConnectionManager is not found. func GetHTTPConnectionManager(filters ...*envoy_listener_v3.Filter) (*envoy_http_v3.HttpConnectionManager, int, error) { for idx, filter := range filters { @@ -491,11 +491,9 @@ func InsertHTTPFilter(filters []*envoy_listener_v3.Filter, filter *envoy_http_v3 if err != nil { return filters, errors.New("failed to insert new HTTP connection manager filter") } - filtersCopy := make([]*envoy_listener_v3.Filter, len(filters)) - copy(filtersCopy, filters) - filtersCopy[idx] = newHttpConMan + filters[idx] = newHttpConMan - return filtersCopy, nil + return filters, nil } // InsertNetworkFilter inserts the given network filter into the filter chain in the location diff --git a/envoyextensions/extensioncommon/resources_test.go b/envoyextensions/extensioncommon/resources_test.go index 477e66494ce5f..659da8770ea65 100644 --- a/envoyextensions/extensioncommon/resources_test.go +++ b/envoyextensions/extensioncommon/resources_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensioncommon diff --git a/envoyextensions/extensioncommon/runtime_config.go b/envoyextensions/extensioncommon/runtime_config.go index 2a5e7d60077be..a20e4ed04e646 100644 --- a/envoyextensions/extensioncommon/runtime_config.go +++ b/envoyextensions/extensioncommon/runtime_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensioncommon diff --git a/envoyextensions/extensioncommon/runtime_config_test.go b/envoyextensions/extensioncommon/runtime_config_test.go index 8c4c9bed6eb69..fa2ac8df5f421 100644 --- a/envoyextensions/extensioncommon/runtime_config_test.go +++ b/envoyextensions/extensioncommon/runtime_config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensioncommon diff --git a/envoyextensions/extensioncommon/upstream_envoy_extender.go b/envoyextensions/extensioncommon/upstream_envoy_extender.go index 35cebe2fa5301..135aca3f82e74 100644 --- a/envoyextensions/extensioncommon/upstream_envoy_extender.go +++ b/envoyextensions/extensioncommon/upstream_envoy_extender.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package extensioncommon diff --git a/envoyextensions/go.mod b/envoyextensions/go.mod index 9a03ccda3679b..080d6fc5a5bc0 100644 --- a/envoyextensions/go.mod +++ b/envoyextensions/go.mod @@ -2,10 +2,7 @@ module github.com/hashicorp/consul/envoyextensions go 1.20 -replace ( - github.com/hashicorp/consul/api => ../api - github.com/hashicorp/consul/sdk => ../sdk -) +replace github.com/hashicorp/consul/api => ../api require ( github.com/envoyproxy/go-control-plane v0.11.0 @@ -40,7 +37,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/sys v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/envoyextensions/go.sum b/envoyextensions/go.sum index b611aa2308ee4..a585ee9834475 100644 --- a/envoyextensions/go.sum +++ b/envoyextensions/go.sum @@ -62,6 +62,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/hashicorp/consul/sdk v0.14.1 h1:ZiwE2bKb+zro68sWzZ1SgHF3kRMBZ94TwOCFRF4ylPs= +github.com/hashicorp/consul/sdk v0.14.1/go.mod h1:vFt03juSzocLRFo59NkeQHHmQa6+g7oU0pfzdI1mUhg= 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= @@ -184,8 +186,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -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/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= diff --git a/envoyextensions/xdscommon/envoy_versioning.go b/envoyextensions/xdscommon/envoy_versioning.go index c5f9d4798c105..393a96bf9e809 100644 --- a/envoyextensions/xdscommon/envoy_versioning.go +++ b/envoyextensions/xdscommon/envoy_versioning.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xdscommon diff --git a/envoyextensions/xdscommon/envoy_versioning_test.go b/envoyextensions/xdscommon/envoy_versioning_test.go index 925e2fa5378f1..a86105e848cde 100644 --- a/envoyextensions/xdscommon/envoy_versioning_test.go +++ b/envoyextensions/xdscommon/envoy_versioning_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xdscommon @@ -151,10 +151,10 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) { } */ for _, v := range []string{ + "1.23.0", "1.23.1", "1.23.2", "1.23.3", "1.23.4", "1.23.5", "1.23.6", "1.23.7", "1.23.8", "1.23.9", "1.23.10", "1.23.11", "1.23.12", "1.24.0", "1.24.1", "1.24.2", "1.24.3", "1.24.4", "1.24.5", "1.24.6", "1.24.7", "1.24.8", "1.24.9", "1.24.10", "1.24.11", "1.24.12", "1.25.0", "1.25.1", "1.25.2", "1.25.3", "1.25.4", "1.25.5", "1.25.6", "1.25.7", "1.25.8", "1.25.9", "1.25.10", "1.25.11", "1.26.0", "1.26.1", "1.26.2", "1.26.3", "1.26.4", "1.26.5", "1.26.6", - "1.27.0", "1.27.1", "1.27.2", } { cases[v] = testcase{expect: SupportedProxyFeatures{}} } diff --git a/envoyextensions/xdscommon/proxysupport.go b/envoyextensions/xdscommon/proxysupport.go index 9e487e1867e27..e2295cf985cf8 100644 --- a/envoyextensions/xdscommon/proxysupport.go +++ b/envoyextensions/xdscommon/proxysupport.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xdscommon @@ -12,10 +12,10 @@ import "strings" // // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions var EnvoyVersions = []string{ - "1.27.2", "1.26.6", "1.25.11", "1.24.12", + "1.23.12", } // UnsupportedEnvoyVersions lists any unsupported Envoy versions (mainly minor versions) that fall diff --git a/envoyextensions/xdscommon/proxysupport_test.go b/envoyextensions/xdscommon/proxysupport_test.go index cc90b726c9d94..042ab5ad874e9 100644 --- a/envoyextensions/xdscommon/proxysupport_test.go +++ b/envoyextensions/xdscommon/proxysupport_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xdscommon diff --git a/envoyextensions/xdscommon/xdscommon.go b/envoyextensions/xdscommon/xdscommon.go index ae40f070210ff..30c82de9ae561 100644 --- a/envoyextensions/xdscommon/xdscommon.go +++ b/envoyextensions/xdscommon/xdscommon.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package xdscommon @@ -54,10 +54,6 @@ const ( SecretType = apiTypePrefix + "envoy.extensions.transport_sockets.tls.v3.Secret" FailoverClusterNamePrefix = "failover-target~" - - // BlackHoleClusterName is the cluster we use for black-holing traffic for cases when a workload - // has no inbound ports to route to. - BlackHoleClusterName = "black-hole-cluster" ) type IndexedResources struct { diff --git a/envoyextensions/xdscommon/xdscommon_test.go b/envoyextensions/xdscommon/xdscommon_test.go index 2d1aec40b54f7..5cca6e13a6192 100644 --- a/envoyextensions/xdscommon/xdscommon_test.go +++ b/envoyextensions/xdscommon/xdscommon_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package xdscommon import ( diff --git a/fixup_acl_move.sh b/fixup_acl_move.sh new file mode 100644 index 0000000000000..2dbc9c6aefe77 --- /dev/null +++ b/fixup_acl_move.sh @@ -0,0 +1,27 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + + +GOIMPORTS=~/go/bin/goimports + +CHANGED=(EnterpriseMeta PartitionOrDefault IsDefaultPartition NamespaceOrDefault NewEnterpriseMetaWithPartition EqualPartitions) + +DIRS=(agent command proto) + +for dir in "${DIRS[@]}" + do + echo "CD to $dir" + pushd $dir + for s in "${CHANGED[@]}" + do + REWRITE='structs.'$s' -> acl.'$s + echo "REPL $REWRITE" + gofmt -w -r="$REWRITE" . + done + popd +done + +find . -name \*.go | xargs fgrep 'acl.' -l | xargs $GOIMPORTS -local "github.com/hashicorp/consul" -w + +make --always-make proto +make go-mod-tidy diff --git a/go.mod b/go.mod index 13b6f835d2ebe..ddbb3e6e555f6 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 - github.com/hashicorp/consul/api v1.24.0 + github.com/hashicorp/consul/api v1.25.1 github.com/hashicorp/consul/envoyextensions v0.4.1 github.com/hashicorp/consul/proto-public v0.4.1 github.com/hashicorp/consul/sdk v0.14.1 @@ -54,7 +54,6 @@ require ( github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-raftchunking v0.7.0 github.com/hashicorp/go-retryablehttp v0.6.7 - github.com/hashicorp/go-rootcerts v1.0.2 github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 github.com/hashicorp/go-sockaddr v1.0.2 github.com/hashicorp/go-syslog v1.0.0 @@ -63,15 +62,14 @@ require ( github.com/hashicorp/golang-lru v0.5.4 github.com/hashicorp/hcdiag v0.5.1 github.com/hashicorp/hcl v1.0.0 - github.com/hashicorp/hcl/v2 v2.14.1 github.com/hashicorp/hcp-scada-provider v0.2.3 - github.com/hashicorp/hcp-sdk-go v0.61.0 + github.com/hashicorp/hcp-sdk-go v0.55.0 github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 github.com/hashicorp/memberlist v0.5.0 github.com/hashicorp/raft v1.5.0 github.com/hashicorp/raft-autopilot v0.1.6 github.com/hashicorp/raft-boltdb/v2 v2.2.2 - github.com/hashicorp/raft-wal v0.4.1 + github.com/hashicorp/raft-wal v0.3.0 github.com/hashicorp/serf v0.10.1 github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 github.com/hashicorp/vault/api v1.8.3 @@ -89,8 +87,6 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/pointerstructure v1.2.1 github.com/mitchellh/reflectwalk v1.0.2 - github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce - github.com/oklog/ulid v1.3.1 github.com/oklog/ulid/v2 v2.1.0 github.com/olekukonko/tablewriter v0.0.4 github.com/patrickmn/go-cache v2.1.0+incompatible @@ -100,8 +96,6 @@ require ( github.com/ryanuber/columnize v2.1.2+incompatible github.com/shirou/gopsutil/v3 v3.22.9 github.com/stretchr/testify v1.8.3 - github.com/xeipuuv/gojsonschema v1.2.0 - github.com/zclconf/go-cty v1.11.1 go.etcd.io/bbolt v1.3.7 go.opentelemetry.io/otel v1.16.0 go.opentelemetry.io/otel/metric v1.16.0 @@ -110,10 +104,10 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 go.uber.org/goleak v1.1.10 golang.org/x/crypto v0.14.0 - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/net v0.17.0 golang.org/x/oauth2 v0.7.0 - golang.org/x/sync v0.3.0 + golang.org/x/sync v0.2.0 golang.org/x/sys v0.13.0 golang.org/x/time v0.3.0 google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e @@ -198,9 +192,11 @@ require ( github.com/hashicorp/go-msgpack v0.5.5 // indirect github.com/hashicorp/go-msgpack/v2 v2.0.0 // indirect github.com/hashicorp/go-plugin v1.4.5 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/hcl/v2 v2.14.1 // indirect github.com/hashicorp/mdns v1.0.4 // indirect github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 // indirect github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect @@ -225,6 +221,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect github.com/oklog/run v1.0.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect @@ -252,25 +249,23 @@ require ( github.com/tklauser/numcpus v0.5.0 // indirect github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect github.com/vmware/govmomi v0.18.0 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect + github.com/zclconf/go-cty v1.11.1 // indirect go.mongodb.org/mongo-driver v1.11.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel/trace v1.16.0 // indirect go.uber.org/atomic v1.9.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/mod v0.12.0 // indirect + golang.org/x/mod v0.10.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + golang.org/x/tools v0.9.1 // indirect google.golang.org/api v0.114.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.2 // indirect - gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/resty.v1 v1.12.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 3598121de6f45..41d8176552c93 100644 --- a/go.sum +++ b/go.sum @@ -571,8 +571,8 @@ github.com/hashicorp/hcl/v2 v2.14.1 h1:x0BpjfZ+CYdbiz+8yZTQ+gdLO7IXvOut7Da+XJayx github.com/hashicorp/hcl/v2 v2.14.1/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= github.com/hashicorp/hcp-scada-provider v0.2.3 h1:AarYR+/Pcv+cMvPdAlb92uOBmZfEH6ny4+DT+4NY2VQ= github.com/hashicorp/hcp-scada-provider v0.2.3/go.mod h1:ZFTgGwkzNv99PLQjTsulzaCplCzOTBh0IUQsPKzrQFo= -github.com/hashicorp/hcp-sdk-go v0.61.0 h1:x4hJ8SlLI5WCE8Uzcu4q5jfdOEz/hFxfUkhAdoFdzSg= -github.com/hashicorp/hcp-sdk-go v0.61.0/go.mod h1:xP7wmWAmdMxs/7+ovH3jZn+MCDhHRj50Rn+m7JIY3Ck= +github.com/hashicorp/hcp-sdk-go v0.55.0 h1:T4sQtgQfQJOD0uucT4hS+GZI1FmoHAQMADj277W++xw= +github.com/hashicorp/hcp-sdk-go v0.55.0/go.mod h1:hZqky4HEzsKwvLOt4QJlZUrjeQmb4UCZUhDP2HyQFfc= github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 h1:n9J0rwVWXDpNd5iZnwY7w4WZyq53/rROeI7OVvLW8Ok= github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -595,8 +595,8 @@ github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qR github.com/hashicorp/raft-boltdb v0.0.0-20220329195025-15018e9b97e0 h1:CO8dBMLH6dvE1jTn/30ZZw3iuPsNfajshWoJTnVc5cc= github.com/hashicorp/raft-boltdb/v2 v2.2.2 h1:rlkPtOllgIcKLxVT4nutqlTH2NRFn+tO1wwZk/4Dxqw= github.com/hashicorp/raft-boltdb/v2 v2.2.2/go.mod h1:N8YgaZgNJLpZC+h+by7vDu5rzsRgONThTEeUS3zWbfY= -github.com/hashicorp/raft-wal v0.4.1 h1:aU8XZ6x8R9BAIB/83Z1dTDtXvDVmv9YVYeXxd/1QBSA= -github.com/hashicorp/raft-wal v0.4.1/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= +github.com/hashicorp/raft-wal v0.3.0 h1:Mi6RPoRbsxIIYZryI+bSTXHD97Ua6rIYO51ibYV9bkY= +github.com/hashicorp/raft-wal v0.3.0/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 h1:O6tNk0s/arubLUbLeCyaRs5xGo9VwmbQazISY/BfPK4= @@ -767,8 +767,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce h1:TqjP/BTDrwN7zP9xyXVuLsMBXYMt6LLYi55PlrIcq8U= -github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:ifHPsLndGGzvgzcaXUvzmt6LxKT4pJ+uzEhtnMt+f7A= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -957,13 +955,6 @@ github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+ github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -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/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= @@ -1049,8 +1040,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1078,8 +1069,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1166,8 +1157,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1342,8 +1333,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1513,8 +1504,6 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.9.1/go.mod h1:vo52Hzryw9PnPHcJfPsBiFW62XhNx5OczbV9y+IMpgc= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/grafana/README.md b/grafana/README.md index 2e8b2b588b75d..b3dec68183a9d 100644 --- a/grafana/README.md +++ b/grafana/README.md @@ -9,7 +9,3 @@ The page for publishing this dashboard is https://grafana.com/grafana/dashboards - Click "share" and export for external publishing - Login to Grafana via the team account (message a manager) - Publish as a new version, including change notes. - -### Grafana dashboard for consul-k8s (control plane) - -A grafana dashboard for monitoring consul-k8s (control plane) can also be found in this directory: `consul-k8s-control-plane-monitoring.json`. This dashboard has not been published to https://grafana.com. diff --git a/grafana/consul-k8s-control-plane-monitoring.json b/grafana/consul-k8s-control-plane-monitoring.json deleted file mode 100644 index 2298a77b53628..0000000000000 --- a/grafana/consul-k8s-control-plane-monitoring.json +++ /dev/null @@ -1,3598 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "id": 3, - "links": [], - "liveNow": false, - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 16, - "panels": [], - "title": "Cluster Status", - "type": "row" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 6, - "x": 0, - "y": 1 - }, - "id": 10, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "", - "limit": 1, - "values": true - }, - "textMode": "auto" - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "consul_consul_server_0_consul_members_servers{pod=\"consul-server-0\"}", - "hide": false, - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "Number of Consul Servers", - "type": "stat" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 8, - "x": 6, - "y": 1 - }, - "id": 60, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "exemplar": false, - "expr": "count(consul_dataplane_envoy_connected)", - "hide": false, - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "Number of Connected Consul-dataplanes", - "type": "stat" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Must be 1", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 1 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 10, - "x": 14, - "y": 1 - }, - "id": 12, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "sum({__name__=~\".+server_isLeader\"})", - "instant": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Number of Leader (1: Healthy)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 6, - "x": 0, - "y": 9 - }, - "id": 61, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "/.*/", - "limit": 1, - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "max(consul_consul_server_0_version{pod=\"consul-server-0\"}) by (version)", - "format": "table", - "hide": false, - "instant": true, - "legendFormat": "", - "range": false, - "refId": "A" - } - ], - "title": "Consul Server Version", - "transformations": [ - { - "id": "organize", - "options": { - "excludeByName": { - "Time": true, - "Value": true - }, - "indexByName": {}, - "renameByName": { - "Time": "" - } - } - } - ], - "type": "stat" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "No data in agentless mode", - "fieldConfig": { - "defaults": { - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 8, - "x": 6, - "y": 9 - }, - "id": 29, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "count(kube_pod_container_resource_limits{pod=~\"consul-client-.*\", container=\"consul\", resource=\"memory\"})", - "hide": false, - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "Number of Consul Clients (No data in agentless mode)", - "type": "stat" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 17 - }, - "id": 40, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 18 - }, - "id": 22, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "expr": "consul_raft_leader_lastContact{quantile=\"0.5\"}", - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "consul_raft_leader_lastContact{quantile=\"0.99\"}", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Raft Leader LastContact 99th and 50th (ms)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Use consul.raft.rpc.appendEntries to understand how long it takes a follower node to process newly received Raft logs from the leader. Like consul.raft.commitTime, increases in this metric can indicate higher load on your Consul servers, and come with a risk of stale data. Since this metric is exposed within each follower, you should aggregate it as both an average (to track overall load on your Raft servers) and a percentile (to watch for outlier nodes).", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 18 - }, - "id": 18, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "consul_raft_rpc_appendEntries{quantile=\"0.99\"}", - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "consul_raft_rpc_appendEntries{quantile=\"0.5\"}", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Follower Append Entries Latency 99th and 50th (ms)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 26 - }, - "id": 20, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "consul_raft_commitTime{quantile=\"0.99\"}", - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "consul_raft_commitTime{quantile=\"0.5\"}", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "Leader Raft Commit Latency 99th and 50th (ms)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 26 - }, - "id": 46, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_raft_fsm_apply_sum[5m])\n/\nrate(consul_raft_fsm_apply_count[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Average Raft FSM Apply Latency per 5 minutes (ms)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 34 - }, - "id": 47, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "sum(rate(consul_raft_apply[5m]))", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Raft Apply Rate per 5 minutes", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "An approximate measurement of the proportion of time the main Raft goroutine is busy and unavailable to accept new work.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 34 - }, - "id": 41, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "expr": "consul_raft_thread_main_saturation{pod=~\"consul-server-.*\",quantile=\"0.9\"}", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Raft thread main saturation (percentage)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "An approximate measurement of the proportion of time the FSM Raft goroutine is busy and unavailable to accept new work.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 42 - }, - "id": 42, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "expr": "consul_raft_thread_fsm_saturation{pod=~\"consul-server-.*\", quantile=\"0.9\"}", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Raft thread FSM saturation (percentage)", - "type": "timeseries" - } - ], - "title": "Raft", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 18 - }, - "id": 43, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Measures the time spent updating the raft store from the serf member information.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 19 - }, - "id": 44, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_leader_reconcile_sum{pod=~\"consul-server-.*\"}[5m])\n/ \nrate(consul_leader_reconcile_count{pod=~\"consul-server-.*\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Average latency of leader reconcile per 5 minutes (ms)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Increments whenever a Consul server becomes a leader.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 19 - }, - "id": 45, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "sum(consul_raft_state_leader{pod=~\"consul-server-.*\"})", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Count of a new leader elected [so far] (increasing only)", - "type": "timeseries" - } - ], - "title": "Leadership Changes", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 19 - }, - "id": 14, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 15, - "x": 0, - "y": 20 - }, - "id": 6, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "expr": "rate(container_cpu_usage_seconds_total{container=\"consul\", pod=~\"consul-server-.*\"}[5m])", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "expr": "kube_pod_container_resource_limits{resource=\"cpu\", container=\"consul\"}", - "hide": true, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "CPU Usage in Seconds (Consul servers)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "All consul servers have the same limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 9, - "x": 15, - "y": 20 - }, - "id": 4, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "exemplar": false, - "expr": "kube_pod_container_resource_limits{resource=\"cpu\", pod=\"consul-server-0\"}", - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "CPU Limit in Seconds (Consul Servers)", - "type": "gauge" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 15, - "x": 0, - "y": 28 - }, - "id": 2, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "expr": "container_memory_working_set_bytes{container=\"consul\", pod=~\"consul-server-.*\"}", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Memory Usage (Consul servers)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "All consul servers have the same limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-BlYlRd" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 9, - "x": 15, - "y": 28 - }, - "id": 8, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "kube_pod_container_resource_limits{resource=\"memory\", pod=\"consul-server-0\"}", - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "Memory Limit (Consul Servers)", - "type": "gauge" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 15, - "x": 0, - "y": 36 - }, - "id": 48, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "sum(rate(container_network_receive_bytes_total{pod=~\"consul-server-.*\"}[5m])) by (pod)", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Received bytes total per 5 minutes (Consul servers)", - "type": "timeseries" - } - ], - "title": "Resource Utilization (Consul Servers)", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 20 - }, - "id": 24, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 15, - "x": 0, - "y": 21 - }, - "id": 26, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(container_cpu_usage_seconds_total{container=\"consul\", pod=~\"consul-client-.*\"}[5m])", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "expr": "kube_pod_container_resource_limits{resource=\"cpu\", container=\"consul\"}", - "hide": true, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "CPU Usage in Seconds (Consul Clients)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "All consul clients have the same limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 9, - "x": 15, - "y": 21 - }, - "id": 28, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "max(kube_pod_container_resource_limits{resource=\"cpu\", pod=~\"consul-client-.*\"})", - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "CPU Limit in Seconds (Consul Clients)", - "type": "gauge" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 15, - "x": 0, - "y": 29 - }, - "id": 23, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "container_memory_working_set_bytes{container=\"consul\", pod=~\"consul-client-.*\"}", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Memory Usage (Consul clients)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "All consul servers have the same limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-BlYlRd" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 9, - "x": 15, - "y": 29 - }, - "id": 25, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "max(kube_pod_container_resource_limits{resource=\"memory\", pod=~\"consul-client-.*\"})", - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "Memory Limit (Consul Clients)", - "type": "gauge" - } - ], - "title": "Resource Utilization (Consul Clients) - N/A in agentless mode", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 21 - }, - "id": 54, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 15, - "x": 0, - "y": 25 - }, - "id": 55, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(container_cpu_usage_seconds_total{pod=~\".*-connect-injector-.*\",container=\"sidecar-injector\"}[5m])", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "builder", - "expr": "kube_pod_container_resource_limits{resource=\"cpu\", container=\"consul\"}", - "hide": true, - "legendFormat": "__auto", - "range": true, - "refId": "B" - } - ], - "title": "CPU Usage in Seconds (Connect Injector)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "All consul servers have the same limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 9, - "x": 15, - "y": 25 - }, - "id": 56, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "max(kube_pod_container_resource_limits{resource=\"cpu\", container=\"sidecar-injector\"})", - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "CPU Limit in Seconds (Connect Injector)", - "type": "gauge" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 15, - "x": 0, - "y": 33 - }, - "id": 59, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "container_memory_working_set_bytes{pod=~\".*-connect-injector-.*\",container=\"sidecar-injector\"}", - "hide": false, - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Memory Usage (Connect Injector)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "All consul servers have the same limit", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-BlYlRd" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 9, - "x": 15, - "y": 33 - }, - "id": 58, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.5.5", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": false, - "expr": "max(kube_pod_container_resource_limits{resource=\"memory\", container=\"sidecar-injector\"})", - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "Memory Limit (Connect Injector)", - "type": "gauge" - } - ], - "title": "Resource Utilization (Connect Injector)", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 22 - }, - "id": 30, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 23 - }, - "id": 31, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "sum(rate(consul_catalog_register_count{pod=~\"consul-server-.*\"}[5m]))", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Catalog Register Count per 5 minutes", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 23 - }, - "id": 34, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_catalog_register_sum{pod=~\"consul-server-.*\"}[5m])\n/\nrate(consul_catalog_register_count{pod=~\"consul-server-.*\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Average latency of catalog register per 5 minutes (ms)", - "type": "timeseries" - } - ], - "title": "Feature: Catalog", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 23 - }, - "id": 49, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 24 - }, - "id": 50, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "sum(rate(consul_acl_ResolveToken_count{pod=~\"consul-server-.*\"}[5m]))", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "ACL Token Resolve Count per 5 minutes", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 24 - }, - "id": 51, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_acl_ResolveToken_sum{pod=~\"consul-server-.*\"}[5m])/rate(consul_acl_ResolveToken_count{pod=~\"consul-server-.*\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Average latency of resolving ACL token per 5 minutes (ms)", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 32 - }, - "id": 52, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_acl_token_cache_hit{pod=~\"consul-server-.*\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Rate of ACL token cache hit per 5 minutes", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 32 - }, - "id": 53, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_acl_token_cache_miss{pod=~\"consul-server-.*\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Rate of ACL token cache miss per 5 minutes", - "type": "timeseries" - } - ], - "title": "ACL", - "type": "row" - }, - { - "collapsed": true, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 24 - }, - "id": 33, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Increments whenever a Consul agent in client mode makes an RPC request to a Consul server", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 22 - }, - "id": 37, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_client_rpc{namespace=\"consul\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Rate of RPC requests per 5 minutes - client side ", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Increments when a server accepts an RPC connection.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 22 - }, - "id": 36, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_rpc_accept_conn{namespace=\"consul\",pod=~\"consul-server-.*\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "RPC Accept Connection Count Rate per 5 minutes - server side", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Increments whenever a Consul agent in client mode makes an RPC request to a Consul server and fails.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 30 - }, - "id": 39, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_client_rpc_failed{namespace=\"consul\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Rate of Failed RPC requests per 5 minutes - client side ", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Increments when a server receives a Consul-related RPC request.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 30 - }, - "id": 32, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_rpc_request{namespace=\"consul\",pod=~\"consul-server-.*\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Rate of RPC requests per 5 minutes - server side", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Increments whenever a Consul agent in client mode makes an RPC request to a Consul server gets rate limited by that agent's limits configuration.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 38 - }, - "id": 38, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_client_rpc_exceeded{namespace=\"consul\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Rate of Exceeded RPC requests per 5 minutes - client side ", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "Increments when a server returns an error from an RPC request.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 38 - }, - "id": 35, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "expr": "rate(consul_rpc_request_error{namespace=\"consul\",pod=~\"consul-server-.*\"}[5m])", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Error rate of RPC requests per 5 minutes - server side", - "type": "timeseries" - } - ], - "title": "RPC", - "type": "row" - } - ], - "refresh": "30s", - "revision": 1, - "schemaVersion": 38, - "style": "dark", - "tags": [], - "templating": { - "list": [] - }, - "time": { - "from": "now-30m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Consul K8s monitoring (control plane)", - "version": 8, - "weekStart": "" -} \ No newline at end of file diff --git a/internal/auth/exports.go b/internal/auth/exports.go deleted file mode 100644 index abbed80abe031..0000000000000 --- a/internal/auth/exports.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package auth - -import ( - "github.com/hashicorp/consul/internal/auth/internal/controllers" - "github.com/hashicorp/consul/internal/auth/internal/controllers/trafficpermissions" - "github.com/hashicorp/consul/internal/auth/internal/mappers/trafficpermissionsmapper" - "github.com/hashicorp/consul/internal/auth/internal/types" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" -) - -var ( - // Controller statuses - - StatusKey = trafficpermissions.StatusKey - TrafficPermissionsConditionComputed = trafficpermissions.ConditionComputed - TrafficPermissionsConditionFailedToCompute = trafficpermissions.ConditionFailedToCompute -) - -// RegisterTypes adds all resource types within the "catalog" API group -// to the given type registry -func RegisterTypes(r resource.Registry) { - types.Register(r) -} - -type ControllerDependencies = controllers.Dependencies - -func DefaultControllerDependencies() ControllerDependencies { - return ControllerDependencies{ - TrafficPermissionsMapper: trafficpermissionsmapper.New(), - } -} - -// RegisterControllers registers controllers for the auth types with -// the given controller manager. -func RegisterControllers(mgr *controller.Manager, deps ControllerDependencies) { - controllers.Register(mgr, deps) -} diff --git a/internal/auth/internal/controllers/register.go b/internal/auth/internal/controllers/register.go deleted file mode 100644 index 03fc31c5bc45d..0000000000000 --- a/internal/auth/internal/controllers/register.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controllers - -import ( - "github.com/hashicorp/consul/internal/auth/internal/controllers/trafficpermissions" - "github.com/hashicorp/consul/internal/controller" -) - -type Dependencies struct { - TrafficPermissionsMapper trafficpermissions.TrafficPermissionsMapper -} - -func Register(mgr *controller.Manager, deps Dependencies) { - mgr.Register(trafficpermissions.Controller(deps.TrafficPermissionsMapper)) -} diff --git a/internal/auth/internal/controllers/trafficpermissions/controller.go b/internal/auth/internal/controllers/trafficpermissions/controller.go deleted file mode 100644 index 9e5912dc5e3c7..0000000000000 --- a/internal/auth/internal/controllers/trafficpermissions/controller.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package trafficpermissions - -import ( - "context" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// TrafficPermissionsMapper is used to map a watch event for a TrafficPermissions resource and translate -// it to a ComputedTrafficPermissions resource which contains the effective permissions -// from all referencing TrafficPermissions resources. -type TrafficPermissionsMapper interface { - // MapTrafficPermissions will take a TrafficPermission resource and return controller requests for all - // ComputedTrafficPermissions associated with that TrafficPermission. - MapTrafficPermissions(context.Context, controller.Runtime, *pbresource.Resource) ([]controller.Request, error) - - // UntrackTrafficPermissions instructs the Mapper to forget about the TrafficPermission. - UntrackTrafficPermissions(*pbresource.ID) - - // GetTrafficPermissionsForCTP returns the tracked TrafficPermissions that are used to create a CTP - GetTrafficPermissionsForCTP(*pbresource.ID) []*pbresource.Reference -} - -// Controller creates a controller for automatic ComputedTrafficPermissions management for -// updates to WorkloadIdentity or TrafficPermission resources. -func Controller(mapper TrafficPermissionsMapper) controller.Controller { - if mapper == nil { - panic("No TrafficPermissionsMapper was provided to the TrafficPermissionsController constructor") - } - - return controller.ForType(pbauth.ComputedTrafficPermissionsType). - WithWatch(pbauth.WorkloadIdentityType, controller.ReplaceType(pbauth.ComputedTrafficPermissionsType)). - WithWatch(pbauth.TrafficPermissionsType, mapper.MapTrafficPermissions). - WithReconciler(&reconciler{mapper: mapper}) -} - -type reconciler struct { - mapper TrafficPermissionsMapper -} - -// Reconcile will reconcile one ComputedTrafficPermission (CTP) in response to some event. -// Events include adding, modifying or deleting a WorkloadIdentity or TrafficPermission. -func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error { - rt.Logger = rt.Logger.With("resource-id", req.ID, "controller", StatusKey) - /* - * A CTP ID could come in for a variety of reasons. - * 1. workload identity create / delete: this results in the creation / deletion of a new CTP - * 2. traffic permission create / modify / delete: this results in a potential modification of an existing CTP - * - * Part 1: Handle Workload Identity changes: - * Check if the workload identity exists. If it doesn't we can stop here. - * CTPs are always generated from WorkloadIdentities, therefore the WI resource must already exist. - * If it is missing, that means it was deleted. - */ - ctpID := req.ID - wi := resource.ReplaceType(pbauth.WorkloadIdentityType, ctpID) - workloadIdentity, err := resource.GetDecodedResource[*pbauth.WorkloadIdentity](ctx, rt.Client, wi) - if err != nil { - rt.Logger.Error("error retrieving corresponding Workload Identity", "error", err) - return err - } - if workloadIdentity == nil || workloadIdentity.Resource == nil { - rt.Logger.Trace("workload identity has been deleted") - return nil - } - - // Check if CTP exists: - oldCTPData, err := resource.GetDecodedResource[*pbauth.ComputedTrafficPermissions](ctx, rt.Client, ctpID) - if err != nil { - rt.Logger.Error("error retrieving computed permissions", "error", err) - return err - } - var oldResource *pbresource.Resource - var owner *pbresource.ID - if oldCTPData == nil { - // CTP does not yet exist, so we need to make a new one - rt.Logger.Trace("creating new computed traffic permissions for workload identity") - owner = workloadIdentity.Resource.Id - } else { - oldResource = oldCTPData.Resource - owner = oldCTPData.Resource.Owner - } - - // Part 2: Recompute a CTP from TP create / modify / delete, or create a new CTP from existing TPs: - latestTrafficPermissions, err := computeNewTrafficPermissions(ctx, rt, r.mapper, ctpID, oldResource) - if err != nil { - rt.Logger.Error("error calculating computed permissions", "error", err) - return err - } - - if oldCTPData != nil && proto.Equal(oldCTPData.Data, latestTrafficPermissions) { - // there are no changes to the computed traffic permissions, and we can return early - rt.Logger.Trace("no new computed traffic permissions") - return nil - } - newCTPData, err := anypb.New(latestTrafficPermissions) - if err != nil { - rt.Logger.Error("error marshalling latest traffic permissions", "error", err) - writeFailedStatus(ctx, rt, oldResource, nil, err.Error()) - return err - } - rt.Logger.Trace("writing computed traffic permissions") - rsp, err := rt.Client.Write(ctx, &pbresource.WriteRequest{ - Resource: &pbresource.Resource{ - Id: req.ID, - Data: newCTPData, - Owner: owner, - }, - }) - if err != nil || rsp.Resource == nil { - rt.Logger.Error("error writing new computed traffic permissions", "error", err) - writeFailedStatus(ctx, rt, oldResource, nil, err.Error()) - return err - } else { - rt.Logger.Trace("new computed traffic permissions were successfully written") - } - newStatus := &pbresource.Status{ - ObservedGeneration: rsp.Resource.Generation, - Conditions: []*pbresource.Condition{ - ConditionComputed(req.ID.Name, latestTrafficPermissions.IsDefault), - }, - } - _, err = rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{ - Id: rsp.Resource.Id, - Key: StatusKey, - Status: newStatus, - }) - return err -} - -func writeFailedStatus(ctx context.Context, rt controller.Runtime, ctp *pbresource.Resource, tp *pbresource.ID, errDetail string) error { - if ctp == nil { - return nil - } - newStatus := &pbresource.Status{ - ObservedGeneration: ctp.Generation, - Conditions: []*pbresource.Condition{ - ConditionFailedToCompute(ctp.Id.Name, tp.Name, errDetail), - }, - } - _, err := rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{ - Id: ctp.Id, - Key: StatusKey, - Status: newStatus, - }) - return err -} - -// computeNewTrafficPermissions will use all associated Traffic Permissions to create new ComputedTrafficPermissions data -func computeNewTrafficPermissions(ctx context.Context, rt controller.Runtime, wm TrafficPermissionsMapper, ctpID *pbresource.ID, ctp *pbresource.Resource) (*pbauth.ComputedTrafficPermissions, error) { - // Part 1: Get all TPs that apply to workload identity - // Get already associated WorkloadIdentities/CTPs for reconcile requests: - trackedTPs := wm.GetTrafficPermissionsForCTP(ctpID) - if len(trackedTPs) > 0 { - rt.Logger.Trace("got tracked traffic permissions for CTP", "tps:", trackedTPs) - } else { - rt.Logger.Trace("found no tracked traffic permissions for CTP") - } - ap := make([]*pbauth.Permission, 0) - dp := make([]*pbauth.Permission, 0) - isDefault := true - for _, t := range trackedTPs { - rsp, err := resource.GetDecodedResource[*pbauth.TrafficPermissions](ctx, rt.Client, resource.IDFromReference(t)) - if err != nil { - rt.Logger.Error("error reading traffic permissions resource for computation", "error", err) - writeFailedStatus(ctx, rt, ctp, resource.IDFromReference(t), err.Error()) - return nil, err - } - if rsp == nil { - rt.Logger.Trace("untracking deleted TrafficPermissions", "traffic-permissions-name", t.Name) - wm.UntrackTrafficPermissions(resource.IDFromReference(t)) - continue - } - isDefault = false - if rsp.Data.Action == pbauth.Action_ACTION_ALLOW { - ap = append(ap, rsp.Data.Permissions...) - } else { - dp = append(dp, rsp.Data.Permissions...) - } - } - return &pbauth.ComputedTrafficPermissions{ - AllowPermissions: ap, - DenyPermissions: dp, - IsDefault: isDefault, - }, nil -} diff --git a/internal/auth/internal/controllers/trafficpermissions/controller_test.go b/internal/auth/internal/controllers/trafficpermissions/controller_test.go deleted file mode 100644 index 910a6fb88e71e..0000000000000 --- a/internal/auth/internal/controllers/trafficpermissions/controller_test.go +++ /dev/null @@ -1,681 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package trafficpermissions - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/auth/internal/mappers/trafficpermissionsmapper" - "github.com/hashicorp/consul/internal/auth/internal/types" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -type controllerSuite struct { - suite.Suite - ctx context.Context - client *rtest.Client - rt controller.Runtime - - mapper *trafficpermissionsmapper.TrafficPermissionsMapper - reconciler *reconciler -} - -func (suite *controllerSuite) SetupTest() { - suite.ctx = testutil.TestContext(suite.T()) - client := svctest.RunResourceService(suite.T(), types.Register) - suite.client = rtest.NewClient(client) - suite.rt = controller.Runtime{ - Client: suite.client, - Logger: testutil.Logger(suite.T()), - } - suite.mapper = trafficpermissionsmapper.New() - suite.reconciler = &reconciler{mapper: suite.mapper} -} - -func (suite *controllerSuite) requireTrafficPermissionsTracking(tp *pbresource.Resource, ids ...*pbresource.ID) { - reqs, err := suite.mapper.MapTrafficPermissions(suite.ctx, suite.rt, tp) - require.NoError(suite.T(), err) - require.Len(suite.T(), reqs, len(ids)) - for _, id := range ids { - prototest.AssertContainsElement(suite.T(), reqs, controller.Request{ID: id}) - } - for _, req := range reqs { - prototest.AssertContainsElement(suite.T(), ids, req.ID) - } -} - -func (suite *controllerSuite) requireCTP(resource *pbresource.Resource, allowExpected []*pbauth.Permission, denyExpected []*pbauth.Permission) { - dec := rtest.MustDecode[*pbauth.ComputedTrafficPermissions](suite.T(), resource) - ctp := dec.Data - require.Len(suite.T(), ctp.AllowPermissions, len(allowExpected)) - require.Len(suite.T(), ctp.DenyPermissions, len(denyExpected)) - prototest.AssertElementsMatch(suite.T(), allowExpected, ctp.AllowPermissions) - prototest.AssertElementsMatch(suite.T(), denyExpected, ctp.DenyPermissions) -} - -func (suite *controllerSuite) TestReconcile_CTPCreate_NoReferencingTrafficPermissionsExist() { - wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - require.NotNil(suite.T(), wi) - id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID() - require.NotNil(suite.T(), id) - - err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // Ensure that the CTP was created - ctp := suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctp, []*pbauth.Permission{}, []*pbauth.Permission{}) -} - -func (suite *controllerSuite) TestReconcile_CTPCreate_ReferencingTrafficPermissionsExist() { - // create dead-end traffic permissions - p1 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{p1}, - }).Write(suite.T(), suite.client) - wi1ID := &pbresource.ID{ - Name: "wi1", - Type: pbauth.ComputedTrafficPermissionsType, - Tenancy: tp1.Id.Tenancy, - } - suite.requireTrafficPermissionsTracking(tp1, wi1ID) - p2 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "wi2", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - suite.requireTrafficPermissionsTracking(tp2, wi1ID) - - // create the workload identity that they reference - wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID() - - err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // Ensure that the CTP was created - ctp := suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctp, []*pbauth.Permission{p2}, []*pbauth.Permission{p1}) - rtest.RequireOwner(suite.T(), ctp, wi.Id, true) -} - -func (suite *controllerSuite) TestReconcile_WorkloadIdentityDelete_ReferencingTrafficPermissionsExist() { - p1 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{p1}, - }).Write(suite.T(), suite.client) - wi1ID := &pbresource.ID{ - Name: "wi1", - Type: pbauth.ComputedTrafficPermissionsType, - Tenancy: tp1.Id.Tenancy, - } - suite.requireTrafficPermissionsTracking(tp1, wi1ID) - p2 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "wi2", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - suite.requireTrafficPermissionsTracking(tp2, wi1ID) - - // create the workload identity that they reference - wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID() - - err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // delete the workload identity - suite.client.MustDelete(suite.T(), wi.Id) - - // re-reconcile: should untrack the CTP - err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) -} - -func (suite *controllerSuite) TestReconcile_WorkloadIdentityDelete_NoReferencingTrafficPermissionsExist() { - // create the workload identity that they reference - wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID() - - err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // delete the workload identity - suite.client.MustDelete(suite.T(), wi.Id) - - // re-reconcile: should untrack the CTP - err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // there should not be any traffic permissions to compute - tps := suite.mapper.GetTrafficPermissionsForCTP(id) - require.Len(suite.T(), tps, 0) -} - -func (suite *controllerSuite) TestReconcile_TrafficPermissionsCreate_DestinationWorkloadIdentityExists() { - // create the workload identity to be referenced - wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID() - - err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - ctpResource := suite.client.RequireResourceExists(suite.T(), id) - assertCTPDefaultStatus(suite.T(), ctpResource, true) - - // create traffic permissions - p1 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{p1}, - }).Write(suite.T(), suite.client) - suite.requireTrafficPermissionsTracking(tp1, id) - - p2 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "wi2", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - suite.requireTrafficPermissionsTracking(tp2, id) - - err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // Ensure that the CTP was updated - ctpResource = suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctpResource, []*pbauth.Permission{p2}, []*pbauth.Permission{p1}) - rtest.RequireOwner(suite.T(), ctpResource, wi.Id, true) - assertCTPDefaultStatus(suite.T(), ctpResource, false) - - // Add another TP - p3 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "wi3", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp3 := rtest.Resource(pbauth.TrafficPermissionsType, "tp3").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{p3}, - }).Write(suite.T(), suite.client) - suite.requireTrafficPermissionsTracking(tp3, id) - - err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // Ensure that the CTP was updated - ctpResource = suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctpResource, []*pbauth.Permission{p2}, []*pbauth.Permission{p1, p3}) - rtest.RequireOwner(suite.T(), ctpResource, wi.Id, true) - assertCTPDefaultStatus(suite.T(), ctpResource, false) - - // Delete the traffic permissions without updating the caches. Ensure is default is right even when the caches contain stale data. - suite.client.MustDelete(suite.T(), tp1.Id) - suite.client.MustDelete(suite.T(), tp2.Id) - suite.client.MustDelete(suite.T(), tp3.Id) - - err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - ctpResource = suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctpResource, []*pbauth.Permission{}, []*pbauth.Permission{}) - rtest.RequireOwner(suite.T(), ctpResource, wi.Id, true) - assertCTPDefaultStatus(suite.T(), ctpResource, true) -} - -func (suite *controllerSuite) TestReconcile_TrafficPermissionsDelete_DestinationWorkloadIdentityExists() { - // create the workload identity to be referenced - wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID() - - err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // create traffic permissions - p1 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{p1}, - }).Write(suite.T(), suite.client) - suite.requireTrafficPermissionsTracking(tp1, id) - p2 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "wi2", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - suite.requireTrafficPermissionsTracking(tp2, id) - - err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - ctp := suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctp, []*pbauth.Permission{p2}, []*pbauth.Permission{p1}) - rtest.RequireOwner(suite.T(), ctp, wi.Id, true) - - // Delete TP2 - suite.client.MustDelete(suite.T(), tp2.Id) - - err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id}) - require.NoError(suite.T(), err) - - // Ensure that the CTP was updated - ctp = suite.client.RequireResourceExists(suite.T(), id) - suite.requireCTP(ctp, []*pbauth.Permission{}, []*pbauth.Permission{p1}) - - // Ensure TP2 is untracked - newTps := suite.mapper.GetTrafficPermissionsForCTP(ctp.Id) - require.Len(suite.T(), newTps, 1) - require.Equal(suite.T(), newTps[0].Name, tp1.Id.Name) -} - -func (suite *controllerSuite) TestReconcile_TrafficPermissionsDelete_DestinationWorkloadIdentityDoesNotExist() { - // create traffic permissions - p1 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{p1}, - }).Write(suite.T(), suite.client) - wi1ID := &pbresource.ID{ - Name: "wi1", - Type: pbauth.ComputedTrafficPermissionsType, - Tenancy: tp1.Id.Tenancy, - } - suite.requireTrafficPermissionsTracking(tp1, wi1ID) - p2 := &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "wi2", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - } - tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - suite.requireTrafficPermissionsTracking(tp2, wi1ID) - - // Delete TP2 - suite.client.MustDelete(suite.T(), tp2.Id) - - // Ensure that no CTPs exist - rsp, err := suite.client.List(suite.ctx, &pbresource.ListRequest{ - Type: pbauth.ComputedTrafficPermissionsType, - Tenancy: resource.DefaultNamespacedTenancy(), - }) - require.NoError(suite.T(), err) - require.Empty(suite.T(), rsp.Resources) -} - -func (suite *controllerSuite) TestControllerBasic() { - // TODO: refactor this - // In this test we check basic operations for a workload identity and referencing traffic permission - mgr := controller.NewManager(suite.client, suite.rt.Logger) - mgr.Register(Controller(suite.mapper)) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - // Add a workload identity - workloadIdentity := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - - // Wait for the controller to record that the CTP has been computed - res := suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id), StatusKey) - // Check that the status was updated - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1", true)) - - // Check that the CTP resource exists and contains no permissions - ctpID := rtest.Resource(pbauth.ComputedTrafficPermissionsType, "wi1").ID() - ctpObject := suite.client.RequireResourceExists(suite.T(), ctpID) - suite.requireCTP(ctpObject, nil, nil) - - // add a traffic permission that references wi1 - p1 := &pbauth.Permission{ - Sources: []*pbauth.Source{{ - IdentityName: "wi2", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - DestinationRules: nil, - } - tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi1"}, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p1}, - }).Write(suite.T(), suite.client) - suite.client.RequireResourceExists(suite.T(), tp1.Id) - // Wait for the controller to record that the CTP has been re-computed - suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id), StatusKey) - // Check that the ctp has been regenerated - ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpID, ctpObject.Version) - rtest.RequireStatusCondition(suite.T(), ctpObject, StatusKey, ConditionComputed("wi1", false)) - // check wi1 - suite.requireCTP(ctpObject, []*pbauth.Permission{p1}, nil) - - // add a traffic permission that references wi2 - p2 := &pbauth.Permission{ - Sources: []*pbauth.Source{{ - IdentityName: "wi1", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - DestinationRules: nil, - } - tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi2"}, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - suite.client.RequireResourceExists(suite.T(), tp2.Id) - // check wi1 is the same - ctpObject = suite.client.RequireResourceExists(suite.T(), ctpID) - suite.requireCTP(ctpObject, []*pbauth.Permission{p1}, nil) - // check no ctp2 - ctpID2 := rtest.Resource(pbauth.ComputedTrafficPermissionsType, "wi2").ID() - suite.client.RequireResourceNotFound(suite.T(), ctpID2) - - // delete tp1 - suite.client.MustDelete(suite.T(), tp1.Id) - suite.client.WaitForDeletion(suite.T(), tp1.Id) - // check wi1 has no permissions - ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpID, ctpObject.Version) - suite.requireCTP(ctpObject, nil, nil) - - // edit tp2 to point to wi1 - rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi1"}, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - // check wi1 has tp2's permissions - ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpID, ctpObject.Version) - suite.requireCTP(ctpObject, []*pbauth.Permission{p2}, nil) - // check no ctp2 - ctpID2 = rtest.Resource(pbauth.ComputedTrafficPermissionsType, "wi2").ID() - suite.client.RequireResourceNotFound(suite.T(), ctpID2) -} - -func (suite *controllerSuite) TestControllerMultipleTrafficPermissions() { - // TODO: refactor this, turn back on once timing flakes are understood - suite.T().Skip("flaky behavior observed") - // In this test we check operations for a workload identity and multiple referencing traffic permissions - mgr := controller.NewManager(suite.client, suite.rt.Logger) - mgr.Register(Controller(suite.mapper)) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - wi1ID := &pbresource.ID{ - Name: "wi1", - Type: pbauth.ComputedTrafficPermissionsType, - Tenancy: resource.DefaultNamespacedTenancy(), - } - // add tp1 and tp2 - p1 := &pbauth.Permission{ - Sources: []*pbauth.Source{{ - IdentityName: "wi2", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - DestinationRules: nil, - } - tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi1"}, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p1}, - }).Write(suite.T(), suite.client) - suite.client.RequireResourceExists(suite.T(), tp1.Id) - suite.requireTrafficPermissionsTracking(tp1, wi1ID) - p2 := &pbauth.Permission{ - Sources: []*pbauth.Source{{ - IdentityName: "wi3", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - DestinationRules: nil, - } - tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi1"}, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - suite.client.RequireResourceExists(suite.T(), tp2.Id) - suite.requireTrafficPermissionsTracking(tp1, wi1ID) - - // Add a workload identity - workloadIdentity := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - ctpID := resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id) - // Wait for the controller to record that the CTP has been computed - res := suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey) - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1", false)) - // check ctp1 has tp1 and tp2 - ctpObject := suite.client.RequireResourceExists(suite.T(), res.Id) - suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, nil) - - // add tp3 - p3 := &pbauth.Permission{ - Sources: []*pbauth.Source{{ - IdentityName: "wi4", - Namespace: "default", - Partition: "default", - Peer: "local", - }}, - DestinationRules: nil, - } - tp3 := rtest.Resource(pbauth.TrafficPermissionsType, "tp3").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi1"}, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{p3}, - }).Write(suite.T(), suite.client) - suite.client.RequireResourceExists(suite.T(), tp3.Id) - // check ctp1 has tp3 - ctpObject = suite.client.WaitForReconciliation(suite.T(), ctpObject.Id, StatusKey) - ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpObject.Id, ctpObject.Version) - suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3}) - - // delete ctp - suite.client.MustDelete(suite.T(), ctpObject.Id) - suite.client.WaitForDeletion(suite.T(), ctpObject.Id) - // check ctp regenerated, has all permissions - res = suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey) - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1", false)) - ctpObject = suite.client.RequireResourceExists(suite.T(), res.Id) - suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3}) - - // delete wi1 - suite.client.MustDelete(suite.T(), workloadIdentity.Id) - suite.client.WaitForDeletion(suite.T(), workloadIdentity.Id) - - // recreate wi1 - rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client) - // check ctp regenerated, has all permissions - res = suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey) - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1", false)) - ctpObject = suite.client.RequireResourceExists(suite.T(), res.Id) - suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3}) - - // delete tp3 - suite.client.MustDelete(suite.T(), tp3.Id) - suite.client.WaitForDeletion(suite.T(), tp3.Id) - suite.client.RequireResourceNotFound(suite.T(), tp3.Id) - // check ctp1 has tp1 and tp2, and not tp3 - res = suite.client.WaitForReconciliation(suite.T(), ctpObject.Id, StatusKey) - ctpObject = suite.client.WaitForNewVersion(suite.T(), res.Id, ctpObject.Version) - suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, nil) - - // add wi2 - workloadIdentity2 := rtest.Resource(pbauth.WorkloadIdentityType, "wi2").Write(suite.T(), suite.client) - // Wait for the controller to record that the CTP has been computed - res2 := suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity2.Id), StatusKey) - rtest.RequireStatusCondition(suite.T(), res2, StatusKey, ConditionComputed("wi2", false)) - // check ctp2 has no permissions - ctpObject2 := suite.client.RequireResourceExists(suite.T(), res2.Id) - suite.requireCTP(ctpObject2, nil, nil) - - // edit all traffic permissions to point to wi2 - tp1 = rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi2"}, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p1}, - }).Write(suite.T(), suite.client) - tp2 = rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi2"}, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{p2}, - }).Write(suite.T(), suite.client) - tp3 = rtest.Resource(pbauth.TrafficPermissionsType, "tp3").WithData(suite.T(), &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi2"}, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{p3}, - }).Write(suite.T(), suite.client) - suite.client.RequireResourceExists(suite.T(), tp1.Id) - suite.client.RequireResourceExists(suite.T(), tp2.Id) - suite.client.RequireResourceExists(suite.T(), tp3.Id) - - // check wi2 has updated with all permissions after 6 reconciles - ctpObject2 = suite.client.WaitForReconciliation(suite.T(), ctpObject2.Id, StatusKey) - res2 = suite.client.WaitForReconciliation(suite.T(), ctpObject2.Id, StatusKey) - suite.client.WaitForResourceState(suite.T(), res2.Id, func(t rtest.T, res *pbresource.Resource) { - suite.requireCTP(res, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3}) - }) - // check wi1 has no permissions after 6 reconciles - ctpObject = suite.client.WaitForReconciliation(suite.T(), ctpObject.Id, StatusKey) - res = suite.client.WaitForReconciliation(suite.T(), ctpObject.Id, StatusKey) - suite.client.WaitForResourceState(suite.T(), res.Id, func(t rtest.T, res *pbresource.Resource) { - suite.requireCTP(res, nil, nil) - }) -} - -func TestController(t *testing.T) { - suite.Run(t, new(controllerSuite)) -} - -func assertCTPDefaultStatus(t *testing.T, resource *pbresource.Resource, isDefault bool) { - dec := rtest.MustDecode[*pbauth.ComputedTrafficPermissions](t, resource) - require.Equal(t, isDefault, dec.Data.IsDefault) -} diff --git a/internal/auth/internal/controllers/trafficpermissions/status.go b/internal/auth/internal/controllers/trafficpermissions/status.go deleted file mode 100644 index bfcc64bc131ce..0000000000000 --- a/internal/auth/internal/controllers/trafficpermissions/status.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package trafficpermissions - -import ( - "fmt" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - StatusKey = "consul.io/traffic-permissions" - StatusTrafficPermissionsComputed = "Traffic permissions have been computed" - StatusTrafficPermissionsNotComputed = "Traffic permissions have not been computed" - ConditionPermissionsAppliedMsg = "Workload identity %s has new permissions" - ConditionNoPermissionsMsg = "Workload identity %s has no permissions" - ConditionPermissionsFailedMsg = "Unable to calculate new permission set for Workload identity %s" -) - -func ConditionComputed(workloadIdentity string, isDefault bool) *pbresource.Condition { - msgTpl := ConditionPermissionsAppliedMsg - if isDefault { - msgTpl = ConditionNoPermissionsMsg - } - return &pbresource.Condition{ - Type: StatusTrafficPermissionsComputed, - State: pbresource.Condition_STATE_TRUE, - Message: fmt.Sprintf(msgTpl, workloadIdentity), - } -} - -func ConditionFailedToCompute(workloadIdentity string, trafficPermissions string, errDetail string) *pbresource.Condition { - message := fmt.Sprintf(ConditionPermissionsFailedMsg, workloadIdentity) - if len(trafficPermissions) > 0 { - message = message + fmt.Sprintf(", traffic permission %s cannot be computed", trafficPermissions) - } - if len(errDetail) > 0 { - message = message + fmt.Sprintf(", error details: %s", errDetail) - } - return &pbresource.Condition{ - Type: StatusTrafficPermissionsNotComputed, - State: pbresource.Condition_STATE_FALSE, - Message: message, - } -} diff --git a/internal/auth/internal/mappers/trafficpermissionsmapper/traffic_permissions_mapper.go b/internal/auth/internal/mappers/trafficpermissionsmapper/traffic_permissions_mapper.go deleted file mode 100644 index be28126458801..0000000000000 --- a/internal/auth/internal/mappers/trafficpermissionsmapper/traffic_permissions_mapper.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package trafficpermissionsmapper - -import ( - "context" - "sync" - - "github.com/hashicorp/consul/internal/auth/internal/types" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type TrafficPermissionsMapper struct { - lock sync.Mutex - mapper *bimapper.Mapper -} - -func New() *TrafficPermissionsMapper { - return &TrafficPermissionsMapper{ - lock: sync.Mutex{}, - mapper: bimapper.New(pbauth.TrafficPermissionsType, pbauth.ComputedTrafficPermissionsType), - } -} - -// TrafficPermissionsMapper functions - -func (tm *TrafficPermissionsMapper) MapTrafficPermissions(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - tm.lock.Lock() - defer tm.lock.Unlock() - var tp pbauth.TrafficPermissions - err := res.Data.UnmarshalTo(&tp) - if err != nil { - return nil, resource.NewErrDataParse(&tp, err) - } - // get new CTP associations based on destination - if len(tp.Destination.IdentityName) == 0 { - // this error should never happen if validation is working - return nil, types.ErrWildcardNotSupported - } - newCTP := &pbresource.ID{ - Name: tp.Destination.IdentityName, - Type: pbauth.ComputedTrafficPermissionsType, - Tenancy: res.Id.Tenancy, - } - requests := []controller.Request{{ID: newCTP}} - // add already associated WorkloadIdentities/CTPs for reconcile requests: - oldCTPs := tm.mapper.LinkIDsForItem(res.Id) - for _, mappedWI := range oldCTPs { - if mappedWI.Name != newCTP.Name { - requests = append(requests, controller.Request{ID: mappedWI}) - } - } - // re-map traffic permission to new CTP - tm.mapper.TrackItem(res.Id, []resource.ReferenceOrID{newCTP}) - return requests, nil -} - -func (tm *TrafficPermissionsMapper) UntrackTrafficPermissions(tp *pbresource.ID) { - tm.lock.Lock() - defer tm.lock.Unlock() - tm.mapper.UntrackItem(tp) -} - -func (tm *TrafficPermissionsMapper) GetTrafficPermissionsForCTP(ctp *pbresource.ID) []*pbresource.Reference { - tm.lock.Lock() - defer tm.lock.Unlock() - return tm.mapper.ItemRefsForLink(ctp) -} diff --git a/internal/auth/internal/types/computed_traffic_permissions.go b/internal/auth/internal/types/computed_traffic_permissions.go deleted file mode 100644 index 800d2a8fb66f4..0000000000000 --- a/internal/auth/internal/types/computed_traffic_permissions.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type DecodedComputedTrafficPermissions = resource.DecodedResource[*pbauth.ComputedTrafficPermissions] - -func RegisterComputedTrafficPermission(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbauth.ComputedTrafficPermissionsType, - Proto: &pbauth.ComputedTrafficPermissions{}, - ACLs: &resource.ACLHooks{ - Read: aclReadHookComputedTrafficPermissions, - Write: aclWriteHookComputedTrafficPermissions, - List: resource.NoOpACLListHook, - }, - Validate: ValidateComputedTrafficPermissions, - Scope: resource.ScopeNamespace, - }) -} - -var ValidateComputedTrafficPermissions = resource.DecodeAndValidate(validateComputedTrafficPermissions) - -func validateComputedTrafficPermissions(res *DecodedComputedTrafficPermissions) error { - var merr error - - for i, permission := range res.Data.AllowPermissions { - wrapErr := func(err error) error { - return resource.ErrInvalidListElement{ - Name: "allow_permissions", - Index: i, - Wrapped: err, - } - } - if err := validatePermission(permission, wrapErr); err != nil { - merr = multierror.Append(merr, err) - } - } - - for i, permission := range res.Data.DenyPermissions { - wrapErr := func(err error) error { - return resource.ErrInvalidListElement{ - Name: "deny_permissions", - Index: i, - Wrapped: err, - } - } - if err := validatePermission(permission, wrapErr); err != nil { - merr = multierror.Append(merr, err) - } - } - - return merr -} - -func aclReadHookComputedTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().TrafficPermissionsReadAllowed(id.Name, authzContext) -} - -func aclWriteHookComputedTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().TrafficPermissionsWriteAllowed(res.Id.Name, authzContext) -} diff --git a/internal/auth/internal/types/computed_traffic_permissions_test.go b/internal/auth/internal/types/computed_traffic_permissions_test.go deleted file mode 100644 index e5c4379a81806..0000000000000 --- a/internal/auth/internal/types/computed_traffic_permissions_test.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestValidateComputedTrafficPermissions_Permissions(t *testing.T) { - for n, tc := range permissionsTestCases() { - t.Run(n, func(t *testing.T) { - - for _, s := range tc.p.Sources { - normalizedTenancyForSource(s, resource.DefaultNamespacedTenancy()) - } - - allowCTP := &pbauth.ComputedTrafficPermissions{ - AllowPermissions: []*pbauth.Permission{tc.p}, - } - - denyCTP := &pbauth.ComputedTrafficPermissions{ - DenyPermissions: []*pbauth.Permission{tc.p}, - } - - for _, ctp := range []*pbauth.ComputedTrafficPermissions{allowCTP, denyCTP} { - res := resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, "tp"). - WithData(t, ctp). - Build() - - err := ValidateComputedTrafficPermissions(res) - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - }) - } -} - -func TestComputedTrafficPermissionsACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource) - readOK string - writeOK string - listOK string - } - - const ( - DENY = "deny" - ALLOW = "allow" - DEFAULT = "default" - ) - - checkF := func(t *testing.T, expect string, got error) { - switch expect { - case ALLOW: - if acl.IsErrPermissionDenied(got) { - t.Fatal("should be allowed") - } - case DENY: - if !acl.IsErrPermissionDenied(got) { - t.Fatal("should be denied") - } - case DEFAULT: - require.Nil(t, got, "expected fallthrough decision") - default: - t.Fatalf("unexpected expectation: %q", expect) - } - } - - reg, ok := registry.Resolve(pbauth.ComputedTrafficPermissionsType) - require.True(t, ok) - - run := func(t *testing.T, tc testcase) { - ctpData := &pbauth.ComputedTrafficPermissions{} - res := resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, "wi1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, ctpData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - config := acl.Config{ - WildcardName: structs.WildcardSpecifier, - } - authz, err := acl.NewAuthorizerFromRules(tc.rules, &config, nil) - require.NoError(t, err) - authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) - - t.Run("read", func(t *testing.T) { - err := reg.ACLs.Read(authz, &acl.AuthorizerContext{}, res.Id, res) - checkF(t, tc.readOK, err) - }) - t.Run("write", func(t *testing.T) { - err := reg.ACLs.Write(authz, &acl.AuthorizerContext{}, res) - checkF(t, tc.writeOK, err) - }) - t.Run("list", func(t *testing.T) { - err := reg.ACLs.List(authz, &acl.AuthorizerContext{}) - checkF(t, tc.listOK, err) - }) - } - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 read, no intentions": { - rules: `identity "wi1" { policy = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 read, deny intentions": { - rules: `identity "wi1" { policy = "read", intentions = "deny" }`, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 read, intentions read": { - rules: `identity "wi1" { policy = "read", intentions = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 write, write intentions": { - rules: `identity "wi1" { policy = "read", intentions = "write" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - "workload identity w1 write, deny intentions": { - rules: `identity "wi1" { policy = "write", intentions = "deny" }`, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 write, intentions read": { - rules: `identity "wi1" { policy = "write", intentions = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 write, intentions write": { - rules: `identity "wi1" { policy = "write", intentions = "write" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/auth/internal/types/errors.go b/internal/auth/internal/types/errors.go deleted file mode 100644 index b79d7a3b98e9b..0000000000000 --- a/internal/auth/internal/types/errors.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import "errors" - -var ( - errInvalidAction = errors.New("action must be either allow or deny") - errSourcesTenancy = errors.New("permissions sources may not specify partitions, peers, and sameness_groups together") - errSourceWildcards = errors.New("permission sources may not have wildcard namespaces and explicit names.") - errSourceExcludes = errors.New("must be defined on wildcard sources") - errInvalidPrefixValues = errors.New("prefix values, regex values, and explicit names must not combined") - ErrWildcardNotSupported = errors.New("traffic permissions without explicit destinations are not yet supported") -) diff --git a/internal/auth/internal/types/traffic_permissions.go b/internal/auth/internal/types/traffic_permissions.go deleted file mode 100644 index bf22fdb0b5fab..0000000000000 --- a/internal/auth/internal/types/traffic_permissions.go +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type DecodedTrafficPermissions = resource.DecodedResource[*pbauth.TrafficPermissions] - -func RegisterTrafficPermissions(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbauth.TrafficPermissionsType, - Proto: &pbauth.TrafficPermissions{}, - ACLs: &resource.ACLHooks{ - Read: resource.DecodeAndAuthorizeRead(aclReadHookTrafficPermissions), - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookTrafficPermissions), - List: resource.NoOpACLListHook, - }, - Validate: ValidateTrafficPermissions, - Mutate: MutateTrafficPermissions, - Scope: resource.ScopeNamespace, - }) -} - -var MutateTrafficPermissions = resource.DecodeAndMutate(mutateTrafficPermissions) - -func mutateTrafficPermissions(res *DecodedTrafficPermissions) (bool, error) { - var changed bool - - for _, p := range res.Data.Permissions { - for _, s := range p.Sources { - if updated := normalizedTenancyForSource(s, res.Id.Tenancy); updated { - changed = true - } - } - } - - return changed, nil -} - -func normalizedTenancyForSource(src *pbauth.Source, parentTenancy *pbresource.Tenancy) bool { - var changed bool - - if t, c := defaultedSourceTenancy(src, parentTenancy); c { - src.Partition = t.Partition - src.Peer = t.PeerName - src.Namespace = t.Namespace - changed = true - } - - for _, e := range src.Exclude { - if t, c := defaultedSourceTenancy(e, parentTenancy); c { - e.Partition = t.Partition - e.Peer = t.PeerName - e.Namespace = t.Namespace - changed = true - } - } - - return changed -} - -func defaultedSourceTenancy(s pbauth.SourceToSpiffe, parentTenancy *pbresource.Tenancy) (*pbresource.Tenancy, bool) { - if !isLocalPeer(s.GetPeer()) { - return nil, false - } - - tenancy := pbauth.SourceToTenancy(s) - - var peerChanged bool - tenancy.PeerName, peerChanged = firstNonEmptyString(tenancy.PeerName, parentTenancy.PeerName, resource.DefaultPeerName) - - var partitionChanged bool - tenancy.Partition, partitionChanged = firstNonEmptyString(tenancy.Partition, parentTenancy.Partition, resource.DefaultPartitionName) - - var namespaceChanged bool - if s.GetIdentityName() != "" { - if tenancy.Partition == parentTenancy.Partition { - tenancy.Namespace, namespaceChanged = firstNonEmptyString(tenancy.Namespace, parentTenancy.Namespace, resource.DefaultNamespaceName) - } else { - tenancy.Namespace, namespaceChanged = firstNonEmptyString(tenancy.Namespace, resource.DefaultNamespaceName, resource.DefaultNamespaceName) - } - } - - return tenancy, peerChanged || partitionChanged || namespaceChanged -} - -func firstNonEmptyString(a, b, c string) (string, bool) { - if a != "" { - return a, false - } - - if b != "" { - return b, true - } - - return c, true -} - -var ValidateTrafficPermissions = resource.DecodeAndValidate(validateTrafficPermissions) - -func validateTrafficPermissions(res *DecodedTrafficPermissions) error { - var merr error - - // enumcover:pbauth.Action - switch res.Data.Action { - case pbauth.Action_ACTION_ALLOW: - case pbauth.Action_ACTION_DENY: - case pbauth.Action_ACTION_UNSPECIFIED: - fallthrough - default: - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "data.action", - Wrapped: errInvalidAction, - }) - } - - if res.Data.Destination == nil || (len(res.Data.Destination.IdentityName) == 0) { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "data.destination", - Wrapped: resource.ErrEmpty, - }) - } - // Validate permissions - for i, permission := range res.Data.Permissions { - wrapErr := func(err error) error { - return resource.ErrInvalidListElement{ - Name: "permissions", - Index: i, - Wrapped: err, - } - } - if err := validatePermission(permission, wrapErr); err != nil { - merr = multierror.Append(merr, err) - } - } - - return merr -} - -func validatePermission(p *pbauth.Permission, wrapErr func(error) error) error { - var merr error - - if len(p.Sources) == 0 { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "sources", - Wrapped: resource.ErrEmpty, - })) - } - - for s, src := range p.Sources { - wrapSrcErr := func(err error) error { - return wrapErr(resource.ErrInvalidListElement{ - Name: "sources", - Index: s, - Wrapped: err, - }) - } - if sourceHasIncompatibleTenancies(src) { - merr = multierror.Append(merr, wrapSrcErr(resource.ErrInvalidListElement{ - Name: "source", - Wrapped: errSourcesTenancy, - })) - } - - if src.Namespace == "" && src.IdentityName != "" { - merr = multierror.Append(merr, wrapSrcErr(resource.ErrInvalidField{ - Name: "source", - Wrapped: errSourceWildcards, - })) - } - - // Excludes are only valid for wildcard sources. - if src.IdentityName != "" && len(src.Exclude) > 0 { - merr = multierror.Append(merr, wrapSrcErr(resource.ErrInvalidField{ - Name: "exclude_sources", - Wrapped: errSourceExcludes, - })) - continue - } - - for e, d := range src.Exclude { - wrapExclSrcErr := func(err error) error { - return wrapErr(resource.ErrInvalidListElement{ - Name: "exclude_sources", - Index: e, - Wrapped: err, - }) - } - if sourceHasIncompatibleTenancies(d) { - merr = multierror.Append(merr, wrapExclSrcErr(resource.ErrInvalidField{ - Name: "exclude_source", - Wrapped: errSourcesTenancy, - })) - } - - if d.Namespace == "" && d.IdentityName != "" { - merr = multierror.Append(merr, wrapExclSrcErr(resource.ErrInvalidField{ - Name: "source", - Wrapped: errSourceWildcards, - })) - } - } - } - for d, dest := range p.DestinationRules { - wrapDestRuleErr := func(err error) error { - return wrapErr(resource.ErrInvalidListElement{ - Name: "destination_rules", - Index: d, - Wrapped: err, - }) - } - if (len(dest.PathExact) > 0 && len(dest.PathPrefix) > 0) || - (len(dest.PathRegex) > 0 && len(dest.PathExact) > 0) || - (len(dest.PathRegex) > 0 && len(dest.PathPrefix) > 0) { - merr = multierror.Append(merr, wrapDestRuleErr(resource.ErrInvalidListElement{ - Name: "destination_rule", - Wrapped: errInvalidPrefixValues, - })) - } - if len(dest.Exclude) > 0 { - for e, excl := range dest.Exclude { - wrapExclPermRuleErr := func(err error) error { - return wrapDestRuleErr(resource.ErrInvalidListElement{ - Name: "exclude_permission_rules", - Index: e, - Wrapped: err, - }) - } - if (len(excl.PathExact) > 0 && len(excl.PathPrefix) > 0) || - (len(excl.PathRegex) > 0 && len(excl.PathExact) > 0) || - (len(excl.PathRegex) > 0 && len(excl.PathPrefix) > 0) { - merr = multierror.Append(merr, wrapExclPermRuleErr(resource.ErrInvalidListElement{ - Name: "exclude_permission_rule", - Wrapped: errInvalidPrefixValues, - })) - } - } - } - } - - return merr -} - -func sourceHasIncompatibleTenancies(src pbauth.SourceToSpiffe) bool { - peerSet := src.GetPeer() != resource.DefaultPeerName - apSet := src.GetPartition() != resource.DefaultPartitionName - sgSet := src.GetSamenessGroup() != "" - - return (apSet && peerSet) || (apSet && sgSet) || (peerSet && sgSet) -} - -func isLocalPeer(p string) bool { - return p == "local" || p == "" -} - -func aclReadHookTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *DecodedTrafficPermissions) error { - return authorizer.ToAllowAuthorizer().TrafficPermissionsReadAllowed(res.Data.Destination.IdentityName, authzContext) -} - -func aclWriteHookTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *DecodedTrafficPermissions) error { - return authorizer.ToAllowAuthorizer().TrafficPermissionsWriteAllowed(res.Data.Destination.IdentityName, authzContext) -} diff --git a/internal/auth/internal/types/traffic_permissions_test.go b/internal/auth/internal/types/traffic_permissions_test.go deleted file mode 100644 index 0948d240b699e..0000000000000 --- a/internal/auth/internal/types/traffic_permissions_test.go +++ /dev/null @@ -1,777 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestValidateTrafficPermissions_ParseError(t *testing.T) { - data := &pbauth.ComputedTrafficPermissions{AllowPermissions: nil} - - res := resourcetest.Resource(pbauth.TrafficPermissionsType, "tp"). - WithData(t, data). - Build() - - err := ValidateTrafficPermissions(res) - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) -} - -func TestValidateTrafficPermissions(t *testing.T) { - cases := map[string]struct { - tp *pbauth.TrafficPermissions - expectErr string - }{ - "ok-minimal": { - tp: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi-1"}, - Action: pbauth.Action_ACTION_ALLOW, - }, - }, - "unspecified-action": { - // Any type other than the TrafficPermissions type would work - // to cause the error we are expecting - tp: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action_ACTION_UNSPECIFIED, - Permissions: nil, - }, - expectErr: `invalid "data.action" field: action must be either allow or deny`, - }, - "invalid-action": { - tp: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "wi1", - }, - Action: pbauth.Action(50), - Permissions: nil, - }, - expectErr: `invalid "data.action" field: action must be either allow or deny`, - }, - "no-destination": { - tp: &pbauth.TrafficPermissions{ - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: nil, - DestinationRules: []*pbauth.DestinationRule{ - { - PathExact: "wi2", - }, - }, - }, - }, - }, - expectErr: `invalid "data.destination" field: cannot be empty`, - }, - "source-tenancy": { - tp: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "w1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Partition: "ap1", - Peer: "cl1", - SamenessGroup: "sg1", - }, - }, - DestinationRules: nil, - }, - }, - }, - expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "sources": invalid element at index 0 of list "source": permissions sources may not specify partitions, peers, and sameness_groups together`, - }, - } - - for n, tc := range cases { - t.Run(n, func(t *testing.T) { - res := resourcetest.Resource(pbauth.TrafficPermissionsType, "tp"). - WithData(t, tc.tp). - Build() - - err := ValidateTrafficPermissions(res) - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - }) - } -} - -type permissionTestCase struct { - p *pbauth.Permission - expectErr string -} - -func permissionsTestCases() map[string]permissionTestCase { - return map[string]permissionTestCase{ - "empty": { - p: &pbauth.Permission{}, - expectErr: `invalid "sources" field: cannot be empty`, - }, - "empty-sources": { - p: &pbauth.Permission{ - Sources: nil, - DestinationRules: []*pbauth.DestinationRule{ - { - PathPrefix: "foo", - Exclude: []*pbauth.ExcludePermissionRule{ - { - PathExact: "baz", - }, - }, - }, - { - PathPrefix: "bar", - }, - }, - }, - expectErr: `invalid "sources" field: cannot be empty`, - }, - "empty-destination-rules": { - p: &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - // wildcard identity name - Namespace: "ns1", - }, - { - Namespace: "ns1", - Exclude: []*pbauth.ExcludeSource{ - // wildcard identity name - {Namespace: "ns1"}, - }, - }, - { - IdentityName: "wi-3", - Namespace: "ns1", - }, - }, - }, - }, - "explicit source with excludes": { - p: &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - IdentityName: "i1", - Exclude: []*pbauth.ExcludeSource{ - { - IdentityName: "i1", - }, - }, - }, - }, - }, - expectErr: `invalid "exclude_sources" field: must be defined on wildcard sources`, - }, - "source-partition-and-peer": { - p: &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - Partition: "ap1", - Peer: "cluster-01", - }, - }, - }, - expectErr: `permissions sources may not specify partitions, peers, and sameness_groups together`, - }, - "source-partition-and-sameness-group": { - p: &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - Partition: "ap1", - SamenessGroup: "sg-1", - }, - }, - }, - expectErr: `permissions sources may not specify partitions, peers, and sameness_groups together`, - }, - "source-peer-and-sameness-group": { - p: &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - Partition: "ap1", - SamenessGroup: "sg-1", - }, - }, - }, - expectErr: `permissions sources may not specify partitions, peers, and sameness_groups together`, - }, - "exclude-source-partition-and-peer": { - p: &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - Exclude: []*pbauth.ExcludeSource{ - { - Partition: "ap1", - Peer: "cluster-01", - }, - }, - }, - }, - }, - expectErr: `permissions sources may not specify partitions, peers, and sameness_groups together`, - }, - "exclude-source-partition-and-sameness-group": { - p: &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - Exclude: []*pbauth.ExcludeSource{ - { - Partition: "ap1", - SamenessGroup: "sg-1", - }, - }, - }, - }, - }, - expectErr: `permissions sources may not specify partitions, peers, and sameness_groups together`, - }, - "exclude-source-peer-and-sameness-group": { - p: &pbauth.Permission{ - Sources: []*pbauth.Source{ - { - Exclude: []*pbauth.ExcludeSource{ - { - Peer: "ap1", - SamenessGroup: "sg-1", - }, - }, - }, - }, - }, - expectErr: `permissions sources may not specify partitions, peers, and sameness_groups together`, - }, - "destination-rule-path-prefix-regex": { - p: &pbauth.Permission{ - Sources: nil, - DestinationRules: []*pbauth.DestinationRule{ - { - PathExact: "wi2", - PathPrefix: "wi", - PathRegex: "wi.*", - }, - }, - }, - expectErr: `invalid element at index 0 of list "destination_rule": prefix values, regex values, and explicit names must not combined`, - }, - } -} - -func TestValidateTrafficPermissions_Permissions(t *testing.T) { - for n, tc := range permissionsTestCases() { - t.Run(n, func(t *testing.T) { - tp := &pbauth.TrafficPermissions{ - Action: pbauth.Action_ACTION_ALLOW, - Destination: &pbauth.Destination{ - IdentityName: "w1", - }, - Permissions: []*pbauth.Permission{tc.p}, - } - - res := resourcetest.Resource(pbauth.TrafficPermissionsType, "tp"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, tp). - Build() - - err := MutateTrafficPermissions(res) - require.NoError(t, err) - - err = ValidateTrafficPermissions(res) - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - }) - } -} - -func TestMutateTrafficPermissions(t *testing.T) { - type testcase struct { - policyTenancy *pbresource.Tenancy - tp *pbauth.TrafficPermissions - expect *pbauth.TrafficPermissions - expectErr string - } - - run := func(t *testing.T, tc testcase) { - tenancy := tc.policyTenancy - if tenancy == nil { - tenancy = resource.DefaultNamespacedTenancy() - } - res := resourcetest.Resource(pbauth.TrafficPermissionsType, "api"). - WithTenancy(tenancy). - WithData(t, tc.tp). - Build() - - err := MutateTrafficPermissions(res) - - got := resourcetest.MustDecode[*pbauth.TrafficPermissions](t, res) - - if tc.expectErr == "" { - require.NoError(t, err) - prototest.AssertDeepEqual(t, tc.expect, got.Data) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - "empty-1": { - tp: &pbauth.TrafficPermissions{}, - expect: &pbauth.TrafficPermissions{}, - }, - "kitchen-sink-default-partition": { - tp: &pbauth.TrafficPermissions{ - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - {}, - { - Peer: "not-default", - }, - { - Namespace: "ns1", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap1", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Peer: "local", - }, - }, - }, - }, - }, - expect: &pbauth.TrafficPermissions{ - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Partition: "default", - Peer: "local", - }, - { - Peer: "not-default", - }, - { - Namespace: "ns1", - Partition: "default", - Peer: "local", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap1", - Peer: "local", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - }, - "kitchen-sink-excludes-default-partition": { - tp: &pbauth.TrafficPermissions{ - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Exclude: []*pbauth.ExcludeSource{ - {}, - { - Peer: "not-default", - }, - { - Namespace: "ns1", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap1", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Peer: "local", - }, - }, - }, - }, - }, - }, - }, - expect: &pbauth.TrafficPermissions{ - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Partition: "default", - Peer: "local", - Exclude: []*pbauth.ExcludeSource{ - { - Partition: "default", - Peer: "local", - }, - { - Peer: "not-default", - }, - { - Namespace: "ns1", - Partition: "default", - Peer: "local", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap1", - Peer: "local", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - }, - }, - }, - "kitchen-sink-non-default-partition": { - policyTenancy: &pbresource.Tenancy{ - Partition: "ap1", - Namespace: "ns3", - PeerName: "local", - }, - tp: &pbauth.TrafficPermissions{ - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - {}, - { - Peer: "not-default", - }, - { - Namespace: "ns1", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap5", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Peer: "local", - }, - { - IdentityName: "i2", - }, - { - IdentityName: "i2", - Partition: "non-default", - }, - }, - }, - }, - }, - expect: &pbauth.TrafficPermissions{ - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Partition: "ap1", - Namespace: "", - Peer: "local", - }, - { - Peer: "not-default", - }, - { - Namespace: "ns1", - Partition: "ap1", - Peer: "local", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap5", - Peer: "local", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap1", - Peer: "local", - }, - { - IdentityName: "i2", - Namespace: "ns3", - Partition: "ap1", - Peer: "local", - }, - { - IdentityName: "i2", - Namespace: "default", - Partition: "non-default", - Peer: "local", - }, - }, - }, - }, - }, - }, - "kitchen-sink-excludes-non-default-partition": { - policyTenancy: &pbresource.Tenancy{ - Partition: "ap1", - Namespace: "ns3", - PeerName: "local", - }, - tp: &pbauth.TrafficPermissions{ - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Exclude: []*pbauth.ExcludeSource{ - {}, - { - Peer: "not-default", - }, - { - Namespace: "ns1", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap5", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Peer: "local", - }, - { - IdentityName: "i2", - }, - }, - }, - }, - }, - }, - }, - expect: &pbauth.TrafficPermissions{ - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Partition: "ap1", - Peer: "local", - Exclude: []*pbauth.ExcludeSource{ - { - Partition: "ap1", - Namespace: "", - Peer: "local", - }, - { - Peer: "not-default", - }, - { - Namespace: "ns1", - Partition: "ap1", - Peer: "local", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap5", - Peer: "local", - }, - { - IdentityName: "i1", - Namespace: "ns1", - Partition: "ap1", - Peer: "local", - }, - { - IdentityName: "i2", - Namespace: "ns3", - Partition: "ap1", - Peer: "local", - }, - }, - }, - }, - }, - }, - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestTrafficPermissionsACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource) - readOK string - writeOK string - listOK string - } - - const ( - DENY = "deny" - ALLOW = "allow" - DEFAULT = "default" - ) - - checkF := func(t *testing.T, expect string, got error) { - switch expect { - case ALLOW: - if acl.IsErrPermissionDenied(got) { - t.Fatal("should be allowed") - } - case DENY: - if !acl.IsErrPermissionDenied(got) { - t.Fatal("should be denied") - } - case DEFAULT: - require.Nil(t, got, "expected fallthrough decision") - default: - t.Fatalf("unexpected expectation: %q", expect) - } - } - - reg, ok := registry.Resolve(pbauth.TrafficPermissionsType) - require.True(t, ok) - - run := func(t *testing.T, tc testcase) { - tpData := &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{IdentityName: "wi1"}, - Action: pbauth.Action_ACTION_ALLOW, - } - res := resourcetest.Resource(pbauth.TrafficPermissionsType, "tp1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, tpData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - config := acl.Config{ - WildcardName: structs.WildcardSpecifier, - } - authz, err := acl.NewAuthorizerFromRules(tc.rules, &config, nil) - require.NoError(t, err) - authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) - - t.Run("read", func(t *testing.T) { - err := reg.ACLs.Read(authz, &acl.AuthorizerContext{}, res.Id, res) - checkF(t, tc.readOK, err) - }) - t.Run("write", func(t *testing.T) { - err := reg.ACLs.Write(authz, &acl.AuthorizerContext{}, res) - checkF(t, tc.writeOK, err) - }) - t.Run("list", func(t *testing.T) { - err := reg.ACLs.List(authz, &acl.AuthorizerContext{}) - checkF(t, tc.listOK, err) - }) - } - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 read, no intentions": { - rules: `identity "wi1" { policy = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 read, deny intentions": { - rules: `identity "wi1" { policy = "read", intentions = "deny" }`, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 read, intentions read": { - rules: `identity "wi1" { policy = "read", intentions = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 write, write intentions": { - rules: `identity "wi1" { policy = "read", intentions = "write" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - "workload identity w1 write, deny intentions": { - rules: `identity "wi1" { policy = "write", intentions = "deny" }`, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 write, intentions read": { - rules: `identity "wi1" { policy = "write", intentions = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity w1 write, intentions write": { - rules: `identity "wi1" { policy = "write", intentions = "write" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/auth/internal/types/types.go b/internal/auth/internal/types/types.go deleted file mode 100644 index 46fc49e1b75fe..0000000000000 --- a/internal/auth/internal/types/types.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/internal/resource" -) - -func Register(r resource.Registry) { - RegisterWorkloadIdentity(r) - RegisterTrafficPermissions(r) - RegisterComputedTrafficPermission(r) -} diff --git a/internal/auth/internal/types/workload_identity.go b/internal/auth/internal/types/workload_identity.go deleted file mode 100644 index a15fd5bf5b2dd..0000000000000 --- a/internal/auth/internal/types/workload_identity.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type DecodedWorkloadIdentity = resource.DecodedResource[*pbauth.WorkloadIdentity] - -func RegisterWorkloadIdentity(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbauth.WorkloadIdentityType, - Proto: &pbauth.WorkloadIdentity{}, - Scope: resource.ScopeNamespace, - ACLs: &resource.ACLHooks{ - Read: aclReadHookWorkloadIdentity, - Write: aclWriteHookWorkloadIdentity, - List: resource.NoOpACLListHook, - }, - Validate: ValidateWorkloadIdentity, - }) -} - -var ValidateWorkloadIdentity = resource.DecodeAndValidate(validateWorkloadIdentity) - -func validateWorkloadIdentity(res *DecodedWorkloadIdentity) error { - // currently the WorkloadIdentity type has no fields. - return nil -} - -func aclReadHookWorkloadIdentity( - authorizer acl.Authorizer, - authzCtx *acl.AuthorizerContext, - id *pbresource.ID, - res *pbresource.Resource, -) error { - if id != nil { - return authorizer.ToAllowAuthorizer().IdentityReadAllowed(id.Name, authzCtx) - } - if res != nil { - return authorizer.ToAllowAuthorizer().IdentityReadAllowed(res.Id.Name, authzCtx) - } - return resource.ErrNeedResource -} - -func aclWriteHookWorkloadIdentity( - authorizer acl.Authorizer, - authzCtx *acl.AuthorizerContext, - res *pbresource.Resource) error { - if res == nil { - return resource.ErrNeedResource - } - return authorizer.ToAllowAuthorizer().IdentityWriteAllowed(res.Id.Name, authzCtx) -} diff --git a/internal/auth/internal/types/workload_identity_test.go b/internal/auth/internal/types/workload_identity_test.go deleted file mode 100644 index 19ed4cbeea87e..0000000000000 --- a/internal/auth/internal/types/workload_identity_test.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func TestWorkloadIdentityACLs(t *testing.T) { - const ( - DENY = "deny" - ALLOW = "allow" - DEFAULT = "default" - ) - - registry := resource.NewRegistry() - Register(registry) - - reg, ok := registry.Resolve(pbauth.WorkloadIdentityType) - require.True(t, ok) - - type testcase struct { - rules string - check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource) - readOK string - writeOK string - listOK string - } - - checkF := func(t *testing.T, expect string, got error) { - switch expect { - case ALLOW: - if acl.IsErrPermissionDenied(got) { - t.Fatal("should be allowed") - } - case DENY: - if !acl.IsErrPermissionDenied(got) { - t.Fatal("should be denied") - } - case DEFAULT: - require.Nil(t, got, "expected fallthrough decision") - default: - t.Fatalf("unexpected expectation: %q", expect) - } - } - - run := func(t *testing.T, tc testcase) { - wid := &pbauth.WorkloadIdentity{} - res := resourcetest.Resource(pbauth.WorkloadIdentityType, "wi1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, wid). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - config := acl.Config{ - WildcardName: structs.WildcardSpecifier, - } - authz, err := acl.NewAuthorizerFromRules(tc.rules, &config, nil) - require.NoError(t, err) - authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) - - t.Run("read", func(t *testing.T) { - err := reg.ACLs.Read(authz, &acl.AuthorizerContext{}, res.Id, res) - checkF(t, tc.readOK, err) - }) - t.Run("write", func(t *testing.T) { - err := reg.ACLs.Write(authz, &acl.AuthorizerContext{}, res) - checkF(t, tc.writeOK, err) - }) - t.Run("list", func(t *testing.T) { - err := reg.ACLs.List(authz, &acl.AuthorizerContext{}) - checkF(t, tc.listOK, err) - }) - t.Run("errors", func(t *testing.T) { - require.ErrorIs(t, reg.ACLs.Read(authz, &acl.AuthorizerContext{}, nil, nil), resource.ErrNeedResource) - require.ErrorIs(t, reg.ACLs.Write(authz, &acl.AuthorizerContext{}, nil), resource.ErrNeedResource) - }) - } - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity wi1 read, no intentions": { - rules: `identity "wi1" { policy = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity wi1 read, deny intentions has no effect": { - rules: `identity "wi1" { policy = "read", intentions = "deny" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity wi1 read, intentions read has no effect": { - rules: `identity "wi1" { policy = "read", intentions = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity wi1 write, write intentions has no effect": { - rules: `identity "wi1" { policy = "read", intentions = "write" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "workload identity wi1 write, deny intentions has no effect": { - rules: `identity "wi1" { policy = "write", intentions = "deny" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - "workload identity wi1 write, intentions read has no effect": { - rules: `identity "wi1" { policy = "write", intentions = "read" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - "workload identity wi1 write, intentions write": { - rules: `identity "wi1" { policy = "write", intentions = "write" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestWorkloadIdentity_ParseError(t *testing.T) { - rsc := resourcetest.Resource(pbauth.WorkloadIdentityType, "example"). - WithData(t, &pbauth.TrafficPermissions{}). - Build() - - err := ValidateWorkloadIdentity(rsc) - var parseErr resource.ErrDataParse - require.ErrorAs(t, err, &parseErr) -} diff --git a/internal/catalog/catalogtest/helpers/acl_hooks_test_helpers.go b/internal/catalog/catalogtest/helpers/acl_hooks_test_helpers.go deleted file mode 100644 index 097647ed08d12..0000000000000 --- a/internal/catalog/catalogtest/helpers/acl_hooks_test_helpers.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package helpers - -import ( - "testing" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/catalog/internal/testhelpers" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RunWorkloadSelectingTypeACLsTests[T catalog.WorkloadSelecting](t *testing.T, typ *pbresource.Type, - getData func(selector *pbcatalog.WorkloadSelector) T, - registerFunc func(registry resource.Registry), -) { - testhelpers.RunWorkloadSelectingTypeACLsTests[T](t, typ, getData, registerFunc) -} diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-service.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-service.json similarity index 87% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-service.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-service.json index 5509e726d8dce..866c384b1d97a 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-service.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-service.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Service" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Service", + "@type": "hashicorp.consul.catalog.v1alpha1.Service", "workloads": { "prefixes": [ "api-" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-1-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-1-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-1-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-1-health.json index d64671960ad73..a1dd1609f297b 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-1-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-1-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-1" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_PASSING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-1.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-1.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-1.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-1.json index fe7d6318fb507..1935a767a19fb 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-1.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-1.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-1" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.1" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-10-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-10-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-10-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-10-health.json index f1f4c05968872..9c60ce7b09135 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-10-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-10-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-10" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_WARNING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-10.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-10.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-10.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-10.json index 768cab21d0205..362baa4099ec0 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-10.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-10.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-10" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.10" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-11-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-11-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-11-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-11-health.json index 4c266d4e2a765..2f8025258075f 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-11-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-11-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-11" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_CRITICAL" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-11.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-11.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-11.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-11.json index c0110034565f1..be9c1898835ea 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-11.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-11.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-11" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.11" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-12-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-12-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-12-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-12-health.json index 9b8079ed4a8d8..dd1026eed11ae 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-12-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-12-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-12" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_MAINTENANCE" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-12.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-12.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-12.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-12.json index 0c406c0ecdcb8..34f34d534239f 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-12.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-12.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-12" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.12" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-13-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-13-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-13-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-13-health.json index 346ebfb2f4898..2a5084afa14ce 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-13-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-13-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-13" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_PASSING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-13.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-13.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-13.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-13.json index acedb1ebd4771..3d896e0365900 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-13.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-13.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-13" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.13" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-14-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-14-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-14-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-14-health.json index 9a97dfda14394..991b66ee526d0 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-14-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-14-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-14" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_WARNING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-14.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-14.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-14.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-14.json index fefe9dabcf3bd..e8712a6c6520b 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-14.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-14.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-14" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.14" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-15-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-15-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-15-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-15-health.json index b289dd269e680..22b2ff83340d7 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-15-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-15-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-15" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_CRITICAL" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-15.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-15.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-15.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-15.json index faddd57fe7042..dbe0f0a44af7a 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-15.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-15.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-15" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.15" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-16-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-16-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-16-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-16-health.json index e4de67be793ef..06e36994387e7 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-16-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-16-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-16" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_MAINTENANCE" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-16.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-16.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-16.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-16.json index 46590c467fb3a..3db40493b1d34 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-16.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-16.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-16" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.16" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-17-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-17-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-17-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-17-health.json index e9955bf2097ee..3b4614cd6f704 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-17-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-17-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-17" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_PASSING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-17.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-17.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-17.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-17.json index bf3069201f5d9..79d26a2b33814 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-17.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-17.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-17" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.17" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-18-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-18-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-18-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-18-health.json index ec8490601267e..7764016a98594 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-18-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-18-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-18" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_WARNING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-18.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-18.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-18.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-18.json index cb96652199b69..04df2611c8679 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-18.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-18.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-18" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.18" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-19-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-19-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-19-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-19-health.json index d353aac240e21..468cddfbcbab8 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-19-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-19-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-19" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_CRITICAL" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-19.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-19.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-19.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-19.json index dcf2cf4b03405..bf9c8fe25a7ff 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-19.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-19.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-19" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.19" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-2-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-2-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-2-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-2-health.json index 08165a75d0a65..d9bf96b62b52e 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-2-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-2-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-2" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_WARNING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-2.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-2.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-2.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-2.json index cc2ea0fdc26e7..b80c0ccb85327 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-2.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-2.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-2" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.2" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-20-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-20-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-20-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-20-health.json index 49283150584c7..98af32bd00fd7 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-20-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-20-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-20" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_MAINTENANCE" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-20.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-20.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-20.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-20.json index 315874eeaf2b5..89723f54fe004 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-20.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-20.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-20" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.20" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-3-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-3-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-3-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-3-health.json index 44bc2a3531bb5..28670cc33728c 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-3-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-3-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-3" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_CRITICAL" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-3.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-3.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-3.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-3.json index 2ecd501d6e989..c5ea7d82a5df9 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-3.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-3.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-3" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.3" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-4-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-4-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-4-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-4-health.json index 5ead7793f1207..041d6eed5afd8 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-4-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-4-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-4" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_MAINTENANCE" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-4.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-4.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-4.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-4.json index 639fdd3f6773a..53934b9d5eea1 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-4.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-4.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-4" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.4" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-5-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-5-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-5-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-5-health.json index f2f1013f20217..1773cb44ca84d 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-5-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-5-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-5" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_PASSING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-5.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-5.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-5.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-5.json index 0e19253d4df5b..cbed9843adb5b 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-5.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-5.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-5" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.5" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-6-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-6-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-6-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-6-health.json index ef0bef454b665..3cf2104ef4fce 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-6-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-6-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-6" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_WARNING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-6.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-6.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-6.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-6.json index fe9780e946980..1646e7c0291c0 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-6.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-6.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-6" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.6" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-7-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-7-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-7-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-7-health.json index f3c963481e0da..d1dbc895fd3ad 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-7-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-7-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-7" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_CRITICAL" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-7.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-7.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-7.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-7.json index 7199c042b8a64..240f1e29a6932 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-7.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-7.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-7" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.7" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-8-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-8-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-8-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-8-health.json index e55348b1ea357..cdbb062703752 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-8-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-8-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-8" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_MAINTENANCE" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-8.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-8.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-8.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-8.json index 8828e1ee2653c..16e686c4b4092 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-8.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-8.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-8" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.8" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-9-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-9-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-9-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-9-health.json index 81ac189b173b0..6d221b07bd965 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-9-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-9-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "api-9" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_PASSING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-9.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-9.json similarity index 89% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-9.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-9.json index 1c02d466fbfe8..9081ff2e9cad9 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/api-workload-9.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/api-workload-9.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Workload" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "api-9" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Workload", + "@type": "hashicorp.consul.catalog.v1alpha1.Workload", "addresses": [ { "host": "172.16.1.9" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/foo-service-endpoints.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/foo-service-endpoints.json similarity index 86% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/foo-service-endpoints.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/foo-service-endpoints.json index fe7925a885010..b96f8805b1510 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/foo-service-endpoints.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/foo-service-endpoints.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "ServiceEndpoints" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Service" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "foo" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.ServiceEndpoints", + "@type": "hashicorp.consul.catalog.v1alpha1.ServiceEndpoints", "endpoints": [ { "addresses": [ diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/foo-service.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/foo-service.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/foo-service.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/foo-service.json index bbe87511e17e0..a79cdb2331661 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/foo-service.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/foo-service.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Service" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "foo" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Service", + "@type": "hashicorp.consul.catalog.v1alpha1.Service", "ports": [ { "target_port": "external-service-port", diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/grpc-api-service.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/grpc-api-service.json similarity index 88% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/grpc-api-service.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/grpc-api-service.json index 7dff2ee10ff34..6aa39628bf0f7 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/grpc-api-service.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/grpc-api-service.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Service" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "grpc-api" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Service", + "@type": "hashicorp.consul.catalog.v1alpha1.Service", "workloads": { "names": [ "api-1", diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/http-api-service.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/http-api-service.json similarity index 82% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/http-api-service.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/http-api-service.json index 02b80d29aef65..989851e725647 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/http-api-service.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/http-api-service.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Service" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "http-api" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Service", + "@type": "hashicorp.consul.catalog.v1alpha1.Service", "workloads": { "prefixes": [ "api-1" diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-1-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-1-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/node-1-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/node-1-health.json index 705eeb6ced262..5f58cda6ae887 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-1-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-1-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Node" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "node-1" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_PASSING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-1.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-1.json similarity index 82% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/node-1.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/node-1.json index a190e5bc1ab1e..c0f618279dcb4 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-1.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-1.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Node" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "node-1" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Node", + "@type": "hashicorp.consul.catalog.v1alpha1.Node", "addresses": [ { "host": "198.18.1.1", diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-2-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-2-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/node-2-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/node-2-health.json index 1e9baaefde5ec..6c67a1c1d1fce 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-2-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-2-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Node" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "node-2" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_WARNING" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-2.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-2.json similarity index 82% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/node-2.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/node-2.json index 218f8d1ae35bb..f68fd86ded71c 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-2.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-2.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Node" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "node-2" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Node", + "@type": "hashicorp.consul.catalog.v1alpha1.Node", "addresses": [ { "host": "198.18.1.2", diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-3-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-3-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/node-3-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/node-3-health.json index 5e2df1a13f8b1..2efa143afa2c2 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-3-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-3-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Node" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "node-3" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_CRITICAL" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-3.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-3.json similarity index 82% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/node-3.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/node-3.json index f02361cd58faa..b8d9a4e1651be 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-3.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-3.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Node" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "node-3" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Node", + "@type": "hashicorp.consul.catalog.v1alpha1.Node", "addresses": [ { "host": "198.18.1.3", diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-4-health.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-4-health.json similarity index 80% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/node-4-health.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/node-4-health.json index f403c929b4eae..a4f425e3cdc36 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-4-health.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-4-health.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "HealthStatus" }, "tenancy": { @@ -15,7 +15,7 @@ "owner": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Node" }, "tenancy": { @@ -26,7 +26,7 @@ "name": "node-4" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.HealthStatus", + "@type": "hashicorp.consul.catalog.v1alpha1.HealthStatus", "type": "synthetic", "status": "HEALTH_MAINTENANCE" } diff --git a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-4.json b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-4.json similarity index 82% rename from internal/catalog/catalogtest/integration_test_data/v2beta1/node-4.json rename to internal/catalog/catalogtest/integration_test_data/v1alpha1/node-4.json index c66e70fd0c64e..17c98cd98dd1b 100644 --- a/internal/catalog/catalogtest/integration_test_data/v2beta1/node-4.json +++ b/internal/catalog/catalogtest/integration_test_data/v1alpha1/node-4.json @@ -2,7 +2,7 @@ "id": { "type": { "group": "catalog", - "group_version": "v2beta1", + "group_version": "v1alpha1", "kind": "Node" }, "tenancy": { @@ -13,7 +13,7 @@ "name": "node-4" }, "data": { - "@type": "hashicorp.consul.catalog.v2beta1.Node", + "@type": "hashicorp.consul.catalog.v1alpha1.Node", "addresses": [ { "host": "198.18.1.4", diff --git a/internal/catalog/catalogtest/run_test.go b/internal/catalog/catalogtest/run_test.go index 5a6e1e62e3548..7c17052d8246d 100644 --- a/internal/catalog/catalogtest/run_test.go +++ b/internal/catalog/catalogtest/run_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package catalogtest import ( @@ -38,10 +35,5 @@ func runInMemResourceServiceAndControllers(t *testing.T, deps controllers.Depend func TestControllers_Integration(t *testing.T) { client := runInMemResourceServiceAndControllers(t, catalog.DefaultControllerDependencies()) - RunCatalogV2Beta1IntegrationTest(t, client) -} - -func TestControllers_Lifecycle(t *testing.T) { - client := runInMemResourceServiceAndControllers(t, catalog.DefaultControllerDependencies()) - RunCatalogV2Beta1LifecycleIntegrationTest(t, client) + RunCatalogV1Alpha1IntegrationTest(t, client) } diff --git a/internal/catalog/catalogtest/test_integration_v2beta1.go b/internal/catalog/catalogtest/test_integration_v1alpha1.go similarity index 66% rename from internal/catalog/catalogtest/test_integration_v2beta1.go rename to internal/catalog/catalogtest/test_integration_v1alpha1.go index 79ffea7e79539..8a7f4cd9a2488 100644 --- a/internal/catalog/catalogtest/test_integration_v2beta1.go +++ b/internal/catalog/catalogtest/test_integration_v1alpha1.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package catalogtest import ( @@ -8,17 +5,17 @@ import ( "fmt" "testing" - "github.com/stretchr/testify/require" - + "github.com/hashicorp/consul/internal/catalog" "github.com/hashicorp/consul/internal/catalog/internal/controllers/endpoints" "github.com/hashicorp/consul/internal/catalog/internal/controllers/nodehealth" "github.com/hashicorp/consul/internal/catalog/internal/controllers/workloadhealth" - "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/internal/catalog/internal/types" rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" "github.com/hashicorp/consul/sdk/testutil" + "github.com/stretchr/testify/require" ) var ( @@ -26,7 +23,7 @@ var ( testData embed.FS ) -// RunCatalogV2Beta1IntegrationTest will push up a bunch of catalog related data and then +// RunCatalogV1Alpha1IntegrationTest will push up a bunch of catalog related data and then // verify that all the expected reconciliations happened correctly. This test is // intended to exercise a large swathe of behavior of the overall catalog package. // Besides just controller reconciliation behavior, the intent is also to verify @@ -38,94 +35,94 @@ var ( // is another RunCatalogIntegrationTestLifeCycle function that can be used for those // purposes. The two are distinct so that the data being published and the assertions // made against the system can be reused in upgrade tests. -func RunCatalogV2Beta1IntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { +func RunCatalogV1Alpha1IntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { t.Helper() - PublishCatalogV2Beta1IntegrationTestData(t, client) - VerifyCatalogV2Beta1IntegrationTestResults(t, client) + PublishCatalogV1Alpha1IntegrationTestData(t, client) + VerifyCatalogV1Alpha1IntegrationTestResults(t, client) } -// PublishCatalogV2Beta1IntegrationTestData will perform a whole bunch of resource writes +// PublishCatalogV1Alpha1IntegrationTestData will perform a whole bunch of resource writes // for Service, ServiceEndpoints, Workload, Node and HealthStatus objects -func PublishCatalogV2Beta1IntegrationTestData(t *testing.T, client pbresource.ResourceServiceClient) { +func PublishCatalogV1Alpha1IntegrationTestData(t *testing.T, client pbresource.ResourceServiceClient) { t.Helper() c := rtest.NewClient(client) - resources := rtest.ParseResourcesFromFilesystem(t, testData, "integration_test_data/v2beta1") + resources := rtest.ParseResourcesFromFilesystem(t, testData, "integration_test_data/v1alpha1") c.PublishResources(t, resources) } -func VerifyCatalogV2Beta1IntegrationTestResults(t *testing.T, client pbresource.ResourceServiceClient) { +func VerifyCatalogV1Alpha1IntegrationTestResults(t *testing.T, client pbresource.ResourceServiceClient) { t.Helper() c := rtest.NewClient(client) testutil.RunStep(t, "resources-exist", func(t *testing.T) { - c.RequireResourceExists(t, rtest.Resource(pbcatalog.ServiceType, "api").ID()) - c.RequireResourceExists(t, rtest.Resource(pbcatalog.ServiceType, "http-api").ID()) - c.RequireResourceExists(t, rtest.Resource(pbcatalog.ServiceType, "grpc-api").ID()) - c.RequireResourceExists(t, rtest.Resource(pbcatalog.ServiceType, "foo").ID()) + c.RequireResourceExists(t, rtest.Resource(catalog.ServiceV1Alpha1Type, "api").ID()) + c.RequireResourceExists(t, rtest.Resource(catalog.ServiceV1Alpha1Type, "http-api").ID()) + c.RequireResourceExists(t, rtest.Resource(catalog.ServiceV1Alpha1Type, "grpc-api").ID()) + c.RequireResourceExists(t, rtest.Resource(catalog.ServiceV1Alpha1Type, "foo").ID()) for i := 1; i < 5; i++ { - nodeId := rtest.Resource(pbcatalog.NodeType, fmt.Sprintf("node-%d", i)).WithTenancy(resource.DefaultNamespacedTenancy()).ID() + nodeId := rtest.Resource(catalog.NodeV1Alpha1Type, fmt.Sprintf("node-%d", i)).ID() c.RequireResourceExists(t, nodeId) - res := c.RequireResourceExists(t, rtest.Resource(pbcatalog.HealthStatusType, fmt.Sprintf("node-%d-health", i)).ID()) + res := c.RequireResourceExists(t, rtest.Resource(catalog.HealthStatusV1Alpha1Type, fmt.Sprintf("node-%d-health", i)).ID()) rtest.RequireOwner(t, res, nodeId, true) } for i := 1; i < 21; i++ { - workloadId := rtest.Resource(pbcatalog.WorkloadType, fmt.Sprintf("api-%d", i)).WithTenancy(resource.DefaultNamespacedTenancy()).ID() + workloadId := rtest.Resource(catalog.WorkloadV1Alpha1Type, fmt.Sprintf("api-%d", i)).ID() c.RequireResourceExists(t, workloadId) - res := c.RequireResourceExists(t, rtest.Resource(pbcatalog.HealthStatusType, fmt.Sprintf("api-%d-health", i)).ID()) + res := c.RequireResourceExists(t, rtest.Resource(catalog.HealthStatusV1Alpha1Type, fmt.Sprintf("api-%d-health", i)).ID()) rtest.RequireOwner(t, res, workloadId, true) } }) testutil.RunStep(t, "node-health-reconciliation", func(t *testing.T) { - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.NodeType, "node-1").ID(), nodehealth.StatusKey, nodehealth.ConditionPassing) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.NodeType, "node-2").ID(), nodehealth.StatusKey, nodehealth.ConditionWarning) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.NodeType, "node-3").ID(), nodehealth.StatusKey, nodehealth.ConditionCritical) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.NodeType, "node-4").ID(), nodehealth.StatusKey, nodehealth.ConditionMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.NodeV1Alpha1Type, "node-1").ID(), nodehealth.StatusKey, nodehealth.ConditionPassing) + c.WaitForStatusCondition(t, rtest.Resource(catalog.NodeV1Alpha1Type, "node-2").ID(), nodehealth.StatusKey, nodehealth.ConditionWarning) + c.WaitForStatusCondition(t, rtest.Resource(catalog.NodeV1Alpha1Type, "node-3").ID(), nodehealth.StatusKey, nodehealth.ConditionCritical) + c.WaitForStatusCondition(t, rtest.Resource(catalog.NodeV1Alpha1Type, "node-4").ID(), nodehealth.StatusKey, nodehealth.ConditionMaintenance) }) testutil.RunStep(t, "workload-health-reconciliation", func(t *testing.T) { - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-1").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadPassing) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-2").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadWarning) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-3").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadCritical) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-4").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadMaintenance) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-5").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeWarning) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-6").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadWarning) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-7").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadCritical) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-8").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-9").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeCritical) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-10").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadCritical) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-11").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadCritical) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-12").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-13").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeMaintenance) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-14").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-15").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-16").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-17").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadPassing) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-18").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadWarning) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-19").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadCritical) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.WorkloadType, "api-20").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-1").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadPassing) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-2").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadWarning) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-3").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadCritical) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-4").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-5").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeWarning) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-6").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadWarning) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-7").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadCritical) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-8").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-9").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeCritical) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-10").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadCritical) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-11").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadCritical) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-12").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-13").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-14").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-15").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-16").ID(), workloadhealth.StatusKey, workloadhealth.ConditionNodeAndWorkloadMaintenance) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-17").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadPassing) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-18").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadWarning) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-19").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadCritical) + c.WaitForStatusCondition(t, rtest.Resource(catalog.WorkloadV1Alpha1Type, "api-20").ID(), workloadhealth.StatusKey, workloadhealth.ConditionWorkloadMaintenance) }) testutil.RunStep(t, "service-reconciliation", func(t *testing.T) { - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.ServiceType, "foo").ID(), endpoints.StatusKey, endpoints.ConditionUnmanaged) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.ServiceType, "api").ID(), endpoints.StatusKey, endpoints.ConditionManaged) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.ServiceType, "http-api").ID(), endpoints.StatusKey, endpoints.ConditionManaged) - c.WaitForStatusCondition(t, rtest.Resource(pbcatalog.ServiceType, "grpc-api").ID(), endpoints.StatusKey, endpoints.ConditionManaged) + c.WaitForStatusCondition(t, rtest.Resource(catalog.ServiceV1Alpha1Type, "foo").ID(), endpoints.StatusKey, endpoints.ConditionUnmanaged) + c.WaitForStatusCondition(t, rtest.Resource(catalog.ServiceV1Alpha1Type, "api").ID(), endpoints.StatusKey, endpoints.ConditionManaged) + c.WaitForStatusCondition(t, rtest.Resource(catalog.ServiceV1Alpha1Type, "http-api").ID(), endpoints.StatusKey, endpoints.ConditionManaged) + c.WaitForStatusCondition(t, rtest.Resource(catalog.ServiceV1Alpha1Type, "grpc-api").ID(), endpoints.StatusKey, endpoints.ConditionManaged) }) testutil.RunStep(t, "service-endpoints-generation", func(t *testing.T) { - verifyServiceEndpoints(t, c, rtest.Resource(pbcatalog.ServiceEndpointsType, "foo").ID(), expectedFooServiceEndpoints()) - verifyServiceEndpoints(t, c, rtest.Resource(pbcatalog.ServiceEndpointsType, "api").ID(), expectedApiServiceEndpoints(t, c)) - verifyServiceEndpoints(t, c, rtest.Resource(pbcatalog.ServiceEndpointsType, "http-api").ID(), expectedHTTPApiServiceEndpoints(t, c)) - verifyServiceEndpoints(t, c, rtest.Resource(pbcatalog.ServiceEndpointsType, "grpc-api").ID(), expectedGRPCApiServiceEndpoints(t, c)) + verifyServiceEndpoints(t, c, rtest.Resource(catalog.ServiceEndpointsV1Alpha1Type, "foo").ID(), expectedFooServiceEndpoints()) + verifyServiceEndpoints(t, c, rtest.Resource(catalog.ServiceEndpointsV1Alpha1Type, "api").ID(), expectedApiServiceEndpoints(t, c)) + verifyServiceEndpoints(t, c, rtest.Resource(catalog.ServiceEndpointsV1Alpha1Type, "http-api").ID(), expectedHTTPApiServiceEndpoints(t, c)) + verifyServiceEndpoints(t, c, rtest.Resource(catalog.ServiceEndpointsV1Alpha1Type, "grpc-api").ID(), expectedGRPCApiServiceEndpoints(t, c)) }) } @@ -153,7 +150,7 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi Endpoints: []*pbcatalog.Endpoint{ // api-1 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-1").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-1").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.1", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.1", External: true, Ports: []string{"mesh"}}, @@ -164,11 +161,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", }, // api-2 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-2").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-2").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.2", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.2", External: true, Ports: []string{"mesh"}}, @@ -179,11 +175,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_WARNING, - Identity: "api", }, // api-3 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-3").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-3").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.3", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.3", External: true, Ports: []string{"mesh"}}, @@ -194,11 +189,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-4 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-4").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-4").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.4", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.4", External: true, Ports: []string{"mesh"}}, @@ -209,11 +203,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-5 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-5").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-5").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.5", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.5", External: true, Ports: []string{"mesh"}}, @@ -224,11 +217,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_WARNING, - Identity: "api", }, // api-6 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-6").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-6").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.6", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.6", External: true, Ports: []string{"mesh"}}, @@ -239,11 +231,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_WARNING, - Identity: "api", }, // api-7 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-7").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-7").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.7", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.7", External: true, Ports: []string{"mesh"}}, @@ -254,11 +245,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-8 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-8").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-8").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.8", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.8", External: true, Ports: []string{"mesh"}}, @@ -269,11 +259,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-9 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-9").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-9").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.9", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.9", External: true, Ports: []string{"mesh"}}, @@ -284,11 +273,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-10 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-10").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-10").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.10", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.10", External: true, Ports: []string{"mesh"}}, @@ -299,11 +287,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-11 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-11").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-11").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.11", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.11", External: true, Ports: []string{"mesh"}}, @@ -314,11 +301,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-12 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-12").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-12").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.12", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.12", External: true, Ports: []string{"mesh"}}, @@ -329,11 +315,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-13 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-13").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-13").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.13", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.13", External: true, Ports: []string{"mesh"}}, @@ -344,11 +329,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-14 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-14").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-14").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.14", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.14", External: true, Ports: []string{"mesh"}}, @@ -359,11 +343,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-15 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-15").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-15").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.15", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.15", External: true, Ports: []string{"mesh"}}, @@ -374,11 +357,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-16 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-16").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-16").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.16", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.16", External: true, Ports: []string{"mesh"}}, @@ -389,11 +371,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-17 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-17").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-17").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.17", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.17", External: true, Ports: []string{"mesh"}}, @@ -404,11 +385,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", }, // api-18 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-18").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-18").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.18", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.18", External: true, Ports: []string{"mesh"}}, @@ -419,11 +399,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_WARNING, - Identity: "api", }, // api-19 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-19").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-19").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.19", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.19", External: true, Ports: []string{"mesh"}}, @@ -434,11 +413,10 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-20 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-20").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-20").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.20", Ports: []string{"grpc", "http", "mesh"}}, {Host: "198.18.2.20", External: true, Ports: []string{"mesh"}}, @@ -449,7 +427,6 @@ func expectedApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.Servi "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, }, } @@ -460,7 +437,7 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S Endpoints: []*pbcatalog.Endpoint{ // api-1 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-1").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-1").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.1", Ports: []string{"http"}}, }, @@ -468,11 +445,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", }, // api-10 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-10").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-10").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.10", Ports: []string{"http"}}, }, @@ -480,11 +456,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-11 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-11").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-11").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.11", Ports: []string{"http"}}, }, @@ -492,11 +467,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-12 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-12").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-12").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.12", Ports: []string{"http"}}, }, @@ -504,11 +478,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-13 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-13").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-13").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.13", Ports: []string{"http"}}, }, @@ -516,11 +489,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-14 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-14").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-14").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.14", Ports: []string{"http"}}, }, @@ -528,11 +500,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-15 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-15").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-15").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.15", Ports: []string{"http"}}, }, @@ -540,11 +511,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-16 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-16").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-16").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.16", Ports: []string{"http"}}, }, @@ -552,11 +522,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-17 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-17").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-17").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.17", Ports: []string{"http"}}, }, @@ -564,11 +533,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", }, // api-18 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-18").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-18").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.18", Ports: []string{"http"}}, }, @@ -576,11 +544,10 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_WARNING, - Identity: "api", }, // api-19 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-19").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-19").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.19", Ports: []string{"http"}}, }, @@ -588,7 +555,6 @@ func expectedHTTPApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, }, } @@ -599,7 +565,7 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S Endpoints: []*pbcatalog.Endpoint{ // api-1 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-1").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-1").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.1", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.1", External: true, Ports: []string{"mesh"}}, @@ -609,11 +575,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", }, // api-2 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-2").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-2").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.2", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.2", External: true, Ports: []string{"mesh"}}, @@ -623,11 +588,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_WARNING, - Identity: "api", }, // api-3 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-3").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-3").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.3", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.3", External: true, Ports: []string{"mesh"}}, @@ -637,11 +601,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-4 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-4").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-4").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.4", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.4", External: true, Ports: []string{"mesh"}}, @@ -651,11 +614,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-5 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-5").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-5").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.5", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.5", External: true, Ports: []string{"mesh"}}, @@ -665,11 +627,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_WARNING, - Identity: "api", }, // api-6 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-6").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-6").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.6", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.6", External: true, Ports: []string{"mesh"}}, @@ -679,11 +640,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_WARNING, - Identity: "api", }, // api-7 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-7").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-7").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.7", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.7", External: true, Ports: []string{"mesh"}}, @@ -693,11 +653,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-8 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-8").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-8").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.8", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.8", External: true, Ports: []string{"mesh"}}, @@ -707,11 +666,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, // api-9 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-9").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-9").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.9", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.9", External: true, Ports: []string{"mesh"}}, @@ -721,11 +679,10 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }, // api-20 { - TargetRef: c.ResolveResourceID(t, rtest.Resource(pbcatalog.WorkloadType, "api-20").ID()), + TargetRef: c.ResolveResourceID(t, rtest.Resource(types.WorkloadV1Alpha1Type, "api-20").ID()), Addresses: []*pbcatalog.WorkloadAddress{ {Host: "172.16.1.20", Ports: []string{"grpc", "mesh"}}, {Host: "198.18.2.20", External: true, Ports: []string{"mesh"}}, @@ -735,14 +692,12 @@ func expectedGRPCApiServiceEndpoints(t *testing.T, c *rtest.Client) *pbcatalog.S "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, HealthStatus: pbcatalog.Health_HEALTH_MAINTENANCE, - Identity: "api", }, }, } } func verifyServiceEndpoints(t *testing.T, c *rtest.Client, id *pbresource.ID, expected *pbcatalog.ServiceEndpoints) { - t.Helper() c.WaitForResourceState(t, id, func(t rtest.T, res *pbresource.Resource) { var actual pbcatalog.ServiceEndpoints err := res.Data.UnmarshalTo(&actual) diff --git a/internal/catalog/catalogtest/test_lifecycle_v2beta1.go b/internal/catalog/catalogtest/test_lifecycle_v2beta1.go deleted file mode 100644 index ea935dd4c56b7..0000000000000 --- a/internal/catalog/catalogtest/test_lifecycle_v2beta1.go +++ /dev/null @@ -1,716 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package catalogtest - -import ( - "testing" - - "github.com/hashicorp/consul/internal/catalog" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" -) - -// RunCatalogV2Beta1LifecycleIntegrationTest intends to excercise functionality of -// managing catalog resources over their normal lifecycle where they will be modified -// several times, change state etc. -func RunCatalogV2Beta1LifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { - t.Helper() - - testutil.RunStep(t, "node-lifecycle", func(t *testing.T) { - RunCatalogV2Beta1NodeLifecycleIntegrationTest(t, client) - }) - - testutil.RunStep(t, "workload-lifecycle", func(t *testing.T) { - RunCatalogV2Beta1WorkloadLifecycleIntegrationTest(t, client) - }) - - testutil.RunStep(t, "endpoints-lifecycle", func(t *testing.T) { - RunCatalogV2Beta1EndpointsLifecycleIntegrationTest(t, client) - }) -} - -// RunCatalogV2Beta1NodeLifecycleIntegrationTest verifies correct functionality of -// the node-health controller. This test will exercise the following behaviors: -// -// * Creating a Node without associated HealthStatuses will mark the node as passing -// * Associating a HealthStatus with a Node will cause recomputation of the Health -// * Changing HealthStatus to a worse health will cause recomputation of the Health -// * Changing HealthStatus to a better health will cause recomputation of the Health -// * Deletion of associated HealthStatuses will recompute the Health (back to passing) -// * Deletion of the node will cause deletion of associated health statuses -func RunCatalogV2Beta1NodeLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { - c := rtest.NewClient(client) - - nodeName := "test-lifecycle" - nodeHealthName := "test-lifecycle-node-status" - - // initial node creation - node := rtest.Resource(pbcatalog.NodeType, nodeName). - WithData(t, &pbcatalog.Node{ - Addresses: []*pbcatalog.NodeAddress{ - {Host: "172.16.2.3"}, - {Host: "198.18.2.3", External: true}, - }, - }). - Write(t, c) - - // wait for the node health controller to mark the node as healthy - c.WaitForStatusCondition(t, node.Id, - catalog.NodeHealthStatusKey, - catalog.NodeHealthConditions[pbcatalog.Health_HEALTH_PASSING]) - - // Its easy enough to simply repeatedly set the health status and it proves - // that going both from better to worse health and worse to better all - // happen as expected. We leave the health in a warning state to allow for - // the subsequent health status deletion to cause the health to go back - // to passing. - healthChanges := []pbcatalog.Health{ - pbcatalog.Health_HEALTH_PASSING, - pbcatalog.Health_HEALTH_WARNING, - pbcatalog.Health_HEALTH_CRITICAL, - pbcatalog.Health_HEALTH_MAINTENANCE, - pbcatalog.Health_HEALTH_CRITICAL, - pbcatalog.Health_HEALTH_WARNING, - pbcatalog.Health_HEALTH_PASSING, - pbcatalog.Health_HEALTH_WARNING, - } - - // This will be set within the loop and used afterwards to delete the health status - var nodeHealth *pbresource.Resource - - // Iterate through the various desired health statuses, updating - // a HealthStatus resource owned by the node and waiting for - // reconciliation at each point - for _, health := range healthChanges { - // update the health check - nodeHealth = setHealthStatus(t, c, node.Id, nodeHealthName, health) - - // wait for reconciliation to kick in and put the node into the right - // health status. - c.WaitForStatusCondition(t, node.Id, - catalog.NodeHealthStatusKey, - catalog.NodeHealthConditions[health]) - } - - // now delete the health status and ensure things go back to passing - c.MustDelete(t, nodeHealth.Id) - - // wait for the node health controller to mark the node as healthy - c.WaitForStatusCondition(t, node.Id, - catalog.NodeHealthStatusKey, - catalog.NodeHealthConditions[pbcatalog.Health_HEALTH_PASSING]) - - // Add the health status back once more, the actual status doesn't matter. - // It just must be owned by the node so that we can show cascading - // deletions of owned health statuses working. - healthStatus := setHealthStatus(t, c, node.Id, nodeHealthName, pbcatalog.Health_HEALTH_CRITICAL) - - // Delete the node and wait for the health status to be deleted. - c.MustDelete(t, node.Id) - c.WaitForDeletion(t, healthStatus.Id) -} - -// RunCatalogV2Beta1WorkloadLifecycleIntegrationTest verifies correct functionality of -// the workload-health controller. This test will exercise the following behaviors: -// -// - Associating a workload with a node causes recomputation of the health and takes -// into account the nodes health -// - Modifying the workloads associated node causes health recomputation and takes into -// account the new nodes health -// - Removal of the node association causes recomputation of health and for no node health -// to be taken into account. -// - Creating a workload without associated health statuses or node association will -// be marked passing -// - Creating a workload without associated health statuses but with a node will -// inherit its health from the node. -// - Changing HealthStatus to a worse health will cause recompuation of the Health -// - Changing HealthStatus to a better health will cause recompuation of the Health -// - Overall health is computed as the worst health amongst the nodes health and all -// of the workloads associated HealthStatuses -// - Deletion of the workload will cause deletion of all associated health statuses. -func RunCatalogV2Beta1WorkloadLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { - c := rtest.NewClient(client) - testutil.RunStep(t, "nodeless-workload", func(t *testing.T) { - runV2Beta1NodelessWorkloadLifecycleIntegrationTest(t, c) - }) - - testutil.RunStep(t, "node-associated-workload", func(t *testing.T) { - runV2Beta1NodeAssociatedWorkloadLifecycleIntegrationTest(t, c) - }) -} - -// runV2Beta1NodelessWorkloadLifecycleIntegrationTest verifies correct functionality of -// the workload-health controller for workloads without node associations. In particular -// the following behaviors are being tested -// -// - Creating a workload without associated health statuses or node association will -// be marked passing -// - Changing HealthStatus to a worse health will cause recompuation of the Health -// - Changing HealthStatus to a better health will cause recompuation of the Health -// - Deletion of associated HealthStatus for a nodeless workload will be set back to passing -// - Deletion of the workload will cause deletion of all associated health statuses. -func runV2Beta1NodelessWorkloadLifecycleIntegrationTest(t *testing.T, c *rtest.Client) { - workloadName := "test-lifecycle-workload" - workloadHealthName := "test-lifecycle-workload-status" - - // create a workload without a node association or health statuses yet - workload := rtest.Resource(pbcatalog.WorkloadType, workloadName). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "198.18.9.8"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - Identity: "test-lifecycle", - }). - Write(t, c) - - // wait for the workload health controller to mark the workload as healthy - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadHealthConditions[pbcatalog.Health_HEALTH_PASSING]) - - // We may not need to iterate through all of these states but its easy - // enough and quick enough to do so. The general rationale is that we - // should move through changing the workloads associated health status - // in this progression. We can prove that moving from better to worse - // health or worse to better both function correctly. - healthChanges := []pbcatalog.Health{ - pbcatalog.Health_HEALTH_PASSING, - pbcatalog.Health_HEALTH_WARNING, - pbcatalog.Health_HEALTH_CRITICAL, - pbcatalog.Health_HEALTH_MAINTENANCE, - pbcatalog.Health_HEALTH_CRITICAL, - pbcatalog.Health_HEALTH_WARNING, - pbcatalog.Health_HEALTH_PASSING, - pbcatalog.Health_HEALTH_WARNING, - } - - var workloadHealth *pbresource.Resource - // Iterate through the various desired health statuses, updating - // a HealthStatus resource owned by the workload and waiting for - // reconciliation at each point - for _, health := range healthChanges { - // update the health status - workloadHealth = setHealthStatus(t, c, workload.Id, workloadHealthName, health) - - // wait for reconciliation to kick in and put the workload into - // the right health status. - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadHealthConditions[health]) - } - - // Now delete the health status, things should go back to passing status - c.MustDelete(t, workloadHealth.Id) - - // ensure the workloads health went back to passing - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadHealthConditions[pbcatalog.Health_HEALTH_PASSING]) - - // Reset the workload health. The actual health is irrelevant, we just want it - // to exist to provde that Health Statuses get deleted along with the workload - // when its deleted. - workloadHealth = setHealthStatus(t, c, workload.Id, workloadHealthName, pbcatalog.Health_HEALTH_WARNING) - - // Delete the workload and wait for the HealthStatus to also be deleted - c.MustDelete(t, workload.Id) - c.WaitForDeletion(t, workloadHealth.Id) -} - -// runV2Beta1NodeAssociatedWorkloadLifecycleIntegrationTest verifies correct functionality of -// the workload-health controller. This test will exercise the following behaviors: -// -// - Associating a workload with a node causes recomputation of the health and takes -// into account the nodes health -// - Modifying the workloads associated node causes health recomputation and takes into -// account the new nodes health -// - Removal of the node association causes recomputation of health and for no node health -// to be taken into account. -// - Creating a workload without associated health statuses but with a node will -// inherit its health from the node. -// - Overall health is computed as the worst health amongst the nodes health and all -// of the workloads associated HealthStatuses -func runV2Beta1NodeAssociatedWorkloadLifecycleIntegrationTest(t *testing.T, c *rtest.Client) { - workloadName := "test-lifecycle" - workloadHealthName := "test-lifecycle" - nodeName1 := "test-lifecycle-1" - nodeName2 := "test-lifecycle-2" - nodeHealthName1 := "test-lifecycle-node-1" - nodeHealthName2 := "test-lifecycle-node-2" - - // Insert a some nodes to link the workloads to at various points throughout the test - node1 := rtest.Resource(pbcatalog.NodeType, nodeName1). - WithData(t, &pbcatalog.Node{ - Addresses: []*pbcatalog.NodeAddress{{Host: "172.17.9.10"}}, - }). - Write(t, c) - node2 := rtest.Resource(pbcatalog.NodeType, nodeName2). - WithData(t, &pbcatalog.Node{ - Addresses: []*pbcatalog.NodeAddress{{Host: "172.17.9.11"}}, - }). - Write(t, c) - - // Set some non-passing health statuses for those nodes. Using non-passing will make - // it easy to see that changing a passing workloads node association appropriately - // impacts the overall workload health. - setHealthStatus(t, c, node1.Id, nodeHealthName1, pbcatalog.Health_HEALTH_CRITICAL) - setHealthStatus(t, c, node2.Id, nodeHealthName2, pbcatalog.Health_HEALTH_WARNING) - - // Add the workload but don't immediately associate with any node. - workload := rtest.Resource(pbcatalog.WorkloadType, workloadName). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "198.18.9.8"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - Identity: "test-lifecycle", - }). - Write(t, c) - - // wait for the workload health controller to mark the workload as healthy - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadHealthConditions[pbcatalog.Health_HEALTH_PASSING]) - - // now modify the workload to associate it with node 1 (currently with CRITICAL health) - workload = rtest.ResourceID(workload.Id). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "198.18.9.8"}}, - Ports: map[string]*pbcatalog.WorkloadPort{"http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}}, - Identity: "test-lifecycle", - // this is the only difference from the previous write - NodeName: node1.Id.Name, - }). - Write(t, c) - - // wait for the workload health controller to mark the workload as critical (due to node 1 having critical health) - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadAndNodeHealthConditions[pbcatalog.Health_HEALTH_PASSING][pbcatalog.Health_HEALTH_CRITICAL]) - - // Now reassociate the workload with node 2. This should cause recalculation of its health into the warning state - workload = rtest.ResourceID(workload.Id). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "198.18.9.8"}}, - Ports: map[string]*pbcatalog.WorkloadPort{"http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}}, - Identity: "test-lifecycle", - // this is the only difference from the previous write - NodeName: node2.Id.Name, - }). - Write(t, c) - - // Wait for the workload health controller to mark the workload as warning (due to node 2 having warning health) - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadAndNodeHealthConditions[pbcatalog.Health_HEALTH_PASSING][pbcatalog.Health_HEALTH_WARNING]) - - // Delete the node, this should cause the health to be recalculated as critical because the node association - // is broken. - c.MustDelete(t, node2.Id) - - // Wait for the workload health controller to mark the workload as critical due to the missing node - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadAndNodeHealthConditions[pbcatalog.Health_HEALTH_PASSING][pbcatalog.Health_HEALTH_CRITICAL]) - - // Now fixup the node association to point at node 1 - workload = rtest.ResourceID(workload.Id). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "198.18.9.8"}}, - Ports: map[string]*pbcatalog.WorkloadPort{"http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}}, - Identity: "test-lifecycle", - // this is the only difference from the previous write - NodeName: node1.Id.Name, - }). - Write(t, c) - - // Also set node 1 health down to WARNING - setHealthStatus(t, c, node1.Id, nodeHealthName1, pbcatalog.Health_HEALTH_WARNING) - - // Wait for the workload health controller to mark the workload as warning (due to node 1 having warning health now) - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadAndNodeHealthConditions[pbcatalog.Health_HEALTH_PASSING][pbcatalog.Health_HEALTH_WARNING]) - - // Now add a critical workload health check to ensure that both node and workload health are accounted for. - setHealthStatus(t, c, workload.Id, workloadHealthName, pbcatalog.Health_HEALTH_CRITICAL) - - // Wait for the workload health to be recomputed and put into the critical status. - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadAndNodeHealthConditions[pbcatalog.Health_HEALTH_CRITICAL][pbcatalog.Health_HEALTH_WARNING]) - - // Reset the workloads health to passing. We expect the overall health to go back to warning - setHealthStatus(t, c, workload.Id, workloadHealthName, pbcatalog.Health_HEALTH_PASSING) - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadAndNodeHealthConditions[pbcatalog.Health_HEALTH_PASSING][pbcatalog.Health_HEALTH_WARNING]) - - // Remove the node association and wait for the health to go back to passing - workload = rtest.ResourceID(workload.Id). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "198.18.9.8"}}, - Ports: map[string]*pbcatalog.WorkloadPort{"http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}}, - Identity: "test-lifecycle", - }). - Write(t, c) - c.WaitForStatusCondition(t, workload.Id, - catalog.WorkloadHealthStatusKey, - catalog.WorkloadHealthConditions[pbcatalog.Health_HEALTH_PASSING]) -} - -// RunCatalogV2Beta1EndpointsLifecycleIntegrationTest verifies the correct functionality of -// the endpoints controller. This test will exercise the following behaviors: -// -// * Services without a selector get marked with status indicating their endpoints are unmanaged -// * Services with a selector get marked with status indicating their endpoints are managed -// * Deleting a service will delete the associated endpoints (regardless of them being managed or not) -// * Moving from managed to unmanaged endpoints will delete the managed endpoints -// * Moving from unmanaged to managed endpoints will overwrite any previous endpoints. -// * A service with a selector that matches no workloads will still have the endpoints object written. -// * Adding ports to a service will recalculate the endpoints -// * Removing ports from a service will recalculate the endpoints -// * Changing the workload will recalculate the endpoints (ports, addresses, or health) -func RunCatalogV2Beta1EndpointsLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { - c := rtest.NewClient(client) - serviceName := "test-lifecycle" - - // Create the service without a selector. We should not see endpoints generated but we should see the - // status updated to note endpoints are not being managed. - service := rtest.Resource(pbcatalog.ServiceType, serviceName). - WithData(t, &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{{TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}}, - }). - Write(t, c) - - // Wait to ensure the status is updated accordingly - c.WaitForStatusCondition(t, service.Id, catalog.EndpointsStatusKey, catalog.EndpointsStatusConditionUnmanaged) - - // Verify that no endpoints were created. - endpointsID := rtest.Resource(pbcatalog.ServiceEndpointsType, serviceName).ID() - c.RequireResourceNotFound(t, endpointsID) - - // Add some empty endpoints (type validations enforce that they are owned by the service) - rtest.ResourceID(endpointsID). - WithData(t, &pbcatalog.ServiceEndpoints{}). - WithOwner(service.Id). - Write(t, c) - - // Now delete the service and ensure that they are cleaned up. - c.MustDelete(t, service.Id) - c.WaitForDeletion(t, endpointsID) - - // Add some workloads to eventually select by the service - - // api-1 has all ports (http, grpc and mesh). It also has a mixture of Addresses - // that select individual ports and one that selects all ports implicitly - api1 := rtest.Resource(pbcatalog.WorkloadType, "api-1"). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1"}, - {Host: "::1", Ports: []string{"grpc"}}, - {Host: "127.0.0.2", Ports: []string{"http"}}, - {Host: "172.17.1.1", Ports: []string{"mesh"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - Identity: "api", - }). - Write(t, c) - - // api-2 has only grpc and mesh ports. It also has a mixture of Addresses that - // select individual ports and one that selects all ports implicitly - api2 := rtest.Resource(pbcatalog.WorkloadType, "api-2"). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1"}, - {Host: "::1", Ports: []string{"grpc"}}, - {Host: "172.17.1.2", Ports: []string{"mesh"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - Identity: "api", - }). - Write(t, c) - - // api-3 has the mesh and HTTP ports. It also has a mixture of Addresses that - // select individual ports and one that selects all ports. - api3 := rtest.Resource(pbcatalog.WorkloadType, "api-3"). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1"}, - {Host: "172.17.1.3", Ports: []string{"mesh"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - Identity: "api", - }). - Write(t, c) - - // Now create a service with unmanaged endpoints again - service = rtest.Resource(pbcatalog.ServiceType, serviceName). - WithData(t, &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{{TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}}, - }). - Write(t, c) - - // Inject the endpoints resource. We want to prove that transition from unmanaged to - // managed endpoints results in overwriting of the old endpoints - rtest.ResourceID(endpointsID). - WithData(t, &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "198.18.1.1", External: true}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": {Port: 443, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", - }, - }, - }). - WithOwner(service.Id). - Write(t, c) - - // Wait to ensure the status is updated accordingly - c.WaitForStatusCondition(t, service.Id, catalog.EndpointsStatusKey, catalog.EndpointsStatusConditionUnmanaged) - - // Now move the service to having managed endpoints - service = rtest.ResourceID(service.Id). - WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"bar"}}, - Ports: []*pbcatalog.ServicePort{{TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}}, - }). - Write(t, c) - - // Verify that this status is updated to show this service as having managed endpoints - c.WaitForStatusCondition(t, service.Id, catalog.EndpointsStatusKey, catalog.EndpointsStatusConditionManaged) - - // Verify that the service endpoints are created. In this case they will be empty - verifyServiceEndpoints(t, c, endpointsID, &pbcatalog.ServiceEndpoints{}) - - // Rewrite the service to select the API workloads - just select the singular port for now - service = rtest.ResourceID(service.Id). - WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"api-"}}, - Ports: []*pbcatalog.ServicePort{{TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}}, - }). - Write(t, c) - - // Wait for the status to be updated. The condition itself will remain unchanged but we are waiting for - // the generations to match to know that the endpoints would have been regenerated - c.WaitForStatusCondition(t, service.Id, catalog.EndpointsStatusKey, catalog.EndpointsStatusConditionManaged) - - // ensure that api-1 and api-3 are selected but api-2 is excluded due to not having the desired port - verifyServiceEndpoints(t, c, endpointsID, &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: api1.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"http"}}, - {Host: "127.0.0.2", Ports: []string{"http"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", - }, - { - TargetRef: api3.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"http"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", - }, - }, - }) - - // Rewrite the service to select the API workloads - changing from selecting the HTTP port to the gRPC port - service = rtest.ResourceID(service.Id). - WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"api-"}}, - Ports: []*pbcatalog.ServicePort{{TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}}, - }). - Write(t, c) - - // Wait for the status to be updated. The condition itself will remain unchanged but we are waiting for - // the generations to match to know that the endpoints would have been regenerated - c.WaitForStatusCondition(t, service.Id, catalog.EndpointsStatusKey, catalog.EndpointsStatusConditionManaged) - - // Check that the endpoints were generated as expected - verifyServiceEndpoints(t, c, endpointsID, &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: api1.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"grpc"}}, - {Host: "::1", Ports: []string{"grpc"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", - }, - { - TargetRef: api2.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"grpc"}}, - {Host: "::1", Ports: []string{"grpc"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", - }, - }, - }) - - // Update the service to change the ports used. This should result in the workload being removed - // from the endpoints - rtest.ResourceID(api2.Id). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1"}, - {Host: "::1", Ports: []string{"http"}}, - {Host: "172.17.1.2", Ports: []string{"mesh"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - Identity: "api", - }). - Write(t, c) - - // Verify that api-2 was removed from the service endpoints as it no longer has a grpc port - verifyServiceEndpoints(t, c, endpointsID, &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: api1.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"grpc"}}, - {Host: "::1", Ports: []string{"grpc"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", - }, - }, - }) - - // Remove the ::1 address from workload api1 which should result in recomputing endpoints - rtest.ResourceID(api1.Id). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1"}, - {Host: "172.17.1.1", Ports: []string{"mesh"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": {Port: 10000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - Identity: "api", - }). - Write(t, c) - - // Verify that api-1 had its addresses modified appropriately - verifyServiceEndpoints(t, c, endpointsID, &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: api1.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"grpc"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", - }, - }, - }) - - // Add a failing health status to the api1 workload to force recomputation of endpoints - setHealthStatus(t, c, api1.Id, "api-failed", pbcatalog.Health_HEALTH_CRITICAL) - - // Verify that api-1 within the endpoints has the expected health - verifyServiceEndpoints(t, c, endpointsID, &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: api1.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"grpc"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", - }, - }, - }) - - // Move the service to being unmanaged. We should see the ServiceEndpoints being removed. - service = rtest.ResourceID(service.Id). - WithData(t, &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{{TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}}, - }). - Write(t, c) - - // Wait for the endpoints controller to inform us that the endpoints are not being managed - c.WaitForStatusCondition(t, service.Id, catalog.EndpointsStatusKey, catalog.EndpointsStatusConditionUnmanaged) - // Ensure that the managed endpoints were deleted - c.WaitForDeletion(t, endpointsID) - - // Put the service back into managed mode. - service = rtest.ResourceID(service.Id). - WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"api-"}}, - Ports: []*pbcatalog.ServicePort{{TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}}, - }). - Write(t, c) - - // Wait for the service endpoints to be regenerated - c.WaitForStatusCondition(t, service.Id, catalog.EndpointsStatusKey, catalog.EndpointsStatusConditionManaged) - c.RequireResourceExists(t, endpointsID) - - // Now delete the service and ensure that the endpoints eventually are deleted as well - c.MustDelete(t, service.Id) - c.WaitForDeletion(t, endpointsID) -} - -func setHealthStatus(t *testing.T, client *rtest.Client, owner *pbresource.ID, name string, health pbcatalog.Health) *pbresource.Resource { - return rtest.Resource(pbcatalog.HealthStatusType, name). - WithData(t, &pbcatalog.HealthStatus{ - Type: "synthetic", - Status: health, - }). - WithOwner(owner). - Write(t, client) -} diff --git a/internal/catalog/exports.go b/internal/catalog/exports.go index 3c43643de4194..61247091be1cf 100644 --- a/internal/catalog/exports.go +++ b/internal/catalog/exports.go @@ -1,59 +1,47 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package catalog import ( "github.com/hashicorp/consul/internal/catalog/internal/controllers" - "github.com/hashicorp/consul/internal/catalog/internal/controllers/endpoints" - "github.com/hashicorp/consul/internal/catalog/internal/controllers/failover" - "github.com/hashicorp/consul/internal/catalog/internal/controllers/nodehealth" - "github.com/hashicorp/consul/internal/catalog/internal/controllers/workloadhealth" - "github.com/hashicorp/consul/internal/catalog/internal/mappers/failovermapper" "github.com/hashicorp/consul/internal/catalog/internal/mappers/nodemapper" + "github.com/hashicorp/consul/internal/catalog/internal/mappers/selectiontracker" "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/selectiontracker" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" ) var ( - // Controller Statuses - NodeHealthStatusKey = nodehealth.StatusKey - NodeHealthStatusConditionHealthy = nodehealth.StatusConditionHealthy - NodeHealthConditions = nodehealth.Conditions - - WorkloadHealthStatusKey = workloadhealth.StatusKey - WorkloadHealthStatusConditionHealthy = workloadhealth.StatusConditionHealthy - WorkloadHealthConditions = workloadhealth.WorkloadConditions - WorkloadAndNodeHealthConditions = workloadhealth.NodeAndWorkloadConditions - - EndpointsStatusKey = endpoints.StatusKey - EndpointsStatusConditionEndpointsManaged = endpoints.StatusConditionEndpointsManaged - EndpointsStatusConditionManaged = endpoints.ConditionManaged - EndpointsStatusConditionUnmanaged = endpoints.ConditionUnmanaged - StatusConditionBoundIdentities = endpoints.StatusConditionBoundIdentities - StatusReasonWorkloadIdentitiesFound = endpoints.StatusReasonWorkloadIdentitiesFound - StatusReasonNoWorkloadIdentitiesFound = endpoints.StatusReasonNoWorkloadIdentitiesFound - - FailoverStatusKey = failover.StatusKey - FailoverStatusConditionAccepted = failover.StatusConditionAccepted - FailoverStatusConditionAcceptedOKReason = failover.OKReason - FailoverStatusConditionAcceptedMissingServiceReason = failover.MissingServiceReason - FailoverStatusConditionAcceptedUnknownPortReason = failover.UnknownPortReason - FailoverStatusConditionAcceptedMissingDestinationServiceReason = failover.MissingDestinationServiceReason - FailoverStatusConditionAcceptedUnknownDestinationPortReason = failover.UnknownDestinationPortReason - FailoverStatusConditionAcceptedUsingMeshDestinationPortReason = failover.UsingMeshDestinationPortReason + // API Group Information + + APIGroup = types.GroupName + VersionV1Alpha1 = types.VersionV1Alpha1 + CurrentVersion = types.CurrentVersion + + // Resource Kind Names. + + WorkloadKind = types.WorkloadKind + ServiceKind = types.ServiceKind + ServiceEndpointsKind = types.ServiceEndpointsKind + VirtualIPsKind = types.VirtualIPsKind + NodeKind = types.NodeKind + HealthStatusKind = types.HealthStatusKind + HealthChecksKind = types.HealthChecksKind + DNSPolicyKind = types.DNSPolicyKind + + // Resource Types for the v1alpha1 version. + + WorkloadV1Alpha1Type = types.WorkloadV1Alpha1Type + ServiceV1Alpha1Type = types.ServiceV1Alpha1Type + ServiceEndpointsV1Alpha1Type = types.ServiceEndpointsV1Alpha1Type + VirtualIPsV1Alpha1Type = types.VirtualIPsV1Alpha1Type + NodeV1Alpha1Type = types.NodeV1Alpha1Type + HealthStatusV1Alpha1Type = types.HealthStatusV1Alpha1Type + HealthChecksV1Alpha1Type = types.HealthChecksV1Alpha1Type + DNSPolicyV1Alpha1Type = types.DNSPolicyV1Alpha1Type ) -type WorkloadSelecting = types.WorkloadSelecting - -func ACLHooksForWorkloadSelectingType[T WorkloadSelecting]() *resource.ACLHooks { - return types.ACLHooksForWorkloadSelectingType[T]() -} - // RegisterTypes adds all resource types within the "catalog" API group // to the given type registry func RegisterTypes(r resource.Registry) { @@ -66,7 +54,6 @@ func DefaultControllerDependencies() ControllerDependencies { return ControllerDependencies{ WorkloadHealthNodeMapper: nodemapper.New(), EndpointsWorkloadMapper: selectiontracker.New(), - FailoverMapper: failovermapper.New(), } } @@ -75,56 +62,3 @@ func DefaultControllerDependencies() ControllerDependencies { func RegisterControllers(mgr *controller.Manager, deps ControllerDependencies) { controllers.Register(mgr, deps) } - -// SimplifyFailoverPolicy fully populates the PortConfigs map and clears the -// Configs map using the provided Service. -func SimplifyFailoverPolicy(svc *pbcatalog.Service, failover *pbcatalog.FailoverPolicy) *pbcatalog.FailoverPolicy { - return types.SimplifyFailoverPolicy(svc, failover) -} - -// FailoverPolicyMapper maintains the bidirectional tracking relationship of a -// FailoverPolicy to the Services related to it. -type FailoverPolicyMapper interface { - TrackFailover(failover *resource.DecodedResource[*pbcatalog.FailoverPolicy]) - UntrackFailover(failoverID *pbresource.ID) - FailoverIDsByService(svcID *pbresource.ID) []*pbresource.ID -} - -func NewFailoverPolicyMapper() FailoverPolicyMapper { - return failovermapper.New() -} - -// ValidateLocalServiceRefNoSection ensures the following: -// -// - ref is non-nil -// - type is ServiceType -// - section is empty -// - tenancy is set and partition/namespace are both non-empty -// - peer_name must be "local" -// -// Each possible validation error is wrapped in the wrapErr function before -// being collected in a multierror.Error. -func ValidateLocalServiceRefNoSection(ref *pbresource.Reference, wrapErr func(error) error) error { - return types.ValidateLocalServiceRefNoSection(ref, wrapErr) -} - -// ValidateSelector ensures that the selector has at least one exact or prefix -// match constraint, and that if a filter is present it is valid. -// -// The selector can be nil, and have zero exact/prefix matches if allowEmpty is -// set to true. -func ValidateSelector(sel *pbcatalog.WorkloadSelector, allowEmpty bool) error { - return types.ValidateSelector(sel, allowEmpty) -} - -func ValidatePortName(name string) error { - return types.ValidatePortName(name) -} - -func IsValidUnixSocketPath(host string) bool { - return types.IsValidUnixSocketPath(host) -} - -func ValidateProtocol(protocol pbcatalog.Protocol) error { - return types.ValidateProtocol(protocol) -} diff --git a/internal/catalog/internal/controllers/endpoints/controller.go b/internal/catalog/internal/controllers/endpoints/controller.go index ef0c20f97961c..1be2a3fd2fadc 100644 --- a/internal/catalog/internal/controllers/endpoints/controller.go +++ b/internal/catalog/internal/controllers/endpoints/controller.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package endpoints @@ -7,14 +7,14 @@ import ( "context" "sort" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - "github.com/hashicorp/consul/internal/catalog/internal/controllers/workloadhealth" + "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" ) const ( @@ -43,9 +43,9 @@ func ServiceEndpointsController(workloadMap WorkloadMapper) controller.Controlle panic("No WorkloadMapper was provided to the ServiceEndpointsController constructor") } - return controller.ForType(pbcatalog.ServiceEndpointsType). - WithWatch(pbcatalog.ServiceType, controller.ReplaceType(pbcatalog.ServiceEndpointsType)). - WithWatch(pbcatalog.WorkloadType, workloadMap.MapWorkload). + return controller.ForType(types.ServiceEndpointsType). + WithWatch(types.ServiceType, controller.ReplaceType(types.ServiceEndpointsType)). + WithWatch(types.WorkloadType, workloadMap.MapWorkload). WithReconciler(newServiceEndpointsReconciler(workloadMap)) } @@ -69,7 +69,7 @@ func (r *serviceEndpointsReconciler) Reconcile(ctx context.Context, rt controlle endpointsID := req.ID serviceID := &pbresource.ID{ - Type: pbcatalog.ServiceType, + Type: types.ServiceType, Tenancy: endpointsID.Tenancy, Name: endpointsID.Name, } @@ -105,19 +105,19 @@ func (r *serviceEndpointsReconciler) Reconcile(ctx context.Context, rt controlle return err } - var statusConditions []*pbresource.Condition + var status *pbresource.Condition if serviceUnderManagement(serviceData.service) { rt.Logger.Trace("service is enabled for automatic endpoint management") // This service should have its endpoints automatically managed - statusConditions = append(statusConditions, ConditionManaged) + status = ConditionManaged // Inform the WorkloadMapper to track this service and its selectors. So // future workload updates that would be matched by the services selectors // cause this service to be rereconciled. r.workloadMap.TrackIDForSelector(req.ID, serviceData.service.GetWorkloads()) - // Now read and unmarshal all workloads selected by the service. It is imperative + // Now read and umarshal all workloads selected by the service. It is imperative // that this happens after we notify the selection tracker to be tracking that // selection criteria. If the order were reversed we could potentially miss // workload creations that should be selected if they happen after gathering @@ -133,12 +133,6 @@ func (r *serviceEndpointsReconciler) Reconcile(ctx context.Context, rt controlle // Calculate the latest endpoints from the already gathered workloads latestEndpoints := workloadsToEndpoints(serviceData.service, workloadData) - // Add status - if endpointsData != nil { - statusConditions = append(statusConditions, - workloadIdentityStatusFromEndpoints(latestEndpoints)) - } - // Before writing the endpoints actually check to see if they are changed if endpointsData == nil || !proto.Equal(endpointsData.endpoints, latestEndpoints) { rt.Logger.Trace("endpoints have changed") @@ -174,7 +168,7 @@ func (r *serviceEndpointsReconciler) Reconcile(ctx context.Context, rt controlle } else { rt.Logger.Trace("endpoints are not being automatically managed") // This service is not having its endpoints automatically managed - statusConditions = append(statusConditions, ConditionUnmanaged) + status = ConditionUnmanaged // Inform the WorkloadMapper that it no longer needs to track this service // as it is no longer under endpoint management @@ -209,7 +203,9 @@ func (r *serviceEndpointsReconciler) Reconcile(ctx context.Context, rt controlle // for that object existing or not. newStatus := &pbresource.Status{ ObservedGeneration: serviceData.resource.Generation, - Conditions: statusConditions, + Conditions: []*pbresource.Condition{ + status, + }, } // If the status is unchanged then we should return and avoid the unnecessary write if resource.EqualStatus(serviceData.resource.Status[StatusKey], newStatus, false) { @@ -314,13 +310,8 @@ func workloadToEndpoint(svc *pbcatalog.Service, data *workloadData) *pbcatalog.E continue } - // If workload protocol is not specified, we will default to service's protocol. - // This is because on some platforms (kubernetes), workload protocol is not always - // known, and so we need to inherit from the service instead. - if workloadPort.Protocol == pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { - workloadPort.Protocol = svcPort.Protocol - } else if workloadPort.Protocol != svcPort.Protocol { - // Otherwise, there's workload port mismatch - ignore it. + if workloadPort.Protocol != svcPort.Protocol { + // workload port mismatch - ignore it continue } @@ -389,16 +380,5 @@ func workloadToEndpoint(svc *pbcatalog.Service, data *workloadData) *pbcatalog.E HealthStatus: health, Addresses: workloadAddrs, Ports: endpointPorts, - Identity: data.workload.Identity, - } -} - -func workloadIdentityStatusFromEndpoints(endpoints *pbcatalog.ServiceEndpoints) *pbresource.Condition { - identities := endpoints.GetIdentities() - - if len(identities) > 0 { - return ConditionIdentitiesFound(identities) } - - return ConditionIdentitiesNotFound } diff --git a/internal/catalog/internal/controllers/endpoints/controller_test.go b/internal/catalog/internal/controllers/endpoints/controller_test.go index 5a0155ef76837..ff53509057a2c 100644 --- a/internal/catalog/internal/controllers/endpoints/controller_test.go +++ b/internal/catalog/internal/controllers/endpoints/controller_test.go @@ -1,26 +1,22 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package endpoints import ( "context" "testing" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" "github.com/hashicorp/consul/internal/catalog/internal/controllers/workloadhealth" + "github.com/hashicorp/consul/internal/catalog/internal/mappers/selectiontracker" "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource/mappers/selectiontracker" rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" ) var ( @@ -64,14 +60,14 @@ func TestWorkloadsToEndpoints(t *testing.T) { workloads := []*workloadData{ { // this workload should result in an endpoints - resource: rtest.Resource(pbcatalog.WorkloadType, "foo"). + resource: rtest.Resource(types.WorkloadType, "foo"). WithData(t, workloadData1). Build(), workload: workloadData1, }, { // this workload should be filtered out - resource: rtest.Resource(pbcatalog.WorkloadType, "bar"). + resource: rtest.Resource(types.WorkloadType, "bar"). WithData(t, workloadData2). Build(), workload: workloadData2, @@ -124,11 +120,10 @@ func TestWorkloadToEndpoint(t *testing.T) { // the protocol is wrong here so it will not show up in the endpoints. "grpc": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, }, - Identity: "test-identity", } data := &workloadData{ - resource: rtest.Resource(pbcatalog.WorkloadType, "foo"). + resource: rtest.Resource(types.WorkloadType, "foo"). WithData(t, workload). Build(), workload: workload, @@ -148,7 +143,6 @@ func TestWorkloadToEndpoint(t *testing.T) { // that we can properly determine the health status and the overall // controller tests will prove that the integration works as expected. HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: workload.Identity, } prototest.AssertDeepEqual(t, expected, workloadToEndpoint(service, data)) @@ -176,7 +170,7 @@ func TestWorkloadToEndpoint_AllAddressesFiltered(t *testing.T) { } data := &workloadData{ - resource: rtest.Resource(pbcatalog.WorkloadType, "foo"). + resource: rtest.Resource(types.WorkloadType, "foo"). WithData(t, workload). Build(), workload: workload, @@ -185,51 +179,6 @@ func TestWorkloadToEndpoint_AllAddressesFiltered(t *testing.T) { require.Nil(t, workloadToEndpoint(service, data)) } -func TestWorkloadToEndpoint_MissingWorkloadProtocol(t *testing.T) { - // This test checks that when a workload is missing its protocol, - // we will default to service's protocol. - - service := &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "test-port", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - workload := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "test-port": {Port: 8080}, - }, - } - - data := &workloadData{ - resource: rtest.Resource(pbcatalog.WorkloadType, "foo"). - WithData(t, workload). - Build(), - workload: workload, - } - - expected := &pbcatalog.Endpoint{ - TargetRef: data.resource.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"test-port"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "test-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - // The health is critical because we are not setting the workload's - // health status. The tests for determineWorkloadHealth will ensure - // that we can properly determine the health status and the overall - // controller tests will prove that the integration works as expected. - HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: workload.Identity, - } - - prototest.AssertDeepEqual(t, expected, workloadToEndpoint(service, data)) -} - func TestServiceUnderManagement(t *testing.T) { // This test ensures that we can properly detect when a service // should have endpoints generated for it vs when those endpoints @@ -292,11 +241,11 @@ func TestDetermineWorkloadHealth(t *testing.T) { cases := map[string]testCase{ "no-status": { - res: rtest.Resource(pbcatalog.WorkloadType, "foo").Build(), + res: rtest.Resource(types.WorkloadType, "foo").Build(), expected: pbcatalog.Health_HEALTH_CRITICAL, }, "condition-not-found": { - res: rtest.Resource(pbcatalog.WorkloadType, "foo"). + res: rtest.Resource(types.WorkloadType, "foo"). WithStatus(workloadhealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ { @@ -310,7 +259,7 @@ func TestDetermineWorkloadHealth(t *testing.T) { expected: pbcatalog.Health_HEALTH_CRITICAL, }, "invalid-reason": { - res: rtest.Resource(pbcatalog.WorkloadType, "foo"). + res: rtest.Resource(types.WorkloadType, "foo"). WithStatus(workloadhealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ { @@ -324,7 +273,7 @@ func TestDetermineWorkloadHealth(t *testing.T) { expected: pbcatalog.Health_HEALTH_CRITICAL, }, "passing": { - res: rtest.Resource(pbcatalog.WorkloadType, "foo"). + res: rtest.Resource(types.WorkloadType, "foo"). WithStatus(workloadhealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ { @@ -338,7 +287,7 @@ func TestDetermineWorkloadHealth(t *testing.T) { expected: pbcatalog.Health_HEALTH_PASSING, }, "warning": { - res: rtest.Resource(pbcatalog.WorkloadType, "foo"). + res: rtest.Resource(types.WorkloadType, "foo"). WithStatus(workloadhealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ { @@ -352,7 +301,7 @@ func TestDetermineWorkloadHealth(t *testing.T) { expected: pbcatalog.Health_HEALTH_WARNING, }, "critical": { - res: rtest.Resource(pbcatalog.WorkloadType, "foo"). + res: rtest.Resource(types.WorkloadType, "foo"). WithStatus(workloadhealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ { @@ -366,7 +315,7 @@ func TestDetermineWorkloadHealth(t *testing.T) { expected: pbcatalog.Health_HEALTH_CRITICAL, }, "maintenance": { - res: rtest.Resource(pbcatalog.WorkloadType, "foo"). + res: rtest.Resource(types.WorkloadType, "foo"). WithStatus(workloadhealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ { @@ -388,50 +337,6 @@ func TestDetermineWorkloadHealth(t *testing.T) { } } -func TestWorkloadIdentityStatusFromEndpoints(t *testing.T) { - cases := map[string]struct { - endpoints *pbcatalog.ServiceEndpoints - expStatus *pbresource.Condition - }{ - "endpoints are nil": { - expStatus: ConditionIdentitiesNotFound, - }, - "endpoints without identities": { - endpoints: &pbcatalog.ServiceEndpoints{}, - expStatus: ConditionIdentitiesNotFound, - }, - "endpoints with identities": { - endpoints: &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - Identity: "foo", - }, - }, - }, - expStatus: ConditionIdentitiesFound([]string{"foo"}), - }, - "endpoints with multiple identities": { - endpoints: &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - Identity: "foo", - }, - { - Identity: "bar", - }, - }, - }, - expStatus: ConditionIdentitiesFound([]string{"bar", "foo"}), - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - prototest.AssertDeepEqual(t, c.expStatus, workloadIdentityStatusFromEndpoints(c.endpoints)) - }) - } -} - type controllerSuite struct { suite.Suite @@ -478,11 +383,11 @@ func (suite *controllerSuite) TestReconcile_ServiceNotFound() { // generate a workload resource to use for checking if it maps // to a service endpoints object - workload := rtest.Resource(pbcatalog.WorkloadType, "foo").Build() + workload := rtest.Resource(types.WorkloadType, "foo").Build() // ensure that the tracker knows about the service prior to // calling reconcile so that we can ensure it removes tracking - id := rtest.Resource(pbcatalog.ServiceEndpointsType, "not-found").ID() + id := rtest.Resource(types.ServiceEndpointsType, "not-found").ID() suite.tracker.TrackIDForSelector(id, &pbcatalog.WorkloadSelector{Prefixes: []string{""}}) // verify that mapping the workload to service endpoints returns a @@ -505,7 +410,7 @@ func (suite *controllerSuite) TestReconcile_NoSelector_NoEndpoints() { // managed. Additionally, with no endpoints pre-existing it will // not attempt to delete them. - service := rtest.Resource(pbcatalog.ServiceType, "test"). + service := rtest.Resource(types.ServiceType, "test"). WithData(suite.T(), &pbcatalog.Service{ Ports: []*pbcatalog.ServicePort{ {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, @@ -513,7 +418,7 @@ func (suite *controllerSuite) TestReconcile_NoSelector_NoEndpoints() { }). Write(suite.T(), suite.client) - endpointsID := rtest.Resource(pbcatalog.ServiceEndpointsType, "test").ID() + endpointsID := rtest.Resource(types.ServiceEndpointsType, "test").ID() err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: endpointsID}) require.NoError(suite.T(), err) @@ -526,7 +431,7 @@ func (suite *controllerSuite) TestReconcile_NoSelector_ManagedEndpoints() { // to unmanaged endpoints for a service, any already generated managed endpoints // get deleted. - service := rtest.Resource(pbcatalog.ServiceType, "test"). + service := rtest.Resource(types.ServiceType, "test"). WithData(suite.T(), &pbcatalog.Service{ Ports: []*pbcatalog.ServicePort{ {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, @@ -534,7 +439,7 @@ func (suite *controllerSuite) TestReconcile_NoSelector_ManagedEndpoints() { }). Write(suite.T(), suite.client) - endpoints := rtest.Resource(pbcatalog.ServiceEndpointsType, "test"). + endpoints := rtest.Resource(types.ServiceEndpointsType, "test"). WithData(suite.T(), &pbcatalog.ServiceEndpoints{}). // this marks these endpoints as under management WithMeta(endpointsMetaManagedBy, StatusKey). @@ -553,7 +458,7 @@ func (suite *controllerSuite) TestReconcile_NoSelector_UnmanagedEndpoints() { // doesn't have its endpoints managed, that we do not delete any unmanaged // ServiceEndpoints resource that the user would have manually written. - service := rtest.Resource(pbcatalog.ServiceType, "test"). + service := rtest.Resource(types.ServiceType, "test"). WithData(suite.T(), &pbcatalog.Service{ Ports: []*pbcatalog.ServicePort{ {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, @@ -561,7 +466,7 @@ func (suite *controllerSuite) TestReconcile_NoSelector_UnmanagedEndpoints() { }). Write(suite.T(), suite.client) - endpoints := rtest.Resource(pbcatalog.ServiceEndpointsType, "test"). + endpoints := rtest.Resource(types.ServiceEndpointsType, "test"). WithData(suite.T(), &pbcatalog.ServiceEndpoints{}). Write(suite.T(), suite.client) @@ -577,7 +482,7 @@ func (suite *controllerSuite) TestReconcile_Managed_NoPreviousEndpoints() { // This test's purpose is to ensure the managed endpoint generation occurs // as expected when there are no pre-existing endpoints. - service := rtest.Resource(pbcatalog.ServiceType, "test"). + service := rtest.Resource(types.ServiceType, "test"). WithData(suite.T(), &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{ Prefixes: []string{""}, @@ -588,9 +493,9 @@ func (suite *controllerSuite) TestReconcile_Managed_NoPreviousEndpoints() { }). Write(suite.T(), suite.client) - endpointsID := rtest.Resource(pbcatalog.ServiceEndpointsType, "test").ID() + endpointsID := rtest.Resource(types.ServiceEndpointsType, "test").ID() - rtest.Resource(pbcatalog.WorkloadType, "test-workload"). + rtest.Resource(types.WorkloadType, "test-workload"). WithData(suite.T(), &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{{Host: "127.0.0.1"}}, Ports: map[string]*pbcatalog.WorkloadPort{ @@ -622,7 +527,7 @@ func (suite *controllerSuite) TestReconcile_Managed_ExistingEndpoints() { // This test's purpose is to ensure that when the current set of endpoints // differs from any prior set of endpoints that the resource gets rewritten. - service := rtest.Resource(pbcatalog.ServiceType, "test"). + service := rtest.Resource(types.ServiceType, "test"). WithData(suite.T(), &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{ Prefixes: []string{""}, @@ -633,12 +538,12 @@ func (suite *controllerSuite) TestReconcile_Managed_ExistingEndpoints() { }). Write(suite.T(), suite.client) - endpoints := rtest.Resource(pbcatalog.ServiceEndpointsType, "test"). + endpoints := rtest.Resource(types.ServiceEndpointsType, "test"). WithData(suite.T(), &pbcatalog.ServiceEndpoints{}). WithOwner(service.Id). Write(suite.T(), suite.client) - rtest.Resource(pbcatalog.WorkloadType, "test-workload"). + rtest.Resource(types.WorkloadType, "test-workload"). WithData(suite.T(), &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{{Host: "127.0.0.1"}}, Ports: map[string]*pbcatalog.WorkloadPort{ @@ -675,7 +580,7 @@ func (suite *controllerSuite) TestController() { // Add a service - there are no workloads so an empty endpoints // object should be created. - service := rtest.Resource(pbcatalog.ServiceType, "api"). + service := rtest.Resource(types.ServiceType, "api"). WithData(suite.T(), &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{ Prefixes: []string{"api-"}, @@ -690,29 +595,24 @@ func (suite *controllerSuite) TestController() { res := suite.client.WaitForReconciliation(suite.T(), service.Id, StatusKey) // Check that the services status was updated accordingly rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionManaged) - rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionIdentitiesNotFound) // Check that the endpoints resource exists and contains 0 endpoints - endpointsID := rtest.Resource(pbcatalog.ServiceEndpointsType, "api").ID() + endpointsID := rtest.Resource(types.ServiceEndpointsType, "api").ID() endpoints := suite.client.RequireResourceExists(suite.T(), endpointsID) suite.requireEndpoints(endpoints) // Now add a workload that would be selected by the service. Leave // the workload in a state where its health has not been reconciled - workload := rtest.Resource(pbcatalog.WorkloadType, "api-1"). + workload := rtest.Resource(types.WorkloadType, "api-1"). WithData(suite.T(), &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{{Host: "127.0.0.1"}}, Ports: map[string]*pbcatalog.WorkloadPort{ "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "grpc": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, }, Identity: "api", }). Write(suite.T(), suite.client) - suite.client.WaitForStatusCondition(suite.T(), service.Id, StatusKey, - ConditionIdentitiesFound([]string{"api"})) - // Wait for the endpoints to be regenerated endpoints = suite.client.WaitForNewVersion(suite.T(), endpointsID, endpoints.Version) @@ -726,7 +626,6 @@ func (suite *controllerSuite) TestController() { "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - Identity: "api", }) // Update the health status of the workload @@ -758,41 +657,12 @@ func (suite *controllerSuite) TestController() { "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, }, HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "api", - }) - - // Update workload identity and check that the status on the service is updated - workload = rtest.Resource(pbcatalog.WorkloadType, "api-1"). - WithData(suite.T(), &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "127.0.0.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "grpc": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - Identity: "endpoints-api-identity", - }). - Write(suite.T(), suite.client) - - suite.client.WaitForStatusCondition(suite.T(), service.Id, StatusKey, ConditionIdentitiesFound([]string{"endpoints-api-identity"})) - - // Verify that the generated endpoints now contain the workload - endpoints = suite.client.WaitForNewVersion(suite.T(), endpointsID, endpoints.Version) - suite.requireEndpoints(endpoints, &pbcatalog.Endpoint{ - TargetRef: workload.Id, - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "127.0.0.1", Ports: []string{"http"}}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - Identity: "endpoints-api-identity", }) // rewrite the service to add more selection criteria. This should trigger // reconciliation but shouldn't result in updating the endpoints because // the actual list of currently selected workloads has not changed - rtest.Resource(pbcatalog.ServiceType, "api"). + rtest.Resource(types.ServiceType, "api"). WithData(suite.T(), &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{ Prefixes: []string{"api-"}, @@ -810,23 +680,6 @@ func (suite *controllerSuite) TestController() { // Verify that the endpoints were not regenerated suite.client.RequireVersionUnchanged(suite.T(), endpointsID, endpoints.Version) - // Update the service. - updatedService := rtest.Resource(pbcatalog.ServiceType, "api"). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - }). - Write(suite.T(), suite.client) - - // Wait for the endpoints to be regenerated - endpoints = suite.client.WaitForNewVersion(suite.T(), endpointsID, endpoints.Version) - rtest.RequireOwner(suite.T(), endpoints, updatedService.Id, false) - // Delete the endpoints. The controller should bring these back momentarily suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: endpointsID}) @@ -836,7 +689,7 @@ func (suite *controllerSuite) TestController() { }) // Move the service to having unmanaged endpoints - rtest.Resource(pbcatalog.ServiceType, "api"). + rtest.Resource(types.ServiceType, "api"). WithData(suite.T(), &pbcatalog.Service{ Ports: []*pbcatalog.ServicePort{ {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, diff --git a/internal/catalog/internal/controllers/endpoints/reconciliation_data.go b/internal/catalog/internal/controllers/endpoints/reconciliation_data.go index 320ad47470d5b..f00ac1595a217 100644 --- a/internal/catalog/internal/controllers/endpoints/reconciliation_data.go +++ b/internal/catalog/internal/controllers/endpoints/reconciliation_data.go @@ -1,20 +1,16 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package endpoints import ( "context" - "fmt" "sort" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - + "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) type serviceData struct { @@ -124,7 +120,7 @@ func gatherWorkloadsForService(ctx context.Context, rt controller.Runtime, svc * // workloads selected by name if they are also matched by a prefix. for _, prefix := range sel.GetPrefixes() { rsp, err := rt.Client.List(ctx, &pbresource.ListRequest{ - Type: pbcatalog.WorkloadType, + Type: types.WorkloadType, Tenancy: svc.resource.Id.Tenancy, NamePrefix: prefix, }) @@ -150,7 +146,7 @@ func gatherWorkloadsForService(ctx context.Context, rt controller.Runtime, svc * } workloadID := &pbresource.ID{ - Type: pbcatalog.WorkloadType, + Type: types.WorkloadType, Tenancy: svc.resource.Id.Tenancy, Name: name, } @@ -170,14 +166,6 @@ func gatherWorkloadsForService(ctx context.Context, rt controller.Runtime, svc * workloadNames[rsp.Resource.Id.Name] = struct{}{} } - if sel.GetFilter() != "" && len(workloads) > 0 { - var err error - workloads, err = resource.FilterResourcesByMetadata(workloads, sel.GetFilter()) - if err != nil { - return nil, fmt.Errorf("error filtering results by metadata: %w", err) - } - } - // Sorting ensures deterministic output. This will help for testing but // the real reason to do this is so we will be able to diff the set of // workloads endpoints to determine if we need to update them. diff --git a/internal/catalog/internal/controllers/endpoints/reconciliation_data_test.go b/internal/catalog/internal/controllers/endpoints/reconciliation_data_test.go index d855c710f6c28..c0c83deda98d6 100644 --- a/internal/catalog/internal/controllers/endpoints/reconciliation_data_test.go +++ b/internal/catalog/internal/controllers/endpoints/reconciliation_data_test.go @@ -1,27 +1,22 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package endpoints import ( "context" "testing" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource" rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" "github.com/hashicorp/consul/sdk/testutil" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) type reconciliationDataSuite struct { @@ -31,16 +26,14 @@ type reconciliationDataSuite struct { client pbresource.ResourceServiceClient rt controller.Runtime - apiServiceData *pbcatalog.Service - apiService *pbresource.Resource - apiServiceSubsetData *pbcatalog.Service - apiServiceSubset *pbresource.Resource - apiEndpoints *pbresource.Resource - api1Workload *pbresource.Resource - api2Workload *pbresource.Resource - api123Workload *pbresource.Resource - web1Workload *pbresource.Resource - web2Workload *pbresource.Resource + apiServiceData *pbcatalog.Service + apiService *pbresource.Resource + apiEndpoints *pbresource.Resource + api1Workload *pbresource.Resource + api2Workload *pbresource.Resource + api123Workload *pbresource.Resource + web1Workload *pbresource.Resource + web2Workload *pbresource.Resource } func (suite *reconciliationDataSuite) SetupTest() { @@ -65,19 +58,12 @@ func (suite *reconciliationDataSuite) SetupTest() { }, }, } - suite.apiServiceSubsetData = proto.Clone(suite.apiServiceData).(*pbcatalog.Service) - suite.apiServiceSubsetData.Workloads.Filter = "(zim in metadata) and (metadata.zim matches `^g.`)" - suite.apiService = rtest.Resource(pbcatalog.ServiceType, "api"). + suite.apiService = rtest.Resource(types.ServiceType, "api"). WithData(suite.T(), suite.apiServiceData). Write(suite.T(), suite.client) - suite.apiServiceSubset = rtest.Resource(pbcatalog.ServiceType, "api-subset"). - WithData(suite.T(), suite.apiServiceSubsetData). - Write(suite.T(), suite.client) - - suite.api1Workload = rtest.Resource(pbcatalog.WorkloadType, "api-1"). - WithMeta("zim", "dib"). + suite.api1Workload = rtest.Resource(types.WorkloadType, "api-1"). WithData(suite.T(), &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ {Host: "127.0.0.1"}, @@ -89,7 +75,7 @@ func (suite *reconciliationDataSuite) SetupTest() { }). Write(suite.T(), suite.client) - suite.api2Workload = rtest.Resource(pbcatalog.WorkloadType, "api-2"). + suite.api2Workload = rtest.Resource(types.WorkloadType, "api-2"). WithData(suite.T(), &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ {Host: "127.0.0.1"}, @@ -101,8 +87,7 @@ func (suite *reconciliationDataSuite) SetupTest() { }). Write(suite.T(), suite.client) - suite.api123Workload = rtest.Resource(pbcatalog.WorkloadType, "api-123"). - WithMeta("zim", "gir"). + suite.api123Workload = rtest.Resource(types.WorkloadType, "api-123"). WithData(suite.T(), &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ {Host: "127.0.0.1"}, @@ -114,8 +99,7 @@ func (suite *reconciliationDataSuite) SetupTest() { }). Write(suite.T(), suite.client) - suite.web1Workload = rtest.Resource(pbcatalog.WorkloadType, "web-1"). - WithMeta("zim", "gaz"). + suite.web1Workload = rtest.Resource(types.WorkloadType, "web-1"). WithData(suite.T(), &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ {Host: "127.0.0.1"}, @@ -127,7 +111,7 @@ func (suite *reconciliationDataSuite) SetupTest() { }). Write(suite.T(), suite.client) - suite.web2Workload = rtest.Resource(pbcatalog.WorkloadType, "web-2"). + suite.web2Workload = rtest.Resource(types.WorkloadType, "web-2"). WithData(suite.T(), &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ {Host: "127.0.0.1"}, @@ -139,11 +123,11 @@ func (suite *reconciliationDataSuite) SetupTest() { }). Write(suite.T(), suite.client) - suite.apiEndpoints = rtest.Resource(pbcatalog.ServiceEndpointsType, "api"). + suite.apiEndpoints = rtest.Resource(types.ServiceEndpointsType, "api"). WithData(suite.T(), &pbcatalog.ServiceEndpoints{ Endpoints: []*pbcatalog.Endpoint{ { - TargetRef: rtest.Resource(pbcatalog.WorkloadType, "api-1").WithTenancy(resource.DefaultNamespacedTenancy()).ID(), + TargetRef: rtest.Resource(types.WorkloadType, "api-1").ID(), Addresses: []*pbcatalog.WorkloadAddress{ { Host: "127.0.0.1", @@ -163,7 +147,7 @@ func (suite *reconciliationDataSuite) SetupTest() { func (suite *reconciliationDataSuite) TestGetServiceData_NotFound() { // This test's purposes is to ensure that NotFound errors when retrieving // the service data are ignored properly. - data, err := getServiceData(suite.ctx, suite.rt, rtest.Resource(pbcatalog.ServiceType, "not-found").WithTenancy(resource.DefaultNamespacedTenancy()).ID()) + data, err := getServiceData(suite.ctx, suite.rt, rtest.Resource(types.ServiceType, "not-found").ID()) require.NoError(suite.T(), err) require.Nil(suite.T(), data) } @@ -187,7 +171,7 @@ func (suite *reconciliationDataSuite) TestGetServiceData_UnmarshalError() { // This test's purpose is to ensure that unmarshlling errors are returned // to the caller. We are using a resource id that points to an endpoints // object instead of a service to ensure that the data will be unmarshallable. - data, err := getServiceData(suite.ctx, suite.rt, rtest.Resource(pbcatalog.ServiceEndpointsType, "api").ID()) + data, err := getServiceData(suite.ctx, suite.rt, rtest.Resource(types.ServiceEndpointsType, "api").ID()) require.Error(suite.T(), err) var parseErr resource.ErrDataParse require.ErrorAs(suite.T(), err, &parseErr) @@ -208,7 +192,7 @@ func (suite *reconciliationDataSuite) TestGetServiceData_Ok() { func (suite *reconciliationDataSuite) TestGetEndpointsData_NotFound() { // This test's purposes is to ensure that NotFound errors when retrieving // the endpoint data are ignored properly. - data, err := getEndpointsData(suite.ctx, suite.rt, rtest.Resource(pbcatalog.ServiceEndpointsType, "not-found").ID()) + data, err := getEndpointsData(suite.ctx, suite.rt, rtest.Resource(types.ServiceEndpointsType, "not-found").ID()) require.NoError(suite.T(), err) require.Nil(suite.T(), data) } @@ -232,7 +216,7 @@ func (suite *reconciliationDataSuite) TestGetEndpointsData_UnmarshalError() { // This test's purpose is to ensure that unmarshlling errors are returned // to the caller. We are using a resource id that points to a service object // instead of an endpoints object to ensure that the data will be unmarshallable. - data, err := getEndpointsData(suite.ctx, suite.rt, rtest.Resource(pbcatalog.ServiceType, "api").ID()) + data, err := getEndpointsData(suite.ctx, suite.rt, rtest.Resource(types.ServiceType, "api").ID()) require.Error(suite.T(), err) var parseErr resource.ErrDataParse require.ErrorAs(suite.T(), err, &parseErr) @@ -271,20 +255,6 @@ func (suite *reconciliationDataSuite) TestGetWorkloadData() { prototest.AssertDeepEqual(suite.T(), suite.web2Workload, data[4].resource) } -func (suite *reconciliationDataSuite) TestGetWorkloadDataWithFilter() { - // This is like TestGetWorkloadData except it exercises the post-read - // filter on the selector. - data, err := getWorkloadData(suite.ctx, suite.rt, &serviceData{ - resource: suite.apiServiceSubset, - service: suite.apiServiceSubsetData, - }) - - require.NoError(suite.T(), err) - require.Len(suite.T(), data, 2) - prototest.AssertDeepEqual(suite.T(), suite.api123Workload, data[0].resource) - prototest.AssertDeepEqual(suite.T(), suite.web1Workload, data[1].resource) -} - func TestReconciliationData(t *testing.T) { suite.Run(t, new(reconciliationDataSuite)) } diff --git a/internal/catalog/internal/controllers/endpoints/status.go b/internal/catalog/internal/controllers/endpoints/status.go index 078d5e9a5f7ff..5388a0fda9126 100644 --- a/internal/catalog/internal/controllers/endpoints/status.go +++ b/internal/catalog/internal/controllers/endpoints/status.go @@ -1,14 +1,9 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package endpoints -import ( - "fmt" - "strings" - - "github.com/hashicorp/consul/proto-public/pbresource" -) +import "github.com/hashicorp/consul/proto-public/pbresource" const ( StatusKey = "consul.io/endpoint-manager" @@ -17,16 +12,8 @@ const ( StatusReasonSelectorNotFound = "SelectorNotFound" StatusReasonSelectorFound = "SelectorFound" - selectorFoundMessage = "A valid workload selector is present within the service." - selectorNotFoundMessage = "Either the workload selector was not present or contained no selection criteria." - - StatusConditionBoundIdentities = "BoundIdentities" - - StatusReasonWorkloadIdentitiesFound = "WorkloadIdentitiesFound" - StatusReasonNoWorkloadIdentitiesFound = "NoWorkloadIdentitiesFound" - - identitiesFoundMessageFormat = "Found workload identities associated with this service: %q." - identitiesNotFoundChangedMessage = "No associated workload identities found." + SelectorFoundMessage = "A valid workload selector is present within the service." + SelectorNotFoundMessage = "Either the workload selector was not present or contained no selection criteria." ) var ( @@ -34,29 +21,13 @@ var ( Type: StatusConditionEndpointsManaged, State: pbresource.Condition_STATE_TRUE, Reason: StatusReasonSelectorFound, - Message: selectorFoundMessage, + Message: SelectorFoundMessage, } ConditionUnmanaged = &pbresource.Condition{ Type: StatusConditionEndpointsManaged, State: pbresource.Condition_STATE_FALSE, Reason: StatusReasonSelectorNotFound, - Message: selectorNotFoundMessage, - } - - ConditionIdentitiesNotFound = &pbresource.Condition{ - Type: StatusConditionBoundIdentities, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonNoWorkloadIdentitiesFound, - Message: identitiesNotFoundChangedMessage, + Message: SelectorNotFoundMessage, } ) - -func ConditionIdentitiesFound(identities []string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionBoundIdentities, - State: pbresource.Condition_STATE_TRUE, - Reason: StatusReasonWorkloadIdentitiesFound, - Message: fmt.Sprintf(identitiesFoundMessageFormat, strings.Join(identities, ",")), - } -} diff --git a/internal/catalog/internal/controllers/failover/controller.go b/internal/catalog/internal/controllers/failover/controller.go deleted file mode 100644 index ef236b954ca4e..0000000000000 --- a/internal/catalog/internal/controllers/failover/controller.go +++ /dev/null @@ -1,276 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package failover - -import ( - "context" - - "github.com/hashicorp/consul/internal/catalog/internal/types" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// FailoverMapper tracks the relationship between a FailoverPolicy an a Service -// it references whether due to name-alignment or from a reference in a -// FailoverDestination leg. -type FailoverMapper interface { - // TrackFailover extracts all Service references from the provided - // FailoverPolicy and indexes them so that MapService can turn Service - // events into FailoverPolicy events properly. - TrackFailover(failover *resource.DecodedResource[*pbcatalog.FailoverPolicy]) - - // UntrackFailover forgets the links inserted by TrackFailover for the - // provided FailoverPolicyID. - UntrackFailover(failoverID *pbresource.ID) - - // MapService will take a Service resource and return controller requests - // for all FailoverPolicies associated with the Service. - MapService(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) -} - -func FailoverPolicyController(mapper FailoverMapper) controller.Controller { - if mapper == nil { - panic("No FailoverMapper was provided to the FailoverPolicyController constructor") - } - return controller.ForType(pbcatalog.FailoverPolicyType). - WithWatch(pbcatalog.ServiceType, mapper.MapService). - WithReconciler(newFailoverPolicyReconciler(mapper)) -} - -type failoverPolicyReconciler struct { - mapper FailoverMapper -} - -func newFailoverPolicyReconciler(mapper FailoverMapper) *failoverPolicyReconciler { - return &failoverPolicyReconciler{ - mapper: mapper, - } -} - -func (r *failoverPolicyReconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error { - // The runtime is passed by value so replacing it here for the remainder of this - // reconciliation request processing will not affect future invocations. - rt.Logger = rt.Logger.With("resource-id", req.ID, "controller", StatusKey) - - rt.Logger.Trace("reconciling failover policy") - - failoverPolicyID := req.ID - - failoverPolicy, err := getFailoverPolicy(ctx, rt, failoverPolicyID) - if err != nil { - rt.Logger.Error("error retrieving failover policy", "error", err) - return err - } - if failoverPolicy == nil { - r.mapper.UntrackFailover(failoverPolicyID) - - // Either the failover policy was deleted, or it doesn't exist but an - // update to a Service came through and we can ignore it. - return nil - } - - r.mapper.TrackFailover(failoverPolicy) - - // FailoverPolicy is name-aligned with the Service it controls. - serviceID := &pbresource.ID{ - Type: pbcatalog.ServiceType, - Tenancy: failoverPolicyID.Tenancy, - Name: failoverPolicyID.Name, - } - - service, err := getService(ctx, rt, serviceID) - if err != nil { - rt.Logger.Error("error retrieving corresponding service", "error", err) - return err - } - destServices := make(map[resource.ReferenceKey]*resource.DecodedResource[*pbcatalog.Service]) - if service != nil { - destServices[resource.NewReferenceKey(serviceID)] = service - } - - // Denorm the ports and stuff. After this we have no empty ports. - if service != nil { - failoverPolicy.Data = types.SimplifyFailoverPolicy( - service.Data, - failoverPolicy.Data, - ) - } - - // Fetch services. - for _, dest := range failoverPolicy.Data.GetUnderlyingDestinations() { - if dest.Ref == nil || !isServiceType(dest.Ref.Type) || dest.Ref.Section != "" { - continue // invalid, not possible due to validation hook - } - - key := resource.NewReferenceKey(dest.Ref) - - if _, ok := destServices[key]; ok { - continue - } - - destID := resource.IDFromReference(dest.Ref) - - destService, err := getService(ctx, rt, destID) - if err != nil { - rt.Logger.Error("error retrieving destination service", "service", key, "error", err) - return err - } - - if destService != nil { - destServices[key] = destService - } - } - - newStatus := computeNewStatus(failoverPolicy, service, destServices) - - if resource.EqualStatus(failoverPolicy.Resource.Status[StatusKey], newStatus, false) { - rt.Logger.Trace("resource's failover policy status is unchanged", - "conditions", newStatus.Conditions) - return nil - } - - _, err = rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{ - Id: failoverPolicy.Resource.Id, - Key: StatusKey, - Status: newStatus, - }) - - if err != nil { - rt.Logger.Error("error encountered when attempting to update the resource's failover policy status", "error", err) - return err - } - - rt.Logger.Trace("resource's failover policy status was updated", - "conditions", newStatus.Conditions) - return nil -} - -func getFailoverPolicy(ctx context.Context, rt controller.Runtime, id *pbresource.ID) (*resource.DecodedResource[*pbcatalog.FailoverPolicy], error) { - return resource.GetDecodedResource[*pbcatalog.FailoverPolicy](ctx, rt.Client, id) -} - -func getService(ctx context.Context, rt controller.Runtime, id *pbresource.ID) (*resource.DecodedResource[*pbcatalog.Service], error) { - return resource.GetDecodedResource[*pbcatalog.Service](ctx, rt.Client, id) -} - -func computeNewStatus( - failoverPolicy *resource.DecodedResource[*pbcatalog.FailoverPolicy], - service *resource.DecodedResource[*pbcatalog.Service], - destServices map[resource.ReferenceKey]*resource.DecodedResource[*pbcatalog.Service], -) *pbresource.Status { - if service == nil { - return &pbresource.Status{ - ObservedGeneration: failoverPolicy.Resource.Generation, - Conditions: []*pbresource.Condition{ - ConditionMissingService, - }, - } - } - - allowedPortProtocols := make(map[string]pbcatalog.Protocol) - for _, port := range service.Data.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - continue // skip - } - allowedPortProtocols[port.TargetPort] = port.Protocol - } - - var conditions []*pbresource.Condition - - if failoverPolicy.Data.Config != nil { - for _, dest := range failoverPolicy.Data.Config.Destinations { - // We know from validation that a Ref must be set, and the type it - // points to is a Service. - // - // Rather than do additional validation, just do a quick - // belt-and-suspenders check-and-skip if something looks weird. - if dest.Ref == nil || !isServiceType(dest.Ref.Type) { - continue - } - - if cond := serviceHasPort(dest, destServices); cond != nil { - conditions = append(conditions, cond) - } - } - // TODO: validate that referenced sameness groups exist - } - - for port, pc := range failoverPolicy.Data.PortConfigs { - if _, ok := allowedPortProtocols[port]; !ok { - conditions = append(conditions, ConditionUnknownPort(port)) - } - - for _, dest := range pc.Destinations { - // We know from validation that a Ref must be set, and the type it - // points to is a Service. - // - // Rather than do additional validation, just do a quick - // belt-and-suspenders check-and-skip if something looks weird. - if dest.Ref == nil || !isServiceType(dest.Ref.Type) { - continue - } - - if cond := serviceHasPort(dest, destServices); cond != nil { - conditions = append(conditions, cond) - } - } - - // TODO: validate that referenced sameness groups exist - } - - if len(conditions) > 0 { - return &pbresource.Status{ - ObservedGeneration: failoverPolicy.Resource.Generation, - Conditions: conditions, - } - } - - return &pbresource.Status{ - ObservedGeneration: failoverPolicy.Resource.Generation, - Conditions: []*pbresource.Condition{ - ConditionOK, - }, - } -} - -func serviceHasPort( - dest *pbcatalog.FailoverDestination, - destServices map[resource.ReferenceKey]*resource.DecodedResource[*pbcatalog.Service], -) *pbresource.Condition { - key := resource.NewReferenceKey(dest.Ref) - destService, ok := destServices[key] - if !ok { - return ConditionMissingDestinationService(dest.Ref) - } - - found := false - mesh := false - for _, port := range destService.Data.Ports { - if port.TargetPort == dest.Port { - found = true - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - mesh = true - } - break - } - } - - if !found { - return ConditionUnknownDestinationPort(dest.Ref, dest.Port) - } else if mesh { - return ConditionUsingMeshDestinationPort(dest.Ref, dest.Port) - } - - return nil -} - -func isServiceType(typ *pbresource.Type) bool { - switch { - case resource.EqualType(typ, pbcatalog.ServiceType): - return true - } - return false -} diff --git a/internal/catalog/internal/controllers/failover/controller_test.go b/internal/catalog/internal/controllers/failover/controller_test.go deleted file mode 100644 index a82a6f0fdee60..0000000000000 --- a/internal/catalog/internal/controllers/failover/controller_test.go +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package failover - -import ( - "context" - "testing" - - "github.com/stretchr/testify/suite" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog/internal/mappers/failovermapper" - "github.com/hashicorp/consul/internal/catalog/internal/types" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/sdk/testutil" -) - -type controllerSuite struct { - suite.Suite - - ctx context.Context - client *rtest.Client - rt controller.Runtime - - failoverMapper FailoverMapper - - ctl failoverPolicyReconciler -} - -func (suite *controllerSuite) SetupTest() { - suite.ctx = testutil.TestContext(suite.T()) - client := svctest.RunResourceService(suite.T(), types.Register) - suite.rt = controller.Runtime{ - Client: client, - Logger: testutil.Logger(suite.T()), - } - suite.client = rtest.NewClient(client) - - suite.failoverMapper = failovermapper.New() -} - -func (suite *controllerSuite) TestController() { - // This test's purpose is to exercise the controller in a halfway realistic - // way, verifying the event triggers work in the live code. - - // Run the controller manager - mgr := controller.NewManager(suite.client, suite.rt.Logger) - mgr.Register(FailoverPolicyController(suite.failoverMapper)) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - // Create an advance pointer to some services. - apiServiceRef := resource.Reference(rtest.Resource(pbcatalog.ServiceType, "api").WithTenancy(resource.DefaultNamespacedTenancy()).ID(), "") - otherServiceRef := resource.Reference(rtest.Resource(pbcatalog.ServiceType, "other").WithTenancy(resource.DefaultNamespacedTenancy()).ID(), "") - - // create a failover without any services - failoverData := &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: apiServiceRef, - }}, - }, - } - failover := rtest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(suite.T(), failoverData). - Write(suite.T(), suite.client) - - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionMissingService) - - // Provide the service. - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"api-"}}, - Ports: []*pbcatalog.ServicePort{{ - TargetPort: "http", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }}, - } - _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithData(suite.T(), apiServiceData). - Write(suite.T(), suite.client) - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionOK) - - // Update the failover to reference an unknown port - failoverData = &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: apiServiceRef, - Port: "http", - }}, - }, - "admin": { - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: apiServiceRef, - Port: "admin", - }}, - }, - }, - } - _ = rtest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(suite.T(), failoverData). - Write(suite.T(), suite.client) - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionUnknownPort("admin")) - - // update the service to fix the stray reference, but point to a mesh port - apiServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"api-"}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "http", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "admin", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - } - _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithData(suite.T(), apiServiceData). - Write(suite.T(), suite.client) - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionUsingMeshDestinationPort(apiServiceRef, "admin")) - - // update the service to fix the stray reference to not be a mesh port - apiServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"api-"}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "http", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "admin", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - } - _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithData(suite.T(), apiServiceData). - Write(suite.T(), suite.client) - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionOK) - - // change failover leg to point to missing service - failoverData = &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: apiServiceRef, - Port: "http", - }}, - }, - "admin": { - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: otherServiceRef, - Port: "admin", - }}, - }, - }, - } - _ = rtest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(suite.T(), failoverData). - Write(suite.T(), suite.client) - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionMissingDestinationService(otherServiceRef)) - - // Create the missing service, but forget the port. - otherServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"other-"}}, - Ports: []*pbcatalog.ServicePort{{ - TargetPort: "http", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }}, - } - _ = rtest.Resource(pbcatalog.ServiceType, "other"). - WithData(suite.T(), otherServiceData). - Write(suite.T(), suite.client) - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionUnknownDestinationPort(otherServiceRef, "admin")) - - // fix the destination leg's port - otherServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"other-"}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "http", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "admin", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - } - _ = rtest.Resource(pbcatalog.ServiceType, "other"). - WithData(suite.T(), otherServiceData). - Write(suite.T(), suite.client) - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionOK) - - // Update the two services to use differnet port names so the easy path doesn't work - apiServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"api-"}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "foo", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "bar", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - } - _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithData(suite.T(), apiServiceData). - Write(suite.T(), suite.client) - - otherServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"other-"}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "foo", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "baz", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - } - _ = rtest.Resource(pbcatalog.ServiceType, "other"). - WithData(suite.T(), otherServiceData). - Write(suite.T(), suite.client) - - failoverData = &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: otherServiceRef, - }}, - }, - } - failover = rtest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(suite.T(), failoverData). - Write(suite.T(), suite.client) - - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionUnknownDestinationPort(otherServiceRef, "bar")) - - // and fix it the silly way by removing it from api+failover - apiServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"api-"}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "foo", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - } - _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithData(suite.T(), apiServiceData). - Write(suite.T(), suite.client) - - suite.client.WaitForStatusCondition(suite.T(), failover.Id, StatusKey, ConditionOK) -} - -func TestFailoverController(t *testing.T) { - suite.Run(t, new(controllerSuite)) -} diff --git a/internal/catalog/internal/controllers/failover/status.go b/internal/catalog/internal/controllers/failover/status.go deleted file mode 100644 index b2801c41ed93e..0000000000000 --- a/internal/catalog/internal/controllers/failover/status.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package failover - -import ( - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - StatusKey = "consul.io/failover-policy" - StatusConditionAccepted = "accepted" - - OKReason = "Ok" - OKMessage = "failover policy was accepted" - - MissingServiceReason = "MissingService" - MissingServiceMessage = "service for failover policy does not exist" - - UnknownPortReason = "UnknownPort" - UnknownPortMessagePrefix = "port is not defined on service: " - - MissingDestinationServiceReason = "MissingDestinationService" - MissingDestinationServiceMessagePrefix = "destination service for failover policy does not exist: " - - UnknownDestinationPortReason = "UnknownDestinationPort" - UnknownDestinationPortMessagePrefix = "port is not defined on destination service: " - - UsingMeshDestinationPortReason = "UsingMeshDestinationPort" - UsingMeshDestinationPortMessagePrefix = "port is a special unroutable mesh port on destination service: " -) - -var ( - ConditionOK = &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_TRUE, - Reason: OKReason, - Message: OKMessage, - } - - ConditionMissingService = &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: MissingServiceReason, - Message: MissingServiceMessage, - } -) - -func ConditionUnknownPort(port string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: UnknownPortReason, - Message: UnknownPortMessagePrefix + port, - } -} - -func ConditionMissingDestinationService(ref *pbresource.Reference) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: MissingDestinationServiceReason, - Message: MissingDestinationServiceMessagePrefix + resource.ReferenceToString(ref), - } -} - -func ConditionUnknownDestinationPort(ref *pbresource.Reference, port string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: UnknownDestinationPortReason, - Message: UnknownDestinationPortMessagePrefix + port + " on " + resource.ReferenceToString(ref), - } -} - -func ConditionUsingMeshDestinationPort(ref *pbresource.Reference, port string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: UnknownDestinationPortReason, - Message: UnknownDestinationPortMessagePrefix + port + " on " + resource.ReferenceToString(ref), - } -} diff --git a/internal/catalog/internal/controllers/nodehealth/controller.go b/internal/catalog/internal/controllers/nodehealth/controller.go index 9ef656b6a8bb9..4e3aff9993ba1 100644 --- a/internal/catalog/internal/controllers/nodehealth/controller.go +++ b/internal/catalog/internal/controllers/nodehealth/controller.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package nodehealth @@ -7,18 +7,18 @@ import ( "context" "fmt" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - + "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) func NodeHealthController() controller.Controller { - return controller.ForType(pbcatalog.NodeType). - WithWatch(pbcatalog.HealthStatusType, controller.MapOwnerFiltered(pbcatalog.NodeType)). + return controller.ForType(types.NodeType). + WithWatch(types.HealthStatusType, controller.MapOwnerFiltered(types.NodeType)). WithReconciler(&nodeHealthReconciler{}) } @@ -89,7 +89,7 @@ func getNodeHealth(ctx context.Context, rt controller.Runtime, nodeRef *pbresour health := pbcatalog.Health_HEALTH_PASSING for _, res := range rsp.Resources { - if resource.EqualType(res.Id.Type, pbcatalog.HealthStatusType) { + if resource.EqualType(res.Id.Type, types.HealthStatusType) { var hs pbcatalog.HealthStatus if err := res.Data.UnmarshalTo(&hs); err != nil { // This should be impossible as the resource service + type validations the diff --git a/internal/catalog/internal/controllers/nodehealth/controller_test.go b/internal/catalog/internal/controllers/nodehealth/controller_test.go index b21c52e521f84..8150fe0bdda3a 100644 --- a/internal/catalog/internal/controllers/nodehealth/controller_test.go +++ b/internal/catalog/internal/controllers/nodehealth/controller_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package nodehealth @@ -8,21 +8,20 @@ import ( "fmt" "testing" - "github.com/oklog/ulid/v2" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/oklog/ulid/v2" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var ( @@ -73,27 +72,27 @@ type nodeHealthControllerTestSuite struct { } func (suite *nodeHealthControllerTestSuite) SetupTest() { - suite.resourceClient = svctest.RunResourceService(suite.T(), types.Register, types.RegisterDNSPolicy) + suite.resourceClient = svctest.RunResourceService(suite.T(), types.Register) suite.runtime = controller.Runtime{Client: suite.resourceClient, Logger: testutil.Logger(suite.T())} // The rest of the setup will be to prime the resource service with some data - suite.nodeNoHealth = resourcetest.Resource(pbcatalog.NodeType, "test-node-no-health"). + suite.nodeNoHealth = resourcetest.Resource(types.NodeType, "test-node-no-health"). WithData(suite.T(), nodeData). Write(suite.T(), suite.resourceClient).Id - suite.nodePassing = resourcetest.Resource(pbcatalog.NodeType, "test-node-passing"). + suite.nodePassing = resourcetest.Resource(types.NodeType, "test-node-passing"). WithData(suite.T(), nodeData). Write(suite.T(), suite.resourceClient).Id - suite.nodeWarning = resourcetest.Resource(pbcatalog.NodeType, "test-node-warning"). + suite.nodeWarning = resourcetest.Resource(types.NodeType, "test-node-warning"). WithData(suite.T(), nodeData). Write(suite.T(), suite.resourceClient).Id - suite.nodeCritical = resourcetest.Resource(pbcatalog.NodeType, "test-node-critical"). + suite.nodeCritical = resourcetest.Resource(types.NodeType, "test-node-critical"). WithData(suite.T(), nodeData). Write(suite.T(), suite.resourceClient).Id - suite.nodeMaintenance = resourcetest.Resource(pbcatalog.NodeType, "test-node-maintenance"). + suite.nodeMaintenance = resourcetest.Resource(types.NodeType, "test-node-maintenance"). WithData(suite.T(), nodeData). Write(suite.T(), suite.resourceClient).Id @@ -122,7 +121,7 @@ func (suite *nodeHealthControllerTestSuite) SetupTest() { for _, node := range []*pbresource.ID{suite.nodePassing, suite.nodeWarning, suite.nodeCritical, suite.nodeMaintenance} { for idx, health := range precedenceHealth { if nodeHealthDesiredStatus[node.Name] >= health { - resourcetest.Resource(pbcatalog.HealthStatusType, fmt.Sprintf("test-check-%s-%d", node.Name, idx)). + resourcetest.Resource(types.HealthStatusType, fmt.Sprintf("test-check-%s-%d", node.Name, idx)). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: health}). WithOwner(node). Write(suite.T(), suite.resourceClient) @@ -133,7 +132,7 @@ func (suite *nodeHealthControllerTestSuite) SetupTest() { // create a DNSPolicy to be owned by the node. The type doesn't really matter it just needs // to be something that doesn't care about its owner. All we want to prove is that we are // filtering out non-HealthStatus types appropriately. - resourcetest.Resource(pbcatalog.DNSPolicyType, "test-policy"). + resourcetest.Resource(types.DNSPolicyType, "test-policy"). WithData(suite.T(), dnsPolicyData). WithOwner(suite.nodeNoHealth). Write(suite.T(), suite.resourceClient) @@ -160,7 +159,7 @@ func (suite *nodeHealthControllerTestSuite) TestGetNodeHealthNoNode() { // no error is returned but also no data is. The default passing // status should then be returned in the same manner as the node // existing but with no associated HealthStatus resources. - ref := resourceID(pbcatalog.NodeType, "foo") + ref := resourceID(types.NodeType, "foo") ref.Uid = ulid.Make().String() health, err := getNodeHealth(context.Background(), suite.runtime, ref) @@ -202,7 +201,7 @@ func (suite *nodeHealthControllerTestSuite) TestReconcileNodeNotFound() { // This test ensures that removed nodes are ignored. In particular we don't // want to propagate the error and indefinitely keep re-reconciling in this case. err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: resourceID(pbcatalog.NodeType, "not-found"), + ID: resourceID(types.NodeType, "not-found"), }) require.NoError(suite.T(), err) } @@ -340,7 +339,7 @@ func (suite *nodeHealthControllerTestSuite) TestController() { // rewrite the resource - this will cause the nodes health // to be rereconciled but wont result in any health change - resourcetest.Resource(pbcatalog.NodeType, suite.nodePassing.Name). + resourcetest.Resource(types.NodeType, suite.nodePassing.Name). WithData(suite.T(), &pbcatalog.Node{ Addresses: []*pbcatalog.NodeAddress{ { @@ -353,7 +352,7 @@ func (suite *nodeHealthControllerTestSuite) TestController() { // wait for rereconciliation to happen suite.waitForReconciliation(suite.nodePassing, "HEALTH_PASSING") - resourcetest.Resource(pbcatalog.HealthStatusType, "failure"). + resourcetest.Resource(types.HealthStatusType, "failure"). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "fake", Status: pbcatalog.Health_HEALTH_CRITICAL}). WithOwner(suite.nodePassing). Write(suite.T(), suite.resourceClient) diff --git a/internal/catalog/internal/controllers/nodehealth/status.go b/internal/catalog/internal/controllers/nodehealth/status.go index 11997bc47e684..14a3151484b59 100644 --- a/internal/catalog/internal/controllers/nodehealth/status.go +++ b/internal/catalog/internal/controllers/nodehealth/status.go @@ -1,10 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package nodehealth import ( - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" ) diff --git a/internal/catalog/internal/controllers/register.go b/internal/catalog/internal/controllers/register.go index df1f7c88c7b2e..5f7fc631a543b 100644 --- a/internal/catalog/internal/controllers/register.go +++ b/internal/catalog/internal/controllers/register.go @@ -1,11 +1,10 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controllers import ( "github.com/hashicorp/consul/internal/catalog/internal/controllers/endpoints" - "github.com/hashicorp/consul/internal/catalog/internal/controllers/failover" "github.com/hashicorp/consul/internal/catalog/internal/controllers/nodehealth" "github.com/hashicorp/consul/internal/catalog/internal/controllers/workloadhealth" "github.com/hashicorp/consul/internal/controller" @@ -14,12 +13,10 @@ import ( type Dependencies struct { WorkloadHealthNodeMapper workloadhealth.NodeMapper EndpointsWorkloadMapper endpoints.WorkloadMapper - FailoverMapper failover.FailoverMapper } func Register(mgr *controller.Manager, deps Dependencies) { mgr.Register(nodehealth.NodeHealthController()) mgr.Register(workloadhealth.WorkloadHealthController(deps.WorkloadHealthNodeMapper)) mgr.Register(endpoints.ServiceEndpointsController(deps.EndpointsWorkloadMapper)) - mgr.Register(failover.FailoverPolicyController(deps.FailoverMapper)) } diff --git a/internal/catalog/internal/controllers/workloadhealth/controller.go b/internal/catalog/internal/controllers/workloadhealth/controller.go index 05cfd36a84bfe..77009697bcd7e 100644 --- a/internal/catalog/internal/controllers/workloadhealth/controller.go +++ b/internal/catalog/internal/controllers/workloadhealth/controller.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package workloadhealth import ( @@ -8,14 +5,14 @@ import ( "errors" "fmt" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "github.com/hashicorp/consul/internal/catalog/internal/controllers/nodehealth" + "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var ( @@ -50,9 +47,9 @@ func WorkloadHealthController(nodeMap NodeMapper) controller.Controller { panic("No NodeMapper was provided to the WorkloadHealthController constructor") } - return controller.ForType(pbcatalog.WorkloadType). - WithWatch(pbcatalog.HealthStatusType, controller.MapOwnerFiltered(pbcatalog.WorkloadType)). - WithWatch(pbcatalog.NodeType, nodeMap.MapNodeToWorkloads). + return controller.ForType(types.WorkloadType). + WithWatch(types.HealthStatusType, controller.MapOwnerFiltered(types.WorkloadType)). + WithWatch(types.NodeType, nodeMap.MapNodeToWorkloads). WithReconciler(&workloadHealthReconciler{nodeMap: nodeMap}) } @@ -109,10 +106,7 @@ func (r *workloadHealthReconciler) Reconcile(ctx context.Context, rt controller. r.nodeMap.UntrackWorkload(res.Id) } - // passing the workload from the response because getWorkloadHealth uses - // resourceClient.ListByOwner which requires ownerID have a Uid and this is the - // safest way for application and test code to ensure Uid is provided. - workloadHealth, err := getWorkloadHealth(ctx, rt, rsp.Resource.Id) + workloadHealth, err := getWorkloadHealth(ctx, rt, req.ID) if err != nil { // This should be impossible under normal operations and will not be exercised // within the unit tests. This can only fail if the resource service fails @@ -202,7 +196,6 @@ func getNodeHealth(ctx context.Context, rt controller.Runtime, nodeRef *pbresour } func getWorkloadHealth(ctx context.Context, rt controller.Runtime, workloadRef *pbresource.ID) (pbcatalog.Health, error) { - rt.Logger.Trace("getWorkloadHealth", "workloadRef", workloadRef) rsp, err := rt.Client.ListByOwner(ctx, &pbresource.ListByOwnerRequest{ Owner: workloadRef, }) @@ -214,7 +207,7 @@ func getWorkloadHealth(ctx context.Context, rt controller.Runtime, workloadRef * workloadHealth := pbcatalog.Health_HEALTH_PASSING for _, res := range rsp.Resources { - if resource.EqualType(res.Id.Type, pbcatalog.HealthStatusType) { + if resource.EqualType(res.Id.Type, types.HealthStatusType) { var hs pbcatalog.HealthStatus if err := res.Data.UnmarshalTo(&hs); err != nil { // This should be impossible and will not be executing in tests. The resource type diff --git a/internal/catalog/internal/controllers/workloadhealth/controller_test.go b/internal/catalog/internal/controllers/workloadhealth/controller_test.go index 9a00a940a07e0..29d93f088d453 100644 --- a/internal/catalog/internal/controllers/workloadhealth/controller_test.go +++ b/internal/catalog/internal/controllers/workloadhealth/controller_test.go @@ -1,20 +1,12 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package workloadhealth import ( "context" "fmt" - "github.com/hashicorp/consul/internal/resource" - "google.golang.org/protobuf/testing/protocmp" "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" "github.com/hashicorp/consul/internal/catalog/internal/controllers/nodehealth" @@ -22,11 +14,15 @@ import ( "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var ( @@ -47,9 +43,13 @@ var ( func resourceID(rtype *pbresource.Type, name string) *pbresource.ID { return &pbresource.ID{ - Type: rtype, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: name, + Type: rtype, + Tenancy: &pbresource.Tenancy{ + Partition: "default", + Namespace: "default", + PeerName: "local", + }, + Name: name, } } @@ -97,7 +97,7 @@ func (suite *controllerSuite) injectNodeWithStatus(name string, health pbcatalog state = pbresource.Condition_STATE_FALSE } - return resourcetest.Resource(pbcatalog.NodeType, name). + return resourcetest.Resource(types.NodeType, name). WithData(suite.T(), nodeData). WithStatus(nodehealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ @@ -147,11 +147,11 @@ func (suite *workloadHealthControllerTestSuite) testReconcileWithNode(nodeHealth node := suite.injectNodeWithStatus("test-node", nodeHealth) - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + workload := resourcetest.Resource(types.WorkloadType, "test-workload"). WithData(suite.T(), workloadData(node.Id.Name)). Write(suite.T(), suite.client) - resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). + resourcetest.Resource(types.HealthStatusType, "test-status"). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: workloadHealth}). WithOwner(workload.Id). Write(suite.T(), suite.client) @@ -166,8 +166,7 @@ func (suite *workloadHealthControllerTestSuite) testReconcileWithNode(nodeHealth reqs, err := suite.mapper.MapNodeToWorkloads(context.Background(), suite.runtime, node) require.NoError(suite.T(), err) require.Len(suite.T(), reqs, 1) - protocmp.Transform() - prototest.AssertDeepEqual(suite.T(), workload.Id, reqs[0].ID, protocmp.IgnoreFields(workload.Id, "uid")) + prototest.AssertDeepEqual(suite.T(), reqs[0].ID, workload.Id) suite.T().Cleanup(func() { // future calls to reconcile would normally have done this as the resource was @@ -191,11 +190,11 @@ func (suite *workloadHealthControllerTestSuite) testReconcileWithNode(nodeHealth // them in one with more branching based off of detecting whether nodes are in use. func (suite *workloadHealthControllerTestSuite) testReconcileWithoutNode(workloadHealth pbcatalog.Health, status *pbresource.Condition) *pbresource.Resource { suite.T().Helper() - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + workload := resourcetest.Resource(types.WorkloadType, "test-workload"). WithData(suite.T(), workloadData("")). Write(suite.T(), suite.client) - resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). + resourcetest.Resource(types.HealthStatusType, "test-status"). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: workloadHealth}). WithOwner(workload.Id). Write(suite.T(), suite.client) @@ -384,14 +383,13 @@ func (suite *workloadHealthControllerTestSuite) TestReconcileNotFound() { // so this test will inject the tracking, issue the Reconcile call which will get a // not found error and then ensure that the tracking was removed. - workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). + workload := resourcetest.Resource(types.WorkloadType, "foo"). WithData(suite.T(), workloadData("test-node")). // don't write this because then in the call to reconcile the resource // would be found and defeat the purpose of the tes - WithTenancy(resource.DefaultNamespacedTenancy()). Build() - node := resourcetest.Resource(pbcatalog.NodeType, "test-node"). + node := resourcetest.Resource(types.NodeType, "test-node"). WithData(suite.T(), nodeData). // Whether this gets written or not doesn't matter Build() @@ -434,15 +432,15 @@ func (suite *workloadHealthControllerTestSuite) TestGetNodeHealthError() { // but the exact error isn't very relevant to the core reason this // test exists. - node := resourcetest.Resource(pbcatalog.NodeType, "test-node"). + node := resourcetest.Resource(types.NodeType, "test-node"). WithData(suite.T(), nodeData). Write(suite.T(), suite.client) - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + workload := resourcetest.Resource(types.WorkloadType, "test-workload"). WithData(suite.T(), workloadData(node.Id.Name)). Write(suite.T(), suite.client) - resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). + resourcetest.Resource(types.HealthStatusType, "test-status"). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_CRITICAL}). WithOwner(workload.Id). Write(suite.T(), suite.client) @@ -502,14 +500,14 @@ func (suite *workloadHealthControllerTestSuite) TestController() { node := suite.injectNodeWithStatus("test-node", pbcatalog.Health_HEALTH_PASSING) // create the workload - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + workload := resourcetest.Resource(types.WorkloadType, "test-workload"). WithData(suite.T(), workloadData(node.Id.Name)). Write(suite.T(), suite.client) // Wait for reconciliation to occur and mark the workload as passing. suite.waitForReconciliation(workload.Id, "HEALTH_PASSING") - // Simulate a node unhealthy + // Simulate a node unhealty suite.injectNodeWithStatus("test-node", pbcatalog.Health_HEALTH_WARNING) // Wait for reconciliation to occur and mark the workload as warning @@ -519,7 +517,7 @@ func (suite *workloadHealthControllerTestSuite) TestController() { // Now register a critical health check that should supercede the nodes // warning status - resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). + resourcetest.Resource(types.HealthStatusType, "test-status"). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_CRITICAL}). WithOwner(workload.Id). Write(suite.T(), suite.client) @@ -528,11 +526,11 @@ func (suite *workloadHealthControllerTestSuite) TestController() { suite.waitForReconciliation(workload.Id, "HEALTH_CRITICAL") // Put the health status back into a passing state and delink the node - resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). + resourcetest.Resource(types.HealthStatusType, "test-status"). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_PASSING}). WithOwner(workload.Id). Write(suite.T(), suite.client) - workload = resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + workload = resourcetest.Resource(types.WorkloadType, "test-workload"). WithData(suite.T(), workloadData("")). Write(suite.T(), suite.client) @@ -546,19 +544,18 @@ func (suite *workloadHealthControllerTestSuite) TestController() { func (suite *workloadHealthControllerTestSuite) waitForReconciliation(id *pbresource.ID, reason string) { suite.T().Helper() - retry.RunWith(&retry.Timer{Wait: 100 * time.Millisecond, Timeout: 5 * time.Second}, - suite.T(), func(r *retry.R) { - rsp, err := suite.client.Read(context.Background(), &pbresource.ReadRequest{ - Id: id, - }) - require.NoError(r, err) - - status, found := rsp.Resource.Status[StatusKey] - require.True(r, found) - require.Equal(r, rsp.Resource.Generation, status.ObservedGeneration) - require.Len(r, status.Conditions, 1) - require.Equal(r, reason, status.Conditions[0].Reason) + retry.Run(suite.T(), func(r *retry.R) { + rsp, err := suite.client.Read(context.Background(), &pbresource.ReadRequest{ + Id: id, }) + require.NoError(r, err) + + status, found := rsp.Resource.Status[StatusKey] + require.True(r, found) + require.Equal(r, rsp.Resource.Generation, status.ObservedGeneration) + require.Len(r, status.Conditions, 1) + require.Equal(r, reason, status.Conditions[0].Reason) + }) } func TestWorkloadHealthController(t *testing.T) { @@ -588,7 +585,7 @@ func (suite *getWorkloadHealthTestSuite) addHealthStatuses(workload *pbresource. for idx, health := range healthStatuses { if desiredHealth >= health { - resourcetest.Resource(pbcatalog.HealthStatusType, fmt.Sprintf("check-%s-%d", workload.Name, idx)). + resourcetest.Resource(types.HealthStatusType, fmt.Sprintf("check-%s-%d", workload.Name, idx)). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: health}). WithOwner(workload). Write(suite.T(), suite.client) @@ -611,7 +608,7 @@ func (suite *getWorkloadHealthTestSuite) TestListError() { func (suite *getWorkloadHealthTestSuite) TestNoHealthStatuses() { // This test's goal is to ensure that when no HealthStatuses are owned by the // workload that the health is assumed to be passing. - workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). + workload := resourcetest.Resource(types.WorkloadType, "foo"). WithData(suite.T(), workloadData("")). Write(suite.T(), suite.client) @@ -633,7 +630,7 @@ func (suite *getWorkloadHealthTestSuite) TestWithStatuses() { } suite.Run(status, func() { - workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). + workload := resourcetest.Resource(types.WorkloadType, "foo"). WithData(suite.T(), workloadData("")). Write(suite.T(), suite.client) @@ -659,7 +656,7 @@ func (suite *getNodeHealthTestSuite) TestNotfound() { // present in the system results in a the critical health but no error. This situation // could occur when a linked node gets removed without the workloads being modified/removed. // When that occurs we want to steer traffic away from the linked node as soon as possible. - health, err := getNodeHealth(context.Background(), suite.runtime, resourceID(pbcatalog.NodeType, "not-found")) + health, err := getNodeHealth(context.Background(), suite.runtime, resourceID(types.NodeType, "not-found")) require.NoError(suite.T(), err) require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) @@ -678,7 +675,7 @@ func (suite *getNodeHealthTestSuite) TestUnreconciled() { // This test's goal is to ensure that nodes with unreconciled health are deemed // critical. Basically, the workload health controller should defer calculating // the workload health until the associated nodes health is known. - node := resourcetest.Resource(pbcatalog.NodeType, "unreconciled"). + node := resourcetest.Resource(types.NodeType, "unreconciled"). WithData(suite.T(), nodeData). Write(suite.T(), suite.client). GetId() @@ -696,7 +693,7 @@ func (suite *getNodeHealthTestSuite) TestNoConditions() { // buggy to add an empty status. However it could also indicate some breaking // change went in. Regardless, the code to handle this state is written // and it will be tested here. - node := resourcetest.Resource(pbcatalog.NodeType, "no-conditions"). + node := resourcetest.Resource(types.NodeType, "no-conditions"). WithData(suite.T(), nodeData). WithStatus(nodehealth.StatusKey, &pbresource.Status{}). Write(suite.T(), suite.client). @@ -716,7 +713,7 @@ func (suite *getNodeHealthTestSuite) TestInvalidReason() { // controller to put it into this state. As users or other controllers could // potentially force it into this state by writing the status themselves, it // would be good to ensure the defined behavior works as expected. - node := resourcetest.Resource(pbcatalog.NodeType, "invalid-reason"). + node := resourcetest.Resource(types.NodeType, "invalid-reason"). WithData(suite.T(), nodeData). WithStatus(nodehealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ diff --git a/internal/catalog/internal/controllers/workloadhealth/status.go b/internal/catalog/internal/controllers/workloadhealth/status.go index 133bd4cec989d..05cc989ddd934 100644 --- a/internal/catalog/internal/controllers/workloadhealth/status.go +++ b/internal/catalog/internal/controllers/workloadhealth/status.go @@ -1,11 +1,8 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package workloadhealth import ( "github.com/hashicorp/consul/internal/catalog/internal/controllers/nodehealth" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" ) diff --git a/internal/catalog/internal/mappers/failovermapper/failover_mapper.go b/internal/catalog/internal/mappers/failovermapper/failover_mapper.go deleted file mode 100644 index 7cd40b47b453a..0000000000000 --- a/internal/catalog/internal/mappers/failovermapper/failover_mapper.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package failovermapper - -import ( - "context" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// Mapper tracks the relationship between a FailoverPolicy an a Service it -// references whether due to name-alignment or from a reference in a -// FailoverDestination leg. -type Mapper struct { - b *bimapper.Mapper -} - -// New creates a new Mapper. -func New() *Mapper { - return &Mapper{ - b: bimapper.New(pbcatalog.FailoverPolicyType, pbcatalog.ServiceType), - } -} - -// TrackFailover extracts all Service references from the provided -// FailoverPolicy and indexes them so that MapService can turn Service events -// into FailoverPolicy events properly. -func (m *Mapper) TrackFailover(failover *resource.DecodedResource[*pbcatalog.FailoverPolicy]) { - destRefs := failover.Data.GetUnderlyingDestinationRefs() - destRefs = append(destRefs, &pbresource.Reference{ - Type: pbcatalog.ServiceType, - Tenancy: failover.Resource.Id.Tenancy, - Name: failover.Resource.Id.Name, - }) - m.trackFailover(failover.Resource.Id, destRefs) -} - -func (m *Mapper) trackFailover(failover *pbresource.ID, services []*pbresource.Reference) { - var servicesAsIDsOrRefs []resource.ReferenceOrID - for _, s := range services { - servicesAsIDsOrRefs = append(servicesAsIDsOrRefs, s) - } - m.b.TrackItem(failover, servicesAsIDsOrRefs) -} - -// UntrackFailover forgets the links inserted by TrackFailover for the provided -// FailoverPolicyID. -func (m *Mapper) UntrackFailover(failoverID *pbresource.ID) { - m.b.UntrackItem(failoverID) -} - -func (m *Mapper) MapService(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - return m.b.MapLink(ctx, rt, res) -} - -func (m *Mapper) FailoverIDsByService(svcID *pbresource.ID) []*pbresource.ID { - return m.b.ItemsForLink(svcID) -} diff --git a/internal/catalog/internal/mappers/failovermapper/failover_mapper_test.go b/internal/catalog/internal/mappers/failovermapper/failover_mapper_test.go deleted file mode 100644 index 6149fddbf2613..0000000000000 --- a/internal/catalog/internal/mappers/failovermapper/failover_mapper_test.go +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package failovermapper - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/catalog/internal/types" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestMapper_Tracking(t *testing.T) { - registry := resource.NewRegistry() - types.Register(registry) - - // Create an advance pointer to some services. - randoSvc := rtest.Resource(pbcatalog.ServiceType, "rando"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.Service{}). - Build() - rtest.ValidateAndNormalize(t, registry, randoSvc) - - apiSvc := rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.Service{}). - Build() - rtest.ValidateAndNormalize(t, registry, apiSvc) - - fooSvc := rtest.Resource(pbcatalog.ServiceType, "foo"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.Service{}). - Build() - rtest.ValidateAndNormalize(t, registry, fooSvc) - - barSvc := rtest.Resource(pbcatalog.ServiceType, "bar"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.Service{}). - Build() - rtest.ValidateAndNormalize(t, registry, barSvc) - - wwwSvc := rtest.Resource(pbcatalog.ServiceType, "www"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.Service{}). - Build() - rtest.ValidateAndNormalize(t, registry, wwwSvc) - - fail1 := rtest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "foo")}, - {Ref: newRef(pbcatalog.ServiceType, "bar")}, - }, - }, - }). - Build() - rtest.ValidateAndNormalize(t, registry, fail1) - failDec1 := rtest.MustDecode[*pbcatalog.FailoverPolicy](t, fail1) - - fail2 := rtest.Resource(pbcatalog.FailoverPolicyType, "www"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "www"), Datacenter: "dc2"}, - {Ref: newRef(pbcatalog.ServiceType, "foo")}, - }, - }, - }). - Build() - rtest.ValidateAndNormalize(t, registry, fail2) - failDec2 := rtest.MustDecode[*pbcatalog.FailoverPolicy](t, fail2) - - fail1_updated := rtest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "bar")}, - }, - }, - }). - Build() - rtest.ValidateAndNormalize(t, registry, fail1_updated) - failDec1_updated := rtest.MustDecode[*pbcatalog.FailoverPolicy](t, fail1_updated) - - m := New() - - // Nothing tracked yet so we assume nothing. - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc) - requireServicesTracked(t, m, fooSvc) - requireServicesTracked(t, m, barSvc) - requireServicesTracked(t, m, wwwSvc) - - // no-ops - m.UntrackFailover(fail1.Id) - - // still nothing - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc) - requireServicesTracked(t, m, fooSvc) - requireServicesTracked(t, m, barSvc) - requireServicesTracked(t, m, wwwSvc) - - // Actually insert some data. - m.TrackFailover(failDec1) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc, fail1.Id) - requireServicesTracked(t, m, fooSvc, fail1.Id) - requireServicesTracked(t, m, barSvc, fail1.Id) - requireServicesTracked(t, m, wwwSvc) - - // track it again, no change - m.TrackFailover(failDec1) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc, fail1.Id) - requireServicesTracked(t, m, fooSvc, fail1.Id) - requireServicesTracked(t, m, barSvc, fail1.Id) - requireServicesTracked(t, m, wwwSvc) - - // track new one that overlaps slightly - m.TrackFailover(failDec2) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc, fail1.Id) - requireServicesTracked(t, m, fooSvc, fail1.Id, fail2.Id) - requireServicesTracked(t, m, barSvc, fail1.Id) - requireServicesTracked(t, m, wwwSvc, fail2.Id) - - // update the original to change it - m.TrackFailover(failDec1_updated) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc, fail1.Id) - requireServicesTracked(t, m, fooSvc, fail2.Id) - requireServicesTracked(t, m, barSvc, fail1.Id) - requireServicesTracked(t, m, wwwSvc, fail2.Id) - - // delete the original - m.UntrackFailover(fail1.Id) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc) - requireServicesTracked(t, m, fooSvc, fail2.Id) - requireServicesTracked(t, m, barSvc) - requireServicesTracked(t, m, wwwSvc, fail2.Id) - - // delete the other one - m.UntrackFailover(fail2.Id) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc) - requireServicesTracked(t, m, fooSvc) - requireServicesTracked(t, m, barSvc) - requireServicesTracked(t, m, wwwSvc) -} - -func requireServicesTracked(t *testing.T, mapper *Mapper, svc *pbresource.Resource, failovers ...*pbresource.ID) { - t.Helper() - - reqs, err := mapper.MapService( - context.Background(), - controller.Runtime{}, - svc, - ) - require.NoError(t, err) - - require.Len(t, reqs, len(failovers)) - - for _, failover := range failovers { - prototest.AssertContainsElement(t, reqs, controller.Request{ID: failover}) - } -} - -func newRef(typ *pbresource.Type, name string) *pbresource.Reference { - return rtest.Resource(typ, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") -} diff --git a/internal/catalog/internal/mappers/nodemapper/node_mapper.go b/internal/catalog/internal/mappers/nodemapper/node_mapper.go index 9c17478d76390..8eea26dd08ca1 100644 --- a/internal/catalog/internal/mappers/nodemapper/node_mapper.go +++ b/internal/catalog/internal/mappers/nodemapper/node_mapper.go @@ -1,24 +1,26 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package nodemapper import ( "context" + "sync" + + "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" ) type NodeMapper struct { - b *bimapper.Mapper + lock sync.Mutex + nodesToWorkloads map[string][]controller.Request + workloadsToNodes map[string]string } func New() *NodeMapper { return &NodeMapper{ - b: bimapper.New(pbcatalog.WorkloadType, pbcatalog.NodeType), + workloadsToNodes: make(map[string]string), + nodesToWorkloads: make(map[string][]controller.Request), } } @@ -26,7 +28,7 @@ func New() *NodeMapper { // the workload and with the name populated from the workloads NodeName field. func (m *NodeMapper) NodeIDFromWorkload(workload *pbresource.Resource, workloadData *pbcatalog.Workload) *pbresource.ID { return &pbresource.ID{ - Type: pbcatalog.NodeType, + Type: types.NodeType, Tenancy: workload.Id.Tenancy, Name: workloadData.NodeName, } @@ -35,20 +37,68 @@ func (m *NodeMapper) NodeIDFromWorkload(workload *pbresource.Resource, workloadD // MapNodeToWorkloads will take a Node resource and return controller requests // for all Workloads associated with the Node. func (m *NodeMapper) MapNodeToWorkloads(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - ids := m.b.ItemIDsForLink(res.Id) - return controller.MakeRequests(pbcatalog.WorkloadType, ids), nil + m.lock.Lock() + defer m.lock.Unlock() + return m.nodesToWorkloads[res.Id.Name], nil } // TrackWorkload instructs the NodeMapper to associate the given workload // ID with the given node ID. func (m *NodeMapper) TrackWorkload(workloadID *pbresource.ID, nodeID *pbresource.ID) { - m.b.TrackItem(workloadID, []resource.ReferenceOrID{ - nodeID, - }) + m.lock.Lock() + defer m.lock.Unlock() + + if previousNode, found := m.workloadsToNodes[workloadID.Name]; found && previousNode == nodeID.Name { + return + } else if found { + // the node association is being changed + m.untrackWorkloadFromNode(workloadID, previousNode) + } + + // Now set up the latest tracking + m.nodesToWorkloads[nodeID.Name] = append(m.nodesToWorkloads[nodeID.Name], controller.Request{ID: workloadID}) + m.workloadsToNodes[workloadID.Name] = nodeID.Name } // UntrackWorkload will cause the node mapper to forget about the specified // workload if it is currently tracking it. func (m *NodeMapper) UntrackWorkload(workloadID *pbresource.ID) { - m.b.UntrackItem(workloadID) + m.lock.Lock() + defer m.lock.Unlock() + + node, found := m.workloadsToNodes[workloadID.Name] + if !found { + return + } + m.untrackWorkloadFromNode(workloadID, node) +} + +// untrackWorkloadFromNode will disassociate the specified workload and node. +// This method will clean up unnecessary tracking entries if the node name +// is no longer associated with any workloads. +func (m *NodeMapper) untrackWorkloadFromNode(workloadID *pbresource.ID, node string) { + foundIdx := -1 + for idx, req := range m.nodesToWorkloads[node] { + if resource.EqualID(req.ID, workloadID) { + foundIdx = idx + break + } + } + + if foundIdx != -1 { + workloads := m.nodesToWorkloads[node] + l := len(workloads) + + if l == 1 { + delete(m.nodesToWorkloads, node) + } else if foundIdx == l-1 { + m.nodesToWorkloads[node] = workloads[:foundIdx] + } else if foundIdx == 0 { + m.nodesToWorkloads[node] = workloads[1:] + } else { + m.nodesToWorkloads[node] = append(workloads[:foundIdx], workloads[foundIdx+1:]...) + } + } + + delete(m.workloadsToNodes, workloadID.Name) } diff --git a/internal/catalog/internal/mappers/nodemapper/node_mapper_test.go b/internal/catalog/internal/mappers/nodemapper/node_mapper_test.go index fda260361fe8d..acfe67cf6b106 100644 --- a/internal/catalog/internal/mappers/nodemapper/node_mapper_test.go +++ b/internal/catalog/internal/mappers/nodemapper/node_mapper_test.go @@ -1,19 +1,16 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package nodemapper import ( "context" "testing" - "github.com/stretchr/testify/require" - + "github.com/hashicorp/consul/internal/catalog/internal/types" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" + "github.com/stretchr/testify/require" ) func TestNodeMapper_NodeIDFromWorkload(t *testing.T) { @@ -24,12 +21,12 @@ func TestNodeMapper_NodeIDFromWorkload(t *testing.T) { // the other fields should be irrelevant } - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + workload := resourcetest.Resource(types.WorkloadType, "test-workload"). WithData(t, data).Build() actual := mapper.NodeIDFromWorkload(workload, data) expected := &pbresource.ID{ - Type: pbcatalog.NodeType, + Type: types.NodeType, Tenancy: workload.Id.Tenancy, Name: "test-node", } @@ -54,11 +51,11 @@ func requireWorkloadsTracked(t *testing.T, mapper *NodeMapper, node *pbresource. func TestNodeMapper_WorkloadTracking(t *testing.T) { mapper := New() - node1 := resourcetest.Resource(pbcatalog.NodeType, "node1"). + node1 := resourcetest.Resource(types.NodeType, "node1"). WithData(t, &pbcatalog.Node{Addresses: []*pbcatalog.NodeAddress{{Host: "198.18.0.1"}}}). Build() - node2 := resourcetest.Resource(pbcatalog.NodeType, "node2"). + node2 := resourcetest.Resource(types.NodeType, "node2"). WithData(t, &pbcatalog.Node{Addresses: []*pbcatalog.NodeAddress{{Host: "198.18.0.2"}}}). Build() @@ -68,11 +65,11 @@ func TestNodeMapper_WorkloadTracking(t *testing.T) { PeerName: "local", } - workload1 := &pbresource.ID{Type: pbcatalog.WorkloadType, Tenancy: tenant, Name: "workload1"} - workload2 := &pbresource.ID{Type: pbcatalog.WorkloadType, Tenancy: tenant, Name: "workload2"} - workload3 := &pbresource.ID{Type: pbcatalog.WorkloadType, Tenancy: tenant, Name: "workload3"} - workload4 := &pbresource.ID{Type: pbcatalog.WorkloadType, Tenancy: tenant, Name: "workload4"} - workload5 := &pbresource.ID{Type: pbcatalog.WorkloadType, Tenancy: tenant, Name: "workload5"} + workload1 := &pbresource.ID{Type: types.WorkloadType, Tenancy: tenant, Name: "workload1"} + workload2 := &pbresource.ID{Type: types.WorkloadType, Tenancy: tenant, Name: "workload2"} + workload3 := &pbresource.ID{Type: types.WorkloadType, Tenancy: tenant, Name: "workload3"} + workload4 := &pbresource.ID{Type: types.WorkloadType, Tenancy: tenant, Name: "workload4"} + workload5 := &pbresource.ID{Type: types.WorkloadType, Tenancy: tenant, Name: "workload5"} // No Workloads have been tracked so the mapper should return empty lists requireWorkloadsTracked(t, mapper, node1) diff --git a/internal/resource/mappers/selectiontracker/selection_tracker.go b/internal/catalog/internal/mappers/selectiontracker/selection_tracker.go similarity index 55% rename from internal/resource/mappers/selectiontracker/selection_tracker.go rename to internal/catalog/internal/mappers/selectiontracker/selection_tracker.go index 5b60680bb546f..3bf229bff65eb 100644 --- a/internal/resource/mappers/selectiontracker/selection_tracker.go +++ b/internal/catalog/internal/mappers/selectiontracker/selection_tracker.go @@ -1,72 +1,61 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package selectiontracker import ( "context" - "fmt" "sync" - "golang.org/x/exp/slices" - "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/radix" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/lib/stringslice" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" ) type WorkloadSelectionTracker struct { lock sync.Mutex - prefixes *radix.Tree[[]*pbresource.ID] - exact *radix.Tree[[]*pbresource.ID] + prefixes *radix.Tree[[]controller.Request] + exact *radix.Tree[[]controller.Request] - // workloadSelectors contains a map keyed on resource references with values + // workloadSelectors contains a map keyed on resource names with values // being the selector that resource is currently associated with. This map // is kept mainly to make tracking removal operations more efficient. // Generally any operation that could take advantage of knowing where // in the trees the resource id is referenced can use this to prevent // needing to search the whole tree. - workloadSelectors map[resource.ReferenceKey]*pbcatalog.WorkloadSelector + workloadSelectors map[string]*pbcatalog.WorkloadSelector } func New() *WorkloadSelectionTracker { return &WorkloadSelectionTracker{ - prefixes: radix.New[[]*pbresource.ID](), - exact: radix.New[[]*pbresource.ID](), - workloadSelectors: make(map[resource.ReferenceKey]*pbcatalog.WorkloadSelector), + prefixes: radix.New[[]controller.Request](), + exact: radix.New[[]controller.Request](), + workloadSelectors: make(map[string]*pbcatalog.WorkloadSelector), } } // MapWorkload will return a slice of controller.Requests with 1 resource for // each resource that selects the specified Workload resource. func (t *WorkloadSelectionTracker) MapWorkload(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - resIds := t.GetIDsForWorkload(res.Id) - - return controller.MakeRequests(nil, resIds), nil -} - -func (t *WorkloadSelectionTracker) GetIDsForWorkload(id *pbresource.ID) []*pbresource.ID { t.lock.Lock() defer t.lock.Unlock() - var result []*pbresource.ID - - workloadTreeKey := treePathFromNameOrPrefix(id.GetTenancy(), id.GetName()) + var reqs []controller.Request // gather the list of all resources that select the specified workload using a prefix match - t.prefixes.WalkPath(workloadTreeKey, func(path string, ids []*pbresource.ID) bool { - result = append(result, ids...) + t.prefixes.WalkPath(res.Id.Name, func(path string, requests []controller.Request) bool { + reqs = append(reqs, requests...) return false }) // gather the list of all resources that select the specified workload using an exact match - exactReqs, _ := t.exact.Get(workloadTreeKey) + exactReqs, _ := t.exact.Get(res.Id.Name) // return the combined list of all resources that select the specified workload - return append(result, exactReqs...) + return append(reqs, exactReqs...), nil } // TrackIDForSelector will associate workloads matching the specified workload @@ -75,8 +64,7 @@ func (t *WorkloadSelectionTracker) TrackIDForSelector(id *pbresource.ID, selecto t.lock.Lock() defer t.lock.Unlock() - ref := resource.NewReferenceKey(id) - if previousSelector, found := t.workloadSelectors[ref]; found { + if previousSelector, found := t.workloadSelectors[id.Name]; found { if stringslice.Equal(previousSelector.Names, selector.Names) && stringslice.Equal(previousSelector.Prefixes, selector.Prefixes) { // the selector is unchanged so do nothing @@ -93,28 +81,24 @@ func (t *WorkloadSelectionTracker) TrackIDForSelector(id *pbresource.ID, selecto // loop over all the exact matching rules and associate those workload names // with the given resource id for _, name := range selector.GetNames() { - key := treePathFromNameOrPrefix(id.GetTenancy(), name) - // lookup any resource id associations for the given workload name - leaf, _ := t.exact.Get(key) + leaf, _ := t.exact.Get(name) // append the ID to the existing request list - t.exact.Insert(key, append(leaf, id)) + t.exact.Insert(name, append(leaf, controller.Request{ID: id})) } // loop over all the prefix matching rules and associate those prefixes // with the given resource id. for _, prefix := range selector.GetPrefixes() { - key := treePathFromNameOrPrefix(id.GetTenancy(), prefix) - // lookup any resource id associations for the given workload name prefix - leaf, _ := t.prefixes.Get(key) + leaf, _ := t.prefixes.Get(prefix) // append the new resource ID to the existing request list - t.prefixes.Insert(key, append(leaf, id)) + t.prefixes.Insert(prefix, append(leaf, controller.Request{ID: id})) } - t.workloadSelectors[ref] = selector + t.workloadSelectors[id.Name] = selector } // UntrackID causes the tracker to stop tracking the given resource ID @@ -124,82 +108,56 @@ func (t *WorkloadSelectionTracker) UntrackID(id *pbresource.ID) { t.untrackID(id) } -// GetSelector returns the currently stored selector for the given ID. -func (t *WorkloadSelectionTracker) GetSelector(id *pbresource.ID) *pbcatalog.WorkloadSelector { - t.lock.Lock() - defer t.lock.Unlock() - - return t.workloadSelectors[resource.NewReferenceKey(id)] -} - // untrackID should be called to stop tracking a resource ID. // This method assumes the lock is already held. Besides modifying // the prefix & name trees to not reference this ID, it will also // delete any corresponding entry within the workloadSelectors map func (t *WorkloadSelectionTracker) untrackID(id *pbresource.ID) { - ref := resource.NewReferenceKey(id) - selector, found := t.workloadSelectors[ref] + selector, found := t.workloadSelectors[id.Name] if !found { return } - exactTreePaths := make([]string, len(selector.GetNames())) - for i, name := range selector.GetNames() { - exactTreePaths[i] = treePathFromNameOrPrefix(id.GetTenancy(), name) - } - - prefixTreePaths := make([]string, len(selector.GetPrefixes())) - for i, prefix := range selector.GetPrefixes() { - prefixTreePaths[i] = treePathFromNameOrPrefix(id.GetTenancy(), prefix) - } - - removeIDFromTreeAtPaths(t.exact, id, exactTreePaths) - removeIDFromTreeAtPaths(t.prefixes, id, prefixTreePaths) + removeIDFromTreeAtPaths(t.exact, id, selector.Names) + removeIDFromTreeAtPaths(t.prefixes, id, selector.Prefixes) // If we don't do this deletion then reinsertion of the id for // tracking in the future could prevent selection criteria from // being properly inserted into the radix trees. - delete(t.workloadSelectors, ref) + delete(t.workloadSelectors, id.Name) } // removeIDFromTree will remove the given resource ID from all leaf nodes in the radix tree. -func removeIDFromTreeAtPaths(t *radix.Tree[[]*pbresource.ID], id *pbresource.ID, paths []string) { +func removeIDFromTreeAtPaths(t *radix.Tree[[]controller.Request], id *pbresource.ID, paths []string) { for _, path := range paths { - ids, _ := t.Get(path) + requests, _ := t.Get(path) foundIdx := -1 - for idx, resID := range ids { - if resource.EqualID(resID, id) { + for idx, req := range requests { + if resource.EqualID(req.ID, id) { foundIdx = idx break } } if foundIdx != -1 { - l := len(ids) - - if foundIdx == l-1 { - ids = ids[:foundIdx] + l := len(requests) + + if l == 1 { + requests = nil + } else if foundIdx == l-1 { + requests = requests[:foundIdx] + } else if foundIdx == 0 { + requests = requests[1:] } else { - ids = slices.Delete(ids, foundIdx, foundIdx+1) + requests = append(requests[:foundIdx], requests[foundIdx+1:]...) } - if len(ids) > 0 { - t.Insert(path, ids) + if len(requests) > 1 { + t.Insert(path, requests) } else { t.Delete(path) } } } } - -// treePathFromNameOrPrefix computes radix tree key from the resource tenancy and a selector name or prefix. -// The keys will be computed in the following form: -// ///. -func treePathFromNameOrPrefix(tenancy *pbresource.Tenancy, nameOrPrefix string) string { - return fmt.Sprintf("%s/%s/%s/%s", - tenancy.GetPartition(), - tenancy.GetPeerName(), - tenancy.GetNamespace(), - nameOrPrefix) -} diff --git a/internal/catalog/internal/mappers/selectiontracker/selection_tracker_test.go b/internal/catalog/internal/mappers/selectiontracker/selection_tracker_test.go new file mode 100644 index 0000000000000..75fa0967c94b3 --- /dev/null +++ b/internal/catalog/internal/mappers/selectiontracker/selection_tracker_test.go @@ -0,0 +1,275 @@ +package selectiontracker + +import ( + "context" + "testing" + + "github.com/hashicorp/consul/internal/catalog/internal/types" + "github.com/hashicorp/consul/internal/controller" + "github.com/hashicorp/consul/internal/radix" + rtest "github.com/hashicorp/consul/internal/resource/resourcetest" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/consul/proto/private/prototest" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +var ( + workloadData = &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + { + Host: "198.18.0.1", + }, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "http": { + Port: 8080, + Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, + }, + }, + } +) + +func TestRemoveIDFromTreeAtPaths(t *testing.T) { + tree := radix.New[[]controller.Request]() + + toRemove := rtest.Resource(types.ServiceEndpointsType, "blah").ID() + other1 := rtest.Resource(types.ServiceEndpointsType, "other1").ID() + other2 := rtest.Resource(types.ServiceEndpointsType, "other1").ID() + + // we are trying to create a tree such that removal of the toRemove id causes a + // few things to happen. + // + // * All the slice modification conditions are executed + // - removal from beginning of the list + // - removal from the end of the list + // - removal of only element in the list + // - removal from middle of the list + // * Paths without matching ids are ignored + + notMatching := []controller.Request{ + {ID: other1}, + {ID: other2}, + } + + matchAtBeginning := []controller.Request{ + {ID: toRemove}, + {ID: other1}, + {ID: other2}, + } + + matchAtEnd := []controller.Request{ + {ID: other1}, + {ID: other2}, + {ID: toRemove}, + } + + matchInMiddle := []controller.Request{ + {ID: other1}, + {ID: toRemove}, + {ID: other2}, + } + + matchOnly := []controller.Request{ + {ID: toRemove}, + } + + tree.Insert("no-match", notMatching) + tree.Insert("match-beginning", matchAtBeginning) + tree.Insert("match-end", matchAtEnd) + tree.Insert("match-middle", matchInMiddle) + tree.Insert("match-only", matchOnly) + + removeIDFromTreeAtPaths(tree, toRemove, []string{ + "no-match", + "match-beginning", + "match-end", + "match-middle", + "match-only", + }) + + reqs, found := tree.Get("no-match") + require.True(t, found) + require.Equal(t, notMatching, reqs) + + reqs, found = tree.Get("match-beginning") + require.True(t, found) + require.Equal(t, notMatching, reqs) + + reqs, found = tree.Get("match-end") + require.True(t, found) + require.Equal(t, notMatching, reqs) + + reqs, found = tree.Get("match-middle") + require.True(t, found) + require.Equal(t, notMatching, reqs) + + // The last tracked request should cause removal from the tree + _, found = tree.Get("match-only") + require.False(t, found) +} + +type selectionTrackerSuite struct { + suite.Suite + + rt controller.Runtime + tracker *WorkloadSelectionTracker + + workloadAPI1 *pbresource.Resource + workloadWeb1 *pbresource.Resource + endpointsFoo *pbresource.ID + endpointsBar *pbresource.ID +} + +func (suite *selectionTrackerSuite) SetupTest() { + suite.tracker = New() + + suite.workloadAPI1 = rtest.Resource(types.WorkloadType, "api-1").WithData(suite.T(), workloadData).Build() + suite.workloadWeb1 = rtest.Resource(types.WorkloadType, "web-1").WithData(suite.T(), workloadData).Build() + suite.endpointsFoo = rtest.Resource(types.ServiceEndpointsType, "foo").ID() + suite.endpointsBar = rtest.Resource(types.ServiceEndpointsType, "bar").ID() +} + +func (suite *selectionTrackerSuite) requireMappedIDs(workload *pbresource.Resource, ids ...*pbresource.ID) { + suite.T().Helper() + + reqs, err := suite.tracker.MapWorkload(context.Background(), suite.rt, workload) + require.NoError(suite.T(), err) + require.Len(suite.T(), reqs, len(ids)) + for _, id := range ids { + prototest.AssertContainsElement(suite.T(), reqs, controller.Request{ID: id}) + } +} + +func (suite *selectionTrackerSuite) TestMapWorkload_Empty() { + // If we aren't tracking anything than the default mapping behavior + // should be to return an empty list of requests. + suite.requireMappedIDs(suite.workloadAPI1) +} + +func (suite *selectionTrackerSuite) TestUntrackID_Empty() { + // this test has no assertions but mainly is here to prove that things + // dont explode if this is attempted. + suite.tracker.UntrackID(suite.endpointsFoo) +} + +func (suite *selectionTrackerSuite) TestTrackAndMap_SingleResource_MultipleWorkloadMappings() { + // This test aims to prove that tracking a resources workload selector and + // then mapping a workload back to that resource works as expected when the + // result set is a single resource. This test will ensure that both prefix + // and exact match criteria are handle correctly and that one resource + // can be mapped from multiple distinct workloads. + + // associate the foo endpoints with some workloads + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Names: []string{"bar", "api", "web-1"}, + Prefixes: []string{"api-"}, + }) + + // Ensure that mappings tracked by prefix work. + suite.requireMappedIDs(suite.workloadAPI1, suite.endpointsFoo) + + // Ensure that mappings tracked by exact match work. + suite.requireMappedIDs(suite.workloadWeb1, suite.endpointsFoo) +} + +func (suite *selectionTrackerSuite) TestTrackAndMap_MultiResource_SingleWorkloadMapping() { + // This test aims to prove that multiple resources selecting of a workload + // will result in multiple requests when mapping that workload. + + // associate the foo endpoints with some workloads + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Prefixes: []string{"api-"}, + }) + + // associate the bar endpoints with some workloads + suite.tracker.TrackIDForSelector(suite.endpointsBar, &pbcatalog.WorkloadSelector{ + Names: []string{"api-1"}, + }) + + // now the mapping should return both endpoints resource ids + suite.requireMappedIDs(suite.workloadAPI1, suite.endpointsFoo, suite.endpointsBar) +} + +func (suite *selectionTrackerSuite) TestDuplicateTracking() { + // This test aims to prove that tracking some ID multiple times doesn't + // result in multiple requests for the same ID + + // associate the foo endpoints with some workloads 3 times without changing + // the selection criteria. The second two times should be no-ops + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Prefixes: []string{"api-"}, + }) + + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Prefixes: []string{"api-"}, + }) + + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Prefixes: []string{"api-"}, + }) + + // regardless of the number of times tracked we should only see a single request + suite.requireMappedIDs(suite.workloadAPI1, suite.endpointsFoo) +} + +func (suite *selectionTrackerSuite) TestModifyTracking() { + // This test aims to prove that modifying selection criteria for a resource + // works as expected. Adding new criteria results in all being tracked. + // Removal of some criteria does't result in removal of all etc. More or + // less we want to ensure that updating selection criteria leaves the + // tracker in a consistent/expected state. + + // track the web-1 workload + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Names: []string{"web-1"}, + }) + + // ensure that api-1 isn't mapped but web-1 is + suite.requireMappedIDs(suite.workloadAPI1) + suite.requireMappedIDs(suite.workloadWeb1, suite.endpointsFoo) + + // now also track the api- prefix + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Names: []string{"web-1"}, + Prefixes: []string{"api-"}, + }) + + // ensure that both workloads are mapped appropriately + suite.requireMappedIDs(suite.workloadAPI1, suite.endpointsFoo) + suite.requireMappedIDs(suite.workloadWeb1, suite.endpointsFoo) + + // now remove the web tracking + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Prefixes: []string{"api-"}, + }) + + // ensure that only api-1 is mapped + suite.requireMappedIDs(suite.workloadAPI1, suite.endpointsFoo) + suite.requireMappedIDs(suite.workloadWeb1) +} + +func (suite *selectionTrackerSuite) TestRemove() { + // This test aims to prove that removal of a resource from tracking + // actually prevents subsequent mapping calls from returning the + // workload. + + // track the web-1 workload + suite.tracker.TrackIDForSelector(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ + Names: []string{"web-1"}, + }) + + // ensure that api-1 isn't mapped but web-1 is + suite.requireMappedIDs(suite.workloadWeb1, suite.endpointsFoo) + + // untrack the resource + suite.tracker.UntrackID(suite.endpointsFoo) + + // ensure that we no longer map the previous workload to the resource + suite.requireMappedIDs(suite.workloadWeb1) +} + +func TestWorkloadSelectionSuite(t *testing.T) { + suite.Run(t, new(selectionTrackerSuite)) +} diff --git a/internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go b/internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go deleted file mode 100644 index 17796a85c59ad..0000000000000 --- a/internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package testhelpers - -import ( - "testing" - - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// WorkloadSelecting denotes a resource type that uses workload selectors. -type WorkloadSelecting interface { - proto.Message - GetWorkloads() *pbcatalog.WorkloadSelector -} - -func RunWorkloadSelectingTypeACLsTests[T WorkloadSelecting](t *testing.T, typ *pbresource.Type, - getData func(selector *pbcatalog.WorkloadSelector) T, - registerFunc func(registry resource.Registry), -) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - registerFunc(registry) - - cases := map[string]resourcetest.ACLTestCase{ - "no rules": { - Rules: ``, - Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), - Typ: typ, - ReadOK: resourcetest.DENY, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test read": { - Rules: `service "test" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write with named selectors and insufficient policy": { - Rules: `service "test" { policy = "write" }`, - Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write with prefixed selectors and insufficient policy": { - Rules: `service "test" { policy = "write" }`, - Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write with named selectors": { - Rules: `service "test" { policy = "write" } service "workload" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "service test write with multiple named selectors": { - Rules: `service "test" { policy = "write" } service "workload1" { policy = "read" } service "workload2" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload1", "workload2"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "service test write with multiple named selectors and insufficient policy": { - Rules: `service "test" { policy = "write" } service "workload1" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload1", "workload2"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write with multiple named selectors and prefixed policy": { - Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload1", "workload2"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "service test write with prefixed selectors": { - Rules: `service "test" { policy = "write" } service_prefix "workload-" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "service test write with prefixed selectors and a policy with more specific prefix than the selector": { - Rules: `service "test" { policy = "write" } service_prefix "workload-" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"wor"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - - "service test write with prefixed selectors and a policy with less specific prefix than the selector": { - Rules: `service "test" { policy = "write" } service_prefix "wor" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - // Prefix-based selectors should not allow writes when a policy only allows - // to read a specific service from that selector. - "service test write with prefixed selectors and a policy with a specific service": { - Rules: `service "test" { policy = "write" } service "workload" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write with multiple prefixed selectors": { - Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-1", "workload-2"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "service test write with multiple prefixed selectors and insufficient policy": { - Rules: `service "test" { policy = "write" } service_prefix "workload-1" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-1", "workload-2"}}), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write with a mix of named and prefixed selectors and insufficient policy": { - Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{ - Prefixes: []string{"workload-1", "workload-2"}, - Names: []string{"other-1", "other-2"}, - }), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write with a mix of named and prefixed selectors and prefixed policy": { - Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" } service_prefix "other" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{ - Prefixes: []string{"workload-1", "workload-2"}, - Names: []string{"other-1", "other-2"}, - }), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "service test write with a mix of named and prefixed selectors and both prefixed and specific policy": { - Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" } service "other-1" { policy = "read" } service "other-2" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{ - Prefixes: []string{"workload-1", "workload-2"}, - Names: []string{"other-1", "other-2"}, - }), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "service test write with a mix of named and prefixed selectors and wildcard service read policy": { - Rules: `service "test" { policy = "write" } service_prefix "" { policy = "read" }`, - Data: getData(&pbcatalog.WorkloadSelector{ - Prefixes: []string{"workload-1", "workload-2"}, - Names: []string{"other-1", "other-2"}, - }), - Typ: typ, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - resourcetest.RunACLTestCase(t, tc, registry) - }) - } -} diff --git a/internal/catalog/internal/types/acl_hooks.go b/internal/catalog/internal/types/acl_hooks.go deleted file mode 100644 index d9ddcb8e93cc1..0000000000000 --- a/internal/catalog/internal/types/acl_hooks.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func aclReadHookResourceWithWorkloadSelector(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), authzContext) -} - -func aclWriteHookResourceWithWorkloadSelector[T WorkloadSelecting](authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, r *resource.DecodedResource[T]) error { - // First check service:write on the name. - err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(r.GetId().GetName(), authzContext) - if err != nil { - return err - } - - // Then also check whether we're allowed to select a service. - for _, name := range r.Data.GetWorkloads().GetNames() { - err = authorizer.ToAllowAuthorizer().ServiceReadAllowed(name, authzContext) - if err != nil { - return err - } - } - - for _, prefix := range r.Data.GetWorkloads().GetPrefixes() { - err = authorizer.ToAllowAuthorizer().ServiceReadPrefixAllowed(prefix, authzContext) - if err != nil { - return err - } - } - - return nil -} - -func ACLHooksForWorkloadSelectingType[T WorkloadSelecting]() *resource.ACLHooks { - return &resource.ACLHooks{ - Read: aclReadHookResourceWithWorkloadSelector, - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookResourceWithWorkloadSelector[T]), - List: resource.NoOpACLListHook, - } -} diff --git a/internal/catalog/internal/types/dns_policy.go b/internal/catalog/internal/types/dns_policy.go index 91dd2615455ca..4c3456027667c 100644 --- a/internal/catalog/internal/types/dns_policy.go +++ b/internal/catalog/internal/types/dns_policy.go @@ -1,36 +1,50 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "math" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/go-multierror" +) - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" +const ( + DNSPolicyKind = "DNSPolicy" ) -type DecodedDNSPolicy = resource.DecodedResource[*pbcatalog.DNSPolicy] +var ( + DNSPolicyV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: DNSPolicyKind, + } + + DNSPolicyType = DNSPolicyV1Alpha1Type +) func RegisterDNSPolicy(r resource.Registry) { r.Register(resource.Registration{ - Type: pbcatalog.DNSPolicyType, + Type: DNSPolicyV1Alpha1Type, Proto: &pbcatalog.DNSPolicy{}, - Scope: resource.ScopeNamespace, Validate: ValidateDNSPolicy, - ACLs: ACLHooksForWorkloadSelectingType[*pbcatalog.DNSPolicy](), }) } -var ValidateDNSPolicy = resource.DecodeAndValidate(validateDNSPolicy) +func ValidateDNSPolicy(res *pbresource.Resource) error { + var policy pbcatalog.DNSPolicy + + if err := res.Data.UnmarshalTo(&policy); err != nil { + return resource.NewErrDataParse(&policy, err) + } -func validateDNSPolicy(res *DecodedDNSPolicy) error { var err error // Ensure that this resource isn't useless and is attempting to // select at least one workload. - if selErr := ValidateSelector(res.Data.Workloads, false); selErr != nil { + if selErr := validateSelector(policy.Workloads, false); selErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, @@ -38,7 +52,7 @@ func validateDNSPolicy(res *DecodedDNSPolicy) error { } // Validate the weights - if weightErr := validateDNSPolicyWeights(res.Data.Weights); weightErr != nil { + if weightErr := validateDNSPolicyWeights(policy.Weights); weightErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "weights", Wrapped: weightErr, diff --git a/internal/catalog/internal/types/dns_policy_test.go b/internal/catalog/internal/types/dns_policy_test.go index 1303d2878cf71..b4c2da3c78aad 100644 --- a/internal/catalog/internal/types/dns_policy_test.go +++ b/internal/catalog/internal/types/dns_policy_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types @@ -7,20 +7,18 @@ import ( "fmt" "testing" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/catalog/internal/testhelpers" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" ) func createDNSPolicyResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { res := &pbresource.Resource{ Id: &pbresource.ID{ - Type: pbcatalog.DNSPolicyType, + Type: DNSPolicyType, Tenancy: &pbresource.Tenancy{ Partition: "default", Namespace: "default", @@ -162,19 +160,3 @@ func TestValidateDNSPolicy_EmptySelector(t *testing.T) { require.ErrorAs(t, err, &actual) require.Equal(t, expected, actual) } - -func TestDNSPolicyACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - RegisterDNSPolicy(registry) - - testhelpers.RunWorkloadSelectingTypeACLsTests[*pbcatalog.DNSPolicy](t, pbcatalog.DNSPolicyType, - func(selector *pbcatalog.WorkloadSelector) *pbcatalog.DNSPolicy { - return &pbcatalog.DNSPolicy{ - Workloads: selector, - Weights: &pbcatalog.Weights{Passing: 1, Warning: 0}, - } - }, - RegisterDNSPolicy, - ) -} diff --git a/internal/catalog/internal/types/errors.go b/internal/catalog/internal/types/errors.go index 3b331a9a6302c..6f0b44c1b3787 100644 --- a/internal/catalog/internal/types/errors.go +++ b/internal/catalog/internal/types/errors.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types diff --git a/internal/catalog/internal/types/errors_test.go b/internal/catalog/internal/types/errors_test.go index 08f227166aa22..7a8157727350c 100644 --- a/internal/catalog/internal/types/errors_test.go +++ b/internal/catalog/internal/types/errors_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types diff --git a/internal/catalog/internal/types/failover_policy.go b/internal/catalog/internal/types/failover_policy.go deleted file mode 100644 index 012150fc046dc..0000000000000 --- a/internal/catalog/internal/types/failover_policy.go +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - - "github.com/hashicorp/go-multierror" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type DecodedFailoverPolicy = resource.DecodedResource[*pbcatalog.FailoverPolicy] - -func RegisterFailoverPolicy(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbcatalog.FailoverPolicyType, - Proto: &pbcatalog.FailoverPolicy{}, - Scope: resource.ScopeNamespace, - Mutate: MutateFailoverPolicy, - Validate: ValidateFailoverPolicy, - ACLs: &resource.ACLHooks{ - Read: aclReadHookFailoverPolicy, - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookFailoverPolicy), - List: resource.NoOpACLListHook, - }, - }) -} - -var MutateFailoverPolicy = resource.DecodeAndMutate(mutateFailoverPolicy) - -func mutateFailoverPolicy(res *DecodedFailoverPolicy) (bool, error) { - changed := false - - // Handle eliding empty configs. - if res.Data.Config != nil && res.Data.Config.IsEmpty() { - res.Data.Config = nil - changed = true - } - - if res.Data.Config != nil { - if mutateFailoverConfig(res.Id.Tenancy, res.Data.Config) { - changed = true - } - } - - for port, pc := range res.Data.PortConfigs { - if pc.IsEmpty() { - delete(res.Data.PortConfigs, port) - changed = true - } else { - if mutateFailoverConfig(res.Id.Tenancy, pc) { - changed = true - } - } - } - if len(res.Data.PortConfigs) == 0 { - res.Data.PortConfigs = nil - changed = true - } - - return changed, nil -} - -func mutateFailoverConfig(policyTenancy *pbresource.Tenancy, config *pbcatalog.FailoverConfig) (changed bool) { - if policyTenancy != nil && !isLocalPeer(policyTenancy.PeerName) { - // TODO(peering/v2): remove this bypass when we know what to do with - // non-local peer references. - return false - } - - for _, dest := range config.Destinations { - if dest.Ref == nil { - continue - } - if dest.Ref.Tenancy != nil && !isLocalPeer(dest.Ref.Tenancy.PeerName) { - // TODO(peering/v2): remove this bypass when we know what to do with - // non-local peer references. - continue - } - - orig := proto.Clone(dest.Ref).(*pbresource.Reference) - resource.DefaultReferenceTenancy( - dest.Ref, - policyTenancy, - resource.DefaultNamespacedTenancy(), // Services are all namespace scoped. - ) - - if !proto.Equal(orig, dest.Ref) { - changed = true - } - } - - return changed -} - -func isLocalPeer(p string) bool { - return p == "local" || p == "" -} - -var ValidateFailoverPolicy = resource.DecodeAndValidate(validateFailoverPolicy) - -func validateFailoverPolicy(res *DecodedFailoverPolicy) error { - var merr error - - if res.Data.Config == nil && len(res.Data.PortConfigs) == 0 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "config", - Wrapped: fmt.Errorf("at least one of config or port_configs must be set"), - }) - } - - if res.Data.Config != nil { - wrapConfigErr := func(err error) error { - return resource.ErrInvalidField{ - Name: "config", - Wrapped: err, - } - } - if cfgErr := validateFailoverConfig(res.Data.Config, false, wrapConfigErr); cfgErr != nil { - merr = multierror.Append(merr, cfgErr) - } - } - - for portName, pc := range res.Data.PortConfigs { - wrapConfigErr := func(err error) error { - return resource.ErrInvalidMapValue{ - Map: "port_configs", - Key: portName, - Wrapped: err, - } - } - if portNameErr := ValidatePortName(portName); portNameErr != nil { - merr = multierror.Append(merr, resource.ErrInvalidMapKey{ - Map: "port_configs", - Key: portName, - Wrapped: portNameErr, - }) - } - - if cfgErr := validateFailoverConfig(pc, true, wrapConfigErr); cfgErr != nil { - merr = multierror.Append(merr, cfgErr) - } - - // TODO: should sameness group be a ref once that's a resource? - } - - return merr -} - -func validateFailoverConfig(config *pbcatalog.FailoverConfig, ported bool, wrapErr func(error) error) error { - var merr error - - if config.SamenessGroup != "" { - // TODO(v2): handle other forms of failover - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "sameness_group", - Wrapped: fmt.Errorf("not supported in this release"), - })) - } - - if len(config.Regions) > 0 { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "regions", - Wrapped: fmt.Errorf("not supported in this release"), - })) - } - - // TODO(peering/v2): remove this bypass when we know what to do with - - if (len(config.Destinations) > 0) == (config.SamenessGroup != "") { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "destinations", - Wrapped: fmt.Errorf("exactly one of destinations or sameness_group should be set"), - })) - } - for i, dest := range config.Destinations { - wrapDestErr := func(err error) error { - return wrapErr(resource.ErrInvalidListElement{ - Name: "destinations", - Index: i, - Wrapped: err, - }) - } - if destErr := validateFailoverPolicyDestination(dest, ported, wrapDestErr); destErr != nil { - merr = multierror.Append(merr, destErr) - } - } - - if config.Mode != pbcatalog.FailoverMode_FAILOVER_MODE_UNSPECIFIED { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "mode", - Wrapped: fmt.Errorf("not supported in this release"), - })) - } - - // TODO(v2): uncomment after this is supported - // switch config.Mode { - // case pbcatalog.FailoverMode_FAILOVER_MODE_UNSPECIFIED: - // // means pbcatalog.FailoverMode_FAILOVER_MODE_SEQUENTIAL - // case pbcatalog.FailoverMode_FAILOVER_MODE_SEQUENTIAL: - // case pbcatalog.FailoverMode_FAILOVER_MODE_ORDER_BY_LOCALITY: - // default: - // merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - // Name: "mode", - // Wrapped: fmt.Errorf("not a supported enum value: %v", config.Mode), - // })) - // } - - // TODO: validate sameness group requirements - - return merr -} - -func validateFailoverPolicyDestination(dest *pbcatalog.FailoverDestination, ported bool, wrapErr func(error) error) error { - var merr error - - wrapRefErr := func(err error) error { - return wrapErr(resource.ErrInvalidField{ - Name: "ref", - Wrapped: err, - }) - } - - if refErr := ValidateLocalServiceRefNoSection(dest.Ref, wrapRefErr); refErr != nil { - merr = multierror.Append(merr, refErr) - } - - // NOTE: Destinations here cannot define ports. Port equality is - // assumed and will be reconciled. - if dest.Port != "" { - if ported { - if portNameErr := ValidatePortName(dest.Port); portNameErr != nil { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "port", - Wrapped: portNameErr, - })) - } - } else { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "port", - Wrapped: fmt.Errorf("ports cannot be specified explicitly for the general failover section since it relies upon port alignment"), - })) - } - } - - hasPeer := false - if dest.Ref != nil { - hasPeer = dest.Ref.Tenancy.PeerName != "" && dest.Ref.Tenancy.PeerName != "local" - } - - if hasPeer && dest.Datacenter != "" { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "datacenter", - Wrapped: fmt.Errorf("ref.tenancy.peer_name and datacenter are mutually exclusive fields"), - })) - } - - return merr -} - -// SimplifyFailoverPolicy fully populates the PortConfigs map and clears the -// Configs map using the provided Service. -func SimplifyFailoverPolicy(svc *pbcatalog.Service, failover *pbcatalog.FailoverPolicy) *pbcatalog.FailoverPolicy { - if failover == nil { - panic("failover is required") - } - if svc == nil { - panic("service is required") - } - - // Copy so we can edit it. - dup := proto.Clone(failover) - failover = dup.(*pbcatalog.FailoverPolicy) - - if failover.PortConfigs == nil { - failover.PortConfigs = make(map[string]*pbcatalog.FailoverConfig) - } - - for _, port := range svc.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - continue // skip - } - - if pc, ok := failover.PortConfigs[port.TargetPort]; ok { - for i, dest := range pc.Destinations { - // Assume port alignment. - if dest.Port == "" { - dest.Port = port.TargetPort - pc.Destinations[i] = dest - } - } - continue - } - - if failover.Config != nil { - // Duplicate because each port will get this uniquely. - pc2 := proto.Clone(failover.Config).(*pbcatalog.FailoverConfig) - for _, dest := range pc2.Destinations { - dest.Port = port.TargetPort - } - failover.PortConfigs[port.TargetPort] = pc2 - } - } - - if failover.Config != nil { - failover.Config = nil - } - - return failover -} - -func aclReadHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - // FailoverPolicy is name-aligned with Service - serviceName := id.Name - - // Check service:read permissions. - return authorizer.ToAllowAuthorizer().ServiceReadAllowed(serviceName, authzContext) -} - -func aclWriteHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *DecodedFailoverPolicy) error { - // FailoverPolicy is name-aligned with Service - serviceName := res.Id.Name - - // Check service:write permissions on the service this is controlling. - if err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(serviceName, authzContext); err != nil { - return err - } - - // Ensure you have service:read on any destination that may be affected by - // traffic FROM this config change. - if res.Data.Config != nil { - for _, dest := range res.Data.Config.Destinations { - destAuthzContext := resource.AuthorizerContext(dest.Ref.GetTenancy()) - destServiceName := dest.Ref.GetName() - if err := authorizer.ToAllowAuthorizer().ServiceReadAllowed(destServiceName, destAuthzContext); err != nil { - return err - } - } - } - for _, pc := range res.Data.PortConfigs { - for _, dest := range pc.Destinations { - destAuthzContext := resource.AuthorizerContext(dest.Ref.GetTenancy()) - destServiceName := dest.Ref.GetName() - if err := authorizer.ToAllowAuthorizer().ServiceReadAllowed(destServiceName, destAuthzContext); err != nil { - return err - } - } - } - - return nil - -} diff --git a/internal/catalog/internal/types/failover_policy_test.go b/internal/catalog/internal/types/failover_policy_test.go deleted file mode 100644 index 5628ed57741cb..0000000000000 --- a/internal/catalog/internal/types/failover_policy_test.go +++ /dev/null @@ -1,849 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestMutateFailoverPolicy(t *testing.T) { - type testcase struct { - policyTenancy *pbresource.Tenancy - failover *pbcatalog.FailoverPolicy - expect *pbcatalog.FailoverPolicy - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithTenancy(tc.policyTenancy). - WithData(t, tc.failover). - Build() - - err := MutateFailoverPolicy(res) - - got := resourcetest.MustDecode[*pbcatalog.FailoverPolicy](t, res) - - if tc.expectErr == "" { - require.NoError(t, err) - prototest.AssertDeepEqual(t, tc.expect, got.Data) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - "empty-1": { - failover: &pbcatalog.FailoverPolicy{}, - expect: &pbcatalog.FailoverPolicy{}, - }, - "empty-config-1": { - failover: &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{}, - }, - expect: &pbcatalog.FailoverPolicy{}, - }, - "empty-config-2": { - failover: &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: make([]*pbcatalog.FailoverDestination, 0), - }, - }, - expect: &pbcatalog.FailoverPolicy{}, - }, - "empty-map-1": { - failover: &pbcatalog.FailoverPolicy{ - PortConfigs: make(map[string]*pbcatalog.FailoverConfig), - }, - expect: &pbcatalog.FailoverPolicy{}, - }, - "empty-map-config-1": { - failover: &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": {}, - }, - }, - expect: &pbcatalog.FailoverPolicy{}, - }, - "empty-map-config-2": { - failover: &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: make([]*pbcatalog.FailoverDestination, 0), - }, - }, - }, - expect: &pbcatalog.FailoverPolicy{}, - }, - "normal": { - failover: &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Mode: pbcatalog.FailoverMode_FAILOVER_MODE_SEQUENTIAL, - Regions: []string{"foo", "bar"}, - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "a")}, - {Ref: newRef(pbcatalog.ServiceType, "b")}, - }, - }, - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "foo")}, - {Ref: newRef(pbcatalog.ServiceType, "bar")}, - }, - }, - "admin": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "y")}, - {Ref: newRef(pbcatalog.ServiceType, "z")}, - }, - }, - }, - }, - expect: &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Mode: pbcatalog.FailoverMode_FAILOVER_MODE_SEQUENTIAL, - Regions: []string{"foo", "bar"}, - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "a")}, - {Ref: newRef(pbcatalog.ServiceType, "b")}, - }, - }, - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "foo")}, - {Ref: newRef(pbcatalog.ServiceType, "bar")}, - }, - }, - "admin": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "y")}, - {Ref: newRef(pbcatalog.ServiceType, "z")}, - }, - }, - }, - }, - }, - "dest ref tenancy defaulting": { - policyTenancy: resourcetest.Tenancy("foo.bar"), - failover: &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Mode: pbcatalog.FailoverMode_FAILOVER_MODE_SEQUENTIAL, - Regions: []string{"foo", "bar"}, - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "", "api")}, - {Ref: newRefWithTenancy(pbcatalog.ServiceType, ".zim", "api")}, - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api")}, - }, - }, - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "", "api")}, - {Ref: newRefWithTenancy(pbcatalog.ServiceType, ".luthor", "api")}, - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "lex.luthor", "api")}, - }, - }, - }, - }, - expect: &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Mode: pbcatalog.FailoverMode_FAILOVER_MODE_SEQUENTIAL, - Regions: []string{"foo", "bar"}, - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api")}, - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "foo.zim", "api")}, - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api")}, - }, - }, - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api")}, - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "foo.luthor", "api")}, - {Ref: newRefWithTenancy(pbcatalog.ServiceType, "lex.luthor", "api")}, - }, - }, - }, - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestValidateFailoverPolicy(t *testing.T) { - type configTestcase struct { - config *pbcatalog.FailoverConfig - expectErr string - } - - type testcase struct { - failover *pbcatalog.FailoverPolicy - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, tc.failover). - Build() - - require.NoError(t, MutateFailoverPolicy(res)) - - // Verify that mutate didn't actually change the object. - got := resourcetest.MustDecode[*pbcatalog.FailoverPolicy](t, res) - prototest.AssertDeepEqual(t, tc.failover, got.Data) - - err := ValidateFailoverPolicy(res) - - // Verify that validate didn't actually change the object. - got = resourcetest.MustDecode[*pbcatalog.FailoverPolicy](t, res) - prototest.AssertDeepEqual(t, tc.failover, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - configCases := map[string]configTestcase{ - "dest with sameness": { - config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api-backup")}, - }, - SamenessGroup: "blah", - }, - // TODO(v2): uncomment after this is supported - // expectErr: `invalid "destinations" field: exactly one of destinations or sameness_group should be set`, - expectErr: `invalid "sameness_group" field: not supported in this release`, - }, - "dest without sameness": { - config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api-backup")}, - }, - }, - }, - "sameness without dest": { - config: &pbcatalog.FailoverConfig{ - SamenessGroup: "blah", - }, - // TODO(v2): remove after this is supported - expectErr: `invalid "sameness_group" field: not supported in this release`, - }, - "regions without dest": { - config: &pbcatalog.FailoverConfig{ - Regions: []string{"us-east1", "us-west2"}, - }, - // TODO(v2): remove after this is supported - expectErr: `invalid "regions" field: not supported in this release`, - }, - "mode without dest": { - config: &pbcatalog.FailoverConfig{ - Mode: pbcatalog.FailoverMode_FAILOVER_MODE_SEQUENTIAL, - }, - // TODO(v2): remove after this is supported - expectErr: `invalid "mode" field: not supported in this release`, - }, - // TODO(v2): uncomment after this is supported - // "mode: invalid": { - // config: &pbcatalog.FailoverConfig{ - // Mode: 99, - // Destinations: []*pbcatalog.FailoverDestination{ - // {Ref: newRef(pbcatalog.ServiceType, "api-backup")}, - // }, - // }, - // expectErr: `invalid "mode" field: not a supported enum value: 99`, - // }, - "dest: no ref": { - config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "ref" field: missing required field`, - }, - "dest: non-service ref": { - config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.WorkloadType, "api-backup")}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "ref" field: invalid "type" field: reference must have type catalog.v2beta1.Service`, - }, - "dest: ref with section": { - config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: resourcetest.Resource(pbcatalog.ServiceType, "api").WithTenancy(resource.DefaultNamespacedTenancy()).Reference("blah")}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "ref" field: invalid "section" field: section cannot be set here`, - }, - // TODO(v2/peering): re-enable when peering can exist - // "dest: ref peer and datacenter": { - // config: &pbcatalog.FailoverConfig{ - // Destinations: []*pbcatalog.FailoverDestination{ - // {Ref: newRefWithPeer(pbcatalog.ServiceType, "api", "peer1"), Datacenter: "dc2"}, - // }, - // }, - // expectErr: `invalid element at index 0 of list "destinations": invalid "datacenter" field: ref.tenancy.peer_name and datacenter are mutually exclusive fields`, - // }, - // TODO(v2/peering): re-enable when peering can exist - // "dest: ref peer without datacenter": { - // config: &pbcatalog.FailoverConfig{ - // Destinations: []*pbcatalog.FailoverDestination{ - // {Ref: newRefWithPeer(pbcatalog.ServiceType, "api", "peer1")}, - // }, - // }, - // }, - "dest: ref datacenter without peer": { - config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api"), Datacenter: "dc2"}, - }, - }, - }, - } - - cases := map[string]testcase{ - // emptiness - "empty": { - failover: &pbcatalog.FailoverPolicy{}, - expectErr: `invalid "config" field: at least one of config or port_configs must be set`, - }, - "non-empty: one port config but no plain config": { - failover: &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api-backup")}, - }, - }, - }, - }, - }, - "non-empty: some plain config but no port configs": { - failover: &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api-backup")}, - }, - }, - }, - }, - // plain config - "plain config: bad dest: any port name": { - failover: &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api-backup"), Port: "web"}, - }, - }, - }, - expectErr: `invalid "config" field: invalid element at index 0 of list "destinations": invalid "port" field: ports cannot be specified explicitly for the general failover section since it relies upon port alignment`, - }, - // ported config - "ported config: bad dest: invalid port name": { - failover: &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api-backup"), Port: "$bad$"}, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid element at index 0 of list "destinations": invalid "port" field: value must match regex: ^[a-z0-9]([a-z0-9\-_]*[a-z0-9])?$`, - }, - "ported config: bad ported in map": { - failover: &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "$bad$": { - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api-backup"), Port: "http"}, - }, - }, - }, - }, - expectErr: `map port_configs contains an invalid key - "$bad$": value must match regex: ^[a-z0-9]([a-z0-9\-_]*[a-z0-9])?$`, - }, - } - - maybeWrap := func(wrapPrefix, base string) string { - if base != "" { - return wrapPrefix + base - } - return "" - } - - for name, tc := range configCases { - cases["plain config: "+name] = testcase{ - failover: &pbcatalog.FailoverPolicy{ - Config: proto.Clone(tc.config).(*pbcatalog.FailoverConfig), - }, - expectErr: maybeWrap(`invalid "config" field: `, tc.expectErr), - } - - cases["ported config: "+name] = testcase{ - failover: &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": proto.Clone(tc.config).(*pbcatalog.FailoverConfig), - }, - }, - expectErr: maybeWrap(`invalid value of key "http" within port_configs: `, tc.expectErr), - } - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestSimplifyFailoverPolicy(t *testing.T) { - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - svc *pbresource.Resource - failover *pbresource.Resource - expect *pbresource.Resource - } - run := func(t *testing.T, tc testcase) { - // Ensure we only use valid inputs. - resourcetest.ValidateAndNormalize(t, registry, tc.svc) - resourcetest.ValidateAndNormalize(t, registry, tc.failover) - resourcetest.ValidateAndNormalize(t, registry, tc.expect) - - svc := resourcetest.MustDecode[*pbcatalog.Service](t, tc.svc) - failover := resourcetest.MustDecode[*pbcatalog.FailoverPolicy](t, tc.failover) - expect := resourcetest.MustDecode[*pbcatalog.FailoverPolicy](t, tc.expect) - - inputFailoverCopy := proto.Clone(failover.Data).(*pbcatalog.FailoverPolicy) - - got := SimplifyFailoverPolicy(svc.Data, failover.Data) - prototest.AssertDeepEqual(t, expect.Data, got) - - // verify input was not altered - prototest.AssertDeepEqual(t, inputFailoverCopy, failover.Data) - } - - newPort := func(name string, virtualPort uint32, protocol pbcatalog.Protocol) *pbcatalog.ServicePort { - return &pbcatalog.ServicePort{ - VirtualPort: virtualPort, - TargetPort: name, - Protocol: protocol, - } - } - - cases := map[string]testcase{ - "implicit with mesh port skipping": { - svc: resourcetest.Resource(pbcatalog.ServiceType, "api"). - WithData(t, &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - newPort("mesh", 21001, pbcatalog.Protocol_PROTOCOL_MESH), - newPort("http", 8080, pbcatalog.Protocol_PROTOCOL_HTTP), - }, - }). - Build(), - failover: resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - }, - }, - }, - }). - Build(), - expect: resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(t, &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - Port: "http", // port defaulted - }, - }, - }, - }, - }). - Build(), - }, - "explicit with port aligned defaulting": { - svc: resourcetest.Resource(pbcatalog.ServiceType, "api"). - WithData(t, &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - newPort("mesh", 9999, pbcatalog.Protocol_PROTOCOL_MESH), - newPort("http", 8080, pbcatalog.Protocol_PROTOCOL_HTTP), - newPort("rest", 8282, pbcatalog.Protocol_PROTOCOL_HTTP2), - }, - }). - Build(), - failover: resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(t, &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - Port: "www", - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - }, - }, - }, - }, - }). - Build(), - expect: resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(t, &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - Port: "www", - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - Port: "http", // port defaulted - }, - }, - }, - }, - }). - Build(), - }, - "implicit port explosion": { - svc: resourcetest.Resource(pbcatalog.ServiceType, "api"). - WithData(t, &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - newPort("http", 8080, pbcatalog.Protocol_PROTOCOL_HTTP), - newPort("rest", 8282, pbcatalog.Protocol_PROTOCOL_HTTP2), - }, - }). - Build(), - failover: resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - }, - }, - }, - }). - Build(), - expect: resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(t, &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - Port: "http", - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - Port: "http", - }, - }, - }, - "rest": { - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - Port: "rest", - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - Port: "rest", - }, - }, - }, - }, - }). - Build(), - }, - "mixed port explosion with skip": { - svc: resourcetest.Resource(pbcatalog.ServiceType, "api"). - WithData(t, &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - newPort("http", 8080, pbcatalog.Protocol_PROTOCOL_HTTP), - newPort("rest", 8282, pbcatalog.Protocol_PROTOCOL_HTTP2), - }, - }). - Build(), - failover: resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - }, - }, - }, - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "rest": { - // TODO(v2): uncomment when this works - // Mode: pbcatalog.FailoverMode_FAILOVER_MODE_ORDER_BY_LOCALITY, - // Regions: []string{"us", "eu"}, - // SamenessGroup: "sameweb", - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - Port: "rest", - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - Port: "rest", - }, - }, - }, - }, - }). - Build(), - expect: resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithData(t, &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - Port: "http", - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - Port: "http", - }, - }, - }, - "rest": { - // TODO(v2): uncomment when this works - // Mode: pbcatalog.FailoverMode_FAILOVER_MODE_ORDER_BY_LOCALITY, - // Regions: []string{"us", "eu"}, - // SamenessGroup: "sameweb", - Destinations: []*pbcatalog.FailoverDestination{ - { - Ref: newRef(pbcatalog.ServiceType, "api-backup"), - Port: "rest", - }, - { - Ref: newRef(pbcatalog.ServiceType, "api-double-backup"), - Port: "rest", - }, - }, - }, - }, - }). - Build(), - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestFailoverPolicyACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - newFailover := func(t *testing.T, name, tenancyStr string, destRefs []*pbresource.Reference) []*pbresource.Resource { - var dr []*pbcatalog.FailoverDestination - for _, destRef := range destRefs { - dr = append(dr, &pbcatalog.FailoverDestination{Ref: destRef}) - } - - res1 := resourcetest.Resource(pbcatalog.FailoverPolicyType, name). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{Destinations: dr}, - }). - Build() - resourcetest.ValidateAndNormalize(t, registry, res1) - - res2 := resourcetest.Resource(pbcatalog.FailoverPolicyType, name). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - WithData(t, &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": {Destinations: dr}, - }, - }). - Build() - resourcetest.ValidateAndNormalize(t, registry, res2) - - return []*pbresource.Resource{res1, res2} - } - - type testcase struct { - res *pbresource.Resource - rules string - check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource) - readOK string - writeOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - serviceRef := func(tenancy, name string) *pbresource.Reference { - return newRefWithTenancy(pbcatalog.ServiceType, tenancy, name) - } - - resOneDest := func(tenancy, destTenancy string) []*pbresource.Resource { - return newFailover(t, "api", tenancy, []*pbresource.Reference{ - serviceRef(destTenancy, "dest1"), - }) - } - - resTwoDests := func(tenancy, destTenancy string) []*pbresource.Resource { - return newFailover(t, "api", tenancy, []*pbresource.Reference{ - serviceRef(destTenancy, "dest1"), - serviceRef(destTenancy, "dest2"), - }) - } - - run := func(t *testing.T, name string, tc resourcetest.ACLTestCase) { - t.Run(name, func(t *testing.T) { - resourcetest.RunACLTestCase(t, tc, registry) - }) - } - - isEnterprise := (structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default") - - serviceRead := func(partition, namespace, name string) string { - if isEnterprise { - return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "read" } } }`, partition, namespace, name) - } - return fmt.Sprintf(` service %q { policy = "read" } `, name) - } - serviceWrite := func(partition, namespace, name string) string { - if isEnterprise { - return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "write" } } }`, partition, namespace, name) - } - return fmt.Sprintf(` service %q { policy = "write" } `, name) - } - - assert := func(t *testing.T, name string, rules string, resList []*pbresource.Resource, readOK, writeOK string) { - for i, res := range resList { - tc := resourcetest.ACLTestCase{ - AuthCtx: resource.AuthorizerContext(res.Id.Tenancy), - Res: res, - Rules: rules, - ReadOK: readOK, - WriteOK: writeOK, - ListOK: DEFAULT, - } - run(t, fmt.Sprintf("%s-%d", name, i), tc) - } - } - - tenancies := []string{"default.default"} - if isEnterprise { - tenancies = append(tenancies, "default.foo", "alpha.default", "alpha.foo") - } - - for _, policyTenancyStr := range tenancies { - t.Run("policy tenancy: "+policyTenancyStr, func(t *testing.T) { - for _, destTenancyStr := range tenancies { - t.Run("dest tenancy: "+destTenancyStr, func(t *testing.T) { - for _, aclTenancyStr := range tenancies { - t.Run("acl tenancy: "+aclTenancyStr, func(t *testing.T) { - aclTenancy := resourcetest.Tenancy(aclTenancyStr) - - maybe := func(match string, parentOnly bool) string { - if policyTenancyStr != aclTenancyStr { - return DENY - } - if !parentOnly && destTenancyStr != aclTenancyStr { - return DENY - } - return match - } - - t.Run("no rules", func(t *testing.T) { - rules := `` - assert(t, "1dest", rules, resOneDest(policyTenancyStr, destTenancyStr), DENY, DENY) - assert(t, "2dests", rules, resTwoDests(policyTenancyStr, destTenancyStr), DENY, DENY) - }) - t.Run("api:read", func(t *testing.T) { - rules := serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "api") - assert(t, "1dest", rules, resOneDest(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) - assert(t, "2dests", rules, resTwoDests(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) - }) - t.Run("api:write", func(t *testing.T) { - rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api") - assert(t, "1dest", rules, resOneDest(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) - assert(t, "2dests", rules, resTwoDests(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) - }) - t.Run("api:write dest1:read", func(t *testing.T) { - rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api") + - serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "dest1") - assert(t, "1dest", rules, resOneDest(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), maybe(ALLOW, false)) - assert(t, "2dests", rules, resTwoDests(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) - }) - }) - } - }) - } - }) - } -} - -func newRef(typ *pbresource.Type, name string) *pbresource.Reference { - return resourcetest.Resource(typ, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") -} - -func newRefWithTenancy(typ *pbresource.Type, tenancyStr, name string) *pbresource.Reference { - return resourcetest.Resource(typ, name). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - Reference("") -} - -func newRefWithPeer(typ *pbresource.Type, name string, peer string) *pbresource.Reference { - ref := newRef(typ, name) - ref.Tenancy.PeerName = peer - return ref -} diff --git a/internal/catalog/internal/types/health_checks.go b/internal/catalog/internal/types/health_checks.go index 3d819e12885aa..7df200ec28eb3 100644 --- a/internal/catalog/internal/types/health_checks.go +++ b/internal/catalog/internal/types/health_checks.go @@ -1,34 +1,48 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/go-multierror" +) - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" +const ( + HealthChecksKind = "HealthChecks" ) -type DecodedHealthChecks = resource.DecodedResource[*pbcatalog.HealthChecks] +var ( + HealthChecksV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: HealthChecksKind, + } + + HealthChecksType = HealthChecksV1Alpha1Type +) func RegisterHealthChecks(r resource.Registry) { r.Register(resource.Registration{ - Type: pbcatalog.HealthChecksType, + Type: HealthChecksV1Alpha1Type, Proto: &pbcatalog.HealthChecks{}, - Scope: resource.ScopeNamespace, Validate: ValidateHealthChecks, - ACLs: ACLHooksForWorkloadSelectingType[*pbcatalog.HealthChecks](), }) } -var ValidateHealthChecks = resource.DecodeAndValidate(validateHealthChecks) +func ValidateHealthChecks(res *pbresource.Resource) error { + var checks pbcatalog.HealthChecks + + if err := res.Data.UnmarshalTo(&checks); err != nil { + return resource.NewErrDataParse(&checks, err) + } -func validateHealthChecks(res *DecodedHealthChecks) error { var err error // Validate the workload selector - if selErr := ValidateSelector(res.Data.Workloads, false); selErr != nil { + if selErr := validateSelector(checks.Workloads, false); selErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, @@ -36,7 +50,7 @@ func validateHealthChecks(res *DecodedHealthChecks) error { } // Validate each check - for idx, check := range res.Data.HealthChecks { + for idx, check := range checks.HealthChecks { if checkErr := validateCheck(check); checkErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "checks", diff --git a/internal/catalog/internal/types/health_checks_test.go b/internal/catalog/internal/types/health_checks_test.go index c9cdf01ae84cf..12c13d3c1a228 100644 --- a/internal/catalog/internal/types/health_checks_test.go +++ b/internal/catalog/internal/types/health_checks_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types @@ -7,21 +7,19 @@ import ( "testing" "time" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/durationpb" - - "github.com/hashicorp/consul/internal/catalog/internal/testhelpers" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" ) func createHealthChecksResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { res := &pbresource.Resource{ Id: &pbresource.ID{ - Type: pbcatalog.HealthChecksType, + Type: HealthChecksType, Tenancy: &pbresource.Tenancy{ Partition: "default", Namespace: "default", @@ -197,12 +195,3 @@ func TestValidateHealthChecks_EmptySelector(t *testing.T) { require.ErrorAs(t, err, &actual) require.Equal(t, expected, actual) } - -func TestHealthChecksACLs(t *testing.T) { - testhelpers.RunWorkloadSelectingTypeACLsTests[*pbcatalog.HealthChecks](t, pbcatalog.HealthChecksType, - func(selector *pbcatalog.WorkloadSelector) *pbcatalog.HealthChecks { - return &pbcatalog.HealthChecks{Workloads: selector} - }, - RegisterHealthChecks, - ) -} diff --git a/internal/catalog/internal/types/health_status.go b/internal/catalog/internal/types/health_status.go index c5ea7e106fa3b..5e5a659475d8c 100644 --- a/internal/catalog/internal/types/health_status.go +++ b/internal/catalog/internal/types/health_status.go @@ -1,49 +1,57 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/go-multierror" ) -type DecodedHealthStatus = resource.DecodedResource[*pbcatalog.HealthStatus] +const ( + HealthStatusKind = "HealthStatus" +) + +var ( + HealthStatusV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: HealthStatusKind, + } + + HealthStatusType = HealthStatusV1Alpha1Type +) func RegisterHealthStatus(r resource.Registry) { r.Register(resource.Registration{ - Type: pbcatalog.HealthStatusType, + Type: HealthStatusV1Alpha1Type, Proto: &pbcatalog.HealthStatus{}, - Scope: resource.ScopeNamespace, Validate: ValidateHealthStatus, - ACLs: &resource.ACLHooks{ - Read: resource.AuthorizeReadWithResource(aclReadHookHealthStatus), - Write: aclWriteHookHealthStatus, - List: resource.NoOpACLListHook, - }, }) } -var ValidateHealthStatus = resource.DecodeAndValidate(validateHealthStatus) +func ValidateHealthStatus(res *pbresource.Resource) error { + var hs pbcatalog.HealthStatus + + if err := res.Data.UnmarshalTo(&hs); err != nil { + return resource.NewErrDataParse(&hs, err) + } -func validateHealthStatus(res *DecodedHealthStatus) error { var err error // Should we allow empty types? I think for now it will be safest to require // the type field is set and we can relax this restriction in the future // if we deem it desirable. - if res.Data.Type == "" { + if hs.Type == "" { err = multierror.Append(err, resource.ErrInvalidField{ Name: "type", Wrapped: resource.ErrMissing, }) } - switch res.Data.Status { + switch hs.Status { case pbcatalog.Health_HEALTH_PASSING, pbcatalog.Health_HEALTH_WARNING, pbcatalog.Health_HEALTH_CRITICAL, @@ -59,42 +67,14 @@ func validateHealthStatus(res *DecodedHealthStatus) error { // owner is currently the resource that this HealthStatus applies to. If we // change this to be a parent reference within the HealthStatus.Data then // we could allow for other owners. - if res.Resource.Owner == nil { + if res.Owner == nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "owner", Wrapped: resource.ErrMissing, }) - } else if !resource.EqualType(res.Owner.Type, pbcatalog.WorkloadType) && !resource.EqualType(res.Owner.Type, pbcatalog.NodeType) { + } else if !resource.EqualType(res.Owner.Type, WorkloadType) && !resource.EqualType(res.Owner.Type, NodeType) { err = multierror.Append(err, resource.ErrOwnerTypeInvalid{ResourceType: res.Id.Type, OwnerType: res.Owner.Type}) } return err } - -func aclReadHookHealthStatus(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - // For a health status of a workload we need to check service:read perms. - if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.WorkloadType) { - return authorizer.ToAllowAuthorizer().ServiceReadAllowed(res.GetOwner().GetName(), authzContext) - } - - // For a health status of a node we need to check node:read perms. - if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.NodeType) { - return authorizer.ToAllowAuthorizer().NodeReadAllowed(res.GetOwner().GetName(), authzContext) - } - - return acl.PermissionDenied("cannot read catalog.HealthStatus because there is no owner") -} - -func aclWriteHookHealthStatus(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - // For a health status of a workload we need to check service:write perms. - if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.WorkloadType) { - return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(res.GetOwner().GetName(), authzContext) - } - - // For a health status of a node we need to check node:write perms. - if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.NodeType) { - return authorizer.ToAllowAuthorizer().NodeWriteAllowed(res.GetOwner().GetName(), authzContext) - } - - return acl.PermissionDenied("cannot write catalog.HealthStatus because there is no owner") -} diff --git a/internal/catalog/internal/types/health_status_test.go b/internal/catalog/internal/types/health_status_test.go index 9482e4770e40a..be9d30d501151 100644 --- a/internal/catalog/internal/types/health_status_test.go +++ b/internal/catalog/internal/types/health_status_test.go @@ -1,19 +1,17 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "testing" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" ) var ( @@ -24,7 +22,7 @@ var ( } defaultHealthStatusOwner = &pbresource.ID{ - Type: pbcatalog.WorkloadType, + Type: WorkloadType, Tenancy: defaultHealthStatusOwnerTenancy, Name: "foo", } @@ -33,7 +31,7 @@ var ( func createHealthStatusResource(t *testing.T, data protoreflect.ProtoMessage, owner *pbresource.ID) *pbresource.Resource { res := &pbresource.Resource{ Id: &pbresource.ID{ - Type: pbcatalog.HealthStatusType, + Type: HealthStatusType, Tenancy: &pbresource.Tenancy{ Partition: "default", Namespace: "default", @@ -65,14 +63,14 @@ func TestValidateHealthStatus_Ok(t *testing.T) { cases := map[string]testCase{ "workload-owned": { owner: &pbresource.ID{ - Type: pbcatalog.WorkloadType, + Type: WorkloadType, Tenancy: defaultHealthStatusOwnerTenancy, Name: "foo-workload", }, }, "node-owned": { owner: &pbresource.ID{ - Type: pbcatalog.NodeType, + Type: NodeType, Tenancy: defaultHealthStatusOwnerTenancy, Name: "bar-node", }, @@ -173,8 +171,8 @@ func TestValidateHealthStatus_InvalidOwner(t *testing.T) { owner: &pbresource.ID{ Type: &pbresource.Type{ Group: "fake", - GroupVersion: pbcatalog.Version, - Kind: pbcatalog.WorkloadKind, + GroupVersion: CurrentVersion, + Kind: WorkloadKind, }, Tenancy: defaultHealthStatusOwnerTenancy, Name: "baz", @@ -183,9 +181,9 @@ func TestValidateHealthStatus_InvalidOwner(t *testing.T) { "group-version-mismatch": { owner: &pbresource.ID{ Type: &pbresource.Type{ - Group: pbcatalog.GroupName, + Group: GroupName, GroupVersion: "v99", - Kind: pbcatalog.WorkloadKind, + Kind: WorkloadKind, }, Tenancy: defaultHealthStatusOwnerTenancy, Name: "baz", @@ -193,7 +191,7 @@ func TestValidateHealthStatus_InvalidOwner(t *testing.T) { }, "kind-mismatch": { owner: &pbresource.ID{ - Type: pbcatalog.ServiceType, + Type: ServiceType, Tenancy: defaultHealthStatusOwnerTenancy, Name: "baz", }, @@ -206,7 +204,7 @@ func TestValidateHealthStatus_InvalidOwner(t *testing.T) { err := ValidateHealthStatus(res) require.Error(t, err) expected := resource.ErrOwnerTypeInvalid{ - ResourceType: pbcatalog.HealthStatusType, + ResourceType: HealthStatusType, OwnerType: tcase.owner.Type, } var actual resource.ErrOwnerTypeInvalid @@ -215,106 +213,3 @@ func TestValidateHealthStatus_InvalidOwner(t *testing.T) { }) } } - -func TestHealthStatusACLs(t *testing.T) { - registry := resource.NewRegistry() - Register(registry) - - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test").ID() - node := resourcetest.Resource(pbcatalog.NodeType, "test").ID() - - healthStatusData := &pbcatalog.HealthStatus{ - Type: "tcp", - Status: pbcatalog.Health_HEALTH_PASSING, - } - - cases := map[string]resourcetest.ACLTestCase{ - "no rules": { - Rules: ``, - Data: healthStatusData, - Owner: workload, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.DENY, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test read": { - Rules: `service "test" { policy = "read" }`, - Data: healthStatusData, - Owner: workload, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write": { - Rules: `service "test" { policy = "write" }`, - Data: healthStatusData, - Owner: workload, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "service test read with node owner": { - Rules: `service "test" { policy = "read" }`, - Data: healthStatusData, - Owner: node, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.DENY, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "service test write with node owner": { - Rules: `service "test" { policy = "write" }`, - Data: healthStatusData, - Owner: node, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.DENY, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "node test read with node owner": { - Rules: `node "test" { policy = "read" }`, - Data: healthStatusData, - Owner: node, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "node test write with node owner": { - Rules: `node "test" { policy = "write" }`, - Data: healthStatusData, - Owner: node, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - "node test read with workload owner": { - Rules: `node "test" { policy = "read" }`, - Data: healthStatusData, - Owner: workload, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.DENY, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "node test write with workload owner": { - Rules: `node "test" { policy = "write" }`, - Data: healthStatusData, - Owner: workload, - Typ: pbcatalog.HealthStatusType, - ReadOK: resourcetest.DENY, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - resourcetest.RunACLTestCase(t, tc, registry) - }) - } -} diff --git a/internal/catalog/internal/types/node.go b/internal/catalog/internal/types/node.go index 1ee68f22ca82e..0d2c795abaa5c 100644 --- a/internal/catalog/internal/types/node.go +++ b/internal/catalog/internal/types/node.go @@ -1,44 +1,47 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/go-multierror" ) -type DecodedNode = resource.DecodedResource[*pbcatalog.Node] +const ( + NodeKind = "Node" +) + +var ( + NodeV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: NodeKind, + } + + NodeType = NodeV1Alpha1Type +) func RegisterNode(r resource.Registry) { r.Register(resource.Registration{ - Type: pbcatalog.NodeType, - Proto: &pbcatalog.Node{}, - // TODO: A node should be partition scoped. However its HealthStatus which is - // namespace scoped has Node as an owner. We do not support ownership between resources - // of differing scope at this time. HealthStatus will probably be split out into two different - // types, one for namespace scoped owners and the other for partition scoped owners. - // Until that time, Node will remain namespace scoped. - Scope: resource.ScopeNamespace, + Type: NodeV1Alpha1Type, + Proto: &pbcatalog.Node{}, Validate: ValidateNode, - ACLs: &resource.ACLHooks{ - Read: aclReadHookNode, - Write: aclWriteHookNode, - List: resource.NoOpACLListHook, - }, }) } -var ValidateNode = resource.DecodeAndValidate(validateNode) +func ValidateNode(res *pbresource.Resource) error { + var node pbcatalog.Node + + if err := res.Data.UnmarshalTo(&node); err != nil { + return resource.NewErrDataParse(&node, err) + } -func validateNode(res *DecodedNode) error { var err error // Validate that the node has at least 1 address - if len(res.Data.Addresses) < 1 { + if len(node.Addresses) < 1 { err = multierror.Append(err, resource.ErrInvalidField{ Name: "addresses", Wrapped: resource.ErrEmpty, @@ -46,7 +49,7 @@ func validateNode(res *DecodedNode) error { } // Validate each node address - for idx, addr := range res.Data.Addresses { + for idx, addr := range node.Addresses { if addrErr := validateNodeAddress(addr); addrErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "addresses", @@ -84,11 +87,3 @@ func validateNodeAddress(addr *pbcatalog.NodeAddress) error { return nil } - -func aclReadHookNode(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().NodeReadAllowed(id.GetName(), authzContext) -} - -func aclWriteHookNode(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().NodeWriteAllowed(res.GetId().GetName(), authzContext) -} diff --git a/internal/catalog/internal/types/node_test.go b/internal/catalog/internal/types/node_test.go index 5a678745e3a3b..93e5ecea329a2 100644 --- a/internal/catalog/internal/types/node_test.go +++ b/internal/catalog/internal/types/node_test.go @@ -1,25 +1,23 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "testing" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" ) func createNodeResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { res := &pbresource.Resource{ Id: &pbresource.ID{ - Type: pbcatalog.NodeType, + Type: NodeType, Tenancy: &pbresource.Tenancy{ Partition: "default", Namespace: "default", @@ -128,48 +126,3 @@ func TestValidateNode_AddressMissingHost(t *testing.T) { require.ErrorAs(t, err, &actual) require.Equal(t, expected, actual) } - -func TestNodeACLs(t *testing.T) { - registry := resource.NewRegistry() - Register(registry) - - nodeData := &pbcatalog.Node{ - Addresses: []*pbcatalog.NodeAddress{ - { - Host: "1.1.1.1", - }, - }, - } - cases := map[string]resourcetest.ACLTestCase{ - "no rules": { - Rules: ``, - Data: nodeData, - Typ: pbcatalog.NodeType, - ReadOK: resourcetest.DENY, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "node test read": { - Rules: `node "test" { policy = "read" }`, - Data: nodeData, - Typ: pbcatalog.NodeType, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.DENY, - ListOK: resourcetest.DEFAULT, - }, - "node test write": { - Rules: `node "test" { policy = "write" }`, - Data: nodeData, - Typ: pbcatalog.NodeType, - ReadOK: resourcetest.ALLOW, - WriteOK: resourcetest.ALLOW, - ListOK: resourcetest.DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - resourcetest.RunACLTestCase(t, tc, registry) - }) - } -} diff --git a/internal/catalog/internal/types/service.go b/internal/catalog/internal/types/service.go index bb56fe10a5710..27e13530e5f3f 100644 --- a/internal/catalog/internal/types/service.go +++ b/internal/catalog/internal/types/service.go @@ -1,49 +1,46 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "math" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/go-multierror" +) - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" +const ( + ServiceKind = "Service" ) -type DecodedService = resource.DecodedResource[*pbcatalog.Service] +var ( + ServiceV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: ServiceKind, + } + + ServiceType = ServiceV1Alpha1Type +) func RegisterService(r resource.Registry) { r.Register(resource.Registration{ - Type: pbcatalog.ServiceType, + Type: ServiceV1Alpha1Type, Proto: &pbcatalog.Service{}, - Scope: resource.ScopeNamespace, Validate: ValidateService, - Mutate: MutateService, - ACLs: ACLHooksForWorkloadSelectingType[*pbcatalog.Service](), }) } -var MutateService = resource.DecodeAndMutate(mutateService) - -func mutateService(res *DecodedService) (bool, error) { - changed := false +func ValidateService(res *pbresource.Resource) error { + var service pbcatalog.Service - // Default service port protocols. - for _, port := range res.Data.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { - port.Protocol = pbcatalog.Protocol_PROTOCOL_TCP - changed = true - } + if err := res.Data.UnmarshalTo(&service); err != nil { + return resource.NewErrDataParse(&service, err) } - return changed, nil -} - -var ValidateService = resource.DecodeAndValidate(validateService) - -func validateService(res *DecodedService) error { var err error // Validate the workload selector. We are allowing selectors with no @@ -51,7 +48,7 @@ func validateService(res *DecodedService) error { // ServiceEndpoints objects for this service such as when desiring to // configure endpoint information for external services that are not // registered as workloads - if selErr := ValidateSelector(res.Data.Workloads, true); selErr != nil { + if selErr := validateSelector(service.Workloads, true); selErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, @@ -61,7 +58,7 @@ func validateService(res *DecodedService) error { usedVirtualPorts := make(map[uint32]int) // Validate each port - for idx, port := range res.Data.Ports { + for idx, port := range service.Ports { if usedIdx, found := usedVirtualPorts[port.VirtualPort]; found { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "ports", @@ -79,7 +76,7 @@ func validateService(res *DecodedService) error { } // validate the target port - if nameErr := ValidatePortName(port.TargetPort); nameErr != nil { + if nameErr := validatePortName(port.TargetPort); nameErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "ports", Index: idx, @@ -90,17 +87,6 @@ func validateService(res *DecodedService) error { }) } - if protoErr := ValidateProtocol(port.Protocol); protoErr != nil { - err = multierror.Append(err, resource.ErrInvalidListElement{ - Name: "ports", - Index: idx, - Wrapped: resource.ErrInvalidField{ - Name: "protocol", - Wrapped: protoErr, - }, - }) - } - // validate the virtual port is within the allowed range - 0 is allowed // to signify that no virtual port should be used and the port will not // be available for transparent proxying within the mesh. @@ -119,7 +105,7 @@ func validateService(res *DecodedService) error { } // Validate that the Virtual IPs are all IP addresses - for idx, vip := range res.Data.VirtualIps { + for idx, vip := range service.VirtualIps { if vipErr := validateIPAddress(vip); vipErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "virtual_ips", diff --git a/internal/catalog/internal/types/service_endpoints.go b/internal/catalog/internal/types/service_endpoints.go index b78a1bc705fa5..8c3d1cf109561 100644 --- a/internal/catalog/internal/types/service_endpoints.go +++ b/internal/catalog/internal/types/service_endpoints.go @@ -1,66 +1,59 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "math" - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/go-multierror" +) + +const ( + ServiceEndpointsKind = "ServiceEndpoints" ) -type DecodedServiceEndpoints = resource.DecodedResource[*pbcatalog.ServiceEndpoints] +var ( + ServiceEndpointsV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: ServiceEndpointsKind, + } + + ServiceEndpointsType = ServiceEndpointsV1Alpha1Type +) func RegisterServiceEndpoints(r resource.Registry) { r.Register(resource.Registration{ - Type: pbcatalog.ServiceEndpointsType, + Type: ServiceEndpointsV1Alpha1Type, Proto: &pbcatalog.ServiceEndpoints{}, - Scope: resource.ScopeNamespace, Validate: ValidateServiceEndpoints, Mutate: MutateServiceEndpoints, - ACLs: &resource.ACLHooks{ - Read: func(authorizer acl.Authorizer, context *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), context) - }, - Write: func(authorizer acl.Authorizer, context *acl.AuthorizerContext, p *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(p.GetId().GetName(), context) - }, - List: resource.NoOpACLListHook, - }, }) } func MutateServiceEndpoints(res *pbresource.Resource) error { if res.Owner == nil { res.Owner = &pbresource.ID{ - Type: pbcatalog.ServiceType, + Type: ServiceV1Alpha1Type, Tenancy: res.Id.Tenancy, Name: res.Id.Name, } } - return nil -} - -var ValidateServiceEndpoints = resource.DecodeAndValidate[*pbcatalog.ServiceEndpoints](validateServiceEndpoints) - -func validateServiceEndpoints(res *DecodedServiceEndpoints) error { var err error - if !resource.EqualType(res.Owner.Type, pbcatalog.ServiceType) { + if !resource.EqualType(res.Owner.Type, ServiceV1Alpha1Type) { err = multierror.Append(err, resource.ErrOwnerTypeInvalid{ - ResourceType: pbcatalog.ServiceEndpointsType, + ResourceType: ServiceEndpointsV1Alpha1Type, OwnerType: res.Owner.Type, }) } if !resource.EqualTenancy(res.Owner.Tenancy, res.Id.Tenancy) { err = multierror.Append(err, resource.ErrOwnerTenantInvalid{ - ResourceType: pbcatalog.ServiceEndpointsType, ResourceTenancy: res.Id.Tenancy, OwnerTenancy: res.Owner.Tenancy, }) @@ -76,8 +69,19 @@ func validateServiceEndpoints(res *DecodedServiceEndpoints) error { }) } - for idx, endpoint := range res.Data.Endpoints { - if endpointErr := validateEndpoint(endpoint, res.Resource); endpointErr != nil { + return err +} + +func ValidateServiceEndpoints(res *pbresource.Resource) error { + var svcEndpoints pbcatalog.ServiceEndpoints + + if err := res.Data.UnmarshalTo(&svcEndpoints); err != nil { + return resource.NewErrDataParse(&svcEndpoints, err) + } + + var err error + for idx, endpoint := range svcEndpoints.Endpoints { + if endpointErr := validateEndpoint(endpoint, res); endpointErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "endpoints", Index: idx, @@ -97,7 +101,7 @@ func validateEndpoint(endpoint *pbcatalog.Endpoint, res *pbresource.Resource) er // corresponding workloads that Consul has knowledge of. if endpoint.TargetRef != nil { // Validate the target reference - if refErr := validateReference(pbcatalog.WorkloadType, res.Id.GetTenancy(), endpoint.TargetRef); refErr != nil { + if refErr := validateReference(WorkloadType, res.Id.GetTenancy(), endpoint.TargetRef); refErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "target_ref", Wrapped: refErr, @@ -124,17 +128,10 @@ func validateEndpoint(endpoint *pbcatalog.Endpoint, res *pbresource.Resource) er }) } - if healthErr := validateHealth(endpoint.HealthStatus); healthErr != nil { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "health_status", - Wrapped: healthErr, - }) - } - // Validate the endpoints ports for portName, port := range endpoint.Ports { // Port names must be DNS labels - if portNameErr := ValidatePortName(portName); portNameErr != nil { + if portNameErr := validatePortName(portName); portNameErr != nil { err = multierror.Append(err, resource.ErrInvalidMapKey{ Map: "ports", Key: portName, @@ -142,17 +139,6 @@ func validateEndpoint(endpoint *pbcatalog.Endpoint, res *pbresource.Resource) er }) } - if protoErr := ValidateProtocol(port.Protocol); protoErr != nil { - err = multierror.Append(err, resource.ErrInvalidMapValue{ - Map: "ports", - Key: portName, - Wrapped: resource.ErrInvalidField{ - Name: "protocol", - Wrapped: protoErr, - }, - }) - } - // As the physical port is the real port the endpoint will be bound to // it must be in the standard 1-65535 range. if port.Port < 1 || port.Port > math.MaxUint16 { @@ -160,7 +146,7 @@ func validateEndpoint(endpoint *pbcatalog.Endpoint, res *pbresource.Resource) er Map: "ports", Key: portName, Wrapped: resource.ErrInvalidField{ - Name: "physical_port", + Name: "phsical_port", Wrapped: errInvalidPhysicalPort, }, }) diff --git a/internal/catalog/internal/types/service_endpoints_test.go b/internal/catalog/internal/types/service_endpoints_test.go index 7a298e3979491..bd902d6246838 100644 --- a/internal/catalog/internal/types/service_endpoints_test.go +++ b/internal/catalog/internal/types/service_endpoints_test.go @@ -1,17 +1,17 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "testing" - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/types/known/anypb" ) var ( @@ -20,20 +20,29 @@ var ( Namespace: "default", PeerName: "local", } +) - badEndpointTenancy = &pbresource.Tenancy{ - Partition: "default", - Namespace: "bad", - PeerName: "local", +func createServiceEndpointsResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { + res := &pbresource.Resource{ + Id: &pbresource.ID{ + Type: ServiceEndpointsType, + Tenancy: defaultEndpointTenancy, + Name: "test-service", + }, } -) + + var err error + res.Data, err = anypb.New(data) + require.NoError(t, err) + return res +} func TestValidateServiceEndpoints_Ok(t *testing.T) { data := &pbcatalog.ServiceEndpoints{ Endpoints: []*pbcatalog.Endpoint{ { TargetRef: &pbresource.ID{ - Type: pbcatalog.WorkloadType, + Type: WorkloadType, Tenancy: defaultEndpointTenancy, Name: "foo", }, @@ -53,15 +62,8 @@ func TestValidateServiceEndpoints_Ok(t *testing.T) { }, } - res := rtest.Resource(pbcatalog.ServiceEndpointsType, "test-service"). - WithTenancy(defaultEndpointTenancy). - WithData(t, data). - Build() - - // fill in owner automatically - require.NoError(t, MutateServiceEndpoints(res)) + res := createServiceEndpointsResource(t, data) - // Now validate that everything is good. err := ValidateServiceEndpoints(res) require.NoError(t, err) } @@ -71,7 +73,7 @@ func TestValidateServiceEndpoints_ParseError(t *testing.T) { // to cause the error we are expecting data := &pbcatalog.IP{Address: "198.18.0.1"} - res := rtest.Resource(pbcatalog.ServiceEndpointsType, "test-service").WithData(t, data).Build() + res := createServiceEndpointsResource(t, data) err := ValidateServiceEndpoints(res) require.Error(t, err) @@ -82,7 +84,7 @@ func TestValidateServiceEndpoints_EndpointInvalid(t *testing.T) { genData := func() *pbcatalog.Endpoint { return &pbcatalog.Endpoint{ TargetRef: &pbresource.ID{ - Type: pbcatalog.WorkloadType, + Type: WorkloadType, Tenancy: defaultEndpointTenancy, Name: "foo", }, @@ -102,7 +104,6 @@ func TestValidateServiceEndpoints_EndpointInvalid(t *testing.T) { } type testCase struct { - owner *pbresource.ID modify func(*pbcatalog.Endpoint) validateErr func(t *testing.T, err error) } @@ -110,10 +111,10 @@ func TestValidateServiceEndpoints_EndpointInvalid(t *testing.T) { cases := map[string]testCase{ "invalid-target": { modify: func(endpoint *pbcatalog.Endpoint) { - endpoint.TargetRef.Type = pbcatalog.NodeType + endpoint.TargetRef.Type = NodeType }, validateErr: func(t *testing.T, err error) { - require.ErrorIs(t, err, resource.ErrInvalidReferenceType{AllowedType: pbcatalog.WorkloadType}) + require.ErrorIs(t, err, resource.ErrInvalidReferenceType{AllowedType: WorkloadType}) }, }, "invalid-address": { @@ -132,20 +133,6 @@ func TestValidateServiceEndpoints_EndpointInvalid(t *testing.T) { require.ErrorIs(t, err, resource.ErrEmpty) }, }, - "invalid-health-status": { - modify: func(endpoint *pbcatalog.Endpoint) { - endpoint.Ports["foo"] = &pbcatalog.WorkloadPort{ - Port: 42, - } - endpoint.HealthStatus = 99 - }, - validateErr: func(t *testing.T, err error) { - rtest.RequireError(t, err, resource.ErrInvalidField{ - Name: "health_status", - Wrapped: resource.NewConstError("not a supported enum value: 99"), - }) - }, - }, "invalid-port-name": { modify: func(endpoint *pbcatalog.Endpoint) { endpoint.Ports[""] = &pbcatalog.WorkloadPort{ @@ -153,29 +140,11 @@ func TestValidateServiceEndpoints_EndpointInvalid(t *testing.T) { } }, validateErr: func(t *testing.T, err error) { - rtest.RequireError(t, err, resource.ErrInvalidMapKey{ - Map: "ports", - Key: "", - Wrapped: resource.ErrEmpty, - }) - }, - }, - "invalid-port-protocol": { - modify: func(endpoint *pbcatalog.Endpoint) { - endpoint.Ports["foo"] = &pbcatalog.WorkloadPort{ - Port: 42, - Protocol: 99, - } - }, - validateErr: func(t *testing.T, err error) { - rtest.RequireError(t, err, resource.ErrInvalidMapValue{ - Map: "ports", - Key: "foo", - Wrapped: resource.ErrInvalidField{ - Name: "protocol", - Wrapped: resource.NewConstError("not a supported enum value: 99"), - }, - }) + var mapErr resource.ErrInvalidMapKey + require.ErrorAs(t, err, &mapErr) + require.Equal(t, "ports", mapErr.Map) + require.Equal(t, "", mapErr.Key) + require.Equal(t, resource.ErrEmpty, mapErr.Wrapped) }, }, "port-0": { @@ -194,51 +163,18 @@ func TestValidateServiceEndpoints_EndpointInvalid(t *testing.T) { require.ErrorIs(t, err, errInvalidPhysicalPort) }, }, - "invalid-owner": { - owner: &pbresource.ID{ - Type: pbcatalog.DNSPolicyType, - Tenancy: badEndpointTenancy, - Name: "wrong", - }, - validateErr: func(t *testing.T, err error) { - rtest.RequireError(t, err, resource.ErrOwnerTypeInvalid{ - ResourceType: pbcatalog.ServiceEndpointsType, - OwnerType: pbcatalog.DNSPolicyType}) - rtest.RequireError(t, err, resource.ErrOwnerTenantInvalid{ - ResourceType: pbcatalog.ServiceEndpointsType, - ResourceTenancy: defaultEndpointTenancy, - OwnerTenancy: badEndpointTenancy, - }) - rtest.RequireError(t, err, resource.ErrInvalidField{ - Name: "name", - Wrapped: errInvalidEndpointsOwnerName{ - Name: "test-service", - OwnerName: "wrong"}, - }) - }, - }, } for name, tcase := range cases { t.Run(name, func(t *testing.T) { - endpoint := genData() - if tcase.modify != nil { - tcase.modify(endpoint) - } + data := genData() + tcase.modify(data) - data := &pbcatalog.ServiceEndpoints{ + res := createServiceEndpointsResource(t, &pbcatalog.ServiceEndpoints{ Endpoints: []*pbcatalog.Endpoint{ - endpoint, + data, }, - } - res := rtest.Resource(pbcatalog.ServiceEndpointsType, "test-service"). - WithTenancy(defaultEndpointTenancy). - WithOwner(tcase.owner). - WithData(t, data). - Build() - - // Run the mututation to setup defaults - require.NoError(t, MutateServiceEndpoints(res)) + }) err := ValidateServiceEndpoints(res) require.Error(t, err) @@ -246,59 +182,3 @@ func TestValidateServiceEndpoints_EndpointInvalid(t *testing.T) { }) } } - -func TestMutateServiceEndpoints_PopulateOwner(t *testing.T) { - res := rtest.Resource(pbcatalog.ServiceEndpointsType, "test-service"). - WithTenancy(defaultEndpointTenancy). - Build() - - require.NoError(t, MutateServiceEndpoints(res)) - require.NotNil(t, res.Owner) - require.True(t, resource.EqualType(res.Owner.Type, pbcatalog.ServiceType)) - require.True(t, resource.EqualTenancy(res.Owner.Tenancy, defaultEndpointTenancy)) - require.Equal(t, res.Owner.Name, res.Id.Name) -} - -func TestServiceEndpointsACLs(t *testing.T) { - registry := resource.NewRegistry() - Register(registry) - - service := rtest.Resource(pbcatalog.ServiceType, "test"). - WithTenancy(resource.DefaultNamespacedTenancy()).ID() - serviceEndpointsData := &pbcatalog.ServiceEndpoints{} - cases := map[string]rtest.ACLTestCase{ - "no rules": { - Rules: ``, - Data: serviceEndpointsData, - Owner: service, - Typ: pbcatalog.ServiceEndpointsType, - ReadOK: rtest.DENY, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test read": { - Rules: `service "test" { policy = "read" }`, - Data: serviceEndpointsData, - Owner: service, - Typ: pbcatalog.ServiceEndpointsType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test write": { - Rules: `service "test" { policy = "write" }`, - Data: serviceEndpointsData, - Owner: service, - Typ: pbcatalog.ServiceEndpointsType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.ALLOW, - ListOK: rtest.DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - rtest.RunACLTestCase(t, tc, registry) - }) - } -} diff --git a/internal/catalog/internal/types/service_test.go b/internal/catalog/internal/types/service_test.go index 18649dda9a0a5..1a0a035d91613 100644 --- a/internal/catalog/internal/types/service_test.go +++ b/internal/catalog/internal/types/service_test.go @@ -1,26 +1,23 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "testing" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/catalog/internal/testhelpers" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" ) func createServiceResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { res := &pbresource.Resource{ Id: &pbresource.ID{ - Type: pbcatalog.ServiceType, + Type: ServiceType, Tenancy: &pbresource.Tenancy{ Partition: "default", Namespace: "default", @@ -36,38 +33,6 @@ func createServiceResource(t *testing.T, data protoreflect.ProtoMessage) *pbreso return res } -func TestMutateServicePorts(t *testing.T) { - data := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo", "bar"}, - }, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_UNSPECIFIED, - }, - { - TargetPort: "http", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - VirtualIps: []string{"198.18.0.1"}, - } - - res := createServiceResource(t, data) - - err := MutateService(res) - require.NoError(t, err) - - got := resourcetest.MustDecode[*pbcatalog.Service](t, res) - - require.Len(t, got.Data.Ports, 2) - require.Equal(t, pbcatalog.Protocol_PROTOCOL_TCP, got.Data.Ports[0].Protocol) - - // Check that specified protocol is not mutated. - require.Equal(t, data.Ports[1].Protocol, got.Data.Ports[1].Protocol) -} - func TestValidateService_Ok(t *testing.T) { data := &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{ @@ -206,37 +171,6 @@ func TestValidateService_VirtualPortReused(t *testing.T) { require.EqualValues(t, 42, actual.Value) } -func TestValidateService_InvalidPortProtocol(t *testing.T) { - data := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{""}, - }, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "foo", - Protocol: 99, - }, - }, - } - - res := createServiceResource(t, data) - - err := ValidateService(res) - - expected := resource.ErrInvalidListElement{ - Name: "ports", - Index: 0, - Wrapped: resource.ErrInvalidField{ - Name: "protocol", - Wrapped: resource.NewConstError("not a supported enum value: 99"), - }, - } - - var actual resource.ErrInvalidListElement - require.ErrorAs(t, err, &actual) - require.Equal(t, expected, actual) -} - func TestValidateService_VirtualPortInvalid(t *testing.T) { data := &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{ @@ -276,12 +210,3 @@ func TestValidateService_InvalidVIP(t *testing.T) { require.Error(t, err) require.ErrorIs(t, err, errNotIPAddress) } - -func TestServiceACLs(t *testing.T) { - testhelpers.RunWorkloadSelectingTypeACLsTests[*pbcatalog.Service](t, pbcatalog.ServiceType, - func(selector *pbcatalog.WorkloadSelector) *pbcatalog.Service { - return &pbcatalog.Service{Workloads: selector} - }, - RegisterService, - ) -} diff --git a/internal/catalog/internal/types/types.go b/internal/catalog/internal/types/types.go index 15ed6b148de76..6ab3730bb2936 100644 --- a/internal/catalog/internal/types/types.go +++ b/internal/catalog/internal/types/types.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types @@ -7,16 +7,19 @@ import ( "github.com/hashicorp/consul/internal/resource" ) +const ( + GroupName = "catalog" + VersionV1Alpha1 = "v1alpha1" + CurrentVersion = VersionV1Alpha1 +) + func Register(r resource.Registry) { RegisterWorkload(r) RegisterService(r) RegisterServiceEndpoints(r) RegisterNode(r) RegisterHealthStatus(r) - RegisterFailoverPolicy(r) - - // todo (v2): re-register once these resources are implemented. - //RegisterHealthChecks(r) - //RegisterDNSPolicy(r) - //RegisterVirtualIPs(r) + RegisterHealthChecks(r) + RegisterDNSPolicy(r) + RegisterVirtualIPs(r) } diff --git a/internal/catalog/internal/types/types_test.go b/internal/catalog/internal/types/types_test.go index 4facd921c368d..d40fc42dd07ca 100644 --- a/internal/catalog/internal/types/types_test.go +++ b/internal/catalog/internal/types/types_test.go @@ -1,16 +1,14 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "testing" - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/stretchr/testify/require" ) func TestTypeRegistration(t *testing.T) { @@ -19,15 +17,14 @@ func TestTypeRegistration(t *testing.T) { // are correct as that would amount more or less to hardcoding structs // from types.go a second time here. requiredKinds := []string{ - pbcatalog.WorkloadKind, - pbcatalog.ServiceKind, - pbcatalog.ServiceEndpointsKind, - pbcatalog.NodeKind, - pbcatalog.HealthStatusKind, - // todo (ishustava): uncomment once we implement these - //pbcatalog.HealthChecksKind, - //pbcatalog.DNSPolicyKind, - //pbcatalog.VirtualIPsKind, + WorkloadKind, + ServiceKind, + ServiceEndpointsKind, + VirtualIPsKind, + NodeKind, + HealthStatusKind, + HealthChecksKind, + DNSPolicyKind, } r := resource.NewRegistry() @@ -36,8 +33,8 @@ func TestTypeRegistration(t *testing.T) { for _, kind := range requiredKinds { t.Run(kind, func(t *testing.T) { registration, ok := r.Resolve(&pbresource.Type{ - Group: pbcatalog.GroupName, - GroupVersion: pbcatalog.Version, + Group: GroupName, + GroupVersion: CurrentVersion, Kind: kind, }) diff --git a/internal/catalog/internal/types/validators.go b/internal/catalog/internal/types/validators.go index 07dfbd3569676..e9fc08562784b 100644 --- a/internal/catalog/internal/types/validators.go +++ b/internal/catalog/internal/types/validators.go @@ -1,21 +1,18 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( - "errors" - "fmt" "net" "regexp" "strings" - "github.com/hashicorp/go-multierror" - "google.golang.org/protobuf/proto" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/go-multierror" + "google.golang.org/protobuf/proto" ) const ( @@ -56,7 +53,7 @@ func isValidDNSLabel(label string) bool { return dnsLabelMatcher.Match([]byte(label)) } -func IsValidUnixSocketPath(host string) bool { +func isValidUnixSocketPath(host string) bool { if len(host) > maxUnixSocketPathLen || !strings.HasPrefix(host, "unix://") || strings.Contains(host, "\000") { return false } @@ -71,14 +68,14 @@ func validateWorkloadHost(host string) error { } // Check if the host represents an IP address, unix socket path or a DNS name - if !isValidIPAddress(host) && !IsValidUnixSocketPath(host) && !isValidDNSName(host) { + if !isValidIPAddress(host) && !isValidUnixSocketPath(host) && !isValidDNSName(host) { return errInvalidWorkloadHostFormat{Host: host} } return nil } -func ValidateSelector(sel *pbcatalog.WorkloadSelector, allowEmpty bool) error { +func validateSelector(sel *pbcatalog.WorkloadSelector, allowEmpty bool) error { if sel == nil { if allowEmpty { return nil @@ -88,20 +85,14 @@ func ValidateSelector(sel *pbcatalog.WorkloadSelector, allowEmpty bool) error { } if len(sel.Names) == 0 && len(sel.Prefixes) == 0 { - if !allowEmpty { - return resource.ErrEmpty + if allowEmpty { + return nil } - if sel.Filter != "" { - return resource.ErrInvalidField{ - Name: "filter", - Wrapped: errors.New("filter cannot be set unless there is a name or prefix selector"), - } - } - return nil + return resource.ErrEmpty } - var merr error + var err error // Validate that all the exact match names are non-empty. This is // mostly for the sake of not admitting values that should always @@ -109,7 +100,7 @@ func ValidateSelector(sel *pbcatalog.WorkloadSelector, allowEmpty bool) error { // This is because workloads must have non-empty names. for idx, name := range sel.Names { if name == "" { - merr = multierror.Append(merr, resource.ErrInvalidListElement{ + err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "names", Index: idx, Wrapped: resource.ErrEmpty, @@ -117,14 +108,7 @@ func ValidateSelector(sel *pbcatalog.WorkloadSelector, allowEmpty bool) error { } } - if err := resource.ValidateMetadataFilter(sel.GetFilter()); err != nil { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "filter", - Wrapped: err, - }) - } - - return merr + return err } func validateIPAddress(ip string) error { @@ -139,7 +123,7 @@ func validateIPAddress(ip string) error { return nil } -func ValidatePortName(name string) error { +func validatePortName(name string) error { if name == "" { return resource.ErrEmpty } @@ -151,22 +135,6 @@ func ValidatePortName(name string) error { return nil } -func ValidateProtocol(protocol pbcatalog.Protocol) error { - // enumcover:pbcatalog.Protocol - switch protocol { - case pbcatalog.Protocol_PROTOCOL_UNSPECIFIED, - // means pbcatalog.FailoverMode_FAILOVER_MODE_TCP - pbcatalog.Protocol_PROTOCOL_TCP, - pbcatalog.Protocol_PROTOCOL_HTTP, - pbcatalog.Protocol_PROTOCOL_HTTP2, - pbcatalog.Protocol_PROTOCOL_GRPC, - pbcatalog.Protocol_PROTOCOL_MESH: - return nil - default: - return resource.NewConstError(fmt.Sprintf("not a supported enum value: %v", protocol)) - } -} - // validateWorkloadAddress will validate the WorkloadAddress type. This involves validating // the Host within the workload address and the ports references. For ports references we // ensure that values in the addresses ports array are present in the set of map keys. @@ -185,7 +153,7 @@ func validateWorkloadAddress(addr *pbcatalog.WorkloadAddress, ports map[string]* // Ensure that unix sockets reference exactly 1 port. They may also indirectly reference 1 port // by the workload having only a single port and omitting any explicit port assignment. - if IsValidUnixSocketPath(addr.Host) && + if isValidUnixSocketPath(addr.Host) && (len(addr.Ports) > 1 || (len(addr.Ports) == 0 && len(ports) > 1)) { err = multierror.Append(err, errUnixSocketMultiport) } @@ -239,95 +207,3 @@ func validateReference(allowedType *pbresource.Type, allowedTenancy *pbresource. return err } - -func validateHealth(health pbcatalog.Health) error { - // enumcover:pbcatalog.Health - switch health { - case pbcatalog.Health_HEALTH_ANY, - pbcatalog.Health_HEALTH_PASSING, - pbcatalog.Health_HEALTH_WARNING, - pbcatalog.Health_HEALTH_CRITICAL, - pbcatalog.Health_HEALTH_MAINTENANCE: - return nil - default: - return resource.NewConstError(fmt.Sprintf("not a supported enum value: %v", health)) - } -} - -// ValidateLocalServiceRefNoSection ensures the following: -// -// - ref is non-nil -// - type is ServiceType -// - section is empty -// - tenancy is set and partition/namespace are both non-empty -// - peer_name must be "local" -// -// Each possible validation error is wrapped in the wrapErr function before -// being collected in a multierror.Error. -func ValidateLocalServiceRefNoSection(ref *pbresource.Reference, wrapErr func(error) error) error { - if ref == nil { - return wrapErr(resource.ErrMissing) - } - - if !resource.EqualType(ref.Type, pbcatalog.ServiceType) { - return wrapErr(resource.ErrInvalidField{ - Name: "type", - Wrapped: resource.ErrInvalidReferenceType{ - AllowedType: pbcatalog.ServiceType, - }, - }) - } - - var merr error - if ref.Section != "" { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "section", - Wrapped: errors.New("section cannot be set here"), - })) - } - - if ref.Tenancy == nil { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "tenancy", - Wrapped: resource.ErrMissing, - })) - } else { - // NOTE: these are Service specific, since that's a Namespace-scoped type. - if ref.Tenancy.Partition == "" { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "tenancy", - Wrapped: resource.ErrInvalidField{ - Name: "partition", - Wrapped: resource.ErrEmpty, - }, - })) - } - if ref.Tenancy.Namespace == "" { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "tenancy", - Wrapped: resource.ErrInvalidField{ - Name: "namespace", - Wrapped: resource.ErrEmpty, - }, - })) - } - if ref.Tenancy.PeerName != "local" { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "tenancy", - Wrapped: resource.ErrInvalidField{ - Name: "peer_name", - Wrapped: errors.New(`must be set to "local"`), - }, - })) - } - } - - if ref.Name == "" { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "name", - Wrapped: resource.ErrMissing, - })) - } - - return merr -} diff --git a/internal/catalog/internal/types/validators_test.go b/internal/catalog/internal/types/validators_test.go index 7a334727a998c..cd3a12c5c0740 100644 --- a/internal/catalog/internal/types/validators_test.go +++ b/internal/catalog/internal/types/validators_test.go @@ -1,20 +1,18 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( - "errors" "fmt" "strings" "testing" - "github.com/hashicorp/go-multierror" - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/go-multierror" + "github.com/stretchr/testify/require" ) func TestIsValidDNSLabel(t *testing.T) { @@ -178,7 +176,7 @@ func TestIsValidUnixSocketPath(t *testing.T) { for name, tcase := range cases { t.Run(name, func(t *testing.T) { - require.Equal(t, tcase.valid, IsValidUnixSocketPath(tcase.name)) + require.Equal(t, tcase.valid, isValidUnixSocketPath(tcase.name)) }) } } @@ -282,49 +280,11 @@ func TestValidateSelector(t *testing.T) { }, }, }, - "filter-with-empty-query": { - selector: &pbcatalog.WorkloadSelector{ - Filter: "garbage.value == zzz", - }, - allowEmpty: true, - err: resource.ErrInvalidField{ - Name: "filter", - Wrapped: errors.New( - `filter cannot be set unless there is a name or prefix selector`, - ), - }, - }, - "bad-filter": { - selector: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo", "bar"}, - Filter: "garbage.value == zzz", - }, - allowEmpty: false, - err: &multierror.Error{ - Errors: []error{ - resource.ErrInvalidField{ - Name: "filter", - Wrapped: fmt.Errorf( - `filter "garbage.value == zzz" is invalid: %w`, - errors.New(`Selector "garbage" is not valid`), - ), - }, - }, - }, - }, - "good-filter": { - selector: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo", "bar"}, - Filter: "metadata.zone == west1", - }, - allowEmpty: false, - err: nil, - }, } for name, tcase := range cases { t.Run(name, func(t *testing.T) { - err := ValidateSelector(tcase.selector, tcase.allowEmpty) + err := validateSelector(tcase.selector, tcase.allowEmpty) if tcase.err == nil { require.NoError(t, err) } else { @@ -361,15 +321,15 @@ func TestValidatePortName(t *testing.T) { // test for the isValidDNSLabel function. t.Run("empty", func(t *testing.T) { - require.Equal(t, resource.ErrEmpty, ValidatePortName("")) + require.Equal(t, resource.ErrEmpty, validatePortName("")) }) t.Run("invalid", func(t *testing.T) { - require.Equal(t, errNotDNSLabel, ValidatePortName("foo.com")) + require.Equal(t, errNotDNSLabel, validatePortName("foo.com")) }) t.Run("ok", func(t *testing.T) { - require.NoError(t, ValidatePortName("http")) + require.NoError(t, validatePortName("http")) }) } @@ -585,7 +545,7 @@ func TestValidateReference(t *testing.T) { PeerName: "local", } - allowedType := pbcatalog.WorkloadType + allowedType := WorkloadType type testCase struct { check *pbresource.ID @@ -602,7 +562,7 @@ func TestValidateReference(t *testing.T) { }, "type-err": { check: &pbresource.ID{ - Type: pbcatalog.NodeType, + Type: NodeType, Tenancy: allowedTenancy, Name: "foo", }, diff --git a/internal/catalog/internal/types/virtual_ips.go b/internal/catalog/internal/types/virtual_ips.go index be692f63ed65a..a27f08df0a77e 100644 --- a/internal/catalog/internal/types/virtual_ips.go +++ b/internal/catalog/internal/types/virtual_ips.go @@ -1,42 +1,46 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/go-multierror" +) + +const ( + VirtualIPsKind = "VirtualIPs" ) -type DecodedVirtualIPs = resource.DecodedResource[*pbcatalog.VirtualIPs] +var ( + VirtualIPsV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: VirtualIPsKind, + } + + VirtualIPsType = VirtualIPsV1Alpha1Type +) func RegisterVirtualIPs(r resource.Registry) { r.Register(resource.Registration{ - Type: pbcatalog.VirtualIPsType, + Type: VirtualIPsV1Alpha1Type, Proto: &pbcatalog.VirtualIPs{}, - Scope: resource.ScopeNamespace, Validate: ValidateVirtualIPs, - ACLs: &resource.ACLHooks{ - Read: func(authorizer acl.Authorizer, context *acl.AuthorizerContext, id *pbresource.ID, p *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), context) - }, - Write: func(authorizer acl.Authorizer, context *acl.AuthorizerContext, p *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(p.GetId().GetName(), context) - }, - List: resource.NoOpACLListHook, - }, }) } -var ValidateVirtualIPs = resource.DecodeAndValidate(validateVirtualIPs) +func ValidateVirtualIPs(res *pbresource.Resource) error { + var vips pbcatalog.VirtualIPs + + if err := res.Data.UnmarshalTo(&vips); err != nil { + return resource.NewErrDataParse(&vips, err) + } -func validateVirtualIPs(res *DecodedVirtualIPs) error { var err error - for idx, ip := range res.Data.Ips { + for idx, ip := range vips.Ips { if vipErr := validateIPAddress(ip.Address); vipErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "ips", diff --git a/internal/catalog/internal/types/virtual_ips_test.go b/internal/catalog/internal/types/virtual_ips_test.go index 0107e1cfd94fa..76d55e7ecd745 100644 --- a/internal/catalog/internal/types/virtual_ips_test.go +++ b/internal/catalog/internal/types/virtual_ips_test.go @@ -1,25 +1,23 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "testing" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" ) func createVirtualIPsResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { res := &pbresource.Resource{ Id: &pbresource.ID{ - Type: pbcatalog.VirtualIPsType, + Type: VirtualIPsType, Tenancy: &pbresource.Tenancy{ Partition: "default", Namespace: "default", @@ -82,47 +80,3 @@ func TestValidateVirtualIPs_InvalidIP(t *testing.T) { require.Error(t, err) require.ErrorIs(t, err, errNotIPAddress) } - -func TestVirtualIPsACLs(t *testing.T) { - registry := resource.NewRegistry() - RegisterVirtualIPs(registry) - - service := rtest.Resource(pbcatalog.ServiceType, "test"). - WithTenancy(resource.DefaultNamespacedTenancy()).ID() - virtualIPsData := &pbcatalog.VirtualIPs{} - cases := map[string]rtest.ACLTestCase{ - "no rules": { - Rules: ``, - Data: virtualIPsData, - Owner: service, - Typ: pbcatalog.VirtualIPsType, - ReadOK: rtest.DENY, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test read": { - Rules: `service "test" { policy = "read" }`, - Data: virtualIPsData, - Owner: service, - Typ: pbcatalog.VirtualIPsType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test write": { - Rules: `service "test" { policy = "write" }`, - Data: virtualIPsData, - Owner: service, - Typ: pbcatalog.VirtualIPsType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.ALLOW, - ListOK: rtest.DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - rtest.RunACLTestCase(t, tc, registry) - }) - } -} diff --git a/internal/catalog/internal/types/workload.go b/internal/catalog/internal/types/workload.go index 8535a6250491d..a0dc7142d1e09 100644 --- a/internal/catalog/internal/types/workload.go +++ b/internal/catalog/internal/types/workload.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types @@ -7,37 +7,45 @@ import ( "math" "sort" - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/go-multierror" ) -type DecodedWorkload = resource.DecodedResource[*pbcatalog.Workload] +const ( + WorkloadKind = "Workload" +) + +var ( + WorkloadV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: WorkloadKind, + } + + WorkloadType = WorkloadV1Alpha1Type +) func RegisterWorkload(r resource.Registry) { r.Register(resource.Registration{ - Type: pbcatalog.WorkloadType, + Type: WorkloadV1Alpha1Type, Proto: &pbcatalog.Workload{}, - Scope: resource.ScopeNamespace, Validate: ValidateWorkload, - ACLs: &resource.ACLHooks{ - Read: aclReadHookWorkload, - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookWorkload), - List: resource.NoOpACLListHook, - }, }) } -var ValidateWorkload = resource.DecodeAndValidate(validateWorkload) +func ValidateWorkload(res *pbresource.Resource) error { + var workload pbcatalog.Workload + + if err := res.Data.UnmarshalTo(&workload); err != nil { + return resource.NewErrDataParse(&workload, err) + } -func validateWorkload(res *DecodedWorkload) error { var err error // Validate that the workload has at least one port - if len(res.Data.Ports) < 1 { + if len(workload.Ports) < 1 { err = multierror.Append(err, resource.ErrInvalidField{ Name: "ports", Wrapped: resource.ErrEmpty, @@ -47,8 +55,8 @@ func validateWorkload(res *DecodedWorkload) error { var meshPorts []string // Validate the Workload Ports - for portName, port := range res.Data.Ports { - if portNameErr := ValidatePortName(portName); portNameErr != nil { + for portName, port := range workload.Ports { + if portNameErr := validatePortName(portName); portNameErr != nil { err = multierror.Append(err, resource.ErrInvalidMapKey{ Map: "ports", Key: portName, @@ -68,17 +76,6 @@ func validateWorkload(res *DecodedWorkload) error { }) } - if protoErr := ValidateProtocol(port.Protocol); protoErr != nil { - err = multierror.Append(err, resource.ErrInvalidMapValue{ - Map: "ports", - Key: portName, - Wrapped: resource.ErrInvalidField{ - Name: "protocol", - Wrapped: protoErr, - }, - }) - } - // Collect the list of mesh ports if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { meshPorts = append(meshPorts, portName) @@ -98,12 +95,12 @@ func validateWorkload(res *DecodedWorkload) error { // If the workload is mesh enabled then a valid identity must be provided. // If not mesh enabled but a non-empty identity is provided then we still // validate that its valid. - if len(meshPorts) > 0 && res.Data.Identity == "" { + if len(meshPorts) > 0 && workload.Identity == "" { err = multierror.Append(err, resource.ErrInvalidField{ Name: "identity", Wrapped: resource.ErrMissing, }) - } else if res.Data.Identity != "" && !isValidDNSLabel(res.Data.Identity) { + } else if workload.Identity != "" && !isValidDNSLabel(workload.Identity) { err = multierror.Append(err, resource.ErrInvalidField{ Name: "identity", Wrapped: errNotDNSLabel, @@ -111,7 +108,7 @@ func validateWorkload(res *DecodedWorkload) error { } // Validate workload locality - if res.Data.Locality != nil && res.Data.Locality.Region == "" && res.Data.Locality.Zone != "" { + if workload.Locality != nil && workload.Locality.Region == "" && workload.Locality.Zone != "" { err = multierror.Append(err, resource.ErrInvalidField{ Name: "locality", Wrapped: errLocalityZoneNoRegion, @@ -120,8 +117,8 @@ func validateWorkload(res *DecodedWorkload) error { // Node associations are optional but if present the name should // be a valid DNS label. - if res.Data.NodeName != "" { - if !isValidDNSLabel(res.Data.NodeName) { + if workload.NodeName != "" { + if !isValidDNSLabel(workload.NodeName) { err = multierror.Append(err, resource.ErrInvalidField{ Name: "node_name", Wrapped: errNotDNSLabel, @@ -129,7 +126,7 @@ func validateWorkload(res *DecodedWorkload) error { } } - if len(res.Data.Addresses) < 1 { + if len(workload.Addresses) < 1 { err = multierror.Append(err, resource.ErrInvalidField{ Name: "addresses", Wrapped: resource.ErrEmpty, @@ -137,8 +134,8 @@ func validateWorkload(res *DecodedWorkload) error { } // Validate Workload Addresses - for idx, addr := range res.Data.Addresses { - if addrErr := validateWorkloadAddress(addr, res.Data.Ports); addrErr != nil { + for idx, addr := range workload.Addresses { + if addrErr := validateWorkloadAddress(addr, workload.Ports); addrErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "addresses", Index: idx, @@ -149,27 +146,3 @@ func validateWorkload(res *DecodedWorkload) error { return err } - -func aclReadHookWorkload(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), authzContext) -} - -func aclWriteHookWorkload(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *DecodedWorkload) error { - // First check service:write on the workload name. - err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(res.GetId().GetName(), authzContext) - if err != nil { - return err - } - - // Check node:read permissions if node is specified. - if res.Data.GetNodeName() != "" { - return authorizer.ToAllowAuthorizer().NodeReadAllowed(res.Data.GetNodeName(), authzContext) - } - - // Check identity:read permissions if identity is specified. - if res.Data.GetIdentity() != "" { - return authorizer.ToAllowAuthorizer().IdentityReadAllowed(res.Data.GetIdentity(), authzContext) - } - - return nil -} diff --git a/internal/catalog/internal/types/workload_selecting.go b/internal/catalog/internal/types/workload_selecting.go deleted file mode 100644 index 6d129bfaa693e..0000000000000 --- a/internal/catalog/internal/types/workload_selecting.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "google.golang.org/protobuf/proto" - - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" -) - -// WorkloadSelecting denotes a resource type that uses workload selectors. -type WorkloadSelecting interface { - proto.Message - GetWorkloads() *pbcatalog.WorkloadSelector -} diff --git a/internal/catalog/internal/types/workload_test.go b/internal/catalog/internal/types/workload_test.go index 1c7f7b825594e..03662472f2254 100644 --- a/internal/catalog/internal/types/workload_test.go +++ b/internal/catalog/internal/types/workload_test.go @@ -1,25 +1,23 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "testing" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" ) func createWorkloadResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { res := &pbresource.Resource{ Id: &pbresource.ID{ - Type: pbcatalog.WorkloadType, + Type: WorkloadType, Tenancy: &pbresource.Tenancy{ Partition: "default", Namespace: "default", @@ -229,30 +227,6 @@ func TestValidateWorkload_InvalidPortName(t *testing.T) { require.Equal(t, expected, actual) } -func TestValidateWorkload_InvalidPortProtocol(t *testing.T) { - data := validWorkload() - data.Ports["foo"] = &pbcatalog.WorkloadPort{ - Port: 42, - Protocol: 99, - } - - res := createWorkloadResource(t, data) - - err := ValidateWorkload(res) - require.Error(t, err) - expected := resource.ErrInvalidMapValue{ - Map: "ports", - Key: "foo", - Wrapped: resource.ErrInvalidField{ - Name: "protocol", - Wrapped: resource.NewConstError("not a supported enum value: 99"), - }, - } - var actual resource.ErrInvalidMapValue - require.ErrorAs(t, err, &actual) - require.Equal(t, expected, actual) -} - func TestValidateWorkload_Port0(t *testing.T) { data := validWorkload() data.Ports["bar"] = &pbcatalog.WorkloadPort{Port: 0} @@ -305,160 +279,3 @@ func TestValidateWorkload_Locality(t *testing.T) { require.ErrorAs(t, err, &actual) require.Equal(t, expected, actual) } - -func TestWorkloadACLs(t *testing.T) { - registry := resource.NewRegistry() - Register(registry) - - cases := map[string]rtest.ACLTestCase{ - "no rules": { - Rules: ``, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.DENY, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test read": { - Rules: `service "test" { policy = "read" }`, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test write": { - Rules: `service "test" { policy = "write" }`, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.ALLOW, - ListOK: rtest.DEFAULT, - }, - "service test write with node": { - Rules: `service "test" { policy = "write" }`, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - NodeName: "test-node", - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test write with workload identity": { - Rules: `service "test" { policy = "write" }`, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - Identity: "test-identity", - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test write with workload identity and node": { - Rules: `service "test" { policy = "write" }`, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - NodeName: "test-node", - Identity: "test-identity", - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.DENY, - ListOK: rtest.DEFAULT, - }, - "service test write with node and node policy": { - Rules: `service "test" { policy = "write" } node "test-node" { policy = "read" }`, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - NodeName: "test-node", - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.ALLOW, - ListOK: rtest.DEFAULT, - }, - "service test write with workload identity and identity policy ": { - Rules: `service "test" { policy = "write" } identity "test-identity" { policy = "read" }`, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - Identity: "test-identity", - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.ALLOW, - ListOK: rtest.DEFAULT, - }, - "service test write with workload identity and node with both node and identity policy": { - Rules: `service "test" { policy = "write" } identity "test-identity" { policy = "read" } node "test-node" { policy = "read" }`, - Data: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - NodeName: "test-node", - Identity: "test-identity", - }, - Typ: pbcatalog.WorkloadType, - ReadOK: rtest.ALLOW, - WriteOK: rtest.ALLOW, - ListOK: rtest.DEFAULT, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - rtest.RunACLTestCase(t, tc, registry) - }) - } -} diff --git a/internal/controller/api.go b/internal/controller/api.go index 5c2fc2e782717..8f5d873368b5d 100644 --- a/internal/controller/api.go +++ b/internal/controller/api.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controller @@ -11,7 +11,6 @@ import ( "github.com/hashicorp/go-hclog" - "github.com/hashicorp/consul/agent/consul/controller/queue" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -47,21 +46,6 @@ func (c Controller) WithWatch(watchedType *pbresource.Type, mapper DependencyMap return c } -// WithCustomWatch adds a custom watch on the given dependency to the controller. Custom mapper -// will be called to map events produced by source to the controller's watched type. -func (c Controller) WithCustomWatch(source *Source, mapper CustomDependencyMapper) Controller { - if source == nil { - panic("source must not be nil") - } - - if mapper == nil { - panic("mapper must not be nil") - } - - c.customWatches = append(c.customWatches, customWatch{source, mapper}) - return c -} - // WithLogger changes the controller's logger. func (c Controller) WithLogger(logger hclog.Logger) Controller { if logger == nil { @@ -123,14 +107,13 @@ func (c Controller) backoff() (time.Duration, time.Duration) { // Use the builder methods in this package (starting with ForType) to construct // a controller, and then pass it to a Manager to be executed. type Controller struct { - managedType *pbresource.Type - reconciler Reconciler - logger hclog.Logger - watches []watch - customWatches []customWatch - baseBackoff time.Duration - maxBackoff time.Duration - placement Placement + managedType *pbresource.Type + reconciler Reconciler + logger hclog.Logger + watches []watch + baseBackoff time.Duration + maxBackoff time.Duration + placement Placement } type watch struct { @@ -138,45 +121,6 @@ type watch struct { mapper DependencyMapper } -// Watch is responsible for watching for custom events from source and adding them to -// the event queue. -func (s *Source) Watch(ctx context.Context, add func(e Event)) error { - for { - select { - case <-ctx.Done(): - return nil - case evt, ok := <-s.Source: - if !ok { - return nil - } - add(evt) - } - } -} - -// Source is used as a generic source of events. This can be used when events aren't coming from resources -// stored by the resource API. -type Source struct { - Source <-chan Event -} - -// Event captures an event in the system which the API can choose to respond to. -type Event struct { - Obj queue.ItemType -} - -// Key returns a string that will be used to de-duplicate items in the queue. -func (e Event) Key() string { - return e.Obj.Key() -} - -// customWatch represent a Watch on a custom Event source and a Mapper to map said -// Events into Requests that the controller can respond to. -type customWatch struct { - source *Source - mapper CustomDependencyMapper -} - // Request represents a request to reconcile the resource with the given ID. type Request struct { // ID of the resource that needs to be reconciled. diff --git a/internal/controller/api_test.go b/internal/controller/api_test.go index 40d3ec99bebdb..e80a2d7d7133e 100644 --- a/internal/controller/api_test.go +++ b/internal/controller/api_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controller_test @@ -25,20 +25,9 @@ func TestController_API(t *testing.T) { rec := newTestReconciler() client := svctest.RunResourceService(t, demo.RegisterTypes) - concertsChan := make(chan controller.Event) - defer close(concertsChan) - concertSource := &controller.Source{Source: concertsChan} - concertMapper := func(ctx context.Context, rt controller.Runtime, event controller.Event) ([]controller.Request, error) { - artistID := event.Obj.(*Concert).artistID - var requests []controller.Request - requests = append(requests, controller.Request{ID: artistID}) - return requests, nil - } - ctrl := controller. ForType(demo.TypeV2Artist). WithWatch(demo.TypeV2Album, controller.MapOwner). - WithCustomWatch(concertSource, concertMapper). WithBackoff(10*time.Millisecond, 100*time.Millisecond). WithReconciler(rec) @@ -80,32 +69,6 @@ func TestController_API(t *testing.T) { prototest.AssertDeepEqual(t, rsp.Resource.Id, req.ID) }) - t.Run("custom watched resource type", func(t *testing.T) { - res, err := demo.GenerateV2Artist() - require.NoError(t, err) - - rsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: res}) - require.NoError(t, err) - - req := rec.wait(t) - prototest.AssertDeepEqual(t, rsp.Resource.Id, req.ID) - - rec.expectNoRequest(t, 500*time.Millisecond) - - concertsChan <- controller.Event{Obj: &Concert{name: "test-concert", artistID: rsp.Resource.Id}} - - watchedReq := rec.wait(t) - prototest.AssertDeepEqual(t, req.ID, watchedReq.ID) - - otherArtist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - concertsChan <- controller.Event{Obj: &Concert{name: "test-concert", artistID: otherArtist.Id}} - - watchedReq = rec.wait(t) - prototest.AssertDeepEqual(t, otherArtist.Id, watchedReq.ID) - }) - t.Run("error retries", func(t *testing.T) { rec.failNext(errors.New("KABOOM")) @@ -303,12 +266,3 @@ func testContext(t *testing.T) context.Context { return ctx } - -type Concert struct { - name string - artistID *pbresource.ID -} - -func (c Concert) Key() string { - return c.name -} diff --git a/internal/controller/controller.go b/internal/controller/controller.go index ac901d355b6e3..54d5c57386a32 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package controller @@ -40,39 +40,20 @@ func (c *controllerRunner) run(ctx context.Context) error { }) }) - for _, w := range c.ctrl.watches { + for _, watch := range c.ctrl.watches { + watch := watch mapQueue := runQueue[mapperRequest](groupCtx, c.ctrl) - watcher := w + // Watched Type Events → Mapper Queue group.Go(func() error { - return c.watch(groupCtx, watcher.watchedType, func(res *pbresource.Resource) { + return c.watch(groupCtx, watch.watchedType, func(res *pbresource.Resource) { mapQueue.Add(mapperRequest{res: res}) }) }) // Mapper Queue → Mapper → Reconciliation Queue group.Go(func() error { - return c.runMapper(groupCtx, watcher, mapQueue, recQueue, func(ctx context.Context, runtime Runtime, itemType queue.ItemType) ([]Request, error) { - return watcher.mapper(ctx, runtime, itemType.(mapperRequest).res) - }) - }) - } - - for _, cw := range c.ctrl.customWatches { - customMapQueue := runQueue[Event](groupCtx, c.ctrl) - watcher := cw - // Custom Events → Mapper Queue - group.Go(func() error { - return watcher.source.Watch(groupCtx, func(e Event) { - customMapQueue.Add(e) - }) - }) - - // Mapper Queue → Mapper → Reconciliation Queue - group.Go(func() error { - return c.runCustomMapper(groupCtx, watcher, customMapQueue, recQueue, func(ctx context.Context, runtime Runtime, itemType queue.ItemType) ([]Request, error) { - return watcher.mapper(ctx, runtime, itemType.(Event)) - }) + return c.runMapper(groupCtx, watch, mapQueue, recQueue) }) } @@ -90,7 +71,7 @@ func runQueue[T queue.ItemType](ctx context.Context, ctrl Controller) queue.Work } func (c *controllerRunner) watch(ctx context.Context, typ *pbresource.Type, add func(*pbresource.Resource)) error { - wl, err := c.client.WatchList(ctx, &pbresource.WatchListRequest{ + watch, err := c.client.WatchList(ctx, &pbresource.WatchListRequest{ Type: typ, Tenancy: &pbresource.Tenancy{ Partition: storage.Wildcard, @@ -104,7 +85,7 @@ func (c *controllerRunner) watch(ctx context.Context, typ *pbresource.Type, add } for { - event, err := wl.Recv() + event, err := watch.Recv() if err != nil { c.logger.Warn("error received from watch", "error", err) return err @@ -118,7 +99,6 @@ func (c *controllerRunner) runMapper( w watch, from queue.WorkQueue[mapperRequest], to queue.WorkQueue[Request], - mapper func(ctx context.Context, runtime Runtime, itemType queue.ItemType) ([]Request, error), ) error { logger := c.logger.With("watched_resource_type", resource.ToGVK(w.watchedType)) @@ -128,36 +108,27 @@ func (c *controllerRunner) runMapper( return nil } - if err := c.doMap(ctx, mapper, to, item, logger); err != nil { + var reqs []Request + err := c.handlePanic(func() error { + var err error + reqs, err = w.mapper(ctx, c.runtime(), item.res) + return err + }) + if err != nil { from.AddRateLimited(item) from.Done(item) continue } - from.Forget(item) - from.Done(item) - } -} - -func (c *controllerRunner) runCustomMapper( - ctx context.Context, - cw customWatch, - from queue.WorkQueue[Event], - to queue.WorkQueue[Request], - mapper func(ctx context.Context, runtime Runtime, itemType queue.ItemType) ([]Request, error), -) error { - logger := c.logger.With("watched_event", cw.source) - - for { - item, shutdown := from.Get() - if shutdown { - return nil - } - - if err := c.doMap(ctx, mapper, to, item, logger); err != nil { - from.AddRateLimited(item) - from.Done(item) - continue + for _, r := range reqs { + if !resource.EqualType(r.ID.Type, c.ctrl.managedType) { + logger.Error("dependency mapper returned request for a resource of the wrong type", + "type_expected", resource.ToGVK(c.ctrl.managedType), + "type_got", resource.ToGVK(r.ID.Type), + ) + continue + } + to.Add(r) } from.Forget(item) @@ -165,29 +136,6 @@ func (c *controllerRunner) runCustomMapper( } } -func (c *controllerRunner) doMap(ctx context.Context, mapper func(ctx context.Context, runtime Runtime, itemType queue.ItemType) ([]Request, error), to queue.WorkQueue[Request], item queue.ItemType, logger hclog.Logger) error { - var reqs []Request - if err := c.handlePanic(func() error { - var err error - reqs, err = mapper(ctx, c.runtime(), item) - return err - }); err != nil { - return err - } - - for _, r := range reqs { - if !resource.EqualType(r.ID.Type, c.ctrl.managedType) { - logger.Error("dependency mapper returned request for a resource of the wrong type", - "type_expected", resource.ToGVK(c.ctrl.managedType), - "type_got", resource.ToGVK(r.ID.Type), - ) - continue - } - to.Add(r) - } - return nil -} - func (c *controllerRunner) runReconciler(ctx context.Context, queue queue.WorkQueue[Request]) error { for { req, shutdown := queue.Get() diff --git a/internal/controller/dependencies.go b/internal/controller/dependencies.go deleted file mode 100644 index 6a91d91ff7b72..0000000000000 --- a/internal/controller/dependencies.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controller - -import ( - "fmt" - "sort" - "strings" - - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func (m *Manager) ValidateDependencies(registrations []resource.Registration) error { - deps := m.CalculateDependencies(registrations) - - return deps.validate() -} - -type Dependencies map[string][]string - -func (deps Dependencies) validate() error { - var merr error - seen := make(map[string]map[string]struct{}) - - mkErr := func(src, dst string) error { - vals := []string{src, dst} - sort.Strings(vals) - return fmt.Errorf("circular dependency between %q and %q", vals[0], vals[1]) - } - - for src, dsts := range deps { - seenDsts := seen[src] - if len(seenDsts) == 0 { - seen[src] = make(map[string]struct{}) - } - - for _, dst := range dsts { - if _, ok := seenDsts[dst]; ok { - merr = multierror.Append(merr, mkErr(src, dst)) - } - - if inverseDsts := seen[dst]; len(inverseDsts) > 0 { - if _, ok := inverseDsts[src]; ok { - merr = multierror.Append(merr, mkErr(src, dst)) - } - } - seen[src][dst] = struct{}{} - } - } - - return merr -} - -func (m *Manager) CalculateDependencies(registrations []resource.Registration) Dependencies { - typeToString := func(t *pbresource.Type) string { - return strings.ToLower(fmt.Sprintf("%s/%s/%s", t.Group, t.GroupVersion, t.Kind)) - } - - out := make(map[string][]string) - for _, r := range registrations { - out[typeToString(r.Type)] = nil - } - - for _, c := range m.controllers { - watches := make([]string, 0, len(c.watches)) - for _, w := range c.watches { - watches = append(watches, typeToString(w.watchedType)) - } - - out[typeToString(c.managedType)] = watches - } - - return out -} - -func (deps Dependencies) ToMermaid() string { - depStrings := make([]string, 0, len(deps)) - - for src, dsts := range deps { - if len(dsts) == 0 { - depStrings = append(depStrings, fmt.Sprintf(" %s", src)) - continue - } - - for _, dst := range dsts { - depStrings = append(depStrings, fmt.Sprintf(" %s --> %s", src, dst)) - } - } - - sort.Slice(depStrings, func(a, b int) bool { - return depStrings[a] < depStrings[b] - }) - out := "flowchart TD\n" + strings.Join(depStrings, "\n") - - return out -} diff --git a/internal/controller/dependencies_test.go b/internal/controller/dependencies_test.go deleted file mode 100644 index 18db58a2853ae..0000000000000 --- a/internal/controller/dependencies_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controller - -import ( - "testing" - - "github.com/hashicorp/consul/internal/testing/golden" - "github.com/stretchr/testify/require" -) - -func TestDependenciesGolden(t *testing.T) { - deps := Dependencies{ - "t1": []string{"t2", "t3"}, - "t2": []string{"t4"}, - "t4": []string{"t1"}, - } - mermaid := deps.ToMermaid() - expected := golden.Get(t, mermaid, "dependencies.golden") - require.Equal(t, expected, mermaid) -} - -func TestValidateDependencies(t *testing.T) { - type testCase struct { - dependencies Dependencies - expectErr string - } - - run := func(t *testing.T, tc testCase) { - err := tc.dependencies.validate() - if len(tc.expectErr) > 0 { - require.Contains(t, err.Error(), tc.expectErr) - } else { - require.NoError(t, err) - } - - } - - cases := map[string]testCase{ - "empty": { - dependencies: nil, - }, - "no circular dependencies": { - dependencies: Dependencies{ - "t1": []string{"t2", "t3"}, - "t2": []string{"t3"}, - "t3": []string{"t4"}, - "t4": nil, - }, - }, - "with circular dependency": { - dependencies: Dependencies{ - "t1": []string{"t2", "t3"}, - "t2": []string{"t1"}, - }, - expectErr: `circular dependency between "t1" and "t2"`, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/controller/dependency_mappers.go b/internal/controller/dependency_mappers.go index 1ac331ffafdd4..c054c4369e94a 100644 --- a/internal/controller/dependency_mappers.go +++ b/internal/controller/dependency_mappers.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package controller import ( @@ -18,14 +15,6 @@ type DependencyMapper func( res *pbresource.Resource, ) ([]Request, error) -// CustomDependencyMapper is called when an Event occurs to determine which of the -// controller's managed resources need to be reconciled. -type CustomDependencyMapper func( - ctx context.Context, - rt Runtime, - event Event, -) ([]Request, error) - // MapOwner implements a DependencyMapper that returns the updated resource's owner. func MapOwner(_ context.Context, _ Runtime, res *pbresource.Resource) ([]Request, error) { var reqs []Request diff --git a/internal/controller/dependency_mappers_test.go b/internal/controller/dependency_mappers_test.go index b9956cdb71f48..b5300bfb9ac98 100644 --- a/internal/controller/dependency_mappers_test.go +++ b/internal/controller/dependency_mappers_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package controller import ( diff --git a/internal/controller/doc.go b/internal/controller/doc.go index db7d944e932e8..28953791525c1 100644 --- a/internal/controller/doc.go +++ b/internal/controller/doc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package controller provides an API for implementing control loops on top of // Consul resources. It is heavily inspired by [Kubebuilder] and the Kubernetes diff --git a/internal/controller/helper.go b/internal/controller/helper.go deleted file mode 100644 index 431ca5e6f3cef..0000000000000 --- a/internal/controller/helper.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controller - -import ( - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// MakeRequests accepts a list of pbresource.ID and pbresource.Reference items, -// and mirrors them into a slice of []controller.Request items where the Type -// of the items has replaced by 'typ'. -func MakeRequests[V resource.ReferenceOrID]( - typ *pbresource.Type, - refs []V, -) []Request { - if len(refs) == 0 { - return nil - } - - out := make([]Request, 0, len(refs)) - for _, ref := range refs { - // if type is not provided, we will use the type in the ID or reference. - if typ == nil { - typ = ref.GetType() - } - out = append(out, Request{ - ID: &pbresource.ID{ - Type: typ, - Tenancy: ref.GetTenancy(), - Name: ref.GetName(), - }, - }) - } - - return out -} diff --git a/internal/controller/helper_test.go b/internal/controller/helper_test.go deleted file mode 100644 index 47509e7a952e1..0000000000000 --- a/internal/controller/helper_test.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controller - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestMakeRequests(t *testing.T) { - redType := &pbresource.Type{ - Group: "colors", - GroupVersion: "vfake", - Kind: "red", - } - blueType := &pbresource.Type{ - Group: "colors", - GroupVersion: "vfake", - Kind: "blue", - } - - casparID := &pbresource.ID{ - Type: redType, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "caspar", - Uid: "ignored", - } - babypantsID := &pbresource.ID{ - Type: redType, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "babypants", - Uid: "ignored", - } - zimRef := &pbresource.Reference{ - Type: redType, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "zim", - Section: "ignored", - } - girRef := &pbresource.Reference{ - Type: redType, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "gir", - Section: "ignored", - } - - newBlueReq := func(name string) Request { - return Request{ - ID: &pbresource.ID{ - Type: blueType, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: name, - }, - } - } - - require.Nil(t, MakeRequests[*pbresource.ID](blueType, nil)) - require.Nil(t, MakeRequests[*pbresource.Reference](blueType, nil)) - - prototest.AssertElementsMatch(t, []Request{ - newBlueReq("caspar"), newBlueReq("babypants"), - }, MakeRequests[*pbresource.ID](blueType, []*pbresource.ID{ - casparID, babypantsID, - })) - - prototest.AssertElementsMatch(t, []Request{ - newBlueReq("gir"), newBlueReq("zim"), - }, MakeRequests[*pbresource.Reference](blueType, []*pbresource.Reference{ - girRef, zimRef, - })) -} diff --git a/internal/controller/lease.go b/internal/controller/lease.go index 596bd2546bce7..2cb00d133019c 100644 --- a/internal/controller/lease.go +++ b/internal/controller/lease.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package controller // Lease is used to ensure controllers are run as singletons (i.e. one leader- diff --git a/internal/controller/manager.go b/internal/controller/manager.go index 1e7e910210616..92c5829c581ec 100644 --- a/internal/controller/manager.go +++ b/internal/controller/manager.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package controller import ( diff --git a/internal/controller/supervisor.go b/internal/controller/supervisor.go index 4abb841f60e0f..5983ff4c4b7b0 100644 --- a/internal/controller/supervisor.go +++ b/internal/controller/supervisor.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package controller import ( diff --git a/internal/controller/supervisor_test.go b/internal/controller/supervisor_test.go index e455565d88b76..1792b8b95c21d 100644 --- a/internal/controller/supervisor_test.go +++ b/internal/controller/supervisor_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package controller import ( diff --git a/internal/controller/testdata/dependencies.golden b/internal/controller/testdata/dependencies.golden deleted file mode 100644 index f0ff372a1634f..0000000000000 --- a/internal/controller/testdata/dependencies.golden +++ /dev/null @@ -1,5 +0,0 @@ -flowchart TD - t1 --> t2 - t1 --> t3 - t2 --> t4 - t4 --> t1 \ No newline at end of file diff --git a/internal/go-sso/oidcauth/auth.go b/internal/go-sso/oidcauth/auth.go index a2f35763a3d0e..c50940780e77d 100644 --- a/internal/go-sso/oidcauth/auth.go +++ b/internal/go-sso/oidcauth/auth.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // package oidcauth bundles up an opinionated approach to authentication using // both the OIDC authorization code workflow and simple JWT decoding (via diff --git a/internal/go-sso/oidcauth/config.go b/internal/go-sso/oidcauth/config.go index 84bbac9e0cbe5..3d51aff19f9be 100644 --- a/internal/go-sso/oidcauth/config.go +++ b/internal/go-sso/oidcauth/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/config_test.go b/internal/go-sso/oidcauth/config_test.go index c72a69e0845f0..0ef4abcd69e53 100644 --- a/internal/go-sso/oidcauth/config_test.go +++ b/internal/go-sso/oidcauth/config_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/internal/strutil/util.go b/internal/go-sso/oidcauth/internal/strutil/util.go index 9cdc0b1acb1c1..50cd24c324913 100644 --- a/internal/go-sso/oidcauth/internal/strutil/util.go +++ b/internal/go-sso/oidcauth/internal/strutil/util.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package strutil diff --git a/internal/go-sso/oidcauth/internal/strutil/util_test.go b/internal/go-sso/oidcauth/internal/strutil/util_test.go index 06d76a6c69d51..2e3fd1919acac 100644 --- a/internal/go-sso/oidcauth/internal/strutil/util_test.go +++ b/internal/go-sso/oidcauth/internal/strutil/util_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package strutil diff --git a/internal/go-sso/oidcauth/jwt.go b/internal/go-sso/oidcauth/jwt.go index fbb6a31669c8e..0695a60c5527f 100644 --- a/internal/go-sso/oidcauth/jwt.go +++ b/internal/go-sso/oidcauth/jwt.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/jwt_test.go b/internal/go-sso/oidcauth/jwt_test.go index 621fb6660b537..9a8d9cf07ed19 100644 --- a/internal/go-sso/oidcauth/jwt_test.go +++ b/internal/go-sso/oidcauth/jwt_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/oidc.go b/internal/go-sso/oidcauth/oidc.go index df00dfcc25f60..dbbf22582abf1 100644 --- a/internal/go-sso/oidcauth/oidc.go +++ b/internal/go-sso/oidcauth/oidc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/oidc_test.go b/internal/go-sso/oidcauth/oidc_test.go index 48de99b641812..288c704d08386 100644 --- a/internal/go-sso/oidcauth/oidc_test.go +++ b/internal/go-sso/oidcauth/oidc_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/oidcauthtest/testing.go b/internal/go-sso/oidcauth/oidcauthtest/testing.go index 0956673c05156..432bcae333e45 100644 --- a/internal/go-sso/oidcauth/oidcauthtest/testing.go +++ b/internal/go-sso/oidcauth/oidcauthtest/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // package oidcauthtest exposes tools to assist in writing unit tests of OIDC // and JWT authentication workflows. diff --git a/internal/go-sso/oidcauth/oidcjwt.go b/internal/go-sso/oidcauth/oidcjwt.go index 14a6b4def2ad4..fec78dae232ee 100644 --- a/internal/go-sso/oidcauth/oidcjwt.go +++ b/internal/go-sso/oidcauth/oidcjwt.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/oidcjwt_test.go b/internal/go-sso/oidcauth/oidcjwt_test.go index 49574856332a5..e1bd0cd919b2e 100644 --- a/internal/go-sso/oidcauth/oidcjwt_test.go +++ b/internal/go-sso/oidcauth/oidcjwt_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/util.go b/internal/go-sso/oidcauth/util.go index 709798dee6353..06cc9054b89c9 100644 --- a/internal/go-sso/oidcauth/util.go +++ b/internal/go-sso/oidcauth/util.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/go-sso/oidcauth/util_test.go b/internal/go-sso/oidcauth/util_test.go index 6cf8bae1b3bd4..1bef6d51c6ae4 100644 --- a/internal/go-sso/oidcauth/util_test.go +++ b/internal/go-sso/oidcauth/util_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package oidcauth diff --git a/internal/mesh/exports.go b/internal/mesh/exports.go index 7b4926c5b08c9..753c10a7ba935 100644 --- a/internal/mesh/exports.go +++ b/internal/mesh/exports.go @@ -1,52 +1,33 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package mesh import ( - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy" "github.com/hashicorp/consul/internal/mesh/internal/types" "github.com/hashicorp/consul/internal/resource" ) var ( - // Controller statuses. - - // Routes controller - RoutesStatusKey = routes.StatusKey - RoutesStatusConditionAccepted = routes.StatusConditionAccepted - RoutesStatusConditionAcceptedMissingParentRefReason = routes.MissingParentRefReason - RoutesStatusConditionAcceptedMissingBackendRefReason = routes.MissingBackendRefReason - RoutesStatusConditionAcceptedParentRefOutsideMeshReason = routes.ParentRefOutsideMeshReason - RoutesStatusConditionAcceptedBackendRefOutsideMeshReason = routes.BackendRefOutsideMeshReason - RoutesStatusConditionAcceptedParentRefUsingMeshPortReason = routes.ParentRefUsingMeshPortReason - RoutesStatusConditionAcceptedBackendRefUsingMeshPortReason = routes.BackendRefUsingMeshPortReason - RoutesStatusConditionAcceptedUnknownParentRefPortReason = routes.UnknownParentRefPortReason - RoutesStatusConditionAcceptedUnknownBackendRefPortReason = routes.UnknownBackendRefPortReason - RoutesStatusConditionAcceptedConflictNotBoundToParentRefReason = routes.ConflictNotBoundToParentRefReason -) + // API Group Information + + APIGroup = types.GroupName + VersionV1Alpha1 = types.VersionV1Alpha1 + CurrentVersion = types.CurrentVersion + + // Resource Kind Names. + + ProxyConfigurationKind = types.ProxyConfigurationKind + UpstreamsKind = types.UpstreamsKind -const ( - // Important constants + // Resource Types for the v1alpha1 version. - NullRouteBackend = types.NullRouteBackend + ProxyConfigurationV1Alpha1Type = types.ProxyConfigurationV1Alpha1Type + UpstreamsV1Alpha1Type = types.UpstreamsV1Alpha1Type ) -// RegisterTypes adds all resource types within the "mesh" API group +// RegisterTypes adds all resource types within the "catalog" API group // to the given type registry func RegisterTypes(r resource.Registry) { types.Register(r) } - -// RegisterControllers registers controllers for the mesh types with -// the given controller Manager. -func RegisterControllers(mgr *controller.Manager, deps ControllerDependencies) { - controllers.Register(mgr, deps) -} - -type TrustDomainFetcher = sidecarproxy.TrustDomainFetcher - -type ControllerDependencies = controllers.Dependencies diff --git a/internal/mesh/internal/controllers/explicitdestinations/controller.go b/internal/mesh/internal/controllers/explicitdestinations/controller.go deleted file mode 100644 index 41eb872896494..0000000000000 --- a/internal/mesh/internal/controllers/explicitdestinations/controller.go +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package explicitdestinations - -import ( - "context" - "fmt" - "sort" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/explicitdestinations/mapper" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ControllerName = "consul.io/explicit-mapper-controller" - -func Controller(mapper *mapper.Mapper) controller.Controller { - if mapper == nil { - panic("mapper is required") - } - - return controller.ForType(pbmesh.ComputedExplicitDestinationsType). - WithWatch(pbmesh.DestinationsType, mapper.MapDestinations). - WithWatch(pbcatalog.WorkloadType, controller.ReplaceType(pbmesh.ComputedExplicitDestinationsType)). - WithWatch(pbcatalog.ServiceType, mapper.MapService). - WithWatch(pbmesh.ComputedRoutesType, mapper.MapComputedRoute). - WithReconciler(&reconciler{mapper: mapper}) -} - -type reconciler struct { - mapper *mapper.Mapper -} - -func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error { - rt.Logger = rt.Logger.With("controller", ControllerName, "id", req.ID) - - // Look up the associated workload. - workloadID := resource.ReplaceType(pbcatalog.WorkloadType, req.ID) - workload, err := resource.GetDecodedResource[*pbcatalog.Workload](ctx, rt.Client, workloadID) - if err != nil { - rt.Logger.Error("error fetching workload", "error", err) - return err - } - - // If workload is not found, the decoded resource will be nil. - if workload == nil || workload.GetResource() == nil || workload.GetData() == nil { - // When workload is not there, we don't need to manually delete the resource - // because it is owned by the workload. In this case, we skip reconcile - // because there's nothing for us to do. - rt.Logger.Trace("the corresponding workload does not exist", "id", workloadID) - r.mapper.UntrackComputedExplicitDestinations(req.ID) - return nil - } - - // Get existing ComputedExplicitDestinations resource (if any). - ced, err := resource.GetDecodedResource[*pbmesh.ComputedExplicitDestinations](ctx, rt.Client, req.ID) - if err != nil { - rt.Logger.Error("error fetching ComputedExplicitDestinations", "error", err) - return err - } - - // If workload is not on the mesh, we need to delete the resource and return - // as for non-mesh workloads there should be no mapper. - if !workload.GetData().IsMeshEnabled() { - rt.Logger.Trace("workload is not on the mesh, skipping reconcile and deleting any corresponding ComputedDestinations", "id", workloadID) - r.mapper.UntrackComputedExplicitDestinations(req.ID) - - // Delete CED only if it exists. - if ced != nil { - _, err = rt.Client.Delete(ctx, &pbresource.DeleteRequest{Id: req.ID}) - if err != nil { - // If there's an error deleting CD, we want to re-trigger reconcile again. - rt.Logger.Error("error deleting ComputedDestinations", "error", err) - return err - } - } - - // Otherwise, return as there's nothing else for us to do. - return nil - } - - // Now get any mapper that we have in the cache that have selectors matching the name - // of this CD (name-aligned with workload). - destinationIDs := r.mapper.DestinationsForWorkload(req.ID) - rt.Logger.Trace("cached destinations IDs", "ids", destinationIDs) - - decodedDestinations, err := r.fetchDestinations(ctx, rt.Client, destinationIDs, workload) - if err != nil { - rt.Logger.Error("error fetching mapper", "error", err) - return err - } - - if len(decodedDestinations) > 0 { - r.mapper.TrackDestinations(req.ID, decodedDestinations) - } else { - r.mapper.UntrackComputedExplicitDestinations(req.ID) - } - - conflicts := findConflicts(decodedDestinations) - - newComputedDestinationsData := &pbmesh.ComputedExplicitDestinations{} - for _, dst := range decodedDestinations { - updatedStatus := &pbresource.Status{ - ObservedGeneration: dst.GetResource().GetGeneration(), - } - - // First check if this resource has a conflict. If it does, update status and don't include it in the computed resource. - if _, ok := conflicts[resource.NewReferenceKey(dst.GetResource().GetId())]; ok { - rt.Logger.Trace("skipping this Destinations resource because it has conflicts with others", "id", dst.GetResource().GetId()) - updatedStatus.Conditions = append(updatedStatus.Conditions, ConditionConflictFound(workload.GetResource().GetId())) - } else { - valid, cond := validate(ctx, rt.Client, dst) - - // Only add it to computed mapper if its mapper are valid. - if valid { - newComputedDestinationsData.Destinations = append(newComputedDestinationsData.Destinations, dst.GetData().GetDestinations()...) - } else { - rt.Logger.Trace("Destinations is not valid", "condition", cond) - } - - updatedStatus.Conditions = append(updatedStatus.Conditions, ConditionConflictNotFound, cond) - } - - // Write status for this destination. - currentStatus := dst.GetResource().GetStatus()[ControllerName] - - // If the status is unchanged then we should return and avoid the unnecessary write - if !resource.EqualStatus(currentStatus, updatedStatus, false) { - rt.Logger.Trace("updating status", "id", dst.GetResource().GetId()) - _, err = rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{ - Id: dst.GetResource().GetId(), - Key: ControllerName, - Status: updatedStatus, - }) - if err != nil { - rt.Logger.Error("error writing new status", "id", dst.GetResource().GetId(), "error", err) - return err - } - } - } - - // If after fetching and validating, we don't have any destinations, - // we need to skip reconcile and delete the resource. - if len(newComputedDestinationsData.GetDestinations()) == 0 { - rt.Logger.Trace("found no destinations associated with this workload") - - if ced != nil { - rt.Logger.Trace("deleting ComputedDestinations") - _, err = rt.Client.Delete(ctx, &pbresource.DeleteRequest{Id: req.ID}) - if err != nil { - // If there's an error deleting CD, we want to re-trigger reconcile again. - rt.Logger.Error("error deleting ComputedExplicitDestinations", "error", err) - return err - } - } - - return nil - } - - // Lastly, write the resource. - if ced == nil || !proto.Equal(ced.GetData(), newComputedDestinationsData) { - rt.Logger.Trace("writing new ComputedExplicitDestinations") - - // First encode the endpoints data as an Any type. - cpcDataAsAny, err := anypb.New(newComputedDestinationsData) - if err != nil { - rt.Logger.Error("error marshalling latest ComputedExplicitDestinations", "error", err) - return err - } - - _, err = rt.Client.Write(ctx, &pbresource.WriteRequest{ - Resource: &pbresource.Resource{ - Id: req.ID, - Owner: workloadID, - Data: cpcDataAsAny, - }, - }) - if err != nil { - rt.Logger.Error("error writing ComputedExplicitDestinations", "error", err) - return err - } - } - - return nil -} - -func validate( - ctx context.Context, - client pbresource.ResourceServiceClient, - destinations *types.DecodedDestinations) (bool, *pbresource.Condition) { - for _, dest := range destinations.GetData().GetDestinations() { - serviceRef := resource.ReferenceToString(dest.DestinationRef) - - // Fetch and validate service. - service, err := resource.GetDecodedResource[*pbcatalog.Service](ctx, client, resource.IDFromReference(dest.DestinationRef)) - if err != nil { - return false, ConditionDestinationServiceReadError(serviceRef) - } - if service == nil { - return false, ConditionDestinationServiceNotFound(serviceRef) - } - - if !service.GetData().IsMeshEnabled() { - return false, ConditionMeshProtocolNotFound(serviceRef) - } - - if service.GetData().FindServicePort(dest.DestinationPort) != nil && - service.GetData().FindServicePort(dest.DestinationPort).Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - return false, ConditionMeshProtocolDestinationPort(serviceRef, dest.DestinationPort) - } - - // Fetch and validate computed routes for service. - serviceID := resource.IDFromReference(dest.DestinationRef) - cr, err := resource.GetDecodedResource[*pbmesh.ComputedRoutes](ctx, client, resource.ReplaceType(pbmesh.ComputedRoutesType, serviceID)) - if err != nil { - return false, ConditionDestinationComputedRoutesReadErr(serviceRef) - } - if cr == nil { - return false, ConditionDestinationComputedRoutesNotFound(serviceRef) - } - - _, ok := cr.Data.PortedConfigs[dest.DestinationPort] - if !ok { - return false, ConditionDestinationComputedRoutesPortNotFound(serviceRef, dest.DestinationPort) - } - - // Otherwise, continue to the next destination. - } - - return true, ConditionDestinationsAccepted() -} - -func (r *reconciler) fetchDestinations( - ctx context.Context, - client pbresource.ResourceServiceClient, - destinationIDs []*pbresource.ID, - workload *types.DecodedWorkload, -) ([]*types.DecodedDestinations, error) { - // Sort all configs alphabetically. - sort.Slice(destinationIDs, func(i, j int) bool { - return destinationIDs[i].GetName() < destinationIDs[j].GetName() - }) - - var decoded []*types.DecodedDestinations - for _, id := range destinationIDs { - res, err := resource.GetDecodedResource[*pbmesh.Destinations](ctx, client, id) - if err != nil { - return nil, err - } - if res == nil || res.GetResource() == nil || res.GetData() == nil { - // If resource is not found, we should untrack it. - r.mapper.UntrackDestinations(id) - continue - } - - if res.Data.Workloads.Filter != "" { - match, err := resource.FilterMatchesResourceMetadata(workload.Resource, res.Data.Workloads.Filter) - if err != nil { - return nil, fmt.Errorf("error checking selector filters: %w", err) - } - if !match { - continue - } - } - - decoded = append(decoded, res) - } - - return decoded, nil -} - -// Find conflicts finds any resources where listen addresses of the destinations are conflicting. -// It will record both resources as conflicting in the resulting map. -func findConflicts(destinations []*types.DecodedDestinations) map[resource.ReferenceKey]struct{} { - addresses := make(map[string]*pbresource.ID) - duplicates := make(map[resource.ReferenceKey]struct{}) - - for _, decDestinations := range destinations { - for _, dst := range decDestinations.GetData().GetDestinations() { - var address string - - switch dst.ListenAddr.(type) { - case *pbmesh.Destination_IpPort: - listenAddr := dst.GetListenAddr().(*pbmesh.Destination_IpPort) - address = fmt.Sprintf("%s:%d", listenAddr.IpPort.GetIp(), listenAddr.IpPort.GetPort()) - case *pbmesh.Destination_Unix: - listenAddr := dst.GetListenAddr().(*pbmesh.Destination_Unix) - address = listenAddr.Unix.GetPath() - default: - continue - } - - if id, ok := addresses[address]; ok { - // if there's already a listen address for one of the mapper, that means we've found a duplicate. - duplicates[resource.NewReferenceKey(decDestinations.GetResource().GetId())] = struct{}{} - - // Also record the original resource as conflicting one. - duplicates[resource.NewReferenceKey(id)] = struct{}{} - - // Don't evaluate the rest of mapper in this resource because this resource already has a duplicate. - break - } else { - // Otherwise, record this address. - addresses[address] = decDestinations.GetResource().GetId() - } - } - } - - return duplicates -} diff --git a/internal/mesh/internal/controllers/explicitdestinations/controller_test.go b/internal/mesh/internal/controllers/explicitdestinations/controller_test.go deleted file mode 100644 index 72004eecbadb8..0000000000000 --- a/internal/mesh/internal/controllers/explicitdestinations/controller_test.go +++ /dev/null @@ -1,846 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package explicitdestinations - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "google.golang.org/protobuf/proto" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/explicitdestinations/mapper" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" -) - -type controllerTestSuite struct { - suite.Suite - - client *resourcetest.Client - runtime controller.Runtime - - ctl *reconciler - ctx context.Context - - workload *pbcatalog.Workload - workloadRes *pbresource.Resource - - dest1 *pbmesh.Destinations - dest2 *pbmesh.Destinations - - destService1 *pbresource.Resource - destService2 *pbresource.Resource - destService3 *pbresource.Resource - - destService1Ref *pbresource.Reference - destService2Ref *pbresource.Reference - destService3Ref *pbresource.Reference - - serviceData *pbcatalog.Service - - destService1Routes *pbmesh.ComputedRoutes - destService2Routes *pbmesh.ComputedRoutes - destService3Routes *pbmesh.ComputedRoutes - - expComputedDest *pbmesh.ComputedExplicitDestinations -} - -func TestFindDuplicates(t *testing.T) { - // Create some conflicting destinations. - dest1 := &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo"}, - }, - Destinations: []*pbmesh.Destination{ - { - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1000, - }, - }, - }, - { - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 2000, - }, - }, - }, - }, - } - dest2 := &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo"}, - }, - Destinations: []*pbmesh.Destination{ - { - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1000, - }, - }, - }, - }, - } - dest3 := &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo"}, - }, - Destinations: []*pbmesh.Destination{ - { - ListenAddr: &pbmesh.Destination_Unix{ - Unix: &pbmesh.UnixSocketAddress{ - Path: "/foo/bar", - }, - }, - }, - }, - } - dest4 := &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo"}, - }, - Destinations: []*pbmesh.Destination{ - { - ListenAddr: &pbmesh.Destination_Unix{ - Unix: &pbmesh.UnixSocketAddress{ - Path: "/foo/bar", - }, - }, - }, - }, - } - destNonConflicting := &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo"}, - }, - Destinations: []*pbmesh.Destination{ - { - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 3000, - }, - }, - }, - { - ListenAddr: &pbmesh.Destination_Unix{ - Unix: &pbmesh.UnixSocketAddress{ - Path: "/baz/bar", - }, - }, - }, - }, - } - - var destinations []*types.DecodedDestinations - dest1Res := resourcetest.Resource(pbmesh.DestinationsType, "dest1"). - WithData(t, dest1). - Build() - destinations = append(destinations, resourcetest.MustDecode[*pbmesh.Destinations](t, dest1Res)) - dest2Res := resourcetest.Resource(pbmesh.DestinationsType, "dest2"). - WithData(t, dest2). - Build() - destinations = append(destinations, resourcetest.MustDecode[*pbmesh.Destinations](t, dest2Res)) - dest3Res := resourcetest.Resource(pbmesh.DestinationsType, "dest3"). - WithData(t, dest3). - Build() - destinations = append(destinations, resourcetest.MustDecode[*pbmesh.Destinations](t, dest3Res)) - dest4Res := resourcetest.Resource(pbmesh.DestinationsType, "dest4"). - WithData(t, dest4). - Build() - destinations = append(destinations, resourcetest.MustDecode[*pbmesh.Destinations](t, dest4Res)) - nonConflictingDestRes := resourcetest.Resource(pbmesh.DestinationsType, "nonConflictingDest"). - WithData(t, destNonConflicting). - Build() - destinations = append(destinations, resourcetest.MustDecode[*pbmesh.Destinations](t, nonConflictingDestRes)) - - duplicates := findConflicts(destinations) - - require.Contains(t, duplicates, resource.NewReferenceKey(dest1Res.Id)) - require.Contains(t, duplicates, resource.NewReferenceKey(dest2Res.Id)) - require.Contains(t, duplicates, resource.NewReferenceKey(dest3Res.Id)) - require.Contains(t, duplicates, resource.NewReferenceKey(dest4Res.Id)) - require.NotContains(t, duplicates, resource.NewReferenceKey(nonConflictingDestRes.Id)) -} - -func (suite *controllerTestSuite) SetupTest() { - resourceClient := svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes) - suite.client = resourcetest.NewClient(resourceClient) - suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())} - suite.ctx = testutil.TestContext(suite.T()) - - suite.ctl = &reconciler{ - mapper: mapper.New(), - } - - suite.workload = &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "1.1.1.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - Identity: "test", - } - - suite.workloadRes = resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). - WithData(suite.T(), suite.workload). - Write(suite.T(), suite.client) - - suite.serviceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"service-1-workloads"}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "admin", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "mesh", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - } - suite.destService1 = resourcetest.Resource(pbcatalog.ServiceType, "dest-service-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), suite.serviceData). - Build() - suite.destService2 = resourcetest.Resource(pbcatalog.ServiceType, "dest-service-2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), suite.serviceData). - Build() - suite.destService3 = resourcetest.Resource(pbcatalog.ServiceType, "dest-service-3"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), suite.serviceData). - Build() - - suite.destService1Ref = resource.Reference(suite.destService1.Id, "") - suite.destService2Ref = resource.Reference(suite.destService2.Id, "") - suite.destService3Ref = resource.Reference(suite.destService3.Id, "") - - suite.destService1Routes = routestest.BuildComputedRoutes(suite.T(), resource.ReplaceType(pbmesh.ComputedRoutesType, suite.destService1.Id), - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.destService1), - ).GetData() - - suite.destService2Routes = routestest.BuildComputedRoutes(suite.T(), resource.ReplaceType(pbmesh.ComputedRoutesType, suite.destService2.Id), - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.destService2), - ).GetData() - - suite.destService3Routes = routestest.BuildComputedRoutes(suite.T(), resource.ReplaceType(pbmesh.ComputedRoutesType, suite.destService3.Id), - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.destService3), - ).GetData() - - suite.dest1 = &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{suite.workloadRes.Id.Name}, - }, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: suite.destService1Ref, - DestinationPort: "tcp", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1000, - }, - }, - }, - { - DestinationRef: suite.destService2Ref, - DestinationPort: "tcp", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 2000, - }, - }, - }, - }, - } - - suite.dest2 = &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"test-"}, - }, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: suite.destService3Ref, - DestinationPort: "tcp", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 3000, - }, - }, - }, - { - DestinationRef: suite.destService2Ref, - DestinationPort: "admin", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 4000, - }, - }, - }, - }, - } - - suite.expComputedDest = &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: suite.destService1Ref, - DestinationPort: "tcp", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1000, - }, - }, - }, - { - DestinationRef: suite.destService2Ref, - DestinationPort: "tcp", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 2000, - }, - }, - }, - { - DestinationRef: suite.destService3Ref, - DestinationPort: "tcp", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 3000, - }, - }, - }, - { - DestinationRef: suite.destService2Ref, - DestinationPort: "admin", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 4000, - }, - }, - }, - }, - } -} - -func (suite *controllerTestSuite) TestReconcile_NoWorkload() { - id := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, "not-found").ID() - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest1"). - WithData(suite.T(), suite.dest1). - Build() - decDest := resourcetest.MustDecode[*pbmesh.Destinations](suite.T(), dest) - suite.ctl.mapper.TrackDestinations(id, []*types.DecodedDestinations{decDest}) - - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: id, - }) - require.NoError(suite.T(), err) - - suite.client.RequireResourceNotFound(suite.T(), id) - - // Check that we're not tracking services for this workload anymore. - reqs, err := suite.ctl.mapper.MapService(context.TODO(), controller.Runtime{}, suite.destService1) - require.NoError(suite.T(), err) - require.Nil(suite.T(), reqs) - - reqs, err = suite.ctl.mapper.MapService(context.TODO(), controller.Runtime{}, suite.destService2) - require.NoError(suite.T(), err) - require.Nil(suite.T(), reqs) -} - -func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() { - resourcetest.Resource(pbcatalog.WorkloadType, "non-mesh"). - WithData(suite.T(), &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "1.1.1.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - }, - }). - Write(suite.T(), suite.client) - - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, "non-mesh"). - Write(suite.T(), suite.client).Id - - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest1"). - WithData(suite.T(), suite.dest1). - Build() - decDest := resourcetest.MustDecode[*pbmesh.Destinations](suite.T(), dest) - suite.ctl.mapper.TrackDestinations(cdID, []*types.DecodedDestinations{decDest}) - - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - require.NoError(suite.T(), err) - - suite.client.RequireResourceNotFound(suite.T(), cdID) - - // Check that we're not tracking services for this workload anymore. - reqs, err := suite.ctl.mapper.MapService(context.TODO(), controller.Runtime{}, suite.destService1) - require.NoError(suite.T(), err) - require.Nil(suite.T(), reqs) - - reqs, err = suite.ctl.mapper.MapService(context.TODO(), controller.Runtime{}, suite.destService2) - require.NoError(suite.T(), err) - require.Nil(suite.T(), reqs) -} - -func (suite *controllerTestSuite) writeServices(t *testing.T) { - // Write all services. - resourcetest.Resource(pbcatalog.ServiceType, suite.destService1Ref.Name). - WithData(t, suite.serviceData). - Write(t, suite.client) - resourcetest.Resource(pbcatalog.ServiceType, suite.destService2Ref.Name). - WithData(t, suite.serviceData). - Write(t, suite.client) - resourcetest.Resource(pbcatalog.ServiceType, suite.destService3Ref.Name). - WithData(t, suite.serviceData). - Write(t, suite.client) -} - -func (suite *controllerTestSuite) writeComputedRoutes(t *testing.T) { - // Write computed routes - resourcetest.Resource(pbmesh.ComputedRoutesType, suite.destService1Ref.Name). - WithData(t, suite.destService1Routes). - Write(t, suite.client) - resourcetest.Resource(pbmesh.ComputedRoutesType, suite.destService2Ref.Name). - WithData(t, suite.destService2Routes). - Write(t, suite.client) - resourcetest.Resource(pbmesh.ComputedRoutesType, suite.destService3Ref.Name). - WithData(t, suite.destService3Routes). - Write(t, suite.client) -} - -func (suite *controllerTestSuite) TestReconcile_HappyPath() { - // Add configs in reverse alphabetical order. - d2 := resourcetest.Resource(pbmesh.DestinationsType, "dest2"). - WithData(suite.T(), suite.dest2). - Write(suite.T(), suite.client) - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, d2) - require.NoError(suite.T(), err) - - d1 := resourcetest.Resource(pbmesh.DestinationsType, "dest1"). - WithData(suite.T(), suite.dest1). - Write(suite.T(), suite.client) - _, err = suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, d1) - require.NoError(suite.T(), err) - - suite.writeServices(suite.T()) - suite.writeComputedRoutes(suite.T()) - - cdID := resource.ReplaceType(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id) - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - - require.NoError(suite.T(), err) - - suite.requireComputedDestinations(suite.T(), cdID) - suite.client.RequireStatusCondition(suite.T(), d1.Id, ControllerName, ConditionDestinationsAccepted()) -} - -func (suite *controllerTestSuite) TestReconcile_NoDestinations() { - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest"). - WithData(suite.T(), suite.dest1). - Build() - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest) - require.NoError(suite.T(), err) - - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - - require.NoError(suite.T(), err) - - suite.client.RequireResourceNotFound(suite.T(), cdID) -} - -func (suite *controllerTestSuite) TestReconcile_AllDestinationsInvalid() { - // We add a destination with services refs that don't exist which should result - // in computed mapper being deleted because all mapper are invalid. - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest"). - WithData(suite.T(), suite.dest1). - Write(suite.T(), suite.client) - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest) - require.NoError(suite.T(), err) - - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - - require.NoError(suite.T(), err) - - suite.client.RequireResourceNotFound(suite.T(), cdID) -} - -func (suite *controllerTestSuite) TestReconcile_StatusUpdate_ConflictingDestination() { - dest1 := resourcetest.Resource(pbmesh.DestinationsType, "dest1"). - WithData(suite.T(), suite.dest1). - Write(suite.T(), suite.client) - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest1) - require.NoError(suite.T(), err) - - // Write a conflicting destinations resource. - destData := proto.Clone(suite.dest2).(*pbmesh.Destinations) - destData.Destinations[0] = suite.dest1.Destinations[0] - - dest2 := resourcetest.Resource(pbmesh.DestinationsType, "dest2"). - WithData(suite.T(), destData). - Write(suite.T(), suite.client) - _, err = suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest2) - require.NoError(suite.T(), err) - - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - require.NoError(suite.T(), err) - suite.client.RequireResourceNotFound(suite.T(), cdID) - - // Expect that the status on both resource is updated showing conflict. - suite.client.RequireStatusCondition(suite.T(), dest1.Id, ControllerName, - ConditionConflictFound(suite.workloadRes.Id)) - suite.client.RequireStatusCondition(suite.T(), dest2.Id, ControllerName, - ConditionConflictFound(suite.workloadRes.Id)) - - // Update dest2 back to have non-conflicting data. - dest2 = resourcetest.Resource(pbmesh.DestinationsType, "dest2"). - WithData(suite.T(), suite.dest2). - Write(suite.T(), suite.client) - _, err = suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest2) - require.NoError(suite.T(), err) - - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - require.NoError(suite.T(), err) - - // Expect status on both to be updated to say that there's no conflict. - suite.client.RequireStatusCondition(suite.T(), dest1.Id, ControllerName, - ConditionConflictNotFound) - suite.client.RequireStatusCondition(suite.T(), dest2.Id, ControllerName, - ConditionConflictNotFound) -} - -func (suite *controllerTestSuite) TestReconcile_StatusUpdate_NoService() { - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest"). - WithData(suite.T(), suite.dest2). - Write(suite.T(), suite.client) - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest) - require.NoError(suite.T(), err) - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - require.NoError(suite.T(), err) - suite.client.RequireResourceNotFound(suite.T(), cdID) - - suite.client.RequireStatusCondition(suite.T(), dest.Id, ControllerName, - ConditionDestinationServiceNotFound(resource.ReferenceToString(suite.destService3Ref))) -} - -func (suite *controllerTestSuite) TestReconcile_StatusUpdate_ServiceNotOnMesh() { - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest"). - WithData(suite.T(), suite.dest2). - Write(suite.T(), suite.client) - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest) - require.NoError(suite.T(), err) - - resourcetest.Resource(pbcatalog.ServiceType, suite.destService3Ref.Name). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{suite.workloadRes.Id.Name}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - }, - }). - Write(suite.T(), suite.client) - - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - require.NoError(suite.T(), err) - suite.client.RequireResourceNotFound(suite.T(), cdID) - - suite.client.RequireStatusCondition(suite.T(), dest.Id, ControllerName, - ConditionMeshProtocolNotFound(resource.ReferenceToString(suite.destService3Ref))) -} - -func (suite *controllerTestSuite) TestReconcile_StatusUpdate_DestinationPortIsMesh() { - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest"). - WithData(suite.T(), suite.dest2). - Write(suite.T(), suite.client) - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest) - require.NoError(suite.T(), err) - - resourcetest.Resource(pbcatalog.ServiceType, suite.destService3Ref.Name). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{suite.workloadRes.Id.Name}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - }). - Write(suite.T(), suite.client) - - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - require.NoError(suite.T(), err) - suite.client.RequireResourceNotFound(suite.T(), cdID) - - suite.client.RequireStatusCondition(suite.T(), dest.Id, ControllerName, - ConditionMeshProtocolDestinationPort(resource.ReferenceToString(suite.destService3Ref), "tcp")) -} - -func (suite *controllerTestSuite) TestReconcile_StatusUpdate_ComputedRoutesNotFound() { - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest"). - WithData(suite.T(), suite.dest2). - Write(suite.T(), suite.client) - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest) - require.NoError(suite.T(), err) - - resourcetest.Resource(pbcatalog.ServiceType, suite.destService3Ref.Name). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{suite.workloadRes.Id.Name}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "mesh", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - }). - Write(suite.T(), suite.client) - - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - require.NoError(suite.T(), err) - suite.client.RequireResourceNotFound(suite.T(), cdID) - - suite.client.RequireStatusCondition(suite.T(), dest.Id, ControllerName, - ConditionDestinationComputedRoutesNotFound(resource.ReferenceToString(suite.destService3Ref))) -} - -func (suite *controllerTestSuite) TestReconcile_StatusUpdate_ComputedRoutesPortNotFound() { - dest := resourcetest.Resource(pbmesh.DestinationsType, "dest"). - WithData(suite.T(), suite.dest2). - Write(suite.T(), suite.client) - _, err := suite.ctl.mapper.MapDestinations(suite.ctx, suite.runtime, dest) - require.NoError(suite.T(), err) - - destService := resourcetest.Resource(pbcatalog.ServiceType, suite.destService3Ref.Name). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{suite.workloadRes.Id.Name}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "mesh", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - }). - Write(suite.T(), suite.client) - - resourcetest.Resource(pbmesh.ComputedRoutesType, destService.Id.Name). - WithData(suite.T(), &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "some-other-port": { - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{}, - }, - }, - }, - }). - Write(suite.T(), suite.client) - - cdID := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cdID, - }) - require.NoError(suite.T(), err) - suite.client.RequireResourceNotFound(suite.T(), cdID) - - suite.client.RequireStatusCondition(suite.T(), dest.Id, ControllerName, - ConditionDestinationComputedRoutesPortNotFound(resource.ReferenceToString(suite.destService3Ref), "tcp")) -} - -func (suite *controllerTestSuite) TestController() { - mgr := controller.NewManager(suite.client, suite.runtime.Logger) - - m := mapper.New() - mgr.Register(Controller(m)) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - cdID := resource.ReplaceType(pbmesh.ComputedExplicitDestinationsType, suite.workloadRes.Id) - - dest1 := resourcetest.Resource(pbmesh.DestinationsType, "dest1"). - WithData(suite.T(), suite.dest1). - Write(suite.T(), suite.client) - - // At this point, none of the services or routes yet exist and so we should see the status of the destinations - // resource to reflect that. The CED resource should not be created in this case. - testutil.RunStep(suite.T(), "check that destinations status is updated", func(t *testing.T) { - retry.Run(t, func(r *retry.R) { - serviceRef := resource.IDToString(suite.destService1.Id) - suite.client.WaitForStatusCondition(r, dest1.Id, ControllerName, ConditionDestinationServiceNotFound(serviceRef)) - - suite.client.RequireResourceNotFound(r, cdID) - }) - }) - - dest2 := resourcetest.Resource(pbmesh.DestinationsType, "dest2"). - WithData(suite.T(), suite.dest2). - Write(suite.T(), suite.client) - - suite.writeServices(suite.T()) - - // After we write services, we expect another reconciliation to be kicked off to validate and find that there are no computed routes. - testutil.RunStep(suite.T(), "check that destinations status says that there are no computed routes", func(t *testing.T) { - retry.Run(t, func(r *retry.R) { - suite.client.WaitForStatusCondition(r, dest1.Id, ControllerName, - ConditionDestinationComputedRoutesNotFound(resource.IDToString(suite.destService1.Id))) - suite.client.WaitForStatusCondition(r, dest2.Id, ControllerName, - ConditionDestinationComputedRoutesNotFound(resource.IDToString(suite.destService3.Id))) - - suite.client.RequireResourceNotFound(r, cdID) - }) - }) - - // Now write computed routes to get a computed resource. - suite.writeComputedRoutes(suite.T()) - - testutil.RunStep(suite.T(), "computed destinations generation", func(t *testing.T) { - retry.Run(t, func(r *retry.R) { - suite.client.RequireResourceExists(r, cdID) - suite.requireComputedDestinations(r, cdID) - }) - }) - - testutil.RunStep(suite.T(), "add another workload", func(t *testing.T) { - // Create another workload that will match only dest2. - matchingWorkload := resourcetest.Resource(pbcatalog.WorkloadType, "test-extra-workload"). - WithData(t, suite.workload). - Write(t, suite.client) - matchingWorkloadCDID := resource.ReplaceType(pbmesh.ComputedExplicitDestinationsType, matchingWorkload.Id) - - retry.Run(t, func(r *retry.R) { - suite.client.RequireResourceExists(r, cdID) - suite.requireComputedDestinations(r, cdID) - - matchingWorkloadCD := suite.client.RequireResourceExists(r, matchingWorkloadCDID) - dec := resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](r, matchingWorkloadCD) - prototest.AssertDeepEqual(r, suite.dest2.GetDestinations(), dec.GetData().GetDestinations()) - }) - }) - - testutil.RunStep(suite.T(), "update workload selector", func(t *testing.T) { - // Update workload selector to no point to some non-existing workload - updatedDestinations := proto.Clone(suite.dest2).(*pbmesh.Destinations) - updatedDestinations.Workloads = &pbcatalog.WorkloadSelector{ - Names: []string{"other-workload"}, - } - - matchingWorkload := resourcetest.Resource(pbcatalog.WorkloadType, "other-workload"). - WithData(t, suite.workload). - Write(t, suite.client) - matchingWorkloadCDID := resource.ReplaceType(pbmesh.ComputedExplicitDestinationsType, matchingWorkload.Id) - resourcetest.Resource(pbmesh.DestinationsType, "dest2"). - WithData(suite.T(), updatedDestinations). - Write(suite.T(), suite.client) - - retry.Run(t, func(r *retry.R) { - res := suite.client.RequireResourceExists(r, cdID) - - // The "test-workload" computed destinations should now be updated to use only proxy dest1. - expDest := &pbmesh.ComputedExplicitDestinations{ - Destinations: suite.dest1.Destinations, - } - dec := resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, res) - prototest.AssertDeepEqual(r, expDest.GetDestinations(), dec.GetData().GetDestinations()) - - matchingWorkloadCD := suite.client.RequireResourceExists(r, matchingWorkloadCDID) - dec = resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](r, matchingWorkloadCD) - prototest.AssertDeepEqual(r, suite.dest2.GetDestinations(), dec.GetData().GetDestinations()) - }) - }) - - // Delete all destinations. - suite.client.MustDelete(suite.T(), dest1.Id) - suite.client.MustDelete(suite.T(), dest2.Id) - - testutil.RunStep(suite.T(), "all destinations are deleted", func(t *testing.T) { - retry.Run(t, func(r *retry.R) { - suite.client.RequireResourceNotFound(r, cdID) - }) - }) -} - -func TestControllerSuite(t *testing.T) { - suite.Run(t, new(controllerTestSuite)) -} - -func (suite *controllerTestSuite) requireComputedDestinations(t resourcetest.T, id *pbresource.ID) { - cdRes := suite.client.RequireResourceExists(t, id) - decCD := resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, cdRes) - prototest.AssertElementsMatch(t, suite.expComputedDest.GetDestinations(), decCD.Data.GetDestinations()) - resourcetest.RequireOwner(t, cdRes, resource.ReplaceType(pbcatalog.WorkloadType, id), true) -} diff --git a/internal/mesh/internal/controllers/explicitdestinations/mapper/mapper.go b/internal/mesh/internal/controllers/explicitdestinations/mapper/mapper.go deleted file mode 100644 index 48e4cb03f7b00..0000000000000 --- a/internal/mesh/internal/controllers/explicitdestinations/mapper/mapper.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package mapper - -import ( - "context" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/mappers/workloadselectionmapper" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type Mapper struct { - workloadSelectionMapper *workloadselectionmapper.Mapper[*pbmesh.Destinations] - - serviceRefMapper *bimapper.Mapper -} - -func New() *Mapper { - return &Mapper{ - workloadSelectionMapper: workloadselectionmapper.New[*pbmesh.Destinations](pbmesh.ComputedExplicitDestinationsType), - serviceRefMapper: bimapper.New(pbmesh.ComputedExplicitDestinationsType, pbcatalog.ServiceType), - } -} - -func (m *Mapper) MapService(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - serviceRef := resource.Reference(res.GetId(), "") - - compDestinations := m.serviceRefMapper.ItemIDsForLink(serviceRef) - - return controller.MakeRequests(pbmesh.ComputedExplicitDestinationsType, compDestinations), nil -} - -func (m *Mapper) MapDestinations(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - return m.workloadSelectionMapper.MapToComputedType(ctx, rt, res) -} - -func (m *Mapper) MapComputedRoute(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - serviceID := resource.ReplaceType(pbcatalog.ServiceType, res.GetId()) - serviceRef := resource.Reference(serviceID, "") - - compDestinations := m.serviceRefMapper.ItemIDsForLink(serviceRef) - - return controller.MakeRequests(pbmesh.ComputedExplicitDestinationsType, compDestinations), nil -} - -func (m *Mapper) TrackDestinations(id *pbresource.ID, destinations []*types.DecodedDestinations) { - var links []resource.ReferenceOrID - for _, dst := range destinations { - for _, d := range dst.GetData().GetDestinations() { - links = append(links, d.DestinationRef) - } - } - - m.serviceRefMapper.TrackItem(id, links) -} - -func (m *Mapper) UntrackComputedExplicitDestinations(id *pbresource.ID) { - m.serviceRefMapper.UntrackItem(id) -} - -func (m *Mapper) UntrackDestinations(id *pbresource.ID) { - m.workloadSelectionMapper.UntrackID(id) -} - -func (m *Mapper) DestinationsForWorkload(id *pbresource.ID) []*pbresource.ID { - return m.workloadSelectionMapper.IDsForWorkload(id) -} diff --git a/internal/mesh/internal/controllers/explicitdestinations/status.go b/internal/mesh/internal/controllers/explicitdestinations/status.go deleted file mode 100644 index 20466561ea593..0000000000000 --- a/internal/mesh/internal/controllers/explicitdestinations/status.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package explicitdestinations - -import ( - "fmt" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - StatusConditionDestinationsAccepted = "DestinationsAccepted" - - StatusReasonMeshProtocolNotFound = "MeshPortProtocolNotFound" - StatusReasonMeshProtocolFound = "AllDestinationServicesValid" - - StatusReasonMeshProtocolDestinationPort = "DestinationWithMeshPortProtocol" - - StatusReasonDestinationServiceNotFound = "ServiceNotFound" - StatusReasonDestinationServiceReadError = "ServiceReadError" - - StatusReasonDestinationComputedRoutesNotFound = "ComputedRoutesNotFound" - StatusReasonDestinationComputedRoutesReadError = "ComputedRoutesReadError" - - StatusReasonDestinationComputedRoutesPortNotFound = "ComputedRoutesPortNotFound" - - StatusConditionConflictFound = "ConflictFound" - StatusReasonDuplicateListenAddress = "ConflictingListenAddress" - StatusReasonNoDuplicateListenAddress = "AllListenAddressesAreUnique" -) - -var ConditionConflictNotFound = &pbresource.Condition{ - Type: StatusConditionConflictFound, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonNoDuplicateListenAddress, - Message: "All mapper have unique listen addresses.", -} - -func ConditionConflictFound(workloadID *pbresource.ID) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionConflictFound, - State: pbresource.Condition_STATE_TRUE, - Reason: StatusReasonDuplicateListenAddress, - Message: fmt.Sprintf("Another Destinations resource selecting workload %q configures the same listen address as one of the mapper in this resource. "+ - "This resource will be skipped.", resource.IDToString(workloadID)), - } -} - -func ConditionMeshProtocolNotFound(serviceRef string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionDestinationsAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonMeshProtocolNotFound, - Message: fmt.Sprintf("service %q cannot be referenced as a Destination because it's not mesh-enabled.", serviceRef), - } -} - -func ConditionDestinationsAccepted() *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionDestinationsAccepted, - State: pbresource.Condition_STATE_TRUE, - Reason: StatusReasonMeshProtocolFound, - Message: "all destination services are valid.", - } -} - -func ConditionDestinationServiceNotFound(serviceRef string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionDestinationsAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonDestinationServiceNotFound, - Message: fmt.Sprintf("service %q does not exist.", serviceRef), - } -} - -func ConditionDestinationServiceReadError(serviceRef string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionDestinationsAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonDestinationServiceReadError, - Message: fmt.Sprintf("error reading service %q", serviceRef), - } -} - -func ConditionMeshProtocolDestinationPort(serviceRef, port string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionDestinationsAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonMeshProtocolDestinationPort, - Message: fmt.Sprintf("destination port %q for service %q has PROTOCOL_MESH which is unsupported for destination services", port, serviceRef), - } -} - -func ConditionDestinationComputedRoutesNotFound(serviceRef string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionDestinationsAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonDestinationComputedRoutesNotFound, - Message: fmt.Sprintf("computed routes %q does not exist.", serviceRef), - } -} - -func ConditionDestinationComputedRoutesReadErr(serviceRef string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionDestinationsAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonDestinationComputedRoutesReadError, - Message: fmt.Sprintf("error reading computed routes for %q service.", serviceRef), - } -} - -func ConditionDestinationComputedRoutesPortNotFound(serviceRef, port string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionDestinationsAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonDestinationComputedRoutesPortNotFound, - Message: fmt.Sprintf("computed routes %q does not exist for port %q.", serviceRef, port), - } -} diff --git a/internal/mesh/internal/controllers/proxyconfiguration/controller.go b/internal/mesh/internal/controllers/proxyconfiguration/controller.go deleted file mode 100644 index e0ac5d42ad48d..0000000000000 --- a/internal/mesh/internal/controllers/proxyconfiguration/controller.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxyconfiguration - -import ( - "context" - "fmt" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/mappers/workloadselectionmapper" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ControllerName = "consul.io/proxy-configuration-controller" - -func Controller(proxyConfigMapper *workloadselectionmapper.Mapper[*pbmesh.ProxyConfiguration]) controller.Controller { - if proxyConfigMapper == nil { - panic("proxy config mapper is required") - } - - return controller.ForType(pbmesh.ComputedProxyConfigurationType). - WithWatch(pbmesh.ProxyConfigurationType, proxyConfigMapper.MapToComputedType). - WithWatch(pbcatalog.WorkloadType, controller.ReplaceType(pbmesh.ComputedProxyConfigurationType)). - WithReconciler(&reconciler{proxyConfigMapper: proxyConfigMapper}) -} - -type reconciler struct { - proxyConfigMapper *workloadselectionmapper.Mapper[*pbmesh.ProxyConfiguration] -} - -func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error { - rt.Logger = rt.Logger.With("controller", ControllerName, "id", req.ID) - - // Look up the associated workload. - workloadID := resource.ReplaceType(pbcatalog.WorkloadType, req.ID) - workload, err := resource.GetDecodedResource[*pbcatalog.Workload](ctx, rt.Client, workloadID) - if err != nil { - rt.Logger.Error("error fetching workload", "error", err) - return err - } - - // If workload is not found, the decoded resource will be nil. - if workload == nil { - // When workload is not there, we don't need to manually delete the resource - // because it is owned by the workload. In this case, we skip reconcile - // because there's nothing for us to do. - rt.Logger.Trace("the corresponding workload does not exist", "id", workloadID) - return nil - } - - // Get existing ComputedProxyConfiguration resource (if any). - cpc, err := resource.GetDecodedResource[*pbmesh.ComputedProxyConfiguration](ctx, rt.Client, req.ID) - if err != nil { - rt.Logger.Error("error fetching ComputedProxyConfiguration", "error", err) - return err - } - - // If workload is not on the mesh, we need to delete the resource and return - // as for non-mesh workloads there should be no proxy configuration. - if !workload.GetData().IsMeshEnabled() { - rt.Logger.Trace("workload is not on the mesh, skipping reconcile and deleting any corresponding ComputedProxyConfiguration", "id", workloadID) - - // Delete CPC only if it exists. - if cpc != nil { - _, err = rt.Client.Delete(ctx, &pbresource.DeleteRequest{Id: req.ID}) - if err != nil { - // If there's an error deleting CPC, we want to re-trigger reconcile again. - rt.Logger.Error("error deleting ComputedProxyConfiguration", "error", err) - return err - } - } - - // Otherwise, return as there's nothing else for us to do. - return nil - } - - // Now get any proxy configurations IDs that we have in the cache that have selectors matching the name - // of this CPC (name-aligned with the workload). - proxyCfgIDs := r.proxyConfigMapper.IDsForWorkload(req.ID) - rt.Logger.Trace("cached proxy cfg IDs", "ids", proxyCfgIDs) - - decodedProxyCfgs, err := r.fetchProxyConfigs(ctx, rt.Client, proxyCfgIDs, workload) - if err != nil { - rt.Logger.Error("error fetching proxy configurations", "error", err) - return err - } - - // If after fetching, we don't have any proxy configs, we need to skip reconcile and delete the resource. - if len(decodedProxyCfgs) == 0 { - rt.Logger.Trace("found no proxy configurations associated with this workload") - - if cpc != nil { - rt.Logger.Trace("deleting ComputedProxyConfiguration") - _, err = rt.Client.Delete(ctx, &pbresource.DeleteRequest{Id: req.ID}) - if err != nil { - // If there's an error deleting CPC, we want to re-trigger reconcile again. - rt.Logger.Error("error deleting ComputedProxyConfiguration", "error", err) - return err - } - } - - return nil - } - - // Next, we need to sort configs so that we can resolve conflicts. - sortedProxyCfgs := SortProxyConfigurations(decodedProxyCfgs, req.ID.GetName()) - - mergedProxyCfg := &pbmesh.ProxyConfiguration{} - // Walk sorted configs in reverse order so that the ones that take precedence - // do not overwrite the ones that don't. - for i := len(sortedProxyCfgs) - 1; i >= 0; i-- { - proto.Merge(mergedProxyCfg, sortedProxyCfgs[i].GetData()) - } - - newCPCData := &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: mergedProxyCfg.GetDynamicConfig(), - BootstrapConfig: mergedProxyCfg.GetBootstrapConfig(), - } - - // Lastly, write the resource. - if cpc == nil || !proto.Equal(cpc.GetData(), newCPCData) { - rt.Logger.Trace("writing new ComputedProxyConfiguration") - - // First encode the endpoints data as an Any type. - cpcDataAsAny, err := anypb.New(newCPCData) - if err != nil { - rt.Logger.Error("error marshalling latest ComputedProxyConfiguration", "error", err) - return err - } - - _, err = rt.Client.Write(ctx, &pbresource.WriteRequest{ - Resource: &pbresource.Resource{ - Id: req.ID, - Owner: workloadID, - Data: cpcDataAsAny, - }, - }) - if err != nil { - rt.Logger.Error("error writing latest ComputedProxyConfiguration", "error", err) - return err - } - } - - return nil -} - -func (r *reconciler) fetchProxyConfigs( - ctx context.Context, - client pbresource.ResourceServiceClient, - proxyCfgIds []*pbresource.ID, - workload *types.DecodedWorkload, -) ([]*types.DecodedProxyConfiguration, error) { - var decoded []*types.DecodedProxyConfiguration - for _, id := range proxyCfgIds { - res, err := resource.GetDecodedResource[*pbmesh.ProxyConfiguration](ctx, client, id) - if err != nil { - return nil, err - } - if res == nil || res.GetResource() == nil || res.GetData() == nil { - // If resource is not found, we should untrack it. - r.proxyConfigMapper.UntrackID(id) - continue - } - - if res.Data.Workloads.Filter != "" { - match, err := resource.FilterMatchesResourceMetadata(workload.Resource, res.Data.Workloads.Filter) - if err != nil { - return nil, fmt.Errorf("error checking selector filters: %w", err) - } - if !match { - continue - } - } - - decoded = append(decoded, res) - } - - return decoded, nil -} diff --git a/internal/mesh/internal/controllers/proxyconfiguration/controller_test.go b/internal/mesh/internal/controllers/proxyconfiguration/controller_test.go deleted file mode 100644 index 554f57ab5a068..0000000000000 --- a/internal/mesh/internal/controllers/proxyconfiguration/controller_test.go +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxyconfiguration - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/durationpb" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/mappers/workloadselectionmapper" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/iptables" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" -) - -type controllerTestSuite struct { - suite.Suite - - client *resourcetest.Client - runtime controller.Runtime - - ctl *reconciler - ctx context.Context - - workload *pbcatalog.Workload - workloadRes *pbresource.Resource - - proxyCfg1 *pbmesh.ProxyConfiguration - proxyCfg2 *pbmesh.ProxyConfiguration - proxyCfg3 *pbmesh.ProxyConfiguration - - expComputedProxyCfg *pbmesh.ComputedProxyConfiguration -} - -func (suite *controllerTestSuite) SetupTest() { - resourceClient := svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes) - suite.client = resourcetest.NewClient(resourceClient) - suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())} - suite.ctx = testutil.TestContext(suite.T()) - - suite.ctl = &reconciler{ - proxyConfigMapper: workloadselectionmapper.New[*pbmesh.ProxyConfiguration](pbmesh.ComputedProxyConfigurationType), - } - - suite.workload = &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "1.1.1.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - Identity: "test", - } - - suite.workloadRes = resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). - WithData(suite.T(), suite.workload). - Write(suite.T(), suite.client) - - suite.proxyCfg1 = &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{suite.workloadRes.Id.Name}, - }, - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - }, - } - - suite.proxyCfg2 = &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"test-"}, - }, - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_DIRECT, // this setting should be overridden by proxycfg1 - LocalConnection: map[string]*pbmesh.ConnectionConfig{ - "tcp": {ConnectTimeout: durationpb.New(2 * time.Second)}, - }, - }, - } - - suite.proxyCfg3 = &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"test-wor"}, - }, - BootstrapConfig: &pbmesh.BootstrapConfig{ - PrometheusBindAddr: "0.0.0.0:9000", - }, - } - - suite.expComputedProxyCfg = &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - TransparentProxy: &pbmesh.TransparentProxy{OutboundListenerPort: iptables.DefaultTProxyOutboundPort}, - LocalConnection: map[string]*pbmesh.ConnectionConfig{ - "tcp": {ConnectTimeout: durationpb.New(2 * time.Second)}, - }, - }, - BootstrapConfig: &pbmesh.BootstrapConfig{ - PrometheusBindAddr: "0.0.0.0:9000", - }, - } -} - -func (suite *controllerTestSuite) TestReconcile_NoWorkload() { - // This test ensures that removed workloads are ignored and don't result - // in the creation of the proxy state template. - id := resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, "not-found").ID() - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: id, - }) - require.NoError(suite.T(), err) - - suite.client.RequireResourceNotFound(suite.T(), id) -} - -func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() { - resourcetest.Resource(pbcatalog.WorkloadType, "non-mesh"). - WithData(suite.T(), &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "1.1.1.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - }, - }). - Write(suite.T(), suite.client) - - cpcID := resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, "non-mesh"). - Write(suite.T(), suite.client).Id - - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cpcID, - }) - require.NoError(suite.T(), err) - - suite.client.RequireResourceNotFound(suite.T(), cpcID) -} - -func (suite *controllerTestSuite) TestReconcile_HappyPath() { - // Write all three proxy cfgs. - pCfg1 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg1"). - WithData(suite.T(), suite.proxyCfg1). - Write(suite.T(), suite.client) - _, err := suite.ctl.proxyConfigMapper.MapToComputedType(suite.ctx, suite.runtime, pCfg1) - require.NoError(suite.T(), err) - - pCfg2 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg2"). - WithData(suite.T(), suite.proxyCfg2). - Write(suite.T(), suite.client) - _, err = suite.ctl.proxyConfigMapper.MapToComputedType(suite.ctx, suite.runtime, pCfg2) - require.NoError(suite.T(), err) - - pCfg3 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg3"). - WithData(suite.T(), suite.proxyCfg3). - Write(suite.T(), suite.client) - _, err = suite.ctl.proxyConfigMapper.MapToComputedType(suite.ctx, suite.runtime, pCfg3) - require.NoError(suite.T(), err) - - cpcID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, suite.workloadRes.Id) - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cpcID, - }) - - require.NoError(suite.T(), err) - - suite.requireComputedProxyConfiguration(suite.T(), cpcID) -} - -func (suite *controllerTestSuite) TestReconcile_NoProxyConfigs() { - // Create a proxy cfg and map it so that it gets saved to cache. - pCfg1 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg1"). - WithData(suite.T(), suite.proxyCfg1). - Build() - _, err := suite.ctl.proxyConfigMapper.MapToComputedType(suite.ctx, suite.runtime, pCfg1) - require.NoError(suite.T(), err) - - cpcID := resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, suite.workloadRes.Id.Name). - Write(suite.T(), suite.client).Id - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: cpcID, - }) - - require.NoError(suite.T(), err) - - suite.client.RequireResourceNotFound(suite.T(), cpcID) -} - -func (suite *controllerTestSuite) TestController() { - // Run the controller manager - mgr := controller.NewManager(suite.client, suite.runtime.Logger) - - m := workloadselectionmapper.New[*pbmesh.ProxyConfiguration](pbmesh.ComputedProxyConfigurationType) - mgr.Register(Controller(m)) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - // Write proxy configs. - pCfg1 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg1"). - WithData(suite.T(), suite.proxyCfg1). - Write(suite.T(), suite.client) - - pCfg2 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg2"). - WithData(suite.T(), suite.proxyCfg2). - Write(suite.T(), suite.client) - - pCfg3 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg3"). - WithData(suite.T(), suite.proxyCfg3). - Write(suite.T(), suite.client) - - cpcID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, suite.workloadRes.Id) - testutil.RunStep(suite.T(), "computed proxy config generation", func(t *testing.T) { - retry.Run(t, func(r *retry.R) { - suite.client.RequireResourceExists(r, cpcID) - suite.requireComputedProxyConfiguration(r, cpcID) - }) - }) - - testutil.RunStep(suite.T(), "add another workload", func(t *testing.T) { - // Create another workload that will match only proxyCfg2. - matchingWorkload := resourcetest.Resource(pbcatalog.WorkloadType, "test-extra-workload"). - WithData(t, suite.workload). - Write(t, suite.client) - matchingWorkloadCPCID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, matchingWorkload.Id) - - retry.Run(t, func(r *retry.R) { - suite.client.RequireResourceExists(r, cpcID) - suite.requireComputedProxyConfiguration(r, cpcID) - - matchingWorkloadCPC := suite.client.RequireResourceExists(r, matchingWorkloadCPCID) - dec := resourcetest.MustDecode[*pbmesh.ComputedProxyConfiguration](r, matchingWorkloadCPC) - prototest.AssertDeepEqual(r, suite.proxyCfg2.GetDynamicConfig(), dec.GetData().GetDynamicConfig()) - prototest.AssertDeepEqual(r, suite.proxyCfg2.GetBootstrapConfig(), dec.GetData().GetBootstrapConfig()) - }) - }) - - testutil.RunStep(suite.T(), "update proxy config selector", func(t *testing.T) { - // Update proxy config selector to no longer select "test-workload" - updatedProxyCfg := proto.Clone(suite.proxyCfg2).(*pbmesh.ProxyConfiguration) - updatedProxyCfg.Workloads = &pbcatalog.WorkloadSelector{ - Names: []string{"test-extra-workload"}, - } - - matchingWorkload := resourcetest.Resource(pbcatalog.WorkloadType, "test-extra-workload"). - WithData(t, suite.workload). - Write(t, suite.client) - matchingWorkloadCPCID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, matchingWorkload.Id) - resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg2"). - WithData(suite.T(), updatedProxyCfg). - Write(suite.T(), suite.client) - - retry.Run(t, func(r *retry.R) { - res := suite.client.RequireResourceExists(r, cpcID) - - // The "test-workload" computed proxy configurations should now be updated to use only proxy cfg 1 and 3. - expProxyCfg := &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - TransparentProxy: &pbmesh.TransparentProxy{OutboundListenerPort: iptables.DefaultTProxyOutboundPort}, - }, - BootstrapConfig: &pbmesh.BootstrapConfig{ - PrometheusBindAddr: "0.0.0.0:9000", - }, - } - dec := resourcetest.MustDecode[*pbmesh.ComputedProxyConfiguration](t, res) - prototest.AssertDeepEqual(r, expProxyCfg.GetDynamicConfig(), dec.GetData().GetDynamicConfig()) - prototest.AssertDeepEqual(r, expProxyCfg.GetBootstrapConfig(), dec.GetData().GetBootstrapConfig()) - - matchingWorkloadCPC := suite.client.RequireResourceExists(r, matchingWorkloadCPCID) - dec = resourcetest.MustDecode[*pbmesh.ComputedProxyConfiguration](r, matchingWorkloadCPC) - prototest.AssertDeepEqual(r, suite.proxyCfg2.GetDynamicConfig(), dec.GetData().GetDynamicConfig()) - prototest.AssertDeepEqual(r, suite.proxyCfg2.GetBootstrapConfig(), dec.GetData().GetBootstrapConfig()) - }) - }) - - // Delete all proxy cfgs. - suite.client.MustDelete(suite.T(), pCfg1.Id) - suite.client.MustDelete(suite.T(), pCfg2.Id) - suite.client.MustDelete(suite.T(), pCfg3.Id) - - testutil.RunStep(suite.T(), "all proxy configs are deleted", func(t *testing.T) { - retry.Run(t, func(r *retry.R) { - suite.client.RequireResourceNotFound(r, cpcID) - }) - }) -} - -func TestControllerSuite(t *testing.T) { - suite.Run(t, new(controllerTestSuite)) -} - -func (suite *controllerTestSuite) requireComputedProxyConfiguration(t resourcetest.T, id *pbresource.ID) { - cpcRes := suite.client.RequireResourceExists(t, id) - decCPC := resourcetest.MustDecode[*pbmesh.ComputedProxyConfiguration](t, cpcRes) - prototest.AssertDeepEqual(t, suite.expComputedProxyCfg, decCPC.Data) - resourcetest.RequireOwner(t, cpcRes, resource.ReplaceType(pbcatalog.WorkloadType, id), true) -} diff --git a/internal/mesh/internal/controllers/proxyconfiguration/sort.go b/internal/mesh/internal/controllers/proxyconfiguration/sort.go deleted file mode 100644 index 771286899d0c4..0000000000000 --- a/internal/mesh/internal/controllers/proxyconfiguration/sort.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxyconfiguration - -import ( - "sort" - "strings" - - "github.com/oklog/ulid/v2" - "golang.org/x/exp/slices" - - "github.com/hashicorp/consul/internal/mesh/internal/types" -) - -// SortProxyConfigurations sorts proxy configurations using the following rules: -// -// 1. Proxy config with a more specific selector wins. For example, -// if there's a proxy config with a name selector and another conflicting -// with a prefix selector, we will choose the one that selects by name because -// it's more specific. For two prefix-based conflicting proxy configs, we will choose -// the one that has the longer prefix. -// 2. Otherwise, the proxy configuration created first (i.e. with an earlier timestamp) wins. -// 3. Lastly, if creation timestamps are the same, the conflict will be resolved using lexicographic -// order. -// -// It returns them in order such that proxy configurations that take precedence occur first in the list. -func SortProxyConfigurations(proxyCfgs []*types.DecodedProxyConfiguration, workloadName string) []*types.DecodedProxyConfiguration { - // Shallow-copy proxy configs so that we don't mutate the original slice. - proxyCfgsToSort := make([]*types.DecodedProxyConfiguration, len(proxyCfgs)) - for i, cfg := range proxyCfgs { - proxyCfgsToSort[i] = cfg - } - - sorter := proxyCfgsSorter{ - proxyCfgs: proxyCfgsToSort, - workloadName: workloadName, - } - - sort.Sort(sorter) - - return sorter.proxyCfgs -} - -type proxyCfgsSorter struct { - proxyCfgs []*types.DecodedProxyConfiguration - workloadName string -} - -func (p proxyCfgsSorter) Len() int { return len(p.proxyCfgs) } - -// Less returns true if i-th element is less than j-th element. -func (p proxyCfgsSorter) Less(i, j int) bool { - iPrefixMatch := p.findLongestPrefixMatch(i) - iMatchesByName := p.matchesByName(i) - - jPrefixMatch := p.findLongestPrefixMatch(j) - jMatchesByName := p.matchesByName(j) - - switch { - // If i matches by name but j doesn't, then i should come before j. - case iMatchesByName && !jMatchesByName: - return true - case !iMatchesByName && jMatchesByName: - return false - case !iMatchesByName && !jMatchesByName: - if len(iPrefixMatch) != len(jPrefixMatch) { - // In this case, the longest prefix wins. - return len(iPrefixMatch) > len(jPrefixMatch) - } - - // Fallthrough to the default case if lengths of prefix matches are the same. - fallthrough - case iMatchesByName && jMatchesByName: - fallthrough - default: - iID := ulid.MustParse(p.proxyCfgs[i].Resource.Id.Uid) - jID := ulid.MustParse(p.proxyCfgs[j].Resource.Id.Uid) - if iID.Time() != jID.Time() { - return iID.Time() < jID.Time() - } else { - // It's impossible for names to be equal, and so we are checking if - // i's name is "less" lexicographically than j's name. - return p.proxyCfgs[i].GetResource().GetId().GetName() < p.proxyCfgs[j].GetResource().GetId().GetName() - } - } -} - -func (p proxyCfgsSorter) Swap(i, j int) { - p.proxyCfgs[i], p.proxyCfgs[j] = p.proxyCfgs[j], p.proxyCfgs[i] -} - -func (p proxyCfgsSorter) matchesByName(idx int) bool { - return slices.Contains(p.proxyCfgs[idx].GetData().GetWorkloads().GetNames(), p.workloadName) -} - -func (p proxyCfgsSorter) findLongestPrefixMatch(idx int) string { - var prefixMatch string - for _, prefix := range p.proxyCfgs[idx].GetData().GetWorkloads().GetPrefixes() { - if strings.Contains(p.workloadName, prefix) && - len(prefix) > len(prefixMatch) { - - prefixMatch = prefix - } - } - - return prefixMatch -} diff --git a/internal/mesh/internal/controllers/proxyconfiguration/sort_test.go b/internal/mesh/internal/controllers/proxyconfiguration/sort_test.go deleted file mode 100644 index 1fbf8254ee609..0000000000000 --- a/internal/mesh/internal/controllers/proxyconfiguration/sort_test.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxyconfiguration - -import ( - "fmt" - "testing" - "time" - - "github.com/oklog/ulid/v2" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestSortProxyConfigurations(t *testing.T) { - workloadName := "foo-123" - cases := map[string]struct { - selectors []*pbcatalog.WorkloadSelector - expSortedIndices []int - }{ - "first matched by name, second by prefix": { - selectors: []*pbcatalog.WorkloadSelector{ - { - Names: []string{workloadName}, - }, - { - Prefixes: []string{"foo-"}, - }, - }, - expSortedIndices: []int{0, 1}, - }, - "first matched by prefix, second by name": { - selectors: []*pbcatalog.WorkloadSelector{ - { - Prefixes: []string{"foo-"}, - }, - { - Names: []string{workloadName}, - }, - }, - expSortedIndices: []int{1, 0}, - }, - "both matched by name (sorted order should match the order of creation)": { - selectors: []*pbcatalog.WorkloadSelector{ - { - Names: []string{workloadName}, - }, - { - Names: []string{workloadName}, - }, - }, - expSortedIndices: []int{0, 1}, - }, - "both matched by different prefix": { - selectors: []*pbcatalog.WorkloadSelector{ - { - Prefixes: []string{"foo"}, - }, - { - Prefixes: []string{"foo-"}, - }, - }, - expSortedIndices: []int{1, 0}, - }, - "both matched by the same prefix": { - selectors: []*pbcatalog.WorkloadSelector{ - { - Prefixes: []string{"foo-"}, - }, - { - Prefixes: []string{"foo-"}, - }, - }, - expSortedIndices: []int{0, 1}, - }, - "both matched by the multiple different prefixes": { - selectors: []*pbcatalog.WorkloadSelector{ - { - Prefixes: []string{"foo-1", "foo-"}, - }, - { - Prefixes: []string{"foo-1", "foo-12"}, - }, - }, - expSortedIndices: []int{1, 0}, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - resourceClient := svctest.RunResourceService(t, types.Register) - - var decProxyCfgs []*types.DecodedProxyConfiguration - for i, ws := range c.selectors { - proxyCfg := &pbmesh.ProxyConfiguration{ - Workloads: ws, - DynamicConfig: &pbmesh.DynamicConfig{}, - } - resName := fmt.Sprintf("cfg-%d", i) - proxyCfgRes := resourcetest.Resource(pbmesh.ProxyConfigurationType, resName). - WithData(t, proxyCfg). - // We need to run it through resource service so that ULIDs are set. - Write(t, resourceClient) - decProxyCfgs = append(decProxyCfgs, resourcetest.MustDecode[*pbmesh.ProxyConfiguration](t, proxyCfgRes)) - - // Wait for a few milliseconds so that creation timestamp will always be different between resources. - time.Sleep(2 * time.Millisecond) - } - - sortedCfgs := SortProxyConfigurations(decProxyCfgs, workloadName) - - for i, idx := range c.expSortedIndices { - prototest.AssertDeepEqual(t, decProxyCfgs[idx], sortedCfgs[i]) - } - }) - } -} - -func TestSortProxyConfigurations_SameCreationTime(t *testing.T) { - var decProxyCfgs []*types.DecodedProxyConfiguration - - proxyCfg := &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo-123"}, - }, - } - - // Make cfg1 name such that it should appear after cfg2 lexicographically. - cfg1 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "def-cfg-1"). - WithData(t, proxyCfg). - Build() - // Explicitly set ulid. For the first one, we'll just the current timestamp. - cfg1.Id.Uid = ulid.Make().String() - - decProxyCfgs = append(decProxyCfgs, resourcetest.MustDecode[*pbmesh.ProxyConfiguration](t, cfg1)) - - cfg2 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "abc-cfg-2"). - WithData(t, proxyCfg). - Build() - // Explicitly set ulid. For the second one, we'll the timestamp of the first one. - parsedCfg1Ulid := ulid.MustParse(cfg1.Id.Uid) - cfg2.Id.Uid = ulid.MustNew(parsedCfg1Ulid.Time(), ulid.DefaultEntropy()).String() - - decProxyCfgs = append(decProxyCfgs, resourcetest.MustDecode[*pbmesh.ProxyConfiguration](t, cfg2)) - - sortedCfgs := SortProxyConfigurations(decProxyCfgs, "foo-123") - - // We expect that given the same creation timestamp, the second proxy cfg should be first - // in the sorted order because of its name. - prototest.AssertDeepEqual(t, decProxyCfgs[0], sortedCfgs[1]) - prototest.AssertDeepEqual(t, decProxyCfgs[1], sortedCfgs[0]) -} diff --git a/internal/mesh/internal/controllers/register.go b/internal/mesh/internal/controllers/register.go deleted file mode 100644 index fec92dba1b304..0000000000000 --- a/internal/mesh/internal/controllers/register.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controllers - -import ( - "context" - - "github.com/hashicorp/consul/agent/leafcert" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/explicitdestinations" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/explicitdestinations/mapper" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/proxyconfiguration" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/xds" - "github.com/hashicorp/consul/internal/mesh/internal/mappers/workloadselectionmapper" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -type Dependencies struct { - TrustDomainFetcher sidecarproxy.TrustDomainFetcher - LocalDatacenter string - DefaultAllow bool - TrustBundleFetcher xds.TrustBundleFetcher - ProxyUpdater xds.ProxyUpdater - LeafCertManager *leafcert.Manager -} - -func Register(mgr *controller.Manager, deps Dependencies) { - endpointsMapper := bimapper.New(pbmesh.ProxyStateTemplateType, pbcatalog.ServiceEndpointsType) - leafMapper := &xds.LeafMapper{ - Mapper: bimapper.New(pbmesh.ProxyStateTemplateType, xds.InternalLeafType), - } - leafCancels := &xds.LeafCancels{ - Cancels: make(map[string]context.CancelFunc), - } - mgr.Register(xds.Controller(endpointsMapper, deps.ProxyUpdater, deps.TrustBundleFetcher, deps.LeafCertManager, leafMapper, leafCancels, deps.LocalDatacenter)) - - mgr.Register( - sidecarproxy.Controller(cache.New(), deps.TrustDomainFetcher, deps.LocalDatacenter, deps.DefaultAllow), - ) - - mgr.Register(routes.Controller()) - - mgr.Register(proxyconfiguration.Controller(workloadselectionmapper.New[*pbmesh.ProxyConfiguration](pbmesh.ComputedProxyConfigurationType))) - mgr.Register(explicitdestinations.Controller(mapper.New())) -} diff --git a/internal/mesh/internal/controllers/routes/bound_refs.go b/internal/mesh/internal/controllers/routes/bound_refs.go deleted file mode 100644 index afdac8460be80..0000000000000 --- a/internal/mesh/internal/controllers/routes/bound_refs.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "sort" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type sectionRefKey struct { - resource.ReferenceKey - Section string -} - -type BoundReferenceCollector struct { - refs map[sectionRefKey]*pbresource.Reference -} - -func NewBoundReferenceCollector() *BoundReferenceCollector { - return &BoundReferenceCollector{ - refs: make(map[sectionRefKey]*pbresource.Reference), - } -} - -func (c *BoundReferenceCollector) List() []*pbresource.Reference { - if len(c.refs) == 0 { - return nil - } - - out := make([]*pbresource.Reference, 0, len(c.refs)) - for _, ref := range c.refs { - out = append(out, ref) - } - - sort.Slice(out, func(i, j int) bool { - return resource.LessReference(out[i], out[j]) - }) - - return out -} - -func (c *BoundReferenceCollector) AddRefOrID(ref resource.ReferenceOrID) { - if c == nil { - return - } - c.AddRef(resource.ReferenceFromReferenceOrID(ref)) -} - -func (c *BoundReferenceCollector) AddRef(ref *pbresource.Reference) { - if c == nil { - return - } - srk := sectionRefKey{ - ReferenceKey: resource.NewReferenceKey(ref), - Section: ref.Section, - } - - if _, ok := c.refs[srk]; ok { - return - } - - c.refs[srk] = ref -} diff --git a/internal/mesh/internal/controllers/routes/controller.go b/internal/mesh/internal/controllers/routes/controller.go deleted file mode 100644 index e55bac45ccb7f..0000000000000 --- a/internal/mesh/internal/controllers/routes/controller.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "context" - - "github.com/hashicorp/go-hclog" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/loader" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/xroutemapper" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func Controller() controller.Controller { - mapper := xroutemapper.New() - - r := &routesReconciler{ - mapper: mapper, - } - return controller.ForType(pbmesh.ComputedRoutesType). - WithWatch(pbmesh.HTTPRouteType, mapper.MapHTTPRoute). - WithWatch(pbmesh.GRPCRouteType, mapper.MapGRPCRoute). - WithWatch(pbmesh.TCPRouteType, mapper.MapTCPRoute). - WithWatch(pbmesh.DestinationPolicyType, mapper.MapDestinationPolicy). - WithWatch(pbcatalog.FailoverPolicyType, mapper.MapFailoverPolicy). - WithWatch(pbcatalog.ServiceType, mapper.MapService). - WithReconciler(r) -} - -type routesReconciler struct { - mapper *xroutemapper.Mapper -} - -func (r *routesReconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error { - // Notably don't inject the resource-id here into the logger, since we have - // to do a fan-out to multiple resources due to xRoutes having multiple - // parent refs. - rt.Logger = rt.Logger.With("controller", StatusKey) - - rt.Logger.Trace("reconciling computed routes") - - loggerFor := func(id *pbresource.ID) hclog.Logger { - return rt.Logger.With("resource-id", id) - } - related, err := loader.LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, r.mapper, req.ID) - if err != nil { - rt.Logger.Error("error loading relevant resources", "error", err) - return err - } - - pending := make(PendingStatuses) - - ValidateXRouteReferences(related, pending) - - generatedResults := GenerateComputedRoutes(related, pending) - - if err := UpdatePendingStatuses(ctx, rt, pending); err != nil { - rt.Logger.Error("error updating statuses for affected relevant resources", "error", err) - return err - } - - for _, result := range generatedResults { - computedRoutesID := result.ID - - logger := rt.Logger.With("resource-id", computedRoutesID) - - prev, err := resource.GetDecodedResource[*pbmesh.ComputedRoutes](ctx, rt.Client, computedRoutesID) - if err != nil { - logger.Error("error loading previous computed routes", "error", err) - return err - } - - if prev != nil { - r.mapper.TrackComputedRoutes(prev) - } else { - r.mapper.UntrackComputedRoutes(computedRoutesID) - } - - if err := ensureComputedRoutesIsSynced(ctx, logger, rt.Client, result, prev); err != nil { - return err - } - } - - return nil -} - -func ensureComputedRoutesIsSynced( - ctx context.Context, - logger hclog.Logger, - client pbresource.ResourceServiceClient, - result *ComputedRoutesResult, - prev *types.DecodedComputedRoutes, -) error { - if result.Data == nil { - return deleteComputedRoutes(ctx, logger, client, prev) - } - - // Upsert the resource if changed. - if prev != nil { - if proto.Equal(prev.Data, result.Data) { - return nil // no change - } - result.ID = prev.Resource.Id - } - - return upsertComputedRoutes(ctx, logger, client, result.ID, result.OwnerID, result.Data) -} - -func upsertComputedRoutes( - ctx context.Context, - logger hclog.Logger, - client pbresource.ResourceServiceClient, - id *pbresource.ID, - ownerID *pbresource.ID, - data *pbmesh.ComputedRoutes, -) error { - mcData, err := anypb.New(data) - if err != nil { - logger.Error("error marshalling new computed routes payload", "error", err) - return err - } - - // Now perform the write. The computed routes resource should be owned - // by the service so that it will automatically be deleted upon service - // deletion. - - _, err = client.Write(ctx, &pbresource.WriteRequest{ - Resource: &pbresource.Resource{ - Id: id, - Owner: ownerID, - Data: mcData, - }, - }) - if err != nil { - logger.Error("error writing computed routes", "error", err) - return err - } - - logger.Trace("updated computed routes resource was successfully written") - - return nil -} - -func deleteComputedRoutes( - ctx context.Context, - logger hclog.Logger, - client pbresource.ResourceServiceClient, - prev *types.DecodedComputedRoutes, -) error { - if prev == nil { - return nil - } - - // The service the computed routes controls no longer participates in the - // mesh at all. - - logger.Trace("removing previous computed routes") - - // This performs a CAS deletion. - _, err := client.Delete(ctx, &pbresource.DeleteRequest{ - Id: prev.Resource.Id, - Version: prev.Resource.Version, - }) - // Potentially we could look for CAS failures by checking if the gRPC - // status code is Aborted. However its an edge case and there could - // possibly be other reasons why the gRPC status code would be aborted - // besides CAS version mismatches. The simplest thing to do is to just - // propagate the error and retry reconciliation later. - if err != nil { - logger.Error("error deleting previous computed routes resource", "error", err) - return err - } - - return nil -} diff --git a/internal/mesh/internal/controllers/routes/controller_test.go b/internal/mesh/internal/controllers/routes/controller_test.go deleted file mode 100644 index 653eac28ed153..0000000000000 --- a/internal/mesh/internal/controllers/routes/controller_test.go +++ /dev/null @@ -1,1340 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "context" - "fmt" - "testing" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" -) - -type controllerSuite struct { - suite.Suite - - ctx context.Context - client *rtest.Client - rt controller.Runtime -} - -func (suite *controllerSuite) SetupTest() { - suite.ctx = testutil.TestContext(suite.T()) - client := svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes) - suite.rt = controller.Runtime{ - Client: client, - Logger: testutil.Logger(suite.T()), - } - suite.client = rtest.NewClient(client) -} - -func (suite *controllerSuite) TestController() { - mgr := controller.NewManager(suite.client, suite.rt.Logger) - mgr.Register(Controller()) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - backendName := func(name, port string) string { - return fmt.Sprintf("catalog.v2beta1.Service/default.local.default/%s?port=%s", name, port) - } - - var ( - apiServiceRef = rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") - fooServiceRef = rtest.Resource(pbcatalog.ServiceType, "foo"). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") - barServiceRef = rtest.Resource(pbcatalog.ServiceType, "bar"). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") - - computedRoutesID = rtest.Resource(pbmesh.ComputedRoutesType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() - ) - - // Start out by creating a single port service and let it create the - // default computed routes for tcp. - - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - // {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), apiServiceData). - Write(suite.T(), suite.client) - - var lastVersion string - testutil.RunStep(suite.T(), "default tcp route", func(t *testing.T) { - // Check that the computed routes resource exists and it has one port that is the default. - expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - UsingDefaultConfig: true, - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{{ - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("api", "tcp"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "tcp"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "tcp", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - - lastVersion = requireNewComputedRoutesVersion(t, suite.client, computedRoutesID, "", expect) - }) - - // Let the default http/http2/grpc routes get created. - - apiServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "http2", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - } - - _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), apiServiceData). - Write(suite.T(), suite.client) - - // also create the fooService so we can point to it. - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "http2", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - } - - _ = rtest.Resource(pbcatalog.ServiceType, "foo"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), fooServiceData). - Write(suite.T(), suite.client) - - testutil.RunStep(suite.T(), "default other routes", func(t *testing.T) { - expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - UsingDefaultConfig: true, - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{{ - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("api", "tcp"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "tcp"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "tcp", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http": { - UsingDefaultConfig: true, - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http2": { - UsingDefaultConfig: true, - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http2"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http2"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http2"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "http2", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "grpc": { - UsingDefaultConfig: true, - Config: &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: []*pbmesh.ComputedGRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("api", "grpc"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "grpc"), - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "grpc"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "grpc", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - - lastVersion = requireNewComputedRoutesVersion(t, suite.client, computedRoutesID, lastVersion, expect) - }) - - // Customize each route type. - - tcpRoute1 := &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "tcp"), - }, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - tcpRoute1ID := rtest.Resource(pbmesh.TCPRouteType, "api-tcp-route1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), tcpRoute1). - Write(suite.T(), suite.client). - Id - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http2"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - httpRoute1ID := rtest.Resource(pbmesh.HTTPRouteType, "api-http-route1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), httpRoute1). - Write(suite.T(), suite.client). - Id - - grpcRoute1 := &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "grpc"), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - grpcRoute1ID := rtest.Resource(pbmesh.GRPCRouteType, "api-grpc-route1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), grpcRoute1). - Write(suite.T(), suite.client). - Id - - testutil.RunStep(suite.T(), "one of each", func(t *testing.T) { - expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(grpcRoute1ID, ""), - resource.Reference(httpRoute1ID, ""), - resource.Reference(tcpRoute1ID, ""), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{{ - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "tcp", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "grpc": { - Config: &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: []*pbmesh.ComputedGRPCRouteRule{ - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), - }}, - }, - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "grpc"), - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "grpc", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http2": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http2"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http2", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - - lastVersion = requireNewComputedRoutesVersion(t, suite.client, computedRoutesID, lastVersion, expect) - - suite.client.WaitForStatusCondition(t, tcpRoute1ID, StatusKey, ConditionXRouteOK) - suite.client.WaitForStatusCondition(t, httpRoute1ID, StatusKey, ConditionXRouteOK) - suite.client.WaitForStatusCondition(t, grpcRoute1ID, StatusKey, ConditionXRouteOK) - }) - - // Add another route, with a bad mapping. - - tcpRoute2 := &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "tcp"), - }, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: newBackendRef(barServiceRef, "", ""), - }}, - }}, - } - tcpRoute2ID := rtest.Resource(pbmesh.TCPRouteType, "api-tcp-route2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), tcpRoute2). - Write(suite.T(), suite.client). - Id - - httpRoute2 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http2"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/healthz", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(barServiceRef, "", ""), - }}, - }}, - } - httpRoute2ID := rtest.Resource(pbmesh.HTTPRouteType, "api-http-route2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), httpRoute2). - Write(suite.T(), suite.client). - Id - - grpcRoute2 := &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "grpc"), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Type: pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT, - Service: "billing", - Method: "charge", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(barServiceRef, "", ""), - }}, - }}, - } - grpcRoute2ID := rtest.Resource(pbmesh.GRPCRouteType, "api-grpc-route2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), grpcRoute2). - Write(suite.T(), suite.client). - Id - - testutil.RunStep(suite.T(), "one good one bad route", func(t *testing.T) { - expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(grpcRoute1ID, ""), - resource.Reference(grpcRoute2ID, ""), - resource.Reference(httpRoute1ID, ""), - resource.Reference(httpRoute2ID, ""), - resource.Reference(tcpRoute1ID, ""), - resource.Reference(tcpRoute2ID, ""), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{ - { - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), - }}, - }, - { - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "tcp", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/healthz", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "grpc": { - Config: &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: []*pbmesh.ComputedGRPCRouteRule{ - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), - }}, - }, - { - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Type: pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT, - Service: "billing", - Method: "charge", - }, - }}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "grpc"), - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "grpc", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http2": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/healthz", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http2"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http2", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - - lastVersion = requireNewComputedRoutesVersion(t, suite.client, computedRoutesID, lastVersion, expect) - - suite.client.WaitForStatusCondition(t, tcpRoute1ID, StatusKey, ConditionXRouteOK) - suite.client.WaitForStatusCondition(t, httpRoute1ID, StatusKey, ConditionXRouteOK) - suite.client.WaitForStatusCondition(t, grpcRoute1ID, StatusKey, ConditionXRouteOK) - - suite.client.WaitForStatusCondition(t, tcpRoute2ID, StatusKey, - ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar"))) - suite.client.WaitForStatusCondition(t, httpRoute2ID, StatusKey, - ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar"))) - suite.client.WaitForStatusCondition(t, grpcRoute2ID, StatusKey, - ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar"))) - }) - - // Update the route2 routes to point to a real service, but overlap in - // their parentrefs with existing ports tied to other xRoutes. - // - // tcp2 -> http1 - // http2 -> grpc1 - // grpc2 -> tcp1 - // - // Also remove customization for the protocol http2. - - tcpRoute2 = &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - rtest.ResourceID(tcpRoute2ID). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), tcpRoute2). - Write(suite.T(), suite.client) - - httpRoute2 = &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "grpc"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/healthz", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - rtest.ResourceID(httpRoute2ID). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), httpRoute2). - Write(suite.T(), suite.client) - - grpcRoute2 = &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "tcp"), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Type: pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT, - Service: "billing", - Method: "charge", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - rtest.ResourceID(grpcRoute2ID). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), grpcRoute2). - Write(suite.T(), suite.client) - - testutil.RunStep(suite.T(), "overlapping xRoutes generate conflicts", func(t *testing.T) { - expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(grpcRoute1ID, ""), - resource.Reference(grpcRoute2ID, ""), - resource.Reference(httpRoute1ID, ""), - resource.Reference(httpRoute2ID, ""), - resource.Reference(tcpRoute1ID, ""), - resource.Reference(tcpRoute2ID, ""), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{{ - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "tcp", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "grpc": { - Config: &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: []*pbmesh.ComputedGRPCRouteRule{ - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), - }}, - }, - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "grpc"), - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "grpc", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http2": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http2"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http2", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - - lastVersion = requireNewComputedRoutesVersion(t, suite.client, computedRoutesID, lastVersion, expect) - - suite.client.WaitForStatusCondition(t, tcpRoute1ID, StatusKey, ConditionXRouteOK) - suite.client.WaitForStatusCondition(t, httpRoute1ID, StatusKey, ConditionXRouteOK) - suite.client.WaitForStatusCondition(t, grpcRoute1ID, StatusKey, ConditionXRouteOK) - - suite.client.WaitForStatusCondition(t, tcpRoute2ID, StatusKey, - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api"), "http", pbmesh.HTTPRouteType)) - suite.client.WaitForStatusCondition(t, httpRoute2ID, StatusKey, - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api"), "grpc", pbmesh.GRPCRouteType)) - suite.client.WaitForStatusCondition(t, grpcRoute2ID, StatusKey, - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api"), "tcp", pbmesh.TCPRouteType)) - }) - - // - Delete the bad routes - // - delete the original grpc route - // - create a new grpc route with a later name so it loses the conflict - // battle, and do a wildcard port binding - - suite.client.MustDelete(suite.T(), tcpRoute2ID) - suite.client.MustDelete(suite.T(), httpRoute2ID) - suite.client.MustDelete(suite.T(), grpcRoute1ID) - suite.client.MustDelete(suite.T(), grpcRoute2ID) - - suite.client.WaitForDeletion(suite.T(), tcpRoute2ID) - suite.client.WaitForDeletion(suite.T(), httpRoute2ID) - suite.client.WaitForDeletion(suite.T(), grpcRoute1ID) - suite.client.WaitForDeletion(suite.T(), grpcRoute2ID) - - // Re-create with newarly the same data (wildcard port now) with a newer name. - grpcRoute1 = &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - grpcRoute1ID = rtest.Resource(pbmesh.GRPCRouteType, "zzz-bad-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), grpcRoute1). - Write(suite.T(), suite.client). - Id - - testutil.RunStep(suite.T(), "overlapping xRoutes due to port wildcarding", func(t *testing.T) { - expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(grpcRoute1ID, ""), - resource.Reference(httpRoute1ID, ""), - resource.Reference(tcpRoute1ID, ""), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{{ - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "tcp", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "grpc": { - Config: &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: []*pbmesh.ComputedGRPCRouteRule{ - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), - }}, - }, - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "grpc"), - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "grpc", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http2": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http2"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http2", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - - suite.client.WaitForStatusConditions(t, grpcRoute1ID, StatusKey, - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api"), "http", pbmesh.HTTPRouteType), - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api"), "http2", pbmesh.HTTPRouteType), - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api"), "tcp", pbmesh.TCPRouteType)) - - lastVersion = requireNewComputedRoutesVersion(t, suite.client, computedRoutesID, "" /*no change*/, expect) - - suite.client.WaitForStatusCondition(t, tcpRoute1ID, StatusKey, ConditionXRouteOK) - suite.client.WaitForStatusCondition(t, httpRoute1ID, StatusKey, ConditionXRouteOK) - - }) - - // Remove the mesh port from api service. - - apiServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "http2", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - } - - _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), apiServiceData). - Write(suite.T(), suite.client) - - testutil.RunStep(suite.T(), "entire generated resource is deleted", func(t *testing.T) { - suite.client.WaitForDeletion(t, computedRoutesID) - - suite.client.WaitForStatusCondition(t, tcpRoute1ID, StatusKey, - ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api"))) - suite.client.WaitForStatusCondition(t, httpRoute1ID, StatusKey, - ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api"))) - suite.client.WaitForStatusCondition(t, grpcRoute1ID, StatusKey, - ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api"))) - }) - - // Get down to just 2 ports for all relevant services. - for _, name := range []string{"foo", "bar", "api"} { - _ = rtest.Resource(pbcatalog.ServiceType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{name + "-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - }). - Write(suite.T(), suite.client) - } - - httpRoute1 = &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(fooServiceRef, "http"), - newParentRef(barServiceRef, "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(apiServiceRef, "", ""), - }}, - }}, - } - httpRoute1ID = rtest.Resource(pbmesh.HTTPRouteType, "route1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), httpRoute1). - Write(suite.T(), suite.client). - Id - - var ( - fooLastVersion string - barLastVersion string - - fooComputedRoutesID = rtest.Resource(pbmesh.ComputedRoutesType, "foo"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() - barComputedRoutesID = rtest.Resource(pbmesh.ComputedRoutesType, "bar"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() - ) - - testutil.RunStep(suite.T(), "create a route linked to two parents", func(t *testing.T) { - expectFoo := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(httpRoute1ID, ""), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(fooServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - expectBar := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - barServiceRef, - resource.Reference(httpRoute1ID, ""), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(barServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - - fooLastVersion = requireNewComputedRoutesVersion(t, suite.client, fooComputedRoutesID, fooLastVersion, expectFoo) - barLastVersion = requireNewComputedRoutesVersion(t, suite.client, barComputedRoutesID, barLastVersion, expectBar) - - suite.client.WaitForStatusCondition(t, httpRoute1ID, StatusKey, ConditionXRouteOK) - }) - - // Remove bar parent - httpRoute1 = &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(fooServiceRef, "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(apiServiceRef, "", ""), - }}, - }}, - } - httpRoute1ID = rtest.Resource(pbmesh.HTTPRouteType, "route1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), httpRoute1). - Write(suite.T(), suite.client). - Id - - testutil.RunStep(suite.T(), "remove a parent ref and show that the old computed routes is reconciled one more time", func(t *testing.T) { - expectBar := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - barServiceRef, - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("bar", "http"), - }}, - }, - }, - }, - }, - UsingDefaultConfig: true, - ParentRef: newParentRef(barServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("bar", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(barServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - } - - barLastVersion = requireNewComputedRoutesVersion(t, suite.client, barComputedRoutesID, barLastVersion, expectBar) - - suite.client.WaitForStatusCondition(t, httpRoute1ID, StatusKey, ConditionXRouteOK) - }) -} - -func newParentRef(ref *pbresource.Reference, port string) *pbmesh.ParentReference { - return &pbmesh.ParentReference{ - Ref: ref, - Port: port, - } -} - -func newBackendRef(ref *pbresource.Reference, port string, datacenter string) *pbmesh.BackendReference { - return &pbmesh.BackendReference{ - Ref: ref, - Port: port, - Datacenter: datacenter, - } -} - -func requireNewComputedRoutesVersion( - t *testing.T, - client *rtest.Client, - id *pbresource.ID, - version string, - expected *pbmesh.ComputedRoutes, -) string { - t.Helper() - - var nextVersion string - retry.Run(t, func(r *retry.R) { - res := client.WaitForNewVersion(r, id, version) - - var mc pbmesh.ComputedRoutes - require.NoError(r, res.Data.UnmarshalTo(&mc)) - prototest.AssertDeepEqual(r, expected, &mc) - - nextVersion = res.Version - }) - return nextVersion -} - -func TestController(t *testing.T) { - suite.Run(t, new(controllerSuite)) -} diff --git a/internal/mesh/internal/controllers/routes/generate.go b/internal/mesh/internal/controllers/routes/generate.go deleted file mode 100644 index 9bfb2808e3035..0000000000000 --- a/internal/mesh/internal/controllers/routes/generate.go +++ /dev/null @@ -1,835 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "fmt" - "time" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/durationpb" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/loader" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// GenerateComputedRoutes walks a set of related resources and assembles them -// into one effective easy-to-consume ComputedRoutes result. -// -// Any status conditions generated during traversal can be queued for -// persistence using the PendingStatuses map. -// -// This should not internally generate, nor return any errors. -func GenerateComputedRoutes( - related *loader.RelatedResources, - pending PendingStatuses, -) []*ComputedRoutesResult { - out := make([]*ComputedRoutesResult, 0, len(related.ComputedRoutesList)) - for _, computedRoutesID := range related.ComputedRoutesList { - out = append(out, compile(related, computedRoutesID, pending)) - } - return out -} - -type ComputedRoutesResult struct { - // ID is always required. - ID *pbresource.ID - // OwnerID is only required on upserts. - OwnerID *pbresource.ID - // Data being empty means delete if exists. - Data *pbmesh.ComputedRoutes -} - -func compile( - related *loader.RelatedResources, - computedRoutesID *pbresource.ID, - pending PendingStatuses, -) *ComputedRoutesResult { - // There is one computed routes resource for the entire service (perfect name alignment). - // - // All ports are embedded within. - - parentServiceID := &pbresource.ID{ - Type: pbcatalog.ServiceType, - Tenancy: computedRoutesID.Tenancy, - Name: computedRoutesID.Name, - } - - parentServiceRef := resource.Reference(parentServiceID, "") - - // The bound reference collector is supposed to aggregate all - // references to resources that influence the production of - // a ComputedRoutes resource. - // - // We only add a reference to the collector if the following are ALL true: - // - // - We load the resource for some reason. - // - The resource is found. - // - We decided to use the information in that resource to produce - // ComputedRoutes. - // - // We currently add all of the data here, but only use the xRoute - // references to enhance the DependencyMappers for this Controller. In the - // future we could use the others, but for now they are harmless to include - // in the produced resource and is beneficial from an audit/debugging - // perspective to know all of the inputs that produced this output. - boundRefCollector := NewBoundReferenceCollector() - - parentServiceDec := related.GetService(parentServiceID) - if parentServiceDec == nil { - return &ComputedRoutesResult{ - ID: computedRoutesID, - Data: nil, // returning nil signals a delete is requested - } - } - parentServiceID = parentServiceDec.Resource.Id // get ULID out of it - - boundRefCollector.AddRefOrID(parentServiceRef) - - var ( - inMesh = false - parentMeshPort string - allowedPortProtocols = make(map[string]pbcatalog.Protocol) - ) - for _, port := range parentServiceDec.Data.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - inMesh = true - parentMeshPort = port.TargetPort - continue // skip - } - allowedPortProtocols[port.TargetPort] = port.Protocol - } - - if !inMesh { - return &ComputedRoutesResult{ - ID: computedRoutesID, - Data: nil, // returning nil signals a delete is requested - } - } - - computedRoutes := &pbmesh.ComputedRoutes{ - PortedConfigs: make(map[string]*pbmesh.ComputedPortRoutes), - } - - // Visit all of the routes relevant to this computed routes. - routeNodesByPort := make(map[string][]*inputRouteNode) - related.WalkRoutesForParentRef(parentServiceRef, func( - rk resource.ReferenceKey, - res *pbresource.Resource, - xroute types.XRouteData, - ) { - var ( - ports []string - wildcardedPort bool - ) - for _, ref := range xroute.GetParentRefs() { - if resource.ReferenceOrIDMatch(ref.Ref, parentServiceRef) { - if ref.Port == "" { - wildcardedPort = true - break - } - if _, ok := allowedPortProtocols[ref.Port]; ok { - ports = append(ports, ref.Port) - } - } - } - - // Do a port explosion. - if wildcardedPort { - ports = nil - for port := range allowedPortProtocols { - ports = append(ports, port) - } - } - - if len(ports) == 0 { - return // not relevant to this computed routes - } - boundRefCollector.AddRefOrID(res.Id) - - for _, port := range ports { - if port == "" { - panic("impossible to have an empty port here") - } - - var node *inputRouteNode - switch route := xroute.(type) { - case *pbmesh.HTTPRoute: - node = compileHTTPRouteNode(port, res, route, related, boundRefCollector) - case *pbmesh.GRPCRoute: - node = compileGRPCRouteNode(port, res, route, related, boundRefCollector) - case *pbmesh.TCPRoute: - node = compileTCPRouteNode(port, res, route, related, boundRefCollector) - default: - panic(fmt.Sprintf("unexpected xroute type: %T", xroute)) - } - - routeNodesByPort[node.ParentPort] = append(routeNodesByPort[node.ParentPort], node) - } - }) - - // Fill in defaults where there was no xroute defined at all. - for port, protocol := range allowedPortProtocols { - if _, ok := routeNodesByPort[port]; !ok { - var typ *pbresource.Type - - // enumcover:pbcatalog.Protocol - switch protocol { - case pbcatalog.Protocol_PROTOCOL_HTTP2: - typ = pbmesh.HTTPRouteType - case pbcatalog.Protocol_PROTOCOL_HTTP: - typ = pbmesh.HTTPRouteType - case pbcatalog.Protocol_PROTOCOL_GRPC: - typ = pbmesh.GRPCRouteType - case pbcatalog.Protocol_PROTOCOL_TCP: - typ = pbmesh.TCPRouteType - case pbcatalog.Protocol_PROTOCOL_MESH: - fallthrough // to default - case pbcatalog.Protocol_PROTOCOL_UNSPECIFIED: - fallthrough // to default - default: - continue // not possible - } - - routeNode := createDefaultRouteNode(parentServiceRef, parentMeshPort, port, typ) - - routeNodesByPort[port] = append(routeNodesByPort[port], routeNode) - } - } - - // First sort the input routes by the final criteria, so we can let the - // stable sort take care of the ultimate tiebreakers. - for port, routeNodes := range routeNodesByPort { - gammaInitialSortWrappedRoutes(routeNodes) - - // Now that they are sorted by age and name, we can figure out which - // xRoute should apply to each port (the first). - var top *inputRouteNode - for i, routeNode := range routeNodes { - if i == 0 { - top = routeNode - continue - } - if top.RouteType != routeNode.RouteType { - // This should only happen with user-provided ones, since we - // would never have two synthetic default routes at once. - res := routeNode.OriginalResource - if res != nil { - pending.AddConditions(resource.NewReferenceKey(res.Id), res, []*pbresource.Condition{ - ConditionConflictNotBoundToParentRef( - parentServiceRef, - port, - top.RouteType, - ), - }) - } - continue - } - top.AppendRulesFrom(routeNode) - top.AddTargetsFrom(routeNode) - } - - // Clear this field as it's no longer used and doesn't make sense once - // this represents multiple xRoutes or defaults. - top.OriginalResource = nil - - // Now we can do the big sort. - gammaSortRouteRules(top) - - // Inject catch-all rules to ensure stray requests will explicitly be blackholed. - if !top.Default { - if types.IsTCPRouteType(top.RouteType) { - if len(top.TCPRules) == 0 { - // User requests traffic blackhole. - appendDefaultRouteNode(top, types.NullRouteBackend) - } - } else { - // There are no match criteria on a TCPRoute, so never a need - // to add a catch-all. - appendDefaultRouteNode(top, types.NullRouteBackend) - } - } - - parentRef := &pbmesh.ParentReference{ - Ref: parentServiceRef, - Port: port, - } - - mc := &pbmesh.ComputedPortRoutes{ - UsingDefaultConfig: top.Default, - ParentRef: parentRef, - Protocol: allowedPortProtocols[port], - Targets: top.NewTargets, - } - - switch { - case resource.EqualType(top.RouteType, pbmesh.HTTPRouteType): - if mc.Protocol == pbcatalog.Protocol_PROTOCOL_TCP { - // The rest are HTTP-like - mc.Protocol = pbcatalog.Protocol_PROTOCOL_HTTP - } - mc.Config = &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: top.HTTPRules, - }, - } - case resource.EqualType(top.RouteType, pbmesh.GRPCRouteType): - mc.Protocol = pbcatalog.Protocol_PROTOCOL_GRPC - mc.Config = &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: top.GRPCRules, - }, - } - case resource.EqualType(top.RouteType, pbmesh.TCPRouteType): - mc.Protocol = pbcatalog.Protocol_PROTOCOL_TCP - mc.Config = &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: top.TCPRules, - }, - } - default: - panic("impossible") - } - - computedRoutes.PortedConfigs[port] = mc - - // The first pass collects the failover policies and generates additional targets. - for _, details := range mc.Targets { - svcRef := details.BackendRef.Ref - - svc := related.GetService(svcRef) - if svc == nil { - panic("impossible at this point; should already have been handled before getting here") - } - boundRefCollector.AddRefOrID(svcRef) - - failoverPolicy := related.GetFailoverPolicyForService(svcRef) - if failoverPolicy != nil { - simpleFailoverPolicy := catalog.SimplifyFailoverPolicy(svc.Data, failoverPolicy.Data) - portFailoverConfig, ok := simpleFailoverPolicy.PortConfigs[details.BackendRef.Port] - if ok { - boundRefCollector.AddRefOrID(failoverPolicy.Resource.Id) - - details.FailoverConfig = compileFailoverConfig( - related, - portFailoverConfig, - mc.Targets, - boundRefCollector, - ) - } - } - } - - // Do a second pass to handle shared things after we've dumped the - // failover legs into here. - for _, details := range mc.Targets { - svcRef := details.BackendRef.Ref - destPolicy := related.GetDestinationPolicyForService(svcRef) - if destPolicy != nil { - portDestConfig, ok := destPolicy.Data.PortConfigs[details.BackendRef.Port] - if ok { - boundRefCollector.AddRefOrID(destPolicy.Resource.Id) - details.DestinationConfig = portDestConfig - } - } - details.DestinationConfig = fillInDefaultDestConfig(details.DestinationConfig) - } - - // Pull target information up to the level of the rules. - switch x := mc.Config.(type) { - case *pbmesh.ComputedPortRoutes_Http: - route := x.Http - for _, rule := range route.Rules { - // If there are multiple legs (split) then choose the first actually set value. - var requestTimeoutFallback *durationpb.Duration - for _, backendRef := range rule.BackendRefs { - if backendRef.BackendTarget == types.NullRouteBackend { - continue - } - details, ok := mc.Targets[backendRef.BackendTarget] - if !ok { - continue - } - if details.DestinationConfig.RequestTimeout != nil { - requestTimeoutFallback = details.DestinationConfig.RequestTimeout - break - } - } - - if requestTimeoutFallback == nil { - continue // nothing to do - } - - if rule.Timeouts == nil { - rule.Timeouts = &pbmesh.HTTPRouteTimeouts{} - } - if rule.Timeouts.Request == nil { - rule.Timeouts.Request = requestTimeoutFallback - } - } - case *pbmesh.ComputedPortRoutes_Grpc: - route := x.Grpc - for _, rule := range route.Rules { - // If there are multiple legs (split) then choose the first actually set value. - var requestTimeoutFallback *durationpb.Duration - for _, backendRef := range rule.BackendRefs { - if backendRef.BackendTarget == types.NullRouteBackend { - continue - } - details, ok := mc.Targets[backendRef.BackendTarget] - if !ok { - continue - } - if details.DestinationConfig.RequestTimeout != nil { - requestTimeoutFallback = details.DestinationConfig.RequestTimeout - break - } - } - - if requestTimeoutFallback == nil { - continue // nothing to do - } - - if rule.Timeouts == nil { - rule.Timeouts = &pbmesh.HTTPRouteTimeouts{} - } - if rule.Timeouts.Request == nil { - rule.Timeouts.Request = requestTimeoutFallback - } - } - case *pbmesh.ComputedPortRoutes_Tcp: - } - - computedRoutes.PortedConfigs[port] = mc - } - - if len(computedRoutes.PortedConfigs) == 0 { - // This service only exposes a "mesh" port, so it cannot be another service's upstream. - return &ComputedRoutesResult{ - ID: computedRoutesID, - Data: nil, // returning nil signals a delete is requested - } - } - - computedRoutes.BoundReferences = boundRefCollector.List() - - return &ComputedRoutesResult{ - ID: computedRoutesID, - OwnerID: parentServiceID, - Data: computedRoutes, - } -} - -func compileFailoverConfig( - related *loader.RelatedResources, - failoverConfig *pbcatalog.FailoverConfig, - targets map[string]*pbmesh.BackendTargetDetails, - brc *BoundReferenceCollector, -) *pbmesh.ComputedFailoverConfig { - if failoverConfig == nil { - return nil - } - - cfc := &pbmesh.ComputedFailoverConfig{ - Destinations: make([]*pbmesh.ComputedFailoverDestination, 0, len(failoverConfig.Destinations)), - Mode: failoverConfig.Mode, - Regions: failoverConfig.Regions, - SamenessGroup: failoverConfig.SamenessGroup, - } - - for _, dest := range failoverConfig.Destinations { - backendRef := &pbmesh.BackendReference{ - Ref: dest.Ref, - Port: dest.Port, - Datacenter: dest.Datacenter, - } - - destSvcRef := dest.Ref - - svc := related.GetService(destSvcRef) - if svc != nil { - brc.AddRefOrID(svc.Resource.Id) - } - - var backendTargetName string - ok, meshPort := shouldRouteTrafficToBackend(svc, backendRef) - if !ok { - continue // skip this leg of failover for now - } - - destTargetName := types.BackendRefToComputedRoutesTarget(backendRef) - - if _, exists := targets[destTargetName]; !exists { - // Add to output as an indirect target. - targets[destTargetName] = &pbmesh.BackendTargetDetails{ - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_INDIRECT, - BackendRef: backendRef, - MeshPort: meshPort, - } - } - backendTargetName = destTargetName - - cfc.Destinations = append(cfc.Destinations, &pbmesh.ComputedFailoverDestination{ - BackendTarget: backendTargetName, - }) - } - return cfc -} - -func fillInDefaultDestConfig(target *pbmesh.DestinationConfig) *pbmesh.DestinationConfig { - base := defaultDestConfig() - - if target == nil { - return proto.Clone(base).(*pbmesh.DestinationConfig) - } - - out := proto.Clone(target).(*pbmesh.DestinationConfig) - - if out.ConnectTimeout == nil { - out.ConnectTimeout = base.GetConnectTimeout() - } - - return out -} - -func defaultDestConfig() *pbmesh.DestinationConfig { - return &pbmesh.DestinationConfig{ - ConnectTimeout: durationpb.New(5 * time.Second), - } -} - -func compileHTTPRouteNode( - port string, - res *pbresource.Resource, - route *pbmesh.HTTPRoute, - serviceGetter serviceGetter, - brc *BoundReferenceCollector, -) *inputRouteNode { - route = protoClone(route) - node := newInputRouteNode(port) - - node.RouteType = pbmesh.HTTPRouteType - node.OriginalResource = res - node.HTTPRules = make([]*pbmesh.ComputedHTTPRouteRule, 0, len(route.Rules)) - for _, rule := range route.Rules { - irule := &pbmesh.ComputedHTTPRouteRule{ - Matches: protoSliceClone(rule.Matches), - Filters: protoSliceClone(rule.Filters), - BackendRefs: make([]*pbmesh.ComputedHTTPBackendRef, 0, len(rule.BackendRefs)), - Timeouts: rule.Timeouts, - Retries: rule.Retries, - } - - // https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteRule - // - // If no matches are specified, the default is a prefix path match - // on “/”, which has the effect of matching every HTTP request. - if len(irule.Matches) == 0 { - irule.Matches = defaultHTTPRouteMatches() - } - for _, match := range irule.Matches { - if match.Path == nil { - // Path specifies a HTTP request path matcher. If this - // field is not specified, a default prefix match on - // the “/” path is provided. - match.Path = defaultHTTPPathMatch() - } - } - - for _, backendRef := range rule.BackendRefs { - // Infer port name from parent ref. - if backendRef.BackendRef.Port == "" { - backendRef.BackendRef.Port = port - } - - var ( - backendTarget string - backendSvc = serviceGetter.GetService(backendRef.BackendRef.Ref) - ) - if backendSvc != nil { - brc.AddRefOrID(backendSvc.Resource.Id) - } - if ok, meshPort := shouldRouteTrafficToBackend(backendSvc, backendRef.BackendRef); ok { - details := &pbmesh.BackendTargetDetails{ - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - BackendRef: backendRef.BackendRef, - MeshPort: meshPort, - } - backendTarget = node.AddTarget(backendRef.BackendRef, details) - } else { - backendTarget = types.NullRouteBackend - } - ibr := &pbmesh.ComputedHTTPBackendRef{ - BackendTarget: backendTarget, - Weight: backendRef.Weight, - Filters: backendRef.Filters, - } - irule.BackendRefs = append(irule.BackendRefs, ibr) - } - - node.HTTPRules = append(node.HTTPRules, irule) - } - - return node -} - -func compileGRPCRouteNode( - port string, - res *pbresource.Resource, - route *pbmesh.GRPCRoute, - serviceGetter serviceGetter, - brc *BoundReferenceCollector, -) *inputRouteNode { - route = protoClone(route) - - node := newInputRouteNode(port) - - node.RouteType = pbmesh.GRPCRouteType - node.OriginalResource = res - node.GRPCRules = make([]*pbmesh.ComputedGRPCRouteRule, 0, len(route.Rules)) - for _, rule := range route.Rules { - irule := &pbmesh.ComputedGRPCRouteRule{ - Matches: protoSliceClone(rule.Matches), - Filters: protoSliceClone(rule.Filters), - BackendRefs: make([]*pbmesh.ComputedGRPCBackendRef, 0, len(rule.BackendRefs)), - Timeouts: rule.Timeouts, - Retries: rule.Retries, - } - - // https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRouteRule - // - // If no matches are specified, the implementation MUST match every gRPC request. - if len(irule.Matches) == 0 { - irule.Matches = defaultGRPCRouteMatches() - } - - for _, backendRef := range rule.BackendRefs { - // Infer port name from parent ref. - if backendRef.BackendRef.Port == "" { - backendRef.BackendRef.Port = port - } - - var ( - backendTarget string - backendSvc = serviceGetter.GetService(backendRef.BackendRef.Ref) - ) - if backendSvc != nil { - brc.AddRefOrID(backendSvc.Resource.Id) - } - if ok, meshPort := shouldRouteTrafficToBackend(backendSvc, backendRef.BackendRef); ok { - details := &pbmesh.BackendTargetDetails{ - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - BackendRef: backendRef.BackendRef, - MeshPort: meshPort, - } - backendTarget = node.AddTarget(backendRef.BackendRef, details) - } else { - backendTarget = types.NullRouteBackend - } - - ibr := &pbmesh.ComputedGRPCBackendRef{ - BackendTarget: backendTarget, - Weight: backendRef.Weight, - Filters: backendRef.Filters, - } - irule.BackendRefs = append(irule.BackendRefs, ibr) - } - - node.GRPCRules = append(node.GRPCRules, irule) - } - - return node -} - -func compileTCPRouteNode( - port string, - res *pbresource.Resource, - route *pbmesh.TCPRoute, - serviceGetter serviceGetter, - brc *BoundReferenceCollector, -) *inputRouteNode { - route = protoClone(route) - - node := newInputRouteNode(port) - - node.RouteType = pbmesh.TCPRouteType - node.OriginalResource = res - node.TCPRules = make([]*pbmesh.ComputedTCPRouteRule, 0, len(route.Rules)) - for _, rule := range route.Rules { - irule := &pbmesh.ComputedTCPRouteRule{ - BackendRefs: make([]*pbmesh.ComputedTCPBackendRef, 0, len(rule.BackendRefs)), - } - - // https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute - - for _, backendRef := range rule.BackendRefs { - // Infer port name from parent ref. - if backendRef.BackendRef.Port == "" { - backendRef.BackendRef.Port = port - } - - var ( - backendTarget string - backendSvc = serviceGetter.GetService(backendRef.BackendRef.Ref) - ) - if backendSvc != nil { - brc.AddRefOrID(backendSvc.Resource.Id) - } - if ok, meshPort := shouldRouteTrafficToBackend(backendSvc, backendRef.BackendRef); ok { - details := &pbmesh.BackendTargetDetails{ - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - BackendRef: backendRef.BackendRef, - MeshPort: meshPort, - } - backendTarget = node.AddTarget(backendRef.BackendRef, details) - } else { - backendTarget = types.NullRouteBackend - } - - ibr := &pbmesh.ComputedTCPBackendRef{ - BackendTarget: backendTarget, - Weight: backendRef.Weight, - } - irule.BackendRefs = append(irule.BackendRefs, ibr) - } - - node.TCPRules = append(node.TCPRules, irule) - } - - return node -} - -func shouldRouteTrafficToBackend(backendSvc *types.DecodedService, backendRef *pbmesh.BackendReference) (bool, string) { - if backendSvc == nil { - return false, "" - } - - var ( - found = false - inMesh = false - meshPort string - ) - for _, port := range backendSvc.Data.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - inMesh = true - meshPort = port.TargetPort - continue - } - if port.TargetPort == backendRef.Port { - found = true - } - } - - return inMesh && found, meshPort -} - -func createDefaultRouteNode( - parentServiceRef *pbresource.Reference, - parentMeshPort string, - port string, - typ *pbresource.Type, -) *inputRouteNode { - // always add the parent as a possible target due to catch-all - defaultBackendRef := &pbmesh.BackendReference{ - Ref: parentServiceRef, - Port: port, - } - - routeNode := newInputRouteNode(port) - - defaultBackendTarget := routeNode.AddTarget(defaultBackendRef, &pbmesh.BackendTargetDetails{ - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - BackendRef: defaultBackendRef, - MeshPort: parentMeshPort, - }) - switch { - case resource.EqualType(pbmesh.HTTPRouteType, typ): - routeNode.RouteType = pbmesh.HTTPRouteType - appendDefaultHTTPRouteRule(routeNode, defaultBackendTarget) - case resource.EqualType(pbmesh.GRPCRouteType, typ): - routeNode.RouteType = pbmesh.GRPCRouteType - appendDefaultGRPCRouteRule(routeNode, defaultBackendTarget) - case resource.EqualType(pbmesh.TCPRouteType, typ): - fallthrough - default: - routeNode.RouteType = pbmesh.TCPRouteType - appendDefaultTCPRouteRule(routeNode, defaultBackendTarget) - } - - routeNode.Default = true - return routeNode -} - -func appendDefaultRouteNode( - routeNode *inputRouteNode, - defaultBackendTarget string, -) { - switch { - case resource.EqualType(pbmesh.HTTPRouteType, routeNode.RouteType): - appendDefaultHTTPRouteRule(routeNode, defaultBackendTarget) - case resource.EqualType(pbmesh.GRPCRouteType, routeNode.RouteType): - appendDefaultGRPCRouteRule(routeNode, defaultBackendTarget) - case resource.EqualType(pbmesh.TCPRouteType, routeNode.RouteType): - fallthrough - default: - appendDefaultTCPRouteRule(routeNode, defaultBackendTarget) - } -} - -func appendDefaultHTTPRouteRule( - routeNode *inputRouteNode, - backendTarget string, -) { - routeNode.HTTPRules = append(routeNode.HTTPRules, &pbmesh.ComputedHTTPRouteRule{ - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendTarget, - }}, - }) -} - -func appendDefaultGRPCRouteRule( - routeNode *inputRouteNode, - backendTarget string, -) { - routeNode.GRPCRules = append(routeNode.GRPCRules, &pbmesh.ComputedGRPCRouteRule{ - Matches: defaultGRPCRouteMatches(), - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendTarget, - }}, - }) -} - -func appendDefaultTCPRouteRule( - routeNode *inputRouteNode, - backendTarget string, -) { - routeNode.TCPRules = append(routeNode.TCPRules, &pbmesh.ComputedTCPRouteRule{ - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendTarget, - }}, - }) -} - -func defaultHTTPRouteMatches() []*pbmesh.HTTPRouteMatch { - return []*pbmesh.HTTPRouteMatch{{ - Path: defaultHTTPPathMatch(), - }} -} - -func defaultHTTPPathMatch() *pbmesh.HTTPPathMatch { - return &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - } -} - -func defaultGRPCRouteMatches() []*pbmesh.GRPCRouteMatch { - return []*pbmesh.GRPCRouteMatch{{}} -} diff --git a/internal/mesh/internal/controllers/routes/generate_test.go b/internal/mesh/internal/controllers/routes/generate_test.go deleted file mode 100644 index 4dc4a9c0793e7..0000000000000 --- a/internal/mesh/internal/controllers/routes/generate_test.go +++ /dev/null @@ -1,1684 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/durationpb" - - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/loader" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestGenerateComputedRoutes(t *testing.T) { - registry := resource.NewRegistry() - types.Register(registry) - catalog.RegisterTypes(registry) - - run := func( - t *testing.T, - related *loader.RelatedResources, - expect []*ComputedRoutesResult, - expectPending PendingStatuses, - ) { - pending := make(PendingStatuses) - - got := GenerateComputedRoutes(related, pending) - - prototest.AssertElementsMatch[*ComputedRoutesResult]( - t, expect, got, - ) - - require.Len(t, pending, len(expectPending)) - if len(expectPending) > 0 { - for rk, expectItem := range expectPending { - gotItem, ok := pending[rk] - require.True(t, ok, "missing expected pending status for %v", rk) - prototest.AssertDeepEqual(t, expectItem, gotItem) - } - for rk := range pending { - _, ok := expectPending[rk] - require.True(t, ok, "extra pending status for %v", rk) - } - } - } - - newService := func(name string, data *pbcatalog.Service) *types.DecodedService { - svc := rtest.Resource(pbcatalog.ServiceType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data).Build() - rtest.ValidateAndNormalize(t, registry, svc) - return rtest.MustDecode[*pbcatalog.Service](t, svc) - } - - newHTTPRoute := func(name string, data *pbmesh.HTTPRoute) *types.DecodedHTTPRoute { - svc := rtest.Resource(pbmesh.HTTPRouteType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data).Build() - rtest.ValidateAndNormalize(t, registry, svc) - return rtest.MustDecode[*pbmesh.HTTPRoute](t, svc) - } - newGRPCRoute := func(name string, data *pbmesh.GRPCRoute) *types.DecodedGRPCRoute { - svc := rtest.Resource(pbmesh.GRPCRouteType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data).Build() - rtest.ValidateAndNormalize(t, registry, svc) - return rtest.MustDecode[*pbmesh.GRPCRoute](t, svc) - } - newTCPRoute := func(name string, data *pbmesh.TCPRoute) *types.DecodedTCPRoute { - svc := rtest.Resource(pbmesh.TCPRouteType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data).Build() - rtest.ValidateAndNormalize(t, registry, svc) - return rtest.MustDecode[*pbmesh.TCPRoute](t, svc) - } - - newDestPolicy := func(name string, data *pbmesh.DestinationPolicy) *types.DecodedDestinationPolicy { - policy := rtest.Resource(pbmesh.DestinationPolicyType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data).Build() - rtest.ValidateAndNormalize(t, registry, policy) - return rtest.MustDecode[*pbmesh.DestinationPolicy](t, policy) - } - - newFailPolicy := func(name string, data *pbcatalog.FailoverPolicy) *types.DecodedFailoverPolicy { - policy := rtest.Resource(pbcatalog.FailoverPolicyType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data).Build() - rtest.ValidateAndNormalize(t, registry, policy) - return rtest.MustDecode[*pbcatalog.FailoverPolicy](t, policy) - } - - backendName := func(name, port string) string { - return fmt.Sprintf("catalog.v2beta1.Service/default.local.default/%s?port=%s", name, port) - } - - var ( - apiServiceID = rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() - apiServiceRef = resource.Reference(apiServiceID, "") - apiComputedRoutesID = rtest.Resource(pbmesh.ComputedRoutesType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() - - fooServiceID = rtest.Resource(pbcatalog.ServiceType, "foo"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() - fooServiceRef = resource.Reference(fooServiceID, "") - - barServiceID = rtest.Resource(pbcatalog.ServiceType, "bar"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() - barServiceRef = resource.Reference(barServiceID, "") - - deadServiceID = rtest.Resource(pbcatalog.ServiceType, "dead"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() - deadServiceRef = resource.Reference(deadServiceID, "") - ) - - t.Run("none", func(t *testing.T) { - run(t, loader.NewRelatedResources(), nil, nil) - }) - - t.Run("no aligned service", func(t *testing.T) { - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID) - expect := []*ComputedRoutesResult{ - { - ID: apiComputedRoutesID, - Data: nil, - }, - } - run(t, related, expect, nil) - }) - - t.Run("aligned service not in mesh", func(t *testing.T) { - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources(newService("api", &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - }, - })) - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - Data: nil, - }} - run(t, related, expect, nil) - }) - - t.Run("aligned service in mesh but no actual ports", func(t *testing.T) { - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources(newService("api", &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - })) - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - Data: nil, - }} - run(t, related, expect, nil) - }) - - t.Run("tcp service with default route", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources(newService("api", apiServiceData)) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{{ - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("api", "tcp"), - }}, - }}, - }, - }, - UsingDefaultConfig: true, - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "tcp"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "tcp", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }}, - } - run(t, related, expect, nil) - }) - - for protoName, protocol := range map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "http2": pbcatalog.Protocol_PROTOCOL_HTTP2, - } { - t.Run(protoName+" service with default route", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: protoName, Protocol: protocol}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources(newService("api", apiServiceData)) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - protoName: { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", protoName), - }}, - }}, - }, - }, - UsingDefaultConfig: true, - ParentRef: newParentRef(apiServiceRef, protoName), - Protocol: protocol, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", protoName): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, protoName, ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - } - - t.Run("grpc service with default route", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources(newService("api", apiServiceData)) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "grpc": { - Config: &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: []*pbmesh.ComputedGRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("api", "grpc"), - }}, - }}, - }, - }, - UsingDefaultConfig: true, - ParentRef: newParentRef(apiServiceRef, "grpc"), - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "grpc"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "grpc", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("all ports with a mix of routes", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "http2", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "http2", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - } - - tcpRoute1 := &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "tcp"), - }, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http2"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - grpcRoute1 := &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "grpc"), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - newTCPRoute("api-tcp-route1", tcpRoute1), - newHTTPRoute("api-http-route1", httpRoute1), - newGRPCRoute("api-grpc-route1", grpcRoute1), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - newRef(pbmesh.GRPCRouteType, "api-grpc-route1"), - newRef(pbmesh.HTTPRouteType, "api-http-route1"), - newRef(pbmesh.TCPRouteType, "api-tcp-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{{ - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), - }}, - }}, - }, - }, - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "tcp", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "http2": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http2"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http2", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - "grpc": { - Config: &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: []*pbmesh.ComputedGRPCRouteRule{ - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), - }}, - }, - { - Matches: []*pbmesh.GRPCRouteMatch{{}}, - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "grpc"), - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "grpc", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("all ports with a wildcard route only bypassing the protocol", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "http2", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "http2", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - newHTTPRoute("api-http-route1", httpRoute1), - ) - - chunk := func(portName string, protocol pbcatalog.Protocol) *pbmesh.ComputedPortRoutes { - return &pbmesh.ComputedPortRoutes{ - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", portName), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, portName), - Protocol: protocol, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", portName): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, portName, ""), - DestinationConfig: defaultDestConfig(), - }, - }, - } - } - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - newRef(pbmesh.HTTPRouteType, "api-http-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - // note: tcp has been upgraded to http in the presence of an HTTPRoute - "tcp": chunk("tcp", pbcatalog.Protocol_PROTOCOL_HTTP), - "http": chunk("http", pbcatalog.Protocol_PROTOCOL_HTTP), - "http2": chunk("http2", pbcatalog.Protocol_PROTOCOL_HTTP2), - "grpc": chunk("grpc", pbcatalog.Protocol_PROTOCOL_GRPC), - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("stale-weird: stale mapper causes visit of irrelevant xRoute", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - apiSvc := newService("api", apiServiceData) - fooSvc := newService("foo", fooServiceData) - apiHTTPRoute1 := newHTTPRoute("api-http-route1", httpRoute1) - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). // deliberately skip adding 'foo' here to exercise the bug - AddResources(apiSvc, fooSvc, apiHTTPRoute1) - - // Update this after the fact, but don't update the inner indexing in - // the 'related' struct. - { - httpRoute1.ParentRefs[0] = newParentRef(newRef(pbcatalog.ServiceType, "foo"), "") - apiHTTPRoute1.Data = httpRoute1 - - anyData, err := anypb.New(httpRoute1) - require.NoError(t, err) - apiHTTPRoute1.Resource.Data = anyData - } - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http"), - }}, - }}, - }, - }, - UsingDefaultConfig: true, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("stale-weird: parent ref uses invalid port", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - // Using bad parent port (www). - newParentRef(newRef(pbcatalog.ServiceType, "api"), "www"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "http", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - newHTTPRoute("api-http-route1", httpRoute1), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http"), - }}, - }}, - }, - }, - UsingDefaultConfig: true, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(apiServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("overlapping xRoutes", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRouteData := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - // Using bad parent port (www). - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "http", ""), - }}, - }}, - } - httpRoute := newHTTPRoute("api-http-route", httpRouteData) - - tcpRouteData := &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - // Using bad parent port (www). - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "http", ""), - }}, - }}, - } - tcpRoute := newTCPRoute("api-tcp-route", tcpRouteData) - // Force them to have the same generation, so that we fall back on - // lexicographic sort on the names as tiebreaker. - // - // api-http-route < api-tcp-route - tcpRoute.Resource.Generation = httpRoute.Resource.Generation - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - httpRoute, - tcpRoute, - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(httpRoute.Resource.Id, ""), - resource.Reference(tcpRoute.Resource.Id, ""), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - - expectPending := make(PendingStatuses) - expectPending[resource.NewReferenceKey(tcpRoute.Resource.Id)] = &PendingResourceStatusUpdate{ - ID: tcpRoute.Resource.Id, - Generation: tcpRoute.Resource.Generation, - NewConditions: []*pbresource.Condition{ - ConditionConflictNotBoundToParentRef( - apiServiceRef, - "http", - pbmesh.HTTPRouteType, - ), - }, - } - - run(t, related, expect, expectPending) - }) - - t.Run("two http routes", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - barServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"bar-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/gir", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - httpRoute2 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/zim", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(barServiceRef, "", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - newService("bar", barServiceData), - newHTTPRoute("api-http-route1", httpRoute1), - newHTTPRoute("api-http-route2", httpRoute2), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - barServiceRef, - fooServiceRef, - newRef(pbmesh.HTTPRouteType, "api-http-route1"), - newRef(pbmesh.HTTPRouteType, "api-http-route2"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/gir", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/zim", - }, - }}, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("bar", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - backendName("bar", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(barServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("http route with empty match path", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: nil, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - newHTTPRoute("api-http-route1", httpRoute1), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - newRef(pbmesh.HTTPRouteType, "api-http-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("stale-weird: destination with no service", func(t *testing.T) { - t.Run("http", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newHTTPRoute("api-http-route1", httpRoute1), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - newRef(pbmesh.HTTPRouteType, "api-http-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - t.Run("grpc", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "grpc", Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - }, - } - - grpcRoute1 := &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "grpc"), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newGRPCRoute("api-grpc-route1", grpcRoute1), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - newRef(pbmesh.GRPCRouteType, "api-grpc-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "grpc": { - ParentRef: newParentRef(apiServiceRef, "grpc"), - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - Config: &pbmesh.ComputedPortRoutes_Grpc{ - Grpc: &pbmesh.ComputedGRPCRoute{ - Rules: []*pbmesh.ComputedGRPCRouteRule{ - { - Matches: defaultGRPCRouteMatches(), - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - { - Matches: defaultGRPCRouteMatches(), - BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - t.Run("tcp", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - }, - } - - tcpRoute1 := &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "tcp"), - }, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newTCPRoute("api-tcp-route1", tcpRoute1), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - newRef(pbmesh.TCPRouteType, "api-tcp-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "tcp": { - ParentRef: newParentRef(apiServiceRef, "tcp"), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{ - Rules: []*pbmesh.ComputedTCPRouteRule{ - { - BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - }) - - t.Run("stale-weird: http destination with service not in mesh", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - newHTTPRoute("api-http-route1", httpRoute1), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - newRef(pbmesh.HTTPRouteType, "api-http-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("http route with dest policy", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - destPolicy := &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - }, - }, - } - portDestConfig := &pbmesh.DestinationConfig{ - ConnectTimeout: durationpb.New(55 * time.Second), - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - newHTTPRoute("api-http-route1", httpRoute1), - newDestPolicy("foo", destPolicy), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - newRef(pbmesh.DestinationPolicyType, "foo"), - newRef(pbmesh.HTTPRouteType, "api-http-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - DestinationConfig: portDestConfig, - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) - - t.Run("http route with failover policy", func(t *testing.T) { - apiServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - fooServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"foo-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - barServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"bar-"}, - }, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - } - - httpRoute1 := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(fooServiceRef, "", ""), - }}, - }}, - } - - failoverPolicy := &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: barServiceRef}, - {Ref: deadServiceRef}, // no service - }, - }, - } - portFailoverConfig := &pbmesh.ComputedFailoverConfig{ - Destinations: []*pbmesh.ComputedFailoverDestination{ - {BackendTarget: backendName("bar", "http")}, - // we skip the dead route - }, - } - - related := loader.NewRelatedResources(). - AddComputedRoutesIDs(apiComputedRoutesID). - AddResources( - newService("api", apiServiceData), - newService("foo", fooServiceData), - newService("bar", barServiceData), - newHTTPRoute("api-http-route1", httpRoute1), - newFailPolicy("foo", failoverPolicy), - ) - - expect := []*ComputedRoutesResult{{ - ID: apiComputedRoutesID, - OwnerID: apiServiceID, - Data: &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - newRef(pbcatalog.FailoverPolicyType, "foo"), - apiServiceRef, - barServiceRef, - fooServiceRef, - newRef(pbmesh.HTTPRouteType, "api-http-route1"), - }, - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Http{ - Http: &pbmesh.ComputedHTTPRoute{ - Rules: []*pbmesh.ComputedHTTPRouteRule{ - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), - }}, - }, - { - Matches: defaultHTTPRouteMatches(), - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: types.NullRouteBackend, - }}, - }, - }, - }, - }, - ParentRef: newParentRef(apiServiceRef, "http"), - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(fooServiceRef, "http", ""), - FailoverConfig: portFailoverConfig, - DestinationConfig: defaultDestConfig(), - }, - backendName("bar", "http"): { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_INDIRECT, - MeshPort: "mesh", - BackendRef: newBackendRef(barServiceRef, "http", ""), - DestinationConfig: defaultDestConfig(), - }, - }, - }, - }, - }, - }} - run(t, related, expect, nil) - }) -} diff --git a/internal/mesh/internal/controllers/routes/intermediate.go b/internal/mesh/internal/controllers/routes/intermediate.go deleted file mode 100644 index bc7aa348eea4e..0000000000000 --- a/internal/mesh/internal/controllers/routes/intermediate.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// inputRouteNode is a dressed up version of an XRoute meant as working state -// for one pass of the compilation procedure. -type inputRouteNode struct { - ParentPort string // always set - - RouteType *pbresource.Type - Default bool - - // only one of these can be set to non-empty - HTTPRules []*pbmesh.ComputedHTTPRouteRule - GRPCRules []*pbmesh.ComputedGRPCRouteRule - TCPRules []*pbmesh.ComputedTCPRouteRule - - NewTargets map[string]*pbmesh.BackendTargetDetails - - // This field is non-nil for nodes based on a single xRoute, and nil for - // composite nodes or default nodes. - OriginalResource *pbresource.Resource -} - -func newInputRouteNode(port string) *inputRouteNode { - return &inputRouteNode{ - ParentPort: port, - NewTargets: make(map[string]*pbmesh.BackendTargetDetails), - } -} - -func (n *inputRouteNode) AddTarget(backendRef *pbmesh.BackendReference, data *pbmesh.BackendTargetDetails) string { - n.Default = false - key := types.BackendRefToComputedRoutesTarget(backendRef) - - if _, ok := n.NewTargets[key]; !ok { - n.NewTargets[key] = data - } - - return key -} - -func (n *inputRouteNode) AddTargetsFrom(next *inputRouteNode) { - n.Default = false - for key, details := range next.NewTargets { - if _, ok := n.NewTargets[key]; !ok { - n.NewTargets[key] = details // add if not already there - } - } -} - -func (n *inputRouteNode) AppendRulesFrom(next *inputRouteNode) { - n.Default = false - switch { - case resource.EqualType(n.RouteType, pbmesh.HTTPRouteType): - n.HTTPRules = append(n.HTTPRules, next.HTTPRules...) - case resource.EqualType(n.RouteType, pbmesh.GRPCRouteType): - n.GRPCRules = append(n.GRPCRules, next.GRPCRules...) - case resource.EqualType(n.RouteType, pbmesh.TCPRouteType): - n.TCPRules = append(n.TCPRules, next.TCPRules...) - default: - panic("impossible") - } -} diff --git a/internal/mesh/internal/controllers/routes/loader/loader.go b/internal/mesh/internal/controllers/routes/loader/loader.go deleted file mode 100644 index 4e7be5e64971f..0000000000000 --- a/internal/mesh/internal/controllers/routes/loader/loader.go +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package loader - -import ( - "context" - "fmt" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/xroutemapper" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type loader struct { - mapper *xroutemapper.Mapper - - mem *memoizingLoader - - // output var - out *RelatedResources - - // working state - mcToLoad map[resource.ReferenceKey]struct{} - mcDone map[resource.ReferenceKey]struct{} -} - -func LoadResourcesForComputedRoutes( - ctx context.Context, - loggerFor func(*pbresource.ID) hclog.Logger, - client pbresource.ResourceServiceClient, - mapper *xroutemapper.Mapper, - computedRoutesID *pbresource.ID, -) (*RelatedResources, error) { - if loggerFor == nil { - loggerFor = func(_ *pbresource.ID) hclog.Logger { - return hclog.NewNullLogger() - } - } - loader := &loader{ - mapper: mapper, - mem: newMemoizingLoader(client), - mcToLoad: make(map[resource.ReferenceKey]struct{}), - mcDone: make(map[resource.ReferenceKey]struct{}), - } - - if err := loader.load(ctx, loggerFor, computedRoutesID); err != nil { - return nil, err - } - - return loader.out, nil -} - -func (l *loader) requestLoad(computedRoutesID *pbresource.ID) { - if !resource.EqualType(computedRoutesID.Type, pbmesh.ComputedRoutesType) { - panic("input must be a ComputedRoutes type") - } - rk := resource.NewReferenceKey(computedRoutesID) - - if _, done := l.mcDone[rk]; done { - return - } - l.mcToLoad[rk] = struct{}{} -} - -func (l *loader) markLoaded(computedRoutesID *pbresource.ID) { - if !resource.EqualType(computedRoutesID.Type, pbmesh.ComputedRoutesType) { - panic("input must be a ComputedRoutes type") - } - rk := resource.NewReferenceKey(computedRoutesID) - - l.mcDone[rk] = struct{}{} - delete(l.mcToLoad, rk) -} - -func (l *loader) nextRequested() *pbresource.ID { - for rk := range l.mcToLoad { - return rk.ToID() - } - return nil -} - -func (l *loader) load( - ctx context.Context, - loggerFor func(*pbresource.ID) hclog.Logger, - computedRoutesID *pbresource.ID, -) error { - l.out = NewRelatedResources() - - // Seed the graph fetch for our starting position. - l.requestLoad(computedRoutesID) - - for { - mcID := l.nextRequested() - if mcID == nil { - break - } - - if err := l.loadOne(ctx, loggerFor, mcID); err != nil { - return err - } - } - - return nil -} - -func (l *loader) loadOne( - ctx context.Context, - loggerFor func(*pbresource.ID) hclog.Logger, - computedRoutesID *pbresource.ID, -) error { - logger := loggerFor(computedRoutesID) - - // There is one computed routes for the entire service (perfect name alignment). - // - // All ports are embedded within. - - parentServiceID := changeResourceType(computedRoutesID, pbcatalog.ServiceType) - parentServiceRef := resource.Reference(parentServiceID, "") - - if err := l.loadUpstreamService(ctx, logger, parentServiceID); err != nil { - return err - } - - if err := l.gatherXRoutesAsInput(ctx, logger, parentServiceRef); err != nil { - return err - } - - l.out.AddComputedRoutesIDs(computedRoutesID) - - l.markLoaded(computedRoutesID) - - return nil -} - -func (l *loader) gatherXRoutesAsInput( - ctx context.Context, - logger hclog.Logger, - parentServiceRef *pbresource.Reference, -) error { - routeIDs := l.mapper.RouteIDsByParentServiceRef(parentServiceRef) - - // read the xRoutes - for _, routeID := range routeIDs { - switch { - case resource.EqualType(routeID.Type, pbmesh.HTTPRouteType): - route, err := l.mem.GetHTTPRoute(ctx, routeID) - if err != nil { - return fmt.Errorf("the resource service has returned an unexpected error loading %s: %w", routeID, err) - } - var routeData types.XRouteData - if route != nil { - routeData = route.Data - } - err = l.gatherSingleXRouteAsInput(ctx, logger, routeID, routeData, func() { - l.out.AddHTTPRoute(route) - }) - if err != nil { - return fmt.Errorf("the resource service has returned an unexpected error loading %s: %w", routeID, err) - } - case resource.EqualType(routeID.Type, pbmesh.GRPCRouteType): - route, err := l.mem.GetGRPCRoute(ctx, routeID) - if err != nil { - return fmt.Errorf("the resource service has returned an unexpected error loading %s: %w", routeID, err) - } - var routeData types.XRouteData - if route != nil { - routeData = route.Data - } - err = l.gatherSingleXRouteAsInput(ctx, logger, routeID, routeData, func() { - l.out.AddGRPCRoute(route) - }) - if err != nil { - return fmt.Errorf("the resource service has returned an unexpected error loading %s: %w", routeID, err) - } - case resource.EqualType(routeID.Type, pbmesh.TCPRouteType): - route, err := l.mem.GetTCPRoute(ctx, routeID) - if err != nil { - return fmt.Errorf("the resource service has returned an unexpected error loading %s: %w", routeID, err) - } - var routeData types.XRouteData - if route != nil { - routeData = route.Data - } - err = l.gatherSingleXRouteAsInput(ctx, logger, routeID, routeData, func() { - l.out.AddTCPRoute(route) - }) - if err != nil { - return fmt.Errorf("the resource service has returned an unexpected error loading %s: %w", routeID, err) - } - default: - logger.Warn("skipping xRoute reference of unknown type", "ID", resource.IDToString(routeID)) - continue - } - } - - return nil -} - -func (l *loader) loadUpstreamService( - ctx context.Context, - logger hclog.Logger, - svcID *pbresource.ID, -) error { - logger = logger.With("service-id", resource.IDToString(svcID)) - - service, err := l.mem.GetService(ctx, svcID) - if err != nil { - logger.Error("error retrieving the service", "serviceID", svcID, "error", err) - return err - } - if service != nil { - l.out.AddService(service) - - failoverPolicyID := changeResourceType(svcID, pbcatalog.FailoverPolicyType) - failoverPolicy, err := l.mem.GetFailoverPolicy(ctx, failoverPolicyID) - if err != nil { - logger.Error("error retrieving the failover policy", "failoverPolicyID", failoverPolicyID, "error", err) - return err - } - if failoverPolicy != nil { - l.mapper.TrackFailoverPolicy(failoverPolicy) - l.out.AddFailoverPolicy(failoverPolicy) - - destRefs := failoverPolicy.Data.GetUnderlyingDestinationRefs() - for _, destRef := range destRefs { - destID := resource.IDFromReference(destRef) - - failService, err := l.mem.GetService(ctx, destID) - if err != nil { - logger.Error("error retrieving a failover destination service", - "serviceID", destID, "error", err) - return err - } - if failService != nil { - l.out.AddService(failService) - - if err := l.loadDestConfig(ctx, logger, failService.Resource.Id); err != nil { - return err - } - } - } - } else { - l.mapper.UntrackFailoverPolicy(failoverPolicyID) - } - - if err := l.loadDestConfig(ctx, logger, svcID); err != nil { - return err - } - } - - return nil -} - -func (l *loader) loadDestConfig( - ctx context.Context, - logger hclog.Logger, - svcID *pbresource.ID, -) error { - destPolicyID := changeResourceType(svcID, pbmesh.DestinationPolicyType) - destPolicy, err := l.mem.GetDestinationPolicy(ctx, destPolicyID) - if err != nil { - logger.Error("error retrieving the destination config", "destPolicyID", destPolicyID, "error", err) - return err - } - if destPolicy != nil { - l.out.AddDestinationPolicy(destPolicy) - } - return nil -} - -func (l *loader) gatherSingleXRouteAsInput( - ctx context.Context, - logger hclog.Logger, - routeID *pbresource.ID, - route types.XRouteData, - relatedRouteCaptureFn func(), -) error { - if route == nil { - logger.Trace("XRoute has been deleted") - l.mapper.UntrackXRoute(routeID) - return nil - } - l.mapper.TrackXRoute(routeID, route) - - relatedRouteCaptureFn() - - for _, parentRef := range route.GetParentRefs() { - if types.IsServiceType(parentRef.Ref.Type) { - parentComputedRoutesID := &pbresource.ID{ - Type: pbmesh.ComputedRoutesType, - Tenancy: parentRef.Ref.Tenancy, - Name: parentRef.Ref.Name, - } - // Note: this will only schedule things to load that have not already been loaded - l.requestLoad(parentComputedRoutesID) - } - } - - for _, backendRef := range route.GetUnderlyingBackendRefs() { - if types.IsServiceType(backendRef.Ref.Type) { - svcID := resource.IDFromReference(backendRef.Ref) - if err := l.loadUpstreamService(ctx, logger, svcID); err != nil { - return err - } - } - } - - return nil -} - -func changeResourceType(id *pbresource.ID, newType *pbresource.Type) *pbresource.ID { - return &pbresource.ID{ - Type: newType, - Tenancy: id.Tenancy, - Name: id.Name, - } -} diff --git a/internal/mesh/internal/controllers/routes/loader/loader_test.go b/internal/mesh/internal/controllers/routes/loader/loader_test.go deleted file mode 100644 index a665635d05f7f..0000000000000 --- a/internal/mesh/internal/controllers/routes/loader/loader_test.go +++ /dev/null @@ -1,413 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package loader - -import ( - "testing" - "time" - - "github.com/hashicorp/go-hclog" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/durationpb" - - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/xroutemapper" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestLoadResourcesForComputedRoutes(t *testing.T) { - ctx := testutil.TestContext(t) - rclient := svctest.RunResourceService(t, types.Register, catalog.RegisterTypes) - rt := controller.Runtime{ - Client: rclient, - Logger: testutil.Logger(t), - } - client := rtest.NewClient(rclient) - - loggerFor := func(id *pbresource.ID) hclog.Logger { - return rt.Logger.With("resource-id", id) - } - - mapper := xroutemapper.New() - - deleteRes := func(id *pbresource.ID, untrack bool) { - client.MustDelete(t, id) - if untrack { - switch { - case types.IsRouteType(id.Type): - mapper.UntrackXRoute(id) - case types.IsFailoverPolicyType(id.Type): - mapper.UntrackFailoverPolicy(id) - } - } - } - - writeHTTP := func(name string, data *pbmesh.HTTPRoute) *types.DecodedHTTPRoute { - res := rtest.Resource(pbmesh.HTTPRouteType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Write(t, client) - mapper.TrackXRoute(res.Id, data) - dec, err := resource.Decode[*pbmesh.HTTPRoute](res) - require.NoError(t, err) - return dec - } - - writeGRPC := func(name string, data *pbmesh.GRPCRoute) *types.DecodedGRPCRoute { - res := rtest.Resource(pbmesh.GRPCRouteType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Write(t, client) - mapper.TrackXRoute(res.Id, data) - dec, err := resource.Decode[*pbmesh.GRPCRoute](res) - require.NoError(t, err) - return dec - } - _ = writeGRPC // TODO - - writeTCP := func(name string, data *pbmesh.TCPRoute) *types.DecodedTCPRoute { - res := rtest.Resource(pbmesh.TCPRouteType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Write(t, client) - mapper.TrackXRoute(res.Id, data) - dec, err := resource.Decode[*pbmesh.TCPRoute](res) - require.NoError(t, err) - return dec - } - _ = writeTCP // TODO - - writeDestPolicy := func(name string, data *pbmesh.DestinationPolicy) *types.DecodedDestinationPolicy { - res := rtest.Resource(pbmesh.DestinationPolicyType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Write(t, client) - dec, err := resource.Decode[*pbmesh.DestinationPolicy](res) - require.NoError(t, err) - return dec - } - - writeFailover := func(name string, data *pbcatalog.FailoverPolicy) *types.DecodedFailoverPolicy { - res := rtest.Resource(pbcatalog.FailoverPolicyType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Write(t, client) - dec, err := resource.Decode[*pbcatalog.FailoverPolicy](res) - require.NoError(t, err) - return dec - } - - writeService := func(name string, data *pbcatalog.Service) *types.DecodedService { - res := rtest.Resource(pbcatalog.ServiceType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Write(t, client) - dec, err := resource.Decode[*pbcatalog.Service](res) - require.NoError(t, err) - return dec - } - - ///////////////////////////////////// - - // Init some port-aligned services. - apiSvc := writeService("api", &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }) - adminSvc := writeService("admin", &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }) - fooSvc := writeService("foo", &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }) - barSvc := writeService("bar", &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }) - - apiRoutesID := &pbresource.ID{ - Type: pbmesh.ComputedRoutesType, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "api", - } - adminRoutesID := &pbresource.ID{ - Type: pbmesh.ComputedRoutesType, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "admin", - } - - testutil.RunStep(t, "only service", func(t *testing.T) { - out, err := LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, mapper, apiRoutesID) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, NewRelatedResources().AddResources( - apiSvc, - ).AddComputedRoutesIDs(apiRoutesID), out) - require.Equal(t, doubleMap(t /* empty */), out.RoutesByParentRef) - }) - - // Write one silly http route - route1 := writeHTTP("api-route1", &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: newRef(pbcatalog.ServiceType, "api"), - // all ports - }}, - }) - - testutil.RunStep(t, "one silly route", func(t *testing.T) { - out, err := LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, mapper, apiRoutesID) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, NewRelatedResources().AddResources( - apiSvc, - route1, - ).AddComputedRoutesIDs(apiRoutesID), out) - require.Equal(t, doubleMap(t, - apiSvc, route1, - ), out.RoutesByParentRef) - }) - - // add a second route that is more interesting and is TCP - route2 := writeTCP("api-route2", &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: newRef(pbcatalog.ServiceType, "api"), - // all ports - }}, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{ - { - BackendRef: &pbmesh.BackendReference{ - Ref: newRef(pbcatalog.ServiceType, "foo"), - }, - Weight: 30, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: newRef(pbcatalog.ServiceType, "bar"), - }, - Weight: 70, - }, - }, - }}, - }) - - testutil.RunStep(t, "two routes", func(t *testing.T) { - out, err := LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, mapper, apiRoutesID) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, NewRelatedResources().AddResources( - apiSvc, - fooSvc, - barSvc, - route1, - route2, - ).AddComputedRoutesIDs(apiRoutesID), out) - require.Equal(t, doubleMap(t, - apiSvc, route1, - apiSvc, route2, - ), out.RoutesByParentRef) - }) - - // update the first to overlap with the second - route1 = writeHTTP("api-route1", &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - { - Ref: newRef(pbcatalog.ServiceType, "api"), - // all ports - }, - { - Ref: newRef(pbcatalog.ServiceType, "admin"), - // all ports - }, - }, - }) - - testutil.RunStep(t, "two overlapping computed routes resources", func(t *testing.T) { - out, err := LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, mapper, apiRoutesID) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, NewRelatedResources().AddResources( - apiSvc, - fooSvc, - barSvc, - adminSvc, - route1, - route2, - ).AddComputedRoutesIDs(apiRoutesID, adminRoutesID), out) - require.Equal(t, doubleMap(t, - apiSvc, route1, - apiSvc, route2, - adminSvc, route1, - ), out.RoutesByParentRef) - }) - - // add a third (GRPC) that overlaps them both - - route3 := writeGRPC("api-route3", &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - { - Ref: newRef(pbcatalog.ServiceType, "api"), - // all ports - }, - { - Ref: newRef(pbcatalog.ServiceType, "admin"), - // all ports - }, - }, - }) - - testutil.RunStep(t, "three overlapping computed routes resources", func(t *testing.T) { - out, err := LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, mapper, apiRoutesID) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, NewRelatedResources().AddResources( - apiSvc, - fooSvc, - barSvc, - adminSvc, - route1, - route2, - route3, - ).AddComputedRoutesIDs(apiRoutesID, adminRoutesID), out) - require.Equal(t, doubleMap(t, - apiSvc, route1, - apiSvc, route2, - apiSvc, route3, - adminSvc, route1, - adminSvc, route3, - ), out.RoutesByParentRef) - }) - - // We untrack the first, but we let the third one be a dangling reference - // so that the loader has to fix it up. - deleteRes(route1.Resource.Id, true) - deleteRes(route3.Resource.Id, false) - - testutil.RunStep(t, "delete first and third route", func(t *testing.T) { - out, err := LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, mapper, apiRoutesID) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, NewRelatedResources().AddResources( - apiSvc, - fooSvc, - barSvc, - route2, - ).AddComputedRoutesIDs(apiRoutesID), out) - require.Equal(t, doubleMap(t, - apiSvc, route2, - ), out.RoutesByParentRef) - }) - - barFailover := writeFailover("bar", &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: newRef(pbcatalog.ServiceType, "admin"), - }}, - }, - }) - - testutil.RunStep(t, "add a failover", func(t *testing.T) { - out, err := LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, mapper, apiRoutesID) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, NewRelatedResources().AddResources( - apiSvc, - fooSvc, - barSvc, - adminSvc, - route2, - barFailover, - ).AddComputedRoutesIDs(apiRoutesID), out) - require.Equal(t, doubleMap(t, - apiSvc, route2, - ), out.RoutesByParentRef) - }) - - fooDestPolicy := writeDestPolicy("foo", &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "www": { - ConnectTimeout: durationpb.New(55 * time.Second), - }, - }, - }) - adminDestPolicy := writeDestPolicy("admin", &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(222 * time.Second), - }, - }, - }) - - testutil.RunStep(t, "add a dest policy", func(t *testing.T) { - out, err := LoadResourcesForComputedRoutes(ctx, loggerFor, rt.Client, mapper, apiRoutesID) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, NewRelatedResources().AddResources( - apiSvc, - fooSvc, - barSvc, - adminSvc, - route2, - barFailover, - fooDestPolicy, - adminDestPolicy, // adminDestPolicy shows up indirectly via a FailoverPolicy - ).AddComputedRoutesIDs(apiRoutesID), out) - require.Equal(t, doubleMap(t, - apiSvc, route2, - ), out.RoutesByParentRef) - }) -} - -func newRef(typ *pbresource.Type, name string) *pbresource.Reference { - return rtest.Resource(typ, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") -} - -type resourceGetter interface { - GetResource() *pbresource.Resource -} - -func doubleMap(t *testing.T, list ...resourceGetter) map[resource.ReferenceKey]map[resource.ReferenceKey]struct{} { - if len(list)%2 != 0 { - t.Fatalf("list must have an even number of references") - } - out := make(map[resource.ReferenceKey]map[resource.ReferenceKey]struct{}) - for i := 0; i < len(list); i += 2 { - svcRK := resource.NewReferenceKey(list[i].GetResource().Id) - routeRK := resource.NewReferenceKey(list[i+1].GetResource().Id) - - m, ok := out[svcRK] - if !ok { - m = make(map[resource.ReferenceKey]struct{}) - out[svcRK] = m - } - m[routeRK] = struct{}{} - } - return out -} diff --git a/internal/mesh/internal/controllers/routes/loader/memoized.go b/internal/mesh/internal/controllers/routes/loader/memoized.go deleted file mode 100644 index 8fe912496f5ab..0000000000000 --- a/internal/mesh/internal/controllers/routes/loader/memoized.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package loader - -import ( - "context" - "fmt" - - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type memoizingLoader struct { - client pbresource.ResourceServiceClient - - mapHTTPRoute map[resource.ReferenceKey]*types.DecodedHTTPRoute - mapGRPCRoute map[resource.ReferenceKey]*types.DecodedGRPCRoute - mapTCPRoute map[resource.ReferenceKey]*types.DecodedTCPRoute - mapDestinationPolicy map[resource.ReferenceKey]*types.DecodedDestinationPolicy - mapFailoverPolicy map[resource.ReferenceKey]*types.DecodedFailoverPolicy - mapService map[resource.ReferenceKey]*types.DecodedService -} - -func newMemoizingLoader(client pbresource.ResourceServiceClient) *memoizingLoader { - if client == nil { - panic("client is required") - } - return &memoizingLoader{ - client: client, - mapHTTPRoute: make(map[resource.ReferenceKey]*types.DecodedHTTPRoute), - mapGRPCRoute: make(map[resource.ReferenceKey]*types.DecodedGRPCRoute), - mapTCPRoute: make(map[resource.ReferenceKey]*types.DecodedTCPRoute), - mapDestinationPolicy: make(map[resource.ReferenceKey]*types.DecodedDestinationPolicy), - mapFailoverPolicy: make(map[resource.ReferenceKey]*types.DecodedFailoverPolicy), - mapService: make(map[resource.ReferenceKey]*types.DecodedService), - } -} - -func (m *memoizingLoader) GetHTTPRoute(ctx context.Context, id *pbresource.ID) (*types.DecodedHTTPRoute, error) { - return getOrCacheResource[*pbmesh.HTTPRoute](ctx, m.client, m.mapHTTPRoute, pbmesh.HTTPRouteType, id) -} - -func (m *memoizingLoader) GetGRPCRoute(ctx context.Context, id *pbresource.ID) (*types.DecodedGRPCRoute, error) { - return getOrCacheResource[*pbmesh.GRPCRoute](ctx, m.client, m.mapGRPCRoute, pbmesh.GRPCRouteType, id) -} - -func (m *memoizingLoader) GetTCPRoute(ctx context.Context, id *pbresource.ID) (*types.DecodedTCPRoute, error) { - return getOrCacheResource[*pbmesh.TCPRoute](ctx, m.client, m.mapTCPRoute, pbmesh.TCPRouteType, id) -} - -func (m *memoizingLoader) GetDestinationPolicy(ctx context.Context, id *pbresource.ID) (*types.DecodedDestinationPolicy, error) { - return getOrCacheResource[*pbmesh.DestinationPolicy](ctx, m.client, m.mapDestinationPolicy, pbmesh.DestinationPolicyType, id) -} - -func (m *memoizingLoader) GetFailoverPolicy(ctx context.Context, id *pbresource.ID) (*types.DecodedFailoverPolicy, error) { - return getOrCacheResource[*pbcatalog.FailoverPolicy](ctx, m.client, m.mapFailoverPolicy, pbcatalog.FailoverPolicyType, id) -} - -func (m *memoizingLoader) GetService(ctx context.Context, id *pbresource.ID) (*types.DecodedService, error) { - return getOrCacheResource[*pbcatalog.Service](ctx, m.client, m.mapService, pbcatalog.ServiceType, id) -} - -func getOrCacheResource[T proto.Message]( - ctx context.Context, - client pbresource.ResourceServiceClient, - cache map[resource.ReferenceKey]*resource.DecodedResource[T], - typ *pbresource.Type, - id *pbresource.ID, -) (*resource.DecodedResource[T], error) { - if !resource.EqualType(id.Type, typ) { - return nil, fmt.Errorf("expected %s not %s", resource.TypeToString(typ), resource.TypeToString(id.Type)) - } - - rk := resource.NewReferenceKey(id) - - if cached, ok := cache[rk]; ok { - return cached, nil // cached value may be nil - } - - dec, err := resource.GetDecodedResource[T](ctx, client, id) - if err != nil { - return nil, err - } - - cache[rk] = dec - return dec, nil -} diff --git a/internal/mesh/internal/controllers/routes/loader/related.go b/internal/mesh/internal/controllers/routes/loader/related.go deleted file mode 100644 index a2ae9d853ab7d..0000000000000 --- a/internal/mesh/internal/controllers/routes/loader/related.go +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package loader - -import ( - "fmt" - - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// RelatedResources is a spiritual successor of *configentry.DiscoveryChainSet -type RelatedResources struct { - ComputedRoutesList []*pbresource.ID - // RoutesByParentRef is a map of a parent Service to the xRoutes that compose it. - RoutesByParentRef map[resource.ReferenceKey]map[resource.ReferenceKey]struct{} - HTTPRoutes map[resource.ReferenceKey]*types.DecodedHTTPRoute - GRPCRoutes map[resource.ReferenceKey]*types.DecodedGRPCRoute - TCPRoutes map[resource.ReferenceKey]*types.DecodedTCPRoute - Services map[resource.ReferenceKey]*types.DecodedService - FailoverPolicies map[resource.ReferenceKey]*types.DecodedFailoverPolicy - DestinationPolicies map[resource.ReferenceKey]*types.DecodedDestinationPolicy -} - -func NewRelatedResources() *RelatedResources { - return &RelatedResources{ - RoutesByParentRef: make(map[resource.ReferenceKey]map[resource.ReferenceKey]struct{}), - HTTPRoutes: make(map[resource.ReferenceKey]*types.DecodedHTTPRoute), - GRPCRoutes: make(map[resource.ReferenceKey]*types.DecodedGRPCRoute), - TCPRoutes: make(map[resource.ReferenceKey]*types.DecodedTCPRoute), - Services: make(map[resource.ReferenceKey]*types.DecodedService), - FailoverPolicies: make(map[resource.ReferenceKey]*types.DecodedFailoverPolicy), - DestinationPolicies: make(map[resource.ReferenceKey]*types.DecodedDestinationPolicy), - } -} - -func (r *RelatedResources) AddComputedRoutesIDs(list ...*pbresource.ID) *RelatedResources { - for _, id := range list { - r.AddComputedRoutesID(id) - } - return r -} - -func (r *RelatedResources) AddComputedRoutesID(id *pbresource.ID) *RelatedResources { - if !resource.EqualType(id.Type, pbmesh.ComputedRoutesType) { - panic(fmt.Sprintf("expected *mesh.ComputedRoutes, not %s", resource.TypeToString(id.Type))) - } - r.ComputedRoutesList = append(r.ComputedRoutesList, id) - return r -} - -// AddResources must only be called with valid *resource.DecodedResource[T] -// types. -// -// This is provided as a testing convenience. Non-test code should call the -// type-specific adder. -func (r *RelatedResources) AddResources(list ...any) *RelatedResources { - for _, res := range list { - r.AddResource(res) - } - return r -} - -// AddResource must only be called with valid *resource.DecodedResource[T] types. -// -// This is provided as a testing convenience. Non-test code should call the -// type-specific adder. -func (r *RelatedResources) AddResource(res any) { - if res == nil { - return - } - - switch dec := res.(type) { - case *types.DecodedHTTPRoute: - r.AddHTTPRoute(dec) - case *types.DecodedGRPCRoute: - r.AddGRPCRoute(dec) - case *types.DecodedTCPRoute: - r.AddTCPRoute(dec) - case *types.DecodedDestinationPolicy: - r.AddDestinationPolicy(dec) - case *types.DecodedService: - r.AddService(dec) - case *types.DecodedFailoverPolicy: - r.AddFailoverPolicy(dec) - default: - panic(fmt.Sprintf("unknown decoded resource type: %T", res)) - } -} - -func (r *RelatedResources) AddHTTPRoute(dec *types.DecodedHTTPRoute) { - r.addRouteSetEntries(dec.Resource, dec.Data) - addResource(dec.Resource.Id, dec, r.HTTPRoutes) -} - -func (r *RelatedResources) AddGRPCRoute(dec *types.DecodedGRPCRoute) { - r.addRouteSetEntries(dec.Resource, dec.Data) - addResource(dec.Resource.Id, dec, r.GRPCRoutes) -} - -func (r *RelatedResources) AddTCPRoute(dec *types.DecodedTCPRoute) { - r.addRouteSetEntries(dec.Resource, dec.Data) - addResource(dec.Resource.Id, dec, r.TCPRoutes) -} - -func (r *RelatedResources) AddDestinationPolicy(dec *types.DecodedDestinationPolicy) { - addResource(dec.Resource.Id, dec, r.DestinationPolicies) -} - -func (r *RelatedResources) AddService(dec *types.DecodedService) { - addResource(dec.Resource.Id, dec, r.Services) -} - -func (r *RelatedResources) AddFailoverPolicy(dec *types.DecodedFailoverPolicy) { - addResource(dec.Resource.Id, dec, r.FailoverPolicies) -} - -func (r *RelatedResources) addRouteSetEntries( - res *pbresource.Resource, - xroute types.XRouteData, -) { - if res == nil || xroute == nil { - return - } - - routeRK := resource.NewReferenceKey(res.Id) - - for _, parentRef := range xroute.GetParentRefs() { - if parentRef.Ref == nil || !types.IsServiceType(parentRef.Ref.Type) { - continue - } - svcRK := resource.NewReferenceKey(parentRef.Ref) - - r.addRouteByParentRef(svcRK, routeRK) - } -} - -func (r *RelatedResources) addRouteByParentRef(svcRK, xRouteRK resource.ReferenceKey) { - m, ok := r.RoutesByParentRef[svcRK] - if !ok { - m = make(map[resource.ReferenceKey]struct{}) - r.RoutesByParentRef[svcRK] = m - } - m[xRouteRK] = struct{}{} -} - -type RouteWalkFunc func( - rk resource.ReferenceKey, - res *pbresource.Resource, - route types.XRouteData, -) - -func (r *RelatedResources) WalkRoutes(fn RouteWalkFunc) { - for rk, route := range r.HTTPRoutes { - fn(rk, route.Resource, route.Data) - } - for rk, route := range r.GRPCRoutes { - fn(rk, route.Resource, route.Data) - } - for rk, route := range r.TCPRoutes { - fn(rk, route.Resource, route.Data) - } -} - -func (r *RelatedResources) WalkRoutesForParentRef(parentRef *pbresource.Reference, fn RouteWalkFunc) { - if !resource.EqualType(parentRef.Type, pbcatalog.ServiceType) { - panic(fmt.Sprintf("expected *catalog.Service, not %s", resource.TypeToString(parentRef.Type))) - } - routeMap := r.RoutesByParentRef[resource.NewReferenceKey(parentRef)] - if len(routeMap) == 0 { - return - } - - for rk := range routeMap { - if route, ok := r.HTTPRoutes[rk]; ok { - fn(rk, route.Resource, route.Data) - continue - } - if route, ok := r.GRPCRoutes[rk]; ok { - fn(rk, route.Resource, route.Data) - continue - } - if route, ok := r.TCPRoutes[rk]; ok { - fn(rk, route.Resource, route.Data) - continue - } - } -} - -func (r *RelatedResources) GetService(ref resource.ReferenceOrID) *types.DecodedService { - return r.Services[resource.NewReferenceKey(ref)] -} - -func (r *RelatedResources) GetFailoverPolicy(ref resource.ReferenceOrID) *types.DecodedFailoverPolicy { - return r.FailoverPolicies[resource.NewReferenceKey(ref)] -} - -func (r *RelatedResources) GetFailoverPolicyForService(ref resource.ReferenceOrID) *types.DecodedFailoverPolicy { - failRef := &pbresource.Reference{ - Type: pbcatalog.FailoverPolicyType, - Tenancy: ref.GetTenancy(), - Name: ref.GetName(), - } - return r.GetFailoverPolicy(failRef) -} - -func (r *RelatedResources) GetDestinationPolicy(ref resource.ReferenceOrID) *types.DecodedDestinationPolicy { - return r.DestinationPolicies[resource.NewReferenceKey(ref)] -} - -func (r *RelatedResources) GetDestinationPolicyForService(ref resource.ReferenceOrID) *types.DecodedDestinationPolicy { - destRef := &pbresource.Reference{ - Type: pbmesh.DestinationPolicyType, - Tenancy: ref.GetTenancy(), - Name: ref.GetName(), - } - return r.GetDestinationPolicy(destRef) -} - -func addResource[V any](id *pbresource.ID, res *V, m map[resource.ReferenceKey]*V) { - if res == nil { - return - } - - rk := resource.NewReferenceKey(id) - if _, ok := m[rk]; !ok { - m[rk] = res - } -} diff --git a/internal/mesh/internal/controllers/routes/pending_status.go b/internal/mesh/internal/controllers/routes/pending_status.go deleted file mode 100644 index 1c33e2db2b82b..0000000000000 --- a/internal/mesh/internal/controllers/routes/pending_status.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "context" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type PendingResourceStatusUpdate struct { - ID *pbresource.ID - Generation string - CurrStatus *pbresource.Status - - NewConditions []*pbresource.Condition -} - -type PendingStatuses map[resource.ReferenceKey]*PendingResourceStatusUpdate - -func (p PendingStatuses) AddConditions( - rk resource.ReferenceKey, - res *pbresource.Resource, - newConditions []*pbresource.Condition, -) { - state, ok := p[rk] - if !ok { - state = &PendingResourceStatusUpdate{ - ID: res.Id, - Generation: res.Generation, - CurrStatus: res.Status[StatusKey], - } - p[rk] = state - } - - state.NewConditions = append(state.NewConditions, newConditions...) -} - -func UpdatePendingStatuses( - ctx context.Context, - rt controller.Runtime, - pending PendingStatuses, -) error { - for _, state := range pending { - logger := rt.Logger.With("resource", resource.IDToString(state.ID)) - - var newStatus *pbresource.Status - if len(state.NewConditions) > 0 { - newStatus = &pbresource.Status{ - ObservedGeneration: state.Generation, - Conditions: state.NewConditions, - } - } else { - newStatus = &pbresource.Status{ - ObservedGeneration: state.Generation, - Conditions: []*pbresource.Condition{ - ConditionXRouteOK, - }, - } - } - if resource.EqualStatus(state.CurrStatus, newStatus, false) { - logger.Trace( - "resource's status is unchanged", - "conditions", newStatus.Conditions, - ) - } else { - _, err := rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{ - Id: state.ID, - Key: StatusKey, - Status: newStatus, - }) - - if err != nil { - logger.Error( - "error encountered when attempting to update the resource's status", - "error", err, - ) - return err - } - - logger.Trace( - "resource's status was updated", - "conditions", newStatus.Conditions, - ) - } - } - - return nil -} diff --git a/internal/mesh/internal/controllers/routes/ref_validation.go b/internal/mesh/internal/controllers/routes/ref_validation.go deleted file mode 100644 index b860eede202db..0000000000000 --- a/internal/mesh/internal/controllers/routes/ref_validation.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/loader" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// ValidateXRouteReferences examines all of the ParentRefs and BackendRefs of -// xRoutes provided and issues status conditions if anything is unacceptable. -func ValidateXRouteReferences(related *loader.RelatedResources, pending PendingStatuses) { - related.WalkRoutes(func( - rk resource.ReferenceKey, - res *pbresource.Resource, - route types.XRouteData, - ) { - parentRefs := route.GetParentRefs() - backendRefs := route.GetUnderlyingBackendRefs() - - conditions := computeNewRouteRefConditions(related, parentRefs, backendRefs) - - pending.AddConditions(rk, res, conditions) - }) -} - -type serviceGetter interface { - GetService(ref resource.ReferenceOrID) *types.DecodedService -} - -func computeNewRouteRefConditions( - related serviceGetter, - parentRefs []*pbmesh.ParentReference, - backendRefs []*pbmesh.BackendReference, -) []*pbresource.Condition { - var conditions []*pbresource.Condition - - // TODO(rb): handle port numbers here too if we are allowing those instead of the name? - - for _, parentRef := range parentRefs { - if parentRef.Ref == nil || !resource.EqualType(parentRef.Ref.Type, pbcatalog.ServiceType) { - continue // not possible due to xRoute validation - } - if parentRef.Ref.Section != "" { - continue // not possible due to xRoute validation - } - if svc := related.GetService(parentRef.Ref); svc != nil { - found := false - usingMesh := false - hasMesh := false - for _, port := range svc.Data.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - hasMesh = true - } - if port.TargetPort == parentRef.Port { - found = true - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - usingMesh = true - } - } - } - switch { - case !hasMesh: - conditions = append(conditions, ConditionParentRefOutsideMesh(parentRef.Ref)) - case !found: - if parentRef.Port != "" { - conditions = append(conditions, ConditionUnknownParentRefPort(parentRef.Ref, parentRef.Port)) - } - case usingMesh: - conditions = append(conditions, ConditionParentRefUsingMeshPort(parentRef.Ref, parentRef.Port)) - } - } else { - conditions = append(conditions, ConditionMissingParentRef(parentRef.Ref)) - } - } - - for _, backendRef := range backendRefs { - if backendRef.Ref == nil || !resource.EqualType(backendRef.Ref.Type, pbcatalog.ServiceType) { - continue // not possible due to xRoute validation - } - if backendRef.Ref.Section != "" { - continue // not possible due to xRoute validation - } - if svc := related.GetService(backendRef.Ref); svc != nil { - found := false - usingMesh := false - hasMesh := false - for _, port := range svc.Data.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - hasMesh = true - } - if port.TargetPort == backendRef.Port { - found = true - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - usingMesh = true - } - } - } - switch { - case !hasMesh: - conditions = append(conditions, ConditionBackendRefOutsideMesh(backendRef.Ref)) - case !found: - if backendRef.Port != "" { - conditions = append(conditions, ConditionUnknownBackendRefPort(backendRef.Ref, backendRef.Port)) - } - case usingMesh: - conditions = append(conditions, ConditionBackendRefUsingMeshPort(backendRef.Ref, backendRef.Port)) - } - } else { - conditions = append(conditions, ConditionMissingBackendRef(backendRef.Ref)) - } - } - - return conditions -} diff --git a/internal/mesh/internal/controllers/routes/ref_validation_test.go b/internal/mesh/internal/controllers/routes/ref_validation_test.go deleted file mode 100644 index 3f6db4207865b..0000000000000 --- a/internal/mesh/internal/controllers/routes/ref_validation_test.go +++ /dev/null @@ -1,233 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "testing" - - "github.com/stretchr/testify/require" - - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestComputeNewRouteRefConditions(t *testing.T) { - registry := resource.NewRegistry() - types.Register(registry) - catalog.RegisterTypes(registry) - - newService := func(name string, ports map[string]pbcatalog.Protocol) *types.DecodedService { - var portSlice []*pbcatalog.ServicePort - for name, proto := range ports { - portSlice = append(portSlice, &pbcatalog.ServicePort{ - TargetPort: name, - Protocol: proto, - }) - } - svc := rtest.Resource(pbcatalog.ServiceType, name). - WithData(t, &pbcatalog.Service{Ports: portSlice}). - Build() - rtest.ValidateAndNormalize(t, registry, svc) - - dec, err := resource.Decode[*pbcatalog.Service](svc) - require.NoError(t, err) - return dec - } - - t.Run("no refs", func(t *testing.T) { - sg := newTestServiceGetter() - got := computeNewRouteRefConditions(sg, nil, nil) - require.Empty(t, got) - }) - - t.Run("parent refs", func(t *testing.T) { - t.Run("with no service", func(t *testing.T) { - sg := newTestServiceGetter() - got := computeNewRouteRefConditions(sg, []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), ""), - }, nil) - require.Len(t, got, 1) - prototest.AssertContainsElement(t, got, ConditionMissingParentRef( - newRef(pbcatalog.ServiceType, "api"), - )) - }) - - t.Run("with service but no mesh port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - })) - got := computeNewRouteRefConditions(sg, []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), ""), - }, nil) - require.Len(t, got, 1) - prototest.AssertContainsElement(t, got, ConditionParentRefOutsideMesh( - newRef(pbcatalog.ServiceType, "api"), - )) - }) - - t.Run("with service but using mesh port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "mesh": pbcatalog.Protocol_PROTOCOL_MESH, - })) - got := computeNewRouteRefConditions(sg, []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "mesh"), - }, nil) - require.Len(t, got, 1) - prototest.AssertContainsElement(t, got, ConditionParentRefUsingMeshPort( - newRef(pbcatalog.ServiceType, "api"), - "mesh", - )) - }) - - t.Run("with service and using missing port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "mesh": pbcatalog.Protocol_PROTOCOL_MESH, - })) - got := computeNewRouteRefConditions(sg, []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "web"), - }, nil) - require.Len(t, got, 1) - prototest.AssertContainsElement(t, got, ConditionUnknownParentRefPort( - newRef(pbcatalog.ServiceType, "api"), - "web", - )) - }) - - t.Run("with service and using empty port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "mesh": pbcatalog.Protocol_PROTOCOL_MESH, - })) - got := computeNewRouteRefConditions(sg, []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), ""), - }, nil) - require.Empty(t, got) - }) - - t.Run("with service and using correct port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "mesh": pbcatalog.Protocol_PROTOCOL_MESH, - })) - got := computeNewRouteRefConditions(sg, []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api"), "http"), - }, nil) - require.Empty(t, got) - }) - }) - - t.Run("backend refs", func(t *testing.T) { - t.Run("with no service", func(t *testing.T) { - sg := newTestServiceGetter() - got := computeNewRouteRefConditions(sg, nil, []*pbmesh.BackendReference{ - newBackendRef(newRef(pbcatalog.ServiceType, "api"), "", ""), - }) - require.Len(t, got, 1) - prototest.AssertContainsElement(t, got, ConditionMissingBackendRef( - newRef(pbcatalog.ServiceType, "api"), - )) - }) - - t.Run("with service but no mesh port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - })) - got := computeNewRouteRefConditions(sg, nil, []*pbmesh.BackendReference{ - newBackendRef(newRef(pbcatalog.ServiceType, "api"), "", ""), - }) - require.Len(t, got, 1) - prototest.AssertContainsElement(t, got, ConditionBackendRefOutsideMesh( - newRef(pbcatalog.ServiceType, "api"), - )) - }) - - t.Run("with service but using mesh port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "mesh": pbcatalog.Protocol_PROTOCOL_MESH, - })) - got := computeNewRouteRefConditions(sg, nil, []*pbmesh.BackendReference{ - newBackendRef(newRef(pbcatalog.ServiceType, "api"), "mesh", ""), - }) - require.Len(t, got, 1) - prototest.AssertContainsElement(t, got, ConditionBackendRefUsingMeshPort( - newRef(pbcatalog.ServiceType, "api"), - "mesh", - )) - }) - - t.Run("with service and using missing port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "mesh": pbcatalog.Protocol_PROTOCOL_MESH, - })) - got := computeNewRouteRefConditions(sg, nil, []*pbmesh.BackendReference{ - newBackendRef(newRef(pbcatalog.ServiceType, "api"), "web", ""), - }) - require.Len(t, got, 1) - prototest.AssertContainsElement(t, got, ConditionUnknownBackendRefPort( - newRef(pbcatalog.ServiceType, "api"), - "web", - )) - }) - - t.Run("with service and using empty port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "mesh": pbcatalog.Protocol_PROTOCOL_MESH, - })) - got := computeNewRouteRefConditions(sg, nil, []*pbmesh.BackendReference{ - newBackendRef(newRef(pbcatalog.ServiceType, "api"), "", ""), - }) - require.Empty(t, got) - }) - - t.Run("with service and using correct port", func(t *testing.T) { - sg := newTestServiceGetter(newService("api", map[string]pbcatalog.Protocol{ - "http": pbcatalog.Protocol_PROTOCOL_HTTP, - "mesh": pbcatalog.Protocol_PROTOCOL_MESH, - })) - got := computeNewRouteRefConditions(sg, nil, []*pbmesh.BackendReference{ - newBackendRef(newRef(pbcatalog.ServiceType, "api"), "http", ""), - }) - require.Empty(t, got) - }) - }) -} - -func newRef(typ *pbresource.Type, name string) *pbresource.Reference { - return rtest.Resource(typ, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") -} - -type testServiceGetter struct { - services map[resource.ReferenceKey]*types.DecodedService -} - -func newTestServiceGetter(svcs ...*types.DecodedService) serviceGetter { - g := &testServiceGetter{ - services: make(map[resource.ReferenceKey]*types.DecodedService), - } - for _, svc := range svcs { - g.services[resource.NewReferenceKey(svc.Resource.Id)] = svc - } - return g -} - -func (g *testServiceGetter) GetService(ref resource.ReferenceOrID) *types.DecodedService { - if g.services == nil { - return nil - } - return g.services[resource.NewReferenceKey(ref)] -} diff --git a/internal/mesh/internal/controllers/routes/routestest/routestest.go b/internal/mesh/internal/controllers/routes/routestest/routestest.go deleted file mode 100644 index 77ba33138d906..0000000000000 --- a/internal/mesh/internal/controllers/routes/routestest/routestest.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routestest - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/loader" - "github.com/hashicorp/consul/internal/mesh/internal/types" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" -) - -func ReconcileComputedRoutes( - t *testing.T, - client pbresource.ResourceServiceClient, - id *pbresource.ID, - decResList ...any, -) *types.DecodedComputedRoutes { - t.Helper() - if client == nil { - panic("client is required") - } - return makeComputedRoutes(t, client, id, decResList...) -} - -func BuildComputedRoutes( - t *testing.T, - id *pbresource.ID, - decResList ...any, -) *types.DecodedComputedRoutes { - t.Helper() - return makeComputedRoutes(t, nil, id, decResList...) -} - -func MutateTargets( - t *testing.T, - routes *pbmesh.ComputedRoutes, - parentPort string, - mutFn func(t *testing.T, details *pbmesh.BackendTargetDetails), -) *pbmesh.ComputedPortRoutes { - t.Helper() - - portConfig, ok := routes.PortedConfigs[parentPort] - require.True(t, ok, "port %q not found in ported_configs", parentPort) - - portConfig = proto.Clone(portConfig).(*pbmesh.ComputedPortRoutes) - - for _, details := range portConfig.Targets { - mutFn(t, details) - } - - return portConfig -} - -func makeComputedRoutes( - t *testing.T, - client pbresource.ResourceServiceClient, - id *pbresource.ID, - decResList ...any, -) *types.DecodedComputedRoutes { - t.Helper() - - related := loader.NewRelatedResources(). - AddComputedRoutesID(id). - AddResources(decResList...) - - pending := make(routes.PendingStatuses) - got := routes.GenerateComputedRoutes(related, pending) - require.Empty(t, pending, "programmer error if there are warnings") - require.Len(t, got, 1, "should only compute one output") - - item := got[0] - - if item.Data == nil { - if client != nil { - ctx := testutil.TestContext(t) - _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: got[0].ID}) - require.NoError(t, err) - } - return nil - } - - b := rtest.ResourceID(id). - // WithOwner(item.OwnerID). - WithData(t, item.Data) - - var res *pbresource.Resource - if client != nil { - res = b.Write(t, client) - } else { - res = b.Build() - } - require.NoError(t, types.ValidateComputedRoutes(res)) - - return rtest.MustDecode[*pbmesh.ComputedRoutes](t, res) -} diff --git a/internal/mesh/internal/controllers/routes/sort_rules.go b/internal/mesh/internal/controllers/routes/sort_rules.go deleted file mode 100644 index a7198d31300f9..0000000000000 --- a/internal/mesh/internal/controllers/routes/sort_rules.go +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "sort" - - "github.com/oklog/ulid" - - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -func gammaSortRouteRules(node *inputRouteNode) { - switch { - case resource.EqualType(node.RouteType, pbmesh.HTTPRouteType): - gammaSortHTTPRouteRules(node.HTTPRules) - case resource.EqualType(node.RouteType, pbmesh.GRPCRouteType): - // TODO(rb): do a determinstic sort of something - case resource.EqualType(node.RouteType, pbmesh.TCPRouteType): - // TODO(rb): do a determinstic sort of something - default: - panic("impossible") - } -} - -func gammaSortHTTPRouteRules(rules []*pbmesh.ComputedHTTPRouteRule) { - // First generate a parallel slice. - sortable := &sortableHTTPRouteRules{ - rules: rules, - derivedInfo: make([]*derivedHTTPRouteRuleInfo, 0, len(rules)), - } - - for _, rule := range rules { - var sr derivedHTTPRouteRuleInfo - for _, m := range rule.Matches { - if m.Path != nil { - switch m.Path.Type { - case pbmesh.PathMatchType_PATH_MATCH_TYPE_EXACT: - sr.hasPathExact = true - case pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX: - sr.hasPathPrefix = true - v := len(m.Path.Value) - if v > sr.pathPrefixLength { - sr.pathPrefixLength = v - } - } - } - - if m.Method != "" { - sr.hasMethod = true - } - if v := len(m.Headers); v > sr.numHeaders { - sr.numHeaders = v - } - if v := len(m.QueryParams); v > sr.numQueryParams { - sr.numQueryParams = v - } - } - sortable.derivedInfo = append(sortable.derivedInfo, &sr) - } - - // Similar to - // "agent/consul/discoverychain/gateway_httproute.go" - // compareHTTPRules - - // Sort this by the GAMMA spec. We assume the caller has pre-sorted this - // for tiebreakers based on resource metadata. - - sort.Stable(sortable) -} - -type derivedHTTPRouteRuleInfo struct { - // sortable fields extracted from route - hasPathExact bool - hasPathPrefix bool - pathPrefixLength int - hasMethod bool - numHeaders int - numQueryParams int -} - -type sortableHTTPRouteRules struct { - rules []*pbmesh.ComputedHTTPRouteRule - derivedInfo []*derivedHTTPRouteRuleInfo -} - -var _ sort.Interface = (*sortableHTTPRouteRules)(nil) - -func (r *sortableHTTPRouteRules) Len() int { return len(r.rules) } - -func (r *sortableHTTPRouteRules) Swap(i, j int) { - r.rules[i], r.rules[j] = r.rules[j], r.rules[i] - r.derivedInfo[i], r.derivedInfo[j] = r.derivedInfo[j], r.derivedInfo[i] -} - -func (r *sortableHTTPRouteRules) Less(i, j int) bool { - a := r.derivedInfo[i] - b := r.derivedInfo[j] - - // (1) “Exact” path match. - switch { - case a.hasPathExact && b.hasPathExact: - // NEXT TIE BREAK - case a.hasPathExact && !b.hasPathExact: - return true - case !a.hasPathExact && b.hasPathExact: - return false - } - - // (2) “Prefix” path match with largest number of characters. - switch { - case a.hasPathPrefix && b.hasPathPrefix: - if a.pathPrefixLength != b.pathPrefixLength { - return a.pathPrefixLength > b.pathPrefixLength - } - // NEXT TIE BREAK - case a.hasPathPrefix && !b.hasPathPrefix: - return true - case !a.hasPathPrefix && b.hasPathPrefix: - return false - } - - // (3) Method match. - switch { - case a.hasMethod && b.hasMethod: - // NEXT TIE BREAK - case a.hasMethod && !b.hasMethod: - return true - case !a.hasMethod && b.hasMethod: - return false - } - - // (4) Largest number of header matches. - switch { - case a.numHeaders == b.numHeaders: - // NEXT TIE BREAK - case a.numHeaders > b.numHeaders: - return true - case a.numHeaders < b.numHeaders: - return false - } - - // (5) Largest number of query param matches. - return a.numQueryParams > b.numQueryParams -} - -// gammaInitialSortWrappedRoutes will sort the original inputs by the -// resource-envelope-only fields before we further stable sort by type-specific -// fields. -// -// If more than 1 route is provided the OriginalResource field must be set on -// all inputs (i.e. no synthetic default routes should be processed here). -func gammaInitialSortWrappedRoutes(routes []*inputRouteNode) { - if len(routes) < 2 { - return - } - - // First sort the input routes by the final criteria, so we can let the - // stable sort take care of the ultimate tiebreakers. - sort.Slice(routes, func(i, j int) bool { - var ( - resA = routes[i].OriginalResource - resB = routes[j].OriginalResource - ) - - if resA == nil || resB == nil { - panic("some provided nodes lacked original resources") - } - - var ( - genA = resA.Generation - genB = resB.Generation - ) - - // (END-1) The oldest Route based on creation timestamp. - // - // Because these are ULIDs, we should be able to lexicographically sort - // them to determine the oldest, but we also need to have a further - // tiebreaker AFTER per-gamma so we cannot. - aULID, aErr := ulid.Parse(genA) - bULID, bErr := ulid.Parse(genB) - if aErr == nil && bErr == nil { - aTime := aULID.Time() - bTime := bULID.Time() - - switch { - case aTime < bTime: - return true - case aTime > bTime: - return false - default: - // NEXT TIE BREAK - } - } - - // (END-2) The Route appearing first in alphabetical order by “{namespace}/{name}”. - var ( - tenancyA = resA.Id.Tenancy - tenancyB = resB.Id.Tenancy - - nsA = tenancyA.Namespace - nsB = tenancyB.Namespace - ) - - if nsA == "" { - nsA = "default" - } - if nsB == "" { - nsB = "default" - } - switch { - case nsA < nsB: - return true - case nsA > nsB: - return false - default: - // NEXT TIE BREAK - } - - return resA.Id.Name < resB.Id.Name - - // We get this for free b/c of the stable sort. - // - // If ties still exist within an HTTPRoute, matching precedence MUST - // be granted to the FIRST matching rule (in list order) with a match - // meeting the above criteria. - }) -} diff --git a/internal/mesh/internal/controllers/routes/sort_rules_test.go b/internal/mesh/internal/controllers/routes/sort_rules_test.go deleted file mode 100644 index 50504f09cf4dc..0000000000000 --- a/internal/mesh/internal/controllers/routes/sort_rules_test.go +++ /dev/null @@ -1,493 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "math/rand" - "sort" - "testing" - - "github.com/stretchr/testify/require" - "golang.org/x/exp/slices" - - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func TestGammaInitialSortWrappedRoutes(t *testing.T) { - // These generations were created with ulid.Make().String() at 1 second - // intervals. They are in ascending order. - generations := []string{ - "01H8HGKHXCAJY7TRNJ06JGEZP9", - "01H8HGKJWMEYWKZATG44QZF0G7", - "01H8HGKKVW2339KFHAFXMEFRHP", - "01H8HGKMV45XAC2W1KCQ7KJ00J", - "01H8HGKNTCB3ZYN16AZ2KSXN54", - "01H8HGKPSN9V3QQXTQVZ1EQM2T", - "01H8HGKQRXMR8NY662AC520CDE", - "01H8HGKRR5C41RHGXY7H3N0JYX", - "01H8HGKSQDNSQ54VN86SBTR149", - "01H8HGKTPPRWFXWHKV90M2WW5R", - } - require.True(t, sort.StringsAreSorted(generations)) - - nodeID := func(node *inputRouteNode) string { - return resource.IDToString(node.OriginalResource.Id) + ":" + node.OriginalResource.Generation - } - - nodeIDSlice := func(nodes []*inputRouteNode) []string { - var out []string - for _, node := range nodes { - out = append(out, nodeID(node)) - } - return out - } - - // newNode will only populate the fields that the sorting function cares - // about. - newNode := func(tenancy *pbresource.Tenancy, name string, gen string) *inputRouteNode { - id := rtest.Resource(pbmesh.HTTPRouteType, name). - WithTenancy(tenancy). - ID() - - res := rtest.ResourceID(id). - WithGeneration(gen). - WithData(t, &pbmesh.HTTPRoute{}). - Build() - - return &inputRouteNode{ - OriginalResource: res, - } - } - - type testcase struct { - routes []*inputRouteNode - } - - run := func(t *testing.T, tc testcase) { - expect := nodeIDSlice(tc.routes) - - if len(tc.routes) > 1 { - // Randomly permute it - in := tc.routes - for { - rand.Shuffle(len(in), func(i, j int) { - in[i], in[j] = in[j], in[i] - }) - curr := nodeIDSlice(tc.routes) - - if slices.Equal(expect, curr) { - // Loop until the shuffle was actually different. - } else { - break - } - - } - } - - gammaInitialSortWrappedRoutes(tc.routes) - - got := nodeIDSlice(tc.routes) - - require.Equal(t, expect, got) - } - - // Order: - // 1. generation older first - // 2. tenancy namespace A first - // 3. object name A first - cases := map[string]testcase{ - "empty": {}, - "one": { - routes: []*inputRouteNode{ - newNode(defaultTenancy(), "foo", generations[0]), - }, - }, - "two: by generation": { - routes: []*inputRouteNode{ - newNode(defaultTenancy(), "foo", generations[0]), - newNode(defaultTenancy(), "foo", generations[1]), - }, - }, - "two: by namespace": { - routes: []*inputRouteNode{ - newNode(&pbresource.Tenancy{Namespace: "aaa"}, "foo", generations[0]), - newNode(&pbresource.Tenancy{Namespace: "bbb"}, "foo", generations[0]), - }, - }, - "two: by name": { - routes: []*inputRouteNode{ - newNode(defaultTenancy(), "bar", generations[0]), - newNode(defaultTenancy(), "foo", generations[0]), - }, - }, - "two: by name with empty namespace": { - routes: []*inputRouteNode{ - newNode(nsTenancy(""), "bar", generations[0]), - newNode(nsTenancy(""), "foo", generations[0]), - }, - }, - "four: by generation": { - routes: []*inputRouteNode{ - newNode(defaultTenancy(), "foo", generations[0]), - newNode(defaultTenancy(), "foo", generations[1]), - newNode(defaultTenancy(), "foo", generations[2]), - newNode(defaultTenancy(), "foo", generations[3]), - }, - }, - "four: by name with some empty namespaces": { - routes: []*inputRouteNode{ - newNode(nsTenancy("aaa"), "foo", generations[0]), - newNode(nsTenancy("bbb"), "foo", generations[0]), - newNode(&pbresource.Tenancy{}, "bar", generations[0]), - newNode(&pbresource.Tenancy{}, "foo", generations[0]), - }, - }, - "mixed": { - // Seed this with data such that each later sort criteria should - // want to be more to the top than an earlier criteria would allow, - // to prove that the sort is going to have to shake out the way the - // algorithm wants it to for maximum algorithm exercise. - routes: []*inputRouteNode{ - // gen beats name - newNode(defaultTenancy(), "zzz", generations[0]), - newNode(defaultTenancy(), "aaa", generations[1]), - // gen beats ns - newNode(nsTenancy("zzz"), "foo", generations[2]), - newNode(nsTenancy("aaa"), "foo", generations[3]), - // ns beats name - newNode(nsTenancy("aaa"), "zzz", generations[4]), - newNode(nsTenancy("bbb"), "aaa", generations[5]), - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestGammaSortHTTPRouteRules(t *testing.T) { - type testcase struct { - rules []*pbmesh.ComputedHTTPRouteRule - } - - // In this test we will use the 'backend target' field to track the rule - // identity to make assertions easy. - - targetSlice := func(rules []*pbmesh.ComputedHTTPRouteRule) []string { - var out []string - for _, rule := range rules { - out = append(out, rule.BackendRefs[0].BackendTarget) - } - return out - } - - run := func(t *testing.T, tc testcase) { - expect := targetSlice(tc.rules) - - if len(tc.rules) > 1 { - // Randomly permute it - in := tc.rules - for { - rand.Shuffle(len(in), func(i, j int) { - in[i], in[j] = in[j], in[i] - }) - curr := targetSlice(tc.rules) - - if slices.Equal(expect, curr) { - // Loop until the shuffle was actually different. - } else { - break - } - - } - } - - gammaSortHTTPRouteRules(tc.rules) - - got := targetSlice(tc.rules) - - require.Equal(t, expect, got) - } - - newRule := func(target string, m ...*pbmesh.HTTPRouteMatch) *pbmesh.ComputedHTTPRouteRule { - return &pbmesh.ComputedHTTPRouteRule{ - Matches: m, - BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: target, - }}, - } - } - - // Rules: - // 1. exact path match exists - // 2. prefix match exists - // 3. prefix match has lots of characters - // 4. has method match - // 5. has lots of header matches - // 6. has lots of query param matches - cases := map[string]testcase{ - "empty": {}, - "one": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", &pbmesh.HTTPRouteMatch{ - // - }), - }, - }, - "two: by exact path match exists": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_EXACT, - Value: "/", - }, - }), - newRule("r2", &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }), - }, - }, - "two: by prefix path match exists": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }), - newRule("r2", &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_REGEX, - Value: "/[a]", - }, - }), - }, - }, - "two: by prefix path match length": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/longer", - }, - }), - newRule("r2", &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/short", - }, - }), - }, - }, - "two: by method match exists": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", &pbmesh.HTTPRouteMatch{ - Method: "GET", - }), - newRule("r2", &pbmesh.HTTPRouteMatch{ - Headers: []*pbmesh.HTTPHeaderMatch{{ - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-blah", - Value: "foo", - }}, - }), - }, - }, - "two: by header match quantity": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", &pbmesh.HTTPRouteMatch{ - Headers: []*pbmesh.HTTPHeaderMatch{ - { - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-blah", - Value: "foo", - }, - { - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-other", - Value: "bar", - }, - }, - }), - newRule("r2", &pbmesh.HTTPRouteMatch{ - Headers: []*pbmesh.HTTPHeaderMatch{{ - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-blah", - Value: "foo", - }}, - }), - }, - }, - "two: by query param match quantity": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", &pbmesh.HTTPRouteMatch{ - QueryParams: []*pbmesh.HTTPQueryParamMatch{ - { - Type: pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT, - Name: "foo", - Value: "1", - }, - { - Type: pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT, - Name: "bar", - Value: "1", - }, - }, - }), - newRule("r2", &pbmesh.HTTPRouteMatch{ - QueryParams: []*pbmesh.HTTPQueryParamMatch{{ - Type: pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT, - Name: "foo", - Value: "1", - }}, - }), - }, - }, - "mixed: has path exact beats has path prefix when both are present": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", - &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_EXACT, - Value: "/", - }, - }, - &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/short", - }, - }, - ), - newRule("r2", &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/longer", - }, - }), - }, - }, - "mixed: longer path prefix beats shorter when both are present": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", - &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/longer", - }, - }, - &pbmesh.HTTPRouteMatch{ - Method: "GET", - }, - ), - newRule("r2", &pbmesh.HTTPRouteMatch{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/short", - }, - }), - }, - }, - "mixed: has method match beats header match when both are present": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", - &pbmesh.HTTPRouteMatch{ - Method: "GET", - }, - &pbmesh.HTTPRouteMatch{ - Headers: []*pbmesh.HTTPHeaderMatch{{ - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-blah", - Value: "foo", - }}, - }, - ), - newRule("r2", &pbmesh.HTTPRouteMatch{ - Headers: []*pbmesh.HTTPHeaderMatch{ - { - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-blah", - Value: "foo", - }, - { - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-other", - Value: "bar", - }, - }, - }), - }, - }, - "mixed: header match beats query param match when both are present": { - rules: []*pbmesh.ComputedHTTPRouteRule{ - newRule("r1", &pbmesh.HTTPRouteMatch{ - Headers: []*pbmesh.HTTPHeaderMatch{ - { - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-blah", - Value: "foo", - }, - { - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-other", - Value: "bar", - }, - }, - QueryParams: []*pbmesh.HTTPQueryParamMatch{{ - Type: pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT, - Name: "foo", - Value: "1", - }}, - }), - newRule("r2", &pbmesh.HTTPRouteMatch{ - QueryParams: []*pbmesh.HTTPQueryParamMatch{ - { - Type: pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT, - Name: "foo", - Value: "1", - }, - { - Type: pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT, - Name: "bar", - Value: "1", - }, - }, - }), - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func newID(typ *pbresource.Type, tenancy *pbresource.Tenancy, name string) *pbresource.ID { - return rtest.Resource(typ, name). - WithTenancy(tenancy). - ID() -} - -func nsTenancy(ns string) *pbresource.Tenancy { - return &pbresource.Tenancy{ - Partition: "default", - Namespace: ns, - PeerName: "local", - } -} - -func defaultTenancy() *pbresource.Tenancy { - return nsTenancy("default") -} diff --git a/internal/mesh/internal/controllers/routes/status.go b/internal/mesh/internal/controllers/routes/status.go deleted file mode 100644 index 71b6b8cd5b0b4..0000000000000 --- a/internal/mesh/internal/controllers/routes/status.go +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "fmt" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - StatusKey = "consul.io/routes-controller" - StatusConditionAccepted = "accepted" - - // conditions on xRoutes - - XRouteOKReason = "Ok" - XRouteOKMessage = "xRoute was accepted" - - MissingParentRefReason = "MissingParentRef" - MissingBackendRefReason = "MissingBackendRef" - - ParentRefOutsideMeshReason = "ParentRefOutsideMesh" - BackendRefOutsideMeshReason = "BackendRefOutsideMesh" - - ParentRefUsingMeshPortReason = "ParentRefUsingMeshPort" - BackendRefUsingMeshPortReason = "BackendRefUsingMeshPort" - - UnknownParentRefPortReason = "UnknownParentRefPort" - UnknownBackendRefPortReason = "UnknownBackendRefPort" - - ConflictNotBoundToParentRefReason = "ConflictNotBoundToParentRef" -) - -var ( - ConditionXRouteOK = &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_TRUE, - Reason: XRouteOKReason, - Message: XRouteOKMessage, - } -) - -func ConditionParentRefUsingMeshPort(ref *pbresource.Reference, port string) *pbresource.Condition { - return conditionRefUsingMeshPort(ref, port, false) -} - -func ConditionBackendRefUsingMeshPort(ref *pbresource.Reference, port string) *pbresource.Condition { - return conditionRefUsingMeshPort(ref, port, true) -} - -func conditionRefUsingMeshPort(ref *pbresource.Reference, port string, forBackend bool) *pbresource.Condition { - reason := ParentRefUsingMeshPortReason - short := "parent" - if forBackend { - reason = BackendRefUsingMeshPortReason - short = "backend" - } - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: reason, - Message: fmt.Sprintf( - "service for %s ref %q uses port %q which is a special unroutable mesh port", - short, - resource.ReferenceToString(ref), - port, - ), - } -} - -func ConditionMissingParentRef(ref *pbresource.Reference) *pbresource.Condition { - return conditionMissingRef(ref, false) -} - -func ConditionMissingBackendRef(ref *pbresource.Reference) *pbresource.Condition { - return conditionMissingRef(ref, true) -} - -func conditionMissingRef(ref *pbresource.Reference, forBackend bool) *pbresource.Condition { - reason := MissingParentRefReason - short := "parent" - if forBackend { - reason = MissingBackendRefReason - short = "backend" - } - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: reason, - Message: fmt.Sprintf( - "service for %s ref %q does not exist", - short, - resource.ReferenceToString(ref), - ), - } -} - -func ConditionParentRefOutsideMesh(ref *pbresource.Reference) *pbresource.Condition { - return conditionRefOutsideMesh(ref, false) -} - -func ConditionBackendRefOutsideMesh(ref *pbresource.Reference) *pbresource.Condition { - return conditionRefOutsideMesh(ref, true) -} - -func conditionRefOutsideMesh(ref *pbresource.Reference, forBackend bool) *pbresource.Condition { - reason := ParentRefOutsideMeshReason - short := "parent" - if forBackend { - reason = BackendRefOutsideMeshReason - short = "backend" - } - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: reason, - Message: fmt.Sprintf( - "service for %s ref %q does not expose a mesh port", - short, - resource.ReferenceToString(ref), - ), - } -} - -func ConditionUnknownParentRefPort(ref *pbresource.Reference, port string) *pbresource.Condition { - return conditionUnknownRefPort(ref, port, false) -} - -func ConditionUnknownBackendRefPort(ref *pbresource.Reference, port string) *pbresource.Condition { - return conditionUnknownRefPort(ref, port, true) -} - -func conditionUnknownRefPort(ref *pbresource.Reference, port string, forBackend bool) *pbresource.Condition { - reason := UnknownParentRefPortReason - short := "parent" - if forBackend { - reason = UnknownBackendRefPortReason - short = "backend" - } - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: reason, - Message: fmt.Sprintf( - "service for %s ref %q does not expose port %q", - short, - resource.ReferenceToString(ref), - port, - ), - } -} - -func ConditionConflictNotBoundToParentRef(ref *pbresource.Reference, port string, realType *pbresource.Type) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: ConflictNotBoundToParentRefReason, - Message: fmt.Sprintf( - "Existing routes of type %q are bound to parent ref %q on port %q preventing this from binding", - resource.TypeToString(realType), - resource.ReferenceToString(ref), - port, - ), - } -} diff --git a/internal/mesh/internal/controllers/routes/util.go b/internal/mesh/internal/controllers/routes/util.go deleted file mode 100644 index 8f9fb87825aea..0000000000000 --- a/internal/mesh/internal/controllers/routes/util.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package routes - -import ( - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/protoutil" -) - -// Deprecated: see protoutil.Clone -func protoClone[T proto.Message](v T) T { - return protoutil.Clone(v) -} - -// Deprecated: see protoutil.CloneSlice -func protoSliceClone[T proto.Message](in []T) []T { - return protoutil.CloneSlice(in) -} diff --git a/internal/mesh/internal/controllers/routes/xroutemapper/util.go b/internal/mesh/internal/controllers/routes/xroutemapper/util.go deleted file mode 100644 index e3d843cb2833c..0000000000000 --- a/internal/mesh/internal/controllers/routes/xroutemapper/util.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xroutemapper - -import ( - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func refSliceToRefSlice(refs []*pbresource.Reference) []resource.ReferenceOrID { - if refs == nil { - return nil - } - out := make([]resource.ReferenceOrID, 0, len(refs)) - for _, ref := range refs { - out = append(out, ref) - } - return out -} - -func parentRefSliceToRefSlice(parentRefs []*pbmesh.ParentReference) []resource.ReferenceOrID { - if parentRefs == nil { - return nil - } - parents := make([]resource.ReferenceOrID, 0, len(parentRefs)) - for _, parentRef := range parentRefs { - if parentRef.Ref != nil { - parents = append(parents, parentRef.Ref) - } - } - return parents -} - -func backendRefSliceToRefSlice(backendRefs []*pbmesh.BackendReference) []resource.ReferenceOrID { - if backendRefs == nil { - return nil - } - backends := make([]resource.ReferenceOrID, 0, len(backendRefs)) - for _, backendRef := range backendRefs { - if backendRef.Ref != nil { - backends = append(backends, backendRef.Ref) - } - } - return backends -} - -func sliceReplaceType(list []*pbresource.ID, typ *pbresource.Type) []*pbresource.ID { - if list == nil { - return nil - } - out := make([]*pbresource.ID, 0, len(list)) - for _, id := range list { - out = append(out, resource.ReplaceType(typ, id)) - } - return out -} diff --git a/internal/mesh/internal/controllers/routes/xroutemapper/xroutemapper.go b/internal/mesh/internal/controllers/routes/xroutemapper/xroutemapper.go deleted file mode 100644 index 2c240ee718196..0000000000000 --- a/internal/mesh/internal/controllers/routes/xroutemapper/xroutemapper.go +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xroutemapper - -import ( - "context" - "fmt" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// Mapper tracks the following relationships: -// -// - xRoute <-> ParentRef Service -// - xRoute <-> BackendRef Service -// - FailoverPolicy <-> DestRef Service -// -// It is the job of the controller, loader, and mapper to keep the mappings up -// to date whenever new data is loaded. Notably because the dep mapper events -// do not signal when data is deleted, it is the job of the reconcile load of -// the data causing the event to notice something has been deleted and to -// untrack it here. -type Mapper struct { - boundRefMapper *bimapper.Mapper - - httpRouteParentMapper *bimapper.Mapper - grpcRouteParentMapper *bimapper.Mapper - tcpRouteParentMapper *bimapper.Mapper - - httpRouteBackendMapper *bimapper.Mapper - grpcRouteBackendMapper *bimapper.Mapper - tcpRouteBackendMapper *bimapper.Mapper - - failMapper catalog.FailoverPolicyMapper -} - -// New creates a new Mapper. -func New() *Mapper { - return &Mapper{ - boundRefMapper: bimapper.NewWithWildcardLinkType(pbmesh.ComputedRoutesType), - - httpRouteParentMapper: bimapper.New(pbmesh.HTTPRouteType, pbcatalog.ServiceType), - grpcRouteParentMapper: bimapper.New(pbmesh.GRPCRouteType, pbcatalog.ServiceType), - tcpRouteParentMapper: bimapper.New(pbmesh.TCPRouteType, pbcatalog.ServiceType), - - httpRouteBackendMapper: bimapper.New(pbmesh.HTTPRouteType, pbcatalog.ServiceType), - grpcRouteBackendMapper: bimapper.New(pbmesh.GRPCRouteType, pbcatalog.ServiceType), - tcpRouteBackendMapper: bimapper.New(pbmesh.TCPRouteType, pbcatalog.ServiceType), - - failMapper: catalog.NewFailoverPolicyMapper(), - } -} - -func (m *Mapper) getRouteBiMappers(typ *pbresource.Type) (parent, backend *bimapper.Mapper) { - switch { - case resource.EqualType(pbmesh.HTTPRouteType, typ): - return m.httpRouteParentMapper, m.httpRouteBackendMapper - case resource.EqualType(pbmesh.GRPCRouteType, typ): - return m.grpcRouteParentMapper, m.grpcRouteBackendMapper - case resource.EqualType(pbmesh.TCPRouteType, typ): - return m.tcpRouteParentMapper, m.tcpRouteBackendMapper - default: - panic("unknown xroute type: " + resource.TypeToString(typ)) - } -} - -func (m *Mapper) walkRouteParentBiMappers(fn func(bm *bimapper.Mapper)) { - for _, bm := range []*bimapper.Mapper{ - m.httpRouteParentMapper, - m.grpcRouteParentMapper, - m.tcpRouteParentMapper, - } { - fn(bm) - } -} - -func (m *Mapper) walkRouteBackendBiMappers(fn func(bm *bimapper.Mapper)) { - for _, bm := range []*bimapper.Mapper{ - m.httpRouteBackendMapper, - m.grpcRouteBackendMapper, - m.tcpRouteBackendMapper, - } { - fn(bm) - } -} - -func (m *Mapper) TrackComputedRoutes(cr *types.DecodedComputedRoutes) { - if cr != nil { - refs := refSliceToRefSlice(cr.Data.BoundReferences) - m.boundRefMapper.TrackItem(cr.Resource.Id, refs) - } -} - -func (m *Mapper) UntrackComputedRoutes(id *pbresource.ID) { - m.boundRefMapper.UntrackItem(id) -} - -// TrackXRoute indexes the xRoute->parentRefService and -// xRoute->backendRefService relationship. -func (m *Mapper) TrackXRoute(id *pbresource.ID, xroute types.XRouteData) { - parent, backend := m.getRouteBiMappers(id.Type) - if parent == nil || backend == nil { - return - } - - parentRefs := parentRefSliceToRefSlice(xroute.GetParentRefs()) - backendRefs := backendRefSliceToRefSlice(xroute.GetUnderlyingBackendRefs()) - - parent.TrackItem(id, parentRefs) - backend.TrackItem(id, backendRefs) -} - -// UntrackXRoute undoes TrackXRoute. -func (m *Mapper) UntrackXRoute(id *pbresource.ID) { - parent, backend := m.getRouteBiMappers(id.Type) - if parent == nil || backend == nil { - return - } - - parent.UntrackItem(id) - backend.UntrackItem(id) -} - -// RouteIDsByParentServiceRef returns xRoute IDs that have a direct parentRef link to -// the provided service. -func (m *Mapper) RouteIDsByParentServiceRef(ref *pbresource.Reference) []*pbresource.ID { - var out []*pbresource.ID - m.walkRouteParentBiMappers(func(bm *bimapper.Mapper) { - got := bm.ItemsForLink(resource.IDFromReference(ref)) - out = append(out, got...) - }) - return out -} - -// RouteIDsByBackendServiceRef returns xRoute IDs that have a direct backendRef -// link to the provided service. -func (m *Mapper) RouteIDsByBackendServiceRef(ref *pbresource.Reference) []*pbresource.ID { - var out []*pbresource.ID - m.walkRouteBackendBiMappers(func(bm *bimapper.Mapper) { - got := bm.ItemsForLink(resource.IDFromReference(ref)) - out = append(out, got...) - }) - return out -} - -// ParentServiceRefsByRouteID is the opposite of RouteIDsByParentServiceRef. -func (m *Mapper) ParentServiceRefsByRouteID(item *pbresource.ID) []*pbresource.Reference { - parent, _ := m.getRouteBiMappers(item.Type) - if parent == nil { - return nil - } - return parent.LinksForItem(item) -} - -// BackendServiceRefsByRouteID is the opposite of RouteIDsByBackendServiceRef. -func (m *Mapper) BackendServiceRefsByRouteID(item *pbresource.ID) []*pbresource.Reference { - _, backend := m.getRouteBiMappers(item.Type) - if backend == nil { - return nil - } - return backend.LinksForItem(item) -} - -// MapHTTPRoute will map HTTPRoute changes to ComputedRoutes changes. -func (m *Mapper) MapHTTPRoute(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - return mapXRouteToComputedRoutes[*pbmesh.HTTPRoute](res, m) -} - -// MapGRPCRoute will map GRPCRoute changes to ComputedRoutes changes. -func (m *Mapper) MapGRPCRoute(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - return mapXRouteToComputedRoutes[*pbmesh.GRPCRoute](res, m) -} - -// MapTCPRoute will map TCPRoute changes to ComputedRoutes changes. -func (m *Mapper) MapTCPRoute(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - return mapXRouteToComputedRoutes[*pbmesh.TCPRoute](res, m) -} - -// mapXRouteToComputedRoutes will map xRoute changes to ComputedRoutes changes. -func mapXRouteToComputedRoutes[T types.XRouteData](res *pbresource.Resource, m *Mapper) ([]controller.Request, error) { - dec, err := resource.Decode[T](res) - if err != nil { - return nil, fmt.Errorf("error unmarshalling xRoute: %w", err) - } - - route := dec.Data - - m.TrackXRoute(res.Id, route) - - refs := parentRefSliceToRefSlice(route.GetParentRefs()) - - // Augment with any bound refs to cover the case where an xRoute used to - // have a parentRef to a service and now no longer does. - prevRefs := m.boundRefMapper.ItemRefsForLink(dec.Resource.Id) - for _, ref := range prevRefs { - refs = append(refs, ref) - } - - return controller.MakeRequests(pbmesh.ComputedRoutesType, refs), nil -} - -func (m *Mapper) MapFailoverPolicy( - _ context.Context, - _ controller.Runtime, - res *pbresource.Resource, -) ([]controller.Request, error) { - if !types.IsFailoverPolicyType(res.Id.Type) { - return nil, fmt.Errorf("type is not a failover policy type: %s", res.Id.Type) - } - - dec, err := resource.Decode[*pbcatalog.FailoverPolicy](res) - if err != nil { - return nil, fmt.Errorf("error unmarshalling failover policy: %w", err) - } - - m.failMapper.TrackFailover(dec) - - // Since this is name-aligned, just switch the type and find routes that - // will route any traffic to this destination service. - svcID := resource.ReplaceType(pbcatalog.ServiceType, res.Id) - - return m.mapXRouteDirectServiceRefToComputedRoutesByID(svcID) -} - -func (m *Mapper) TrackFailoverPolicy(failover *types.DecodedFailoverPolicy) { - if failover != nil { - m.failMapper.TrackFailover(failover) - } -} - -func (m *Mapper) UntrackFailoverPolicy(failoverPolicyID *pbresource.ID) { - m.failMapper.UntrackFailover(failoverPolicyID) -} - -func (m *Mapper) MapDestinationPolicy( - _ context.Context, - _ controller.Runtime, - res *pbresource.Resource, -) ([]controller.Request, error) { - if !types.IsDestinationPolicyType(res.Id.Type) { - return nil, fmt.Errorf("type is not a destination policy type: %s", res.Id.Type) - } - - // Since this is name-aligned, just switch the type and find routes that - // will route any traffic to this destination service. - svcID := resource.ReplaceType(pbcatalog.ServiceType, res.Id) - - return m.mapXRouteDirectServiceRefToComputedRoutesByID(svcID) -} - -func (m *Mapper) MapService( - _ context.Context, - _ controller.Runtime, - res *pbresource.Resource, -) ([]controller.Request, error) { - // Ultimately we want to wake up a ComputedRoutes if either of the - // following exist: - // - // 1. xRoute[parentRef=OUTPUT_EVENT; backendRef=INPUT_EVENT] - // 2. xRoute[parentRef=OUTPUT_EVENT; backendRef=SOMETHING], FailoverPolicy[name=SOMETHING, destRef=INPUT_EVENT] - - // (case 2) First find all failover policies that have a reference to our input service. - failPolicyIDs := m.failMapper.FailoverIDsByService(res.Id) - effectiveServiceIDs := sliceReplaceType(failPolicyIDs, pbcatalog.ServiceType) - - // (case 1) Do the direct mapping also. - effectiveServiceIDs = append(effectiveServiceIDs, res.Id) - - var reqs []controller.Request - for _, svcID := range effectiveServiceIDs { - got, err := m.mapXRouteDirectServiceRefToComputedRoutesByID(svcID) - if err != nil { - return nil, err - } - reqs = append(reqs, got...) - } - - return reqs, nil -} - -// NOTE: this function does not interrogate down into failover policies -func (m *Mapper) mapXRouteDirectServiceRefToComputedRoutesByID(svcID *pbresource.ID) ([]controller.Request, error) { - if !types.IsServiceType(svcID.Type) { - return nil, fmt.Errorf("type is not a service type: %s", svcID.Type) - } - - // return 1 hit for the name aligned mesh config - primaryReq := controller.Request{ - ID: resource.ReplaceType(pbmesh.ComputedRoutesType, svcID), - } - - svcRef := resource.Reference(svcID, "") - - // Find all routes with an explicit backend ref to this service. - // - // the "name aligned" inclusion above should handle the implicit default - // destination implied by a parent ref without us having to do much more. - routeIDs := m.RouteIDsByBackendServiceRef(svcRef) - - out := make([]controller.Request, 0, 1+len(routeIDs)) // estimated - out = append(out, primaryReq) - - for _, routeID := range routeIDs { - // Find all parent refs of this route. - svcRefs := m.ParentServiceRefsByRouteID(routeID) - - out = append(out, controller.MakeRequests( - pbmesh.ComputedRoutesType, - svcRefs, - )...) - } - - return out, nil -} diff --git a/internal/mesh/internal/controllers/routes/xroutemapper/xroutemapper_test.go b/internal/mesh/internal/controllers/routes/xroutemapper/xroutemapper_test.go deleted file mode 100644 index e74b049b7dce6..0000000000000 --- a/internal/mesh/internal/controllers/routes/xroutemapper/xroutemapper_test.go +++ /dev/null @@ -1,694 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xroutemapper - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/durationpb" - - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestMapper_HTTPRoute_Tracking(t *testing.T) { - testMapper_Tracking(t, pbmesh.HTTPRouteType, func(t *testing.T, parentRefs []*pbmesh.ParentReference, backendRefs []*pbmesh.BackendReference) proto.Message { - route := &pbmesh.HTTPRoute{ - ParentRefs: parentRefs, - } - for _, backendRef := range backendRefs { - route.Rules = append(route.Rules, &pbmesh.HTTPRouteRule{ - BackendRefs: []*pbmesh.HTTPBackendRef{ - {BackendRef: backendRef}, - }, - }) - } - return route - }) -} - -func TestMapper_GRPCRoute_Tracking(t *testing.T) { - testMapper_Tracking(t, pbmesh.GRPCRouteType, func(t *testing.T, parentRefs []*pbmesh.ParentReference, backendRefs []*pbmesh.BackendReference) proto.Message { - route := &pbmesh.GRPCRoute{ - ParentRefs: parentRefs, - } - for _, backendRef := range backendRefs { - route.Rules = append(route.Rules, &pbmesh.GRPCRouteRule{ - BackendRefs: []*pbmesh.GRPCBackendRef{ - {BackendRef: backendRef}, - }, - }) - } - return route - }) -} - -func TestMapper_TCPRoute_Tracking(t *testing.T) { - testMapper_Tracking(t, pbmesh.TCPRouteType, func(t *testing.T, parentRefs []*pbmesh.ParentReference, backendRefs []*pbmesh.BackendReference) proto.Message { - route := &pbmesh.TCPRoute{ - ParentRefs: parentRefs, - } - for _, backendRef := range backendRefs { - route.Rules = append(route.Rules, &pbmesh.TCPRouteRule{ - BackendRefs: []*pbmesh.TCPBackendRef{ - {BackendRef: backendRef}, - }, - }) - } - return route - }) -} - -func testMapper_Tracking(t *testing.T, typ *pbresource.Type, newRoute func(t *testing.T, parentRefs []*pbmesh.ParentReference, backendRefs []*pbmesh.BackendReference) proto.Message) { - registry := resource.NewRegistry() - types.Register(registry) - catalog.RegisterTypes(registry) - - newService := func(name string) *pbresource.Resource { - svc := rtest.Resource(pbcatalog.ServiceType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.Service{}). - Build() - rtest.ValidateAndNormalize(t, registry, svc) - return svc - } - - newDestPolicy := func(name string, dur time.Duration) *pbresource.Resource { - policy := rtest.Resource(pbmesh.DestinationPolicyType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(dur), - }, - }, - }).Build() - rtest.ValidateAndNormalize(t, registry, policy) - return policy - } - - newFailPolicy := func(name string, refs ...*pbresource.Reference) *pbresource.Resource { - var dests []*pbcatalog.FailoverDestination - for _, ref := range refs { - dests = append(dests, &pbcatalog.FailoverDestination{ - Ref: ref, - }) - } - policy := rtest.Resource(pbcatalog.FailoverPolicyType, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: dests, - }, - }).Build() - rtest.ValidateAndNormalize(t, registry, policy) - return policy - } - - apiComputedRoutes := newID(pbmesh.ComputedRoutesType, "api") - wwwComputedRoutes := newID(pbmesh.ComputedRoutesType, "www") - barComputedRoutes := newID(pbmesh.ComputedRoutesType, "bar") - fooComputedRoutes := newID(pbmesh.ComputedRoutesType, "foo") - zimComputedRoutes := newID(pbmesh.ComputedRoutesType, "zim") - girComputedRoutes := newID(pbmesh.ComputedRoutesType, "gir") - - m := New() - - var ( - apiSvc = newService("api") - wwwSvc = newService("www") - barSvc = newService("bar") - fooSvc = newService("foo") - zimSvc = newService("zim") - girSvc = newService("gir") - - apiSvcRef = resource.Reference(apiSvc.Id, "") - wwwSvcRef = resource.Reference(wwwSvc.Id, "") - barSvcRef = resource.Reference(barSvc.Id, "") - fooSvcRef = resource.Reference(fooSvc.Id, "") - zimSvcRef = resource.Reference(zimSvc.Id, "") - girSvcRef = resource.Reference(girSvc.Id, "") - - apiDest = newDestPolicy("api", 55*time.Second) - wwwDest = newDestPolicy("www", 123*time.Second) - - // Start out easy and don't have failover policies that reference other services. - apiFail = newFailPolicy("api", newRef(pbcatalog.ServiceType, "api")) - wwwFail = newFailPolicy("www", newRef(pbcatalog.ServiceType, "www")) - barFail = newFailPolicy("bar", newRef(pbcatalog.ServiceType, "bar")) - ) - - testutil.RunStep(t, "only name aligned defaults", func(t *testing.T) { - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes) - requireTracking(t, m, fooSvc, fooComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes) - - // This will track the failover policies. - requireTracking(t, m, apiFail, apiComputedRoutes) - requireTracking(t, m, wwwFail, wwwComputedRoutes) - requireTracking(t, m, barFail, barComputedRoutes) - - // verify other helper methods - for _, ref := range []*pbresource.Reference{apiSvcRef, wwwSvcRef, barSvcRef, fooSvcRef, zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - var ( - route1 *pbresource.Resource - ) - testutil.RunStep(t, "track a name-aligned xroute", func(t *testing.T) { - // First route will also not cross any services. - route1 := rtest.Resource(typ, "route-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, newRoute(t, - []*pbmesh.ParentReference{ - {Ref: newRef(pbcatalog.ServiceType, "api")}, - }, - []*pbmesh.BackendReference{ - newBackendRef("api"), - }, - )).Build() - rtest.ValidateAndNormalize(t, registry, route1) - - requireTracking(t, m, route1, apiComputedRoutes) - - // Now 'api' references should trigger more, but be duplicate-suppressed. - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes) - requireTracking(t, m, fooSvc, fooComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes) - - requireTracking(t, m, apiFail, apiComputedRoutes) - requireTracking(t, m, wwwFail, wwwComputedRoutes) - requireTracking(t, m, barFail, barComputedRoutes) - - // verify other helper methods - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef}, m.BackendServiceRefsByRouteID(route1.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef}, m.ParentServiceRefsByRouteID(route1.Id)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id}, m.RouteIDsByBackendServiceRef(apiSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id}, m.RouteIDsByParentServiceRef(apiSvcRef)) - - for _, ref := range []*pbresource.Reference{wwwSvcRef, barSvcRef, fooSvcRef, zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - testutil.RunStep(t, "make the route cross services", func(t *testing.T) { - route1 = rtest.Resource(typ, "route-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, newRoute(t, - []*pbmesh.ParentReference{ - {Ref: newRef(pbcatalog.ServiceType, "api")}, - }, - []*pbmesh.BackendReference{ - newBackendRef("www"), - }, - )).Build() - rtest.ValidateAndNormalize(t, registry, route1) - - // Now witness the update. - requireTracking(t, m, route1, apiComputedRoutes) - - // Now 'api' references should trigger different things. - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes, apiComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes) - requireTracking(t, m, fooSvc, fooComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes, apiComputedRoutes) - - requireTracking(t, m, apiFail, apiComputedRoutes) - requireTracking(t, m, wwwFail, wwwComputedRoutes, apiComputedRoutes) - requireTracking(t, m, barFail, barComputedRoutes) - - // verify other helper methods - prototest.AssertElementsMatch(t, []*pbresource.Reference{wwwSvcRef}, m.BackendServiceRefsByRouteID(route1.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef}, m.ParentServiceRefsByRouteID(route1.Id)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(apiSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id}, m.RouteIDsByParentServiceRef(apiSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id}, m.RouteIDsByBackendServiceRef(wwwSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(wwwSvcRef)) - - for _, ref := range []*pbresource.Reference{barSvcRef, fooSvcRef, zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - var ( - route2 *pbresource.Resource - ) - testutil.RunStep(t, "make another route sharing a parent with the first", func(t *testing.T) { - route2 = rtest.Resource(typ, "route-2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, newRoute(t, - []*pbmesh.ParentReference{ - {Ref: newRef(pbcatalog.ServiceType, "api")}, - {Ref: newRef(pbcatalog.ServiceType, "foo")}, - }, - []*pbmesh.BackendReference{ - newBackendRef("bar"), - }, - )).Build() - rtest.ValidateAndNormalize(t, registry, route1) - - // Now witness a route with multiple parents, overlapping the other route. - requireTracking(t, m, route2, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes, apiComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, fooSvc, fooComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes, apiComputedRoutes) - - requireTracking(t, m, apiFail, apiComputedRoutes) - requireTracking(t, m, wwwFail, wwwComputedRoutes, apiComputedRoutes) - requireTracking(t, m, barFail, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, route1, apiComputedRoutes) - // skip re-verifying route2 - // requireTracking(t, m, route2, apiComputedRoutes, fooComputedRoutes) - - // verify other helper methods - prototest.AssertElementsMatch(t, []*pbresource.Reference{wwwSvcRef}, m.BackendServiceRefsByRouteID(route1.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef}, m.ParentServiceRefsByRouteID(route1.Id)) - - prototest.AssertElementsMatch(t, []*pbresource.Reference{barSvcRef}, m.BackendServiceRefsByRouteID(route2.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef, fooSvcRef}, m.ParentServiceRefsByRouteID(route2.Id)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(apiSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id, route2.Id}, m.RouteIDsByParentServiceRef(apiSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id}, m.RouteIDsByBackendServiceRef(wwwSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(wwwSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByBackendServiceRef(barSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(barSvcRef)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(fooSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByParentServiceRef(fooSvcRef)) - - for _, ref := range []*pbresource.Reference{zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - testutil.RunStep(t, "update the failover policy to cross services", func(t *testing.T) { - apiFail = newFailPolicy("api", - newRef(pbcatalog.ServiceType, "foo"), - newRef(pbcatalog.ServiceType, "zim")) - requireTracking(t, m, apiFail, apiComputedRoutes) - - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes, apiComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, fooSvc, fooComputedRoutes, apiComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes, apiComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes, apiComputedRoutes) - - // skipping verification of apiFail b/c it happened above already - // requireTracking(t, m, apiFail, apiComputedRoutes) - requireTracking(t, m, wwwFail, wwwComputedRoutes, apiComputedRoutes) - requireTracking(t, m, barFail, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, route1, apiComputedRoutes) - requireTracking(t, m, route2, apiComputedRoutes, fooComputedRoutes) - - // verify other helper methods - prototest.AssertElementsMatch(t, []*pbresource.Reference{wwwSvcRef}, m.BackendServiceRefsByRouteID(route1.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef}, m.ParentServiceRefsByRouteID(route1.Id)) - - prototest.AssertElementsMatch(t, []*pbresource.Reference{barSvcRef}, m.BackendServiceRefsByRouteID(route2.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef, fooSvcRef}, m.ParentServiceRefsByRouteID(route2.Id)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(apiSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id, route2.Id}, m.RouteIDsByParentServiceRef(apiSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id}, m.RouteIDsByBackendServiceRef(wwwSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(wwwSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByBackendServiceRef(barSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(barSvcRef)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(fooSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByParentServiceRef(fooSvcRef)) - - for _, ref := range []*pbresource.Reference{zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - testutil.RunStep(t, "set a new failover policy for a service in route2", func(t *testing.T) { - barFail = newFailPolicy("bar", - newRef(pbcatalog.ServiceType, "gir")) - requireTracking(t, m, barFail, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes, apiComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, fooSvc, fooComputedRoutes, apiComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes, apiComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes, apiComputedRoutes) - - requireTracking(t, m, apiFail, apiComputedRoutes) - requireTracking(t, m, wwwFail, wwwComputedRoutes, apiComputedRoutes) - // skipping verification of barFail b/c it happened above already - // requireTracking(t, m, barFail, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, route1, apiComputedRoutes) - requireTracking(t, m, route2, apiComputedRoutes, fooComputedRoutes) - - // verify other helper methods - prototest.AssertElementsMatch(t, []*pbresource.Reference{wwwSvcRef}, m.BackendServiceRefsByRouteID(route1.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef}, m.ParentServiceRefsByRouteID(route1.Id)) - - prototest.AssertElementsMatch(t, []*pbresource.Reference{barSvcRef}, m.BackendServiceRefsByRouteID(route2.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef, fooSvcRef}, m.ParentServiceRefsByRouteID(route2.Id)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(apiSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id, route2.Id}, m.RouteIDsByParentServiceRef(apiSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route1.Id}, m.RouteIDsByBackendServiceRef(wwwSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(wwwSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByBackendServiceRef(barSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(barSvcRef)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(fooSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByParentServiceRef(fooSvcRef)) - - for _, ref := range []*pbresource.Reference{zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - testutil.RunStep(t, "delete first route", func(t *testing.T) { - m.UntrackXRoute(route1.Id) - route1 = nil - - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, fooSvc, fooComputedRoutes, apiComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes, apiComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes) - - requireTracking(t, m, apiFail, apiComputedRoutes) - requireTracking(t, m, wwwFail, wwwComputedRoutes) - requireTracking(t, m, barFail, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, route2, apiComputedRoutes, fooComputedRoutes) - - // verify other helper methods - prototest.AssertElementsMatch(t, []*pbresource.Reference{barSvcRef}, m.BackendServiceRefsByRouteID(route2.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef, fooSvcRef}, m.ParentServiceRefsByRouteID(route2.Id)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(apiSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByParentServiceRef(apiSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByBackendServiceRef(barSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(barSvcRef)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(fooSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByParentServiceRef(fooSvcRef)) - - for _, ref := range []*pbresource.Reference{wwwSvcRef, zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - testutil.RunStep(t, "delete all failover", func(t *testing.T) { - m.UntrackFailoverPolicy(apiFail.Id) - m.UntrackFailoverPolicy(wwwFail.Id) - m.UntrackFailoverPolicy(barFail.Id) - - apiFail = nil - wwwFail = nil - barFail = nil - - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes, apiComputedRoutes, fooComputedRoutes) - - requireTracking(t, m, fooSvc, fooComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes) - - requireTracking(t, m, route2, apiComputedRoutes, fooComputedRoutes) - - // verify other helper methods - prototest.AssertElementsMatch(t, []*pbresource.Reference{barSvcRef}, m.BackendServiceRefsByRouteID(route2.Id)) - prototest.AssertElementsMatch(t, []*pbresource.Reference{apiSvcRef, fooSvcRef}, m.ParentServiceRefsByRouteID(route2.Id)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(apiSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByParentServiceRef(apiSvcRef)) - - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByBackendServiceRef(barSvcRef)) - require.Empty(t, m.RouteIDsByParentServiceRef(barSvcRef)) - - require.Empty(t, m.RouteIDsByBackendServiceRef(fooSvcRef)) - prototest.AssertElementsMatch(t, []*pbresource.ID{route2.Id}, m.RouteIDsByParentServiceRef(fooSvcRef)) - - for _, ref := range []*pbresource.Reference{wwwSvcRef, zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - testutil.RunStep(t, "delete second route", func(t *testing.T) { - m.UntrackXRoute(route2.Id) - route2 = nil - - requireTracking(t, m, apiSvc, apiComputedRoutes) - requireTracking(t, m, wwwSvc, wwwComputedRoutes) - requireTracking(t, m, barSvc, barComputedRoutes) - - requireTracking(t, m, fooSvc, fooComputedRoutes) - requireTracking(t, m, zimSvc, zimComputedRoutes) - requireTracking(t, m, girSvc, girComputedRoutes) - - requireTracking(t, m, apiDest, apiComputedRoutes) - requireTracking(t, m, wwwDest, wwwComputedRoutes) - - // verify other helper methods - for _, ref := range []*pbresource.Reference{apiSvcRef, wwwSvcRef, barSvcRef, fooSvcRef, zimSvcRef, girSvcRef} { - require.Empty(t, m.RouteIDsByBackendServiceRef(ref)) - require.Empty(t, m.RouteIDsByParentServiceRef(ref)) - } - }) - - testutil.RunStep(t, "removal of a parent still triggers for old computed routes until the bound reference is cleared", func(t *testing.T) { - route1 = rtest.Resource(typ, "route-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, newRoute(t, - []*pbmesh.ParentReference{ - {Ref: newRef(pbcatalog.ServiceType, "bar")}, - {Ref: newRef(pbcatalog.ServiceType, "foo")}, - }, - []*pbmesh.BackendReference{ - newBackendRef("api"), - }, - )).Build() - rtest.ValidateAndNormalize(t, registry, route1) - - requireTracking(t, m, route1, barComputedRoutes, fooComputedRoutes) - - // Simulate a Reconcile that would update the mapper. - // - // NOTE: we do not ValidateAndNormalize these since the mapper doesn't use the data. - fooCR := rtest.ResourceID(fooComputedRoutes). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiSvcRef, - fooSvcRef, - resource.Reference(route1.Id, ""), - }, - }).Build() - m.TrackComputedRoutes(rtest.MustDecode[*pbmesh.ComputedRoutes](t, fooCR)) - - barCR := rtest.ResourceID(barComputedRoutes). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiSvcRef, - barSvcRef, - resource.Reference(route1.Id, ""), - }, - }).Build() - m.TrackComputedRoutes(rtest.MustDecode[*pbmesh.ComputedRoutes](t, barCR)) - - // Still has the same tracking. - requireTracking(t, m, route1, barComputedRoutes, fooComputedRoutes) - - // Now change the route to remove "bar" - - route1 = rtest.Resource(typ, "route-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, newRoute(t, - []*pbmesh.ParentReference{ - {Ref: newRef(pbcatalog.ServiceType, "foo")}, - }, - []*pbmesh.BackendReference{ - newBackendRef("api"), - }, - )).Build() - rtest.ValidateAndNormalize(t, registry, route1) - - // Now we see that it still emits the event for bar, so we get a chance to update it. - requireTracking(t, m, route1, barComputedRoutes, fooComputedRoutes) - - // Update the bound references on 'bar' to remove the route - barCR = rtest.ResourceID(barComputedRoutes). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiSvcRef, - barSvcRef, - }, - }).Build() - m.TrackComputedRoutes(rtest.MustDecode[*pbmesh.ComputedRoutes](t, barCR)) - - // Now 'bar' no longer has a link to the route. - requireTracking(t, m, route1, fooComputedRoutes) - }) -} - -func requireTracking( - t *testing.T, - mapper *Mapper, - res *pbresource.Resource, - computedRoutesIDs ...*pbresource.ID, -) { - t.Helper() - - require.NotNil(t, res) - - var ( - reqs []controller.Request - err error - ) - switch { - case resource.EqualType(pbmesh.HTTPRouteType, res.Id.Type): - reqs, err = mapper.MapHTTPRoute(context.Background(), controller.Runtime{}, res) - case resource.EqualType(pbmesh.GRPCRouteType, res.Id.Type): - reqs, err = mapper.MapGRPCRoute(context.Background(), controller.Runtime{}, res) - case resource.EqualType(pbmesh.TCPRouteType, res.Id.Type): - reqs, err = mapper.MapTCPRoute(context.Background(), controller.Runtime{}, res) - case resource.EqualType(pbmesh.DestinationPolicyType, res.Id.Type): - reqs, err = mapper.MapDestinationPolicy(context.Background(), controller.Runtime{}, res) - case resource.EqualType(pbcatalog.FailoverPolicyType, res.Id.Type): - reqs, err = mapper.MapFailoverPolicy(context.Background(), controller.Runtime{}, res) - case resource.EqualType(pbcatalog.ServiceType, res.Id.Type): - reqs, err = mapper.MapService(context.Background(), controller.Runtime{}, res) - default: - t.Fatalf("unhandled resource type: %s", resource.TypeToString(res.Id.Type)) - } - - require.NoError(t, err) - reqs = testDeduplicateRequests(reqs) - require.Len(t, reqs, len(computedRoutesIDs)) - for _, computedRoutesID := range computedRoutesIDs { - require.NotNil(t, computedRoutesID) - prototest.AssertContainsElement(t, reqs, controller.Request{ID: computedRoutesID}) - } -} - -func newBackendRef(name string) *pbmesh.BackendReference { - return &pbmesh.BackendReference{ - Ref: newRef(pbcatalog.ServiceType, name), - } -} - -func newRef(typ *pbresource.Type, name string) *pbresource.Reference { - return rtest.Resource(typ, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") -} - -func newID(typ *pbresource.Type, name string) *pbresource.ID { - return rtest.Resource(typ, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() -} - -func testDeduplicateRequests(reqs []controller.Request) []controller.Request { - type resID struct { - resource.ReferenceKey - UID string - } - - out := make([]controller.Request, 0, len(reqs)) - seen := make(map[resID]struct{}) - - for _, req := range reqs { - rid := resID{ - ReferenceKey: resource.NewReferenceKey(req.ID), - UID: req.ID.Uid, - } - if _, ok := seen[rid]; !ok { - out = append(out, req) - seen[rid] = struct{}{} - } - } - - return out -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go b/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go deleted file mode 100644 index 459c68666b98e..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/builder.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "fmt" - - "github.com/hashicorp/consul/internal/resource" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// Builder builds a ProxyStateTemplate. -type Builder struct { - id *pbresource.ID - proxyStateTemplate *pbmesh.ProxyStateTemplate - proxyCfg *pbmesh.ComputedProxyConfiguration - trustDomain string - localDatacenter string - defaultAllow bool -} - -func New( - id *pbresource.ID, - identity *pbresource.Reference, - trustDomain string, - dc string, - defaultAllow bool, - proxyCfg *pbmesh.ComputedProxyConfiguration, -) *Builder { - if !resource.EqualType(pbmesh.ProxyStateTemplateType, id.GetType()) { - panic(fmt.Sprintf("wrong type: expected pbmesh.ProxyStateTemplate, but got %T", id.Type)) - } - - if !resource.EqualType(pbauth.WorkloadIdentityType, identity.GetType()) { - panic(fmt.Sprintf("wrong type: expected pbauth.WorkloadIdentityType, but got %T", identity.Type)) - } - return &Builder{ - id: id, - trustDomain: trustDomain, - localDatacenter: dc, - defaultAllow: defaultAllow, - proxyCfg: proxyCfg, - proxyStateTemplate: &pbmesh.ProxyStateTemplate{ - ProxyState: &pbmesh.ProxyState{ - Identity: identity, - Clusters: make(map[string]*pbproxystate.Cluster), - Endpoints: make(map[string]*pbproxystate.Endpoints), - Routes: make(map[string]*pbproxystate.Route), - }, - RequiredEndpoints: make(map[string]*pbproxystate.EndpointRef), - RequiredLeafCertificates: make(map[string]*pbproxystate.LeafCertificateRef), - RequiredTrustBundles: make(map[string]*pbproxystate.TrustBundleRef), - }, - } -} - -func (b *Builder) Build() *pbmesh.ProxyStateTemplate { - workloadIdentity := b.proxyStateTemplate.ProxyState.Identity.Name - b.proxyStateTemplate.RequiredLeafCertificates[workloadIdentity] = &pbproxystate.LeafCertificateRef{ - Name: workloadIdentity, - Namespace: b.id.Tenancy.Namespace, - Partition: b.id.Tenancy.Partition, - } - - b.proxyStateTemplate.RequiredTrustBundles[b.id.Tenancy.PeerName] = &pbproxystate.TrustBundleRef{ - Peer: b.id.Tenancy.PeerName, - } - - finalCleanupOfProxyStateTemplate(b.proxyStateTemplate) - - return b.proxyStateTemplate -} - -func finalCleanupOfProxyStateTemplate(pst *pbmesh.ProxyStateTemplate) { - if pst.ProxyState != nil { - // Ensure all clusters have names by duplicating them from the map - // if the above assembly code neglected any. - for name, cluster := range pst.ProxyState.Clusters { - if cluster.Name == "" && name != "" { - cluster.Name = name - } - } - } -} - -type ListenerBuilder struct { - listener *pbproxystate.Listener - builder *Builder -} - -func (b *Builder) NewListenerBuilder(l *pbproxystate.Listener) *ListenerBuilder { - return &ListenerBuilder{ - listener: l, - builder: b, - } -} - -func (l *ListenerBuilder) buildListener() { - if l.listener != nil { - l.builder.proxyStateTemplate.ProxyState.Listeners = append(l.builder.proxyStateTemplate.ProxyState.Listeners, l.listener) - } -} - -type RouterBuilder struct { - router *pbproxystate.Router - builder *ListenerBuilder -} - -func (b *ListenerBuilder) NewRouterBuilder(r *pbproxystate.Router) *RouterBuilder { - return &RouterBuilder{ - router: r, - builder: b, - } -} - -func (r *RouterBuilder) buildRouter() { - r.builder.listener.Routers = append(r.builder.listener.Routers, r.router) -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/builder_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/builder_test.go deleted file mode 100644 index 4128fc0839505..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/builder_test.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "flag" - "os" - "testing" - - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestMain(m *testing.M) { - flag.Parse() - os.Exit(m.Run()) -} - -func protoToJSON(t *testing.T, pb proto.Message) string { - return prototest.ProtoToJSON(t, pb) -} - -func JSONToProxyTemplate(t *testing.T, json []byte) *pbmesh.ProxyStateTemplate { - t.Helper() - proxyTemplate := &pbmesh.ProxyStateTemplate{} - m := protojson.UnmarshalOptions{} - err := m.Unmarshal(json, proxyTemplate) - require.NoError(t, err) - return proxyTemplate -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go deleted file mode 100644 index 289c8c76548e1..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "fmt" - "sort" - "testing" - - "github.com/stretchr/testify/require" - - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/mesh/internal/types/intermediate" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/internal/testing/golden" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func TestBuildMultiportImplicitDestinations(t *testing.T) { - // TODO(rb/v2): add a fetchertest package to construct implicit upstreams - // correctly from inputs. the following is far too manual and error prone - // to be an accurate representation of what implicit upstreams look like. - const ( - apiApp = "api-app" - apiApp2 = "api-app2" - trustDomain = "foo.consul" - datacenter = "dc1" - ) - proxyCfg := &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - TransparentProxy: &pbmesh.TransparentProxy{ - OutboundListenerPort: 15001, - }, - }, - } - - multiportServiceData := &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - VirtualPort: 7070, - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "tcp2", - VirtualPort: 8081, - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "http", - VirtualPort: 8080, - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "mesh", - VirtualPort: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - } - - multiportEndpointsData := &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "10.0.0.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - } - apiAppService := resourcetest.Resource(pbcatalog.ServiceType, apiApp). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, multiportServiceData). - Build() - - apiApp2Service := resourcetest.Resource(pbcatalog.ServiceType, apiApp2). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, multiportServiceData). - Build() - - apiAppEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, apiApp). - WithOwner(apiAppService.Id). - WithData(t, multiportEndpointsData). - WithTenancy(resource.DefaultNamespacedTenancy()).Build() - - apiApp2Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, apiApp2). - WithOwner(apiApp2Service.Id). - WithData(t, multiportEndpointsData). - WithTenancy(resource.DefaultNamespacedTenancy()).Build() - - mwEndpointsData := &pbcatalog.ServiceEndpoints{ // variant on apiAppEndpoints - Endpoints: []*pbcatalog.Endpoint{ - { - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "10.0.0.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - { - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "10.0.0.2"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - } - mwEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, apiApp). - WithOwner(apiAppService.Id). - WithData(t, mwEndpointsData). - WithTenancy(resource.DefaultNamespacedTenancy()).Build() - - apiAppIdentity := &pbresource.Reference{ - Name: fmt.Sprintf("%s-identity", apiApp), - Tenancy: apiAppEndpoints.Id.Tenancy, - } - - apiApp2Identity := &pbresource.Reference{ - Name: fmt.Sprintf("%s-identity", apiApp2), - Tenancy: apiApp2Endpoints.Id.Tenancy, - } - - apiAppComputedRoutesID := resource.ReplaceType(pbmesh.ComputedRoutesType, apiAppService.Id) - apiAppComputedRoutes := routestest.BuildComputedRoutes(t, apiAppComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, apiAppService), - ) - require.NotNil(t, apiAppComputedRoutes) - - apiApp2ComputedRoutesID := resource.ReplaceType(pbmesh.ComputedRoutesType, apiApp2Service.Id) - apiApp2ComputedRoutes := routestest.BuildComputedRoutes(t, apiApp2ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, apiApp2Service), - ) - require.NotNil(t, apiApp2ComputedRoutes) - - newImplicitDestination := func( - svc *pbresource.Resource, - endpoints *pbresource.Resource, - computedRoutes *types.DecodedComputedRoutes, - identities []*pbresource.Reference, - virtualIPs []string, - ) []*intermediate.Destination { - svcDec := resourcetest.MustDecode[*pbcatalog.Service](t, svc) - seDec := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](t, endpoints) - - var out []*intermediate.Destination - for _, port := range svcDec.Data.Ports { - portName := port.TargetPort - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - continue - } - - dest := &intermediate.Destination{ - Service: svcDec, - ComputedPortRoutes: routestest.MutateTargets(t, computedRoutes.Data, portName, func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(svc.Id, details.BackendRef.Ref) && details.BackendRef.Port == portName: - details.ServiceEndpointsId = endpoints.Id - details.ServiceEndpoints = seDec.Data - details.IdentityRefs = identities - } - }), - VirtualIPs: virtualIPs, - } - out = append(out, dest) - } - return out - } - - apiAppDestinations := newImplicitDestination( - apiAppService, - apiAppEndpoints, - apiAppComputedRoutes, - []*pbresource.Reference{apiAppIdentity}, - []string{"1.1.1.1"}, - ) - - apiApp2Destinations := newImplicitDestination( - apiApp2Service, - apiApp2Endpoints, - apiApp2ComputedRoutes, - []*pbresource.Reference{apiApp2Identity}, - []string{"2.2.2.2", "3.3.3.3"}, - ) - - mwDestinations := newImplicitDestination( - apiAppService, - mwEndpoints, - apiAppComputedRoutes, - []*pbresource.Reference{apiAppIdentity}, - []string{"1.1.1.1"}, - ) - - twoImplicitDestinations := append( - append([]*intermediate.Destination{}, apiAppDestinations...), - apiApp2Destinations..., - ) - - cases := map[string]struct { - getDestinations func() []*intermediate.Destination - }{ - // Most basic test that multiport configuration works - "destination/multiport-l4-and-l7-single-implicit-destination-tproxy": { - getDestinations: func() []*intermediate.Destination { return apiAppDestinations }, - }, - // Test shows that with multiple workloads for a service exposing the same ports, the routers - // and clusters do not get duplicated. - "destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy": { - getDestinations: func() []*intermediate.Destination { return mwDestinations }, - }, - // Test shows that with multiple workloads for a service exposing the same ports, the routers - // and clusters do not get duplicated. - "destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy": { - getDestinations: func() []*intermediate.Destination { return twoImplicitDestinations }, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), trustDomain, datacenter, false, proxyCfg). - BuildDestinations(c.getDestinations()). - Build() - - // sort routers because of test flakes where order was flip flopping. - actualRouters := proxyTmpl.ProxyState.Listeners[0].Routers - sort.Slice(actualRouters, func(i, j int) bool { - return actualRouters[i].String() < actualRouters[j].String() - }) - - actual := protoToJSON(t, proxyTmpl) - expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+".golden")) - - // sort routers on listener from golden file - expectedRouters := expected.ProxyState.Listeners[0].Routers - sort.Slice(expectedRouters, func(i, j int) bool { - return expectedRouters[i].String() < expectedRouters[j].String() - }) - - // convert back to json after sorting so that test output does not contain extraneous fields. - require.Equal(t, protoToJSON(t, expected), protoToJSON(t, proxyTmpl)) - }) - } -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go deleted file mode 100644 index f2c4901c89b6d..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go +++ /dev/null @@ -1,715 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "fmt" - "time" - - "github.com/hashicorp/consul/agent/xds/naming" - - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/agent/connect" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/mesh/internal/types/intermediate" - "github.com/hashicorp/consul/internal/protoutil" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// BuildDestinations creates listeners, routers, clusters, and endpointRefs for all destinations -// and adds them to the proxyState. -func (b *Builder) BuildDestinations(destinations []*intermediate.Destination) *Builder { - var lb *ListenerBuilder - if b.proxyCfg.IsTransparentProxy() { - lb = b.addTransparentProxyOutboundListener(b.proxyCfg.DynamicConfig.TransparentProxy.OutboundListenerPort) - lb.listener.DefaultRouter = lb.addL4RouterForDirect(naming.OriginalDestinationClusterName, fmt.Sprintf("upstream.%s", naming.OriginalDestinationClusterName)).router - b.addL4ClusterForDirect(naming.OriginalDestinationClusterName) - } - - for _, destination := range destinations { - b.buildDestination(lb, destination) - } - - if b.proxyCfg.IsTransparentProxy() { - lb.buildListener() - } - - return b -} - -func (b *Builder) buildDestination( - tproxyOutboundListenerBuilder *ListenerBuilder, - destination *intermediate.Destination, -) *Builder { - var ( - effectiveProtocol = destination.ComputedPortRoutes.Protocol - targets = destination.ComputedPortRoutes.Targets - ) - - cpr := destination.ComputedPortRoutes - - var lb *ListenerBuilder - if destination.Explicit != nil { - lb = b.addExplicitOutboundListener(destination.Explicit) - } else { - lb = tproxyOutboundListenerBuilder - } - - // router matches based on destination ports should only occur on - // implicit destinations for explicit - var virtualPortNumber uint32 - if destination.Explicit == nil { - for _, port := range destination.Service.Data.Ports { - if port.TargetPort == cpr.ParentRef.Port { - virtualPortNumber = port.VirtualPort - } - } - } - - defaultDC := func(dc string) string { - if destination.Explicit != nil { - dc = orDefault(dc, destination.Explicit.Datacenter) - } - dc = orDefault(dc, b.localDatacenter) - if dc != b.localDatacenter { - panic("cross datacenter service discovery clusters are not supported in v2") - } - return dc - } - - statPrefix := DestinationStatPrefix( - cpr.ParentRef.Ref, - cpr.ParentRef.Port, - defaultDC(""), - ) - - var routeName string - if destination.Explicit != nil { - routeName = lb.listener.Name - } else { - routeName = DestinationResourceID(cpr.ParentRef.Ref, cpr.ParentRef.Port) - } - - var ( - useRDS bool - needsNullRouteCluster bool - ) - switch config := cpr.Config.(type) { - case *pbmesh.ComputedPortRoutes_Http: - // NOTE: this could be HTTP/HTTP2/GRPC - useRDS = true - - route := config.Http - - // this corresponds to roughly "makeUpstreamRouteForDiscoveryChain" - - var proxyRouteRules []*pbproxystate.RouteRule - for _, routeRule := range route.Rules { - for _, backendRef := range routeRule.BackendRefs { - if backendRef.BackendTarget == types.NullRouteBackend { - needsNullRouteCluster = true - } - } - destConfig := b.makeDestinationConfiguration(routeRule.Timeouts, routeRule.Retries) - headerMutations := applyRouteFilters(destConfig, routeRule.Filters) - applyLoadBalancerPolicy(destConfig, cpr, routeRule.BackendRefs) - - dest := b.makeHTTPRouteDestination( - routeRule.BackendRefs, - destConfig, - targets, - defaultDC, - ) - - // Explode out by matches - for _, match := range routeRule.Matches { - routeMatch := makeHTTPRouteMatch(match) - - proxyRouteRules = append(proxyRouteRules, &pbproxystate.RouteRule{ - Match: routeMatch, - Destination: protoutil.Clone(dest), - HeaderMutations: protoutil.CloneSlice(headerMutations), - }) - } - } - - b.addRoute(routeName, &pbproxystate.Route{ - VirtualHosts: []*pbproxystate.VirtualHost{{ - Name: routeName, - Domains: []string{"*"}, - RouteRules: proxyRouteRules, - }}, - }) - - case *pbmesh.ComputedPortRoutes_Grpc: - useRDS = true - route := config.Grpc - - var proxyRouteRules []*pbproxystate.RouteRule - for _, routeRule := range route.Rules { - for _, backendRef := range routeRule.BackendRefs { - if backendRef.BackendTarget == types.NullRouteBackend { - needsNullRouteCluster = true - } - } - destConfig := b.makeDestinationConfiguration(routeRule.Timeouts, routeRule.Retries) - headerMutations := applyRouteFilters(destConfig, routeRule.Filters) - applyLoadBalancerPolicy(destConfig, cpr, routeRule.BackendRefs) - - // nolint:staticcheck - dest := b.makeGRPCRouteDestination( - routeRule.BackendRefs, - destConfig, - targets, - defaultDC, - ) - - // Explode out by matches - for _, match := range routeRule.Matches { - routeMatch := makeGRPCRouteMatch(match) - - proxyRouteRules = append(proxyRouteRules, &pbproxystate.RouteRule{ - Match: routeMatch, - Destination: protoutil.Clone(dest), - HeaderMutations: protoutil.CloneSlice(headerMutations), - }) - } - } - - b.addRoute(routeName, &pbproxystate.Route{ - VirtualHosts: []*pbproxystate.VirtualHost{{ - Name: routeName, - Domains: []string{"*"}, - RouteRules: proxyRouteRules, - }}, - }) - - case *pbmesh.ComputedPortRoutes_Tcp: - route := config.Tcp - useRDS = false - - if len(route.Rules) != 1 { - panic("not possible due to validation and computation") - } - - // When not using RDS we must generate a cluster name to attach to - // the filter chain. With RDS, cluster names get attached to the - // dynamic routes instead. - - routeRule := route.Rules[0] - - for _, backendRef := range routeRule.BackendRefs { - if backendRef.BackendTarget == types.NullRouteBackend { - needsNullRouteCluster = true - } - } - - switch len(routeRule.BackendRefs) { - case 0: - panic("not possible to have a tcp route rule with no backend refs") - case 1: - tcpBackendRef := routeRule.BackendRefs[0] - - clusterName := b.backendTargetToClusterName(tcpBackendRef.BackendTarget, targets, defaultDC) - - rb := lb.addL4RouterForDirect(clusterName, statPrefix) - if destination.Explicit == nil { - rb.addIPAndPortMatch(destination.VirtualIPs, virtualPortNumber) - } - rb.buildRouter() - default: - clusters := make([]*pbproxystate.L4WeightedDestinationCluster, 0, len(routeRule.BackendRefs)) - for _, tcpBackendRef := range routeRule.BackendRefs { - clusterName := b.backendTargetToClusterName(tcpBackendRef.BackendTarget, targets, defaultDC) - - clusters = append(clusters, &pbproxystate.L4WeightedDestinationCluster{ - Name: clusterName, - Weight: wrapperspb.UInt32(tcpBackendRef.Weight), - }) - } - - rb := lb.addL4RouterForSplit(clusters, statPrefix) - if destination.Explicit == nil { - rb.addIPAndPortMatch(destination.VirtualIPs, virtualPortNumber) - } - rb.buildRouter() - } - } - - if useRDS { - if !isProtocolHTTPLike(effectiveProtocol) { - panic(fmt.Sprintf("it should not be possible to have a tcp protocol here: %v", effectiveProtocol)) - } - - rb := lb.addL7Router(routeName, "", effectiveProtocol) - if destination.Explicit == nil { - rb.addIPAndPortMatch(destination.VirtualIPs, virtualPortNumber) - } - rb.buildRouter() - } else { - if isProtocolHTTPLike(effectiveProtocol) { - panic(fmt.Sprintf("it should not be possible to have an http-like protocol here: %v", effectiveProtocol)) - } - } - - // Build outbound listener if the destination is explicit. - if destination.Explicit != nil { - lb.buildListener() - } - - if needsNullRouteCluster { - b.addNullRouteCluster() - } - - for _, details := range targets { - // NOTE: we only emit clusters for DIRECT targets here. The others will - // be folded into one or more aggregate clusters somehow. - if details.Type != pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT { - continue - } - - connectTimeout := details.DestinationConfig.ConnectTimeout - loadBalancer := details.DestinationConfig.LoadBalancer - - // NOTE: we collect both DIRECT and INDIRECT target information here. - dc := defaultDC(details.BackendRef.Datacenter) - portName := details.BackendRef.Port - - sni := DestinationSNI( - details.BackendRef.Ref, - dc, - b.trustDomain, - ) - clusterName := fmt.Sprintf("%s.%s", portName, sni) - - egName := "" - if details.FailoverConfig != nil { - egName = fmt.Sprintf("%s%d~%s", xdscommon.FailoverClusterNamePrefix, 0, clusterName) - } - egBase := b.newClusterEndpointGroup(egName, sni, portName, details.IdentityRefs, connectTimeout, loadBalancer) - - var endpointGroups []*pbproxystate.EndpointGroup - - // Original target is the first (or only) target. - endpointGroups = append(endpointGroups, egBase) - b.addEndpointsRef(clusterName, details.ServiceEndpointsId, details.MeshPort) - - if details.FailoverConfig != nil { - failover := details.FailoverConfig - // TODO(v2): handle other forms of failover (regions/locality/etc) - - for i, dest := range failover.Destinations { - if dest.BackendTarget == types.NullRouteBackend { - continue // not possible - } - destDetails, ok := targets[dest.BackendTarget] - if !ok { - continue // not possible - } - - destConnectTimeout := destDetails.DestinationConfig.ConnectTimeout - destLoadBalancer := destDetails.DestinationConfig.LoadBalancer - - destDC := defaultDC(destDetails.BackendRef.Datacenter) - destPortName := destDetails.BackendRef.Port - - destSNI := DestinationSNI( - destDetails.BackendRef.Ref, - destDC, - b.trustDomain, - ) - - // index 0 was already given to non-fail original - failoverGroupIndex := i + 1 - destClusterName := fmt.Sprintf("%s%d~%s", xdscommon.FailoverClusterNamePrefix, failoverGroupIndex, clusterName) - - egDest := b.newClusterEndpointGroup(destClusterName, destSNI, destPortName, destDetails.IdentityRefs, destConnectTimeout, destLoadBalancer) - - endpointGroups = append(endpointGroups, egDest) - b.addEndpointsRef(destClusterName, destDetails.ServiceEndpointsId, destDetails.MeshPort) - } - } - - b.addCluster(clusterName, endpointGroups, connectTimeout, pbproxystate.Protocol(effectiveProtocol)) - } - - return b -} - -const NullRouteClusterName = "null_route_cluster" - -func (b *Builder) addNullRouteCluster() *Builder { - cluster := &pbproxystate.Cluster{ - Name: NullRouteClusterName, - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Static{ - Static: &pbproxystate.StaticEndpointGroup{ - Config: &pbproxystate.StaticEndpointGroupConfig{ - ConnectTimeout: durationpb.New(10 * time.Second), - }, - }, - }, - }, - }, - Protocol: pbproxystate.Protocol_PROTOCOL_TCP, - } - - b.proxyStateTemplate.ProxyState.Clusters[cluster.Name] = cluster - return b -} - -func (b *ListenerBuilder) addL4RouterForDirect(clusterName, statPrefix string) *RouterBuilder { - // For explicit destinations, we have no filter chain match, and filters - // are based on port protocol. - router := &pbproxystate.Router{} - - if statPrefix == "" { - statPrefix = "upstream." - } - - router.Destination = &pbproxystate.Router_L4{ - L4: &pbproxystate.L4Destination{ - Destination: &pbproxystate.L4Destination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: clusterName, - }, - }, - StatPrefix: statPrefix, - }, - } - - return b.NewRouterBuilder(router) -} - -func (b *Builder) addL4ClusterForDirect(clusterName string) *Builder { - cluster := &pbproxystate.Cluster{ - Name: clusterName, - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Passthrough{ - Passthrough: &pbproxystate.PassthroughEndpointGroup{ - Config: &pbproxystate.PassthroughEndpointGroupConfig{ - ConnectTimeout: durationpb.New(5 * time.Second), - }, - }, - }, - }, - }, - Protocol: pbproxystate.Protocol_PROTOCOL_TCP, - } - - b.proxyStateTemplate.ProxyState.Clusters[cluster.Name] = cluster - return b -} - -func (b *ListenerBuilder) addL4RouterForSplit( - clusters []*pbproxystate.L4WeightedDestinationCluster, - statPrefix string, -) *RouterBuilder { - // For explicit destinations, we have no filter chain match, and filters - // are based on port protocol. - router := &pbproxystate.Router{} - - if statPrefix == "" { - statPrefix = "upstream." - } - - router.Destination = &pbproxystate.Router_L4{ - L4: &pbproxystate.L4Destination{ - Destination: &pbproxystate.L4Destination_WeightedClusters{ - WeightedClusters: &pbproxystate.L4WeightedClusterGroup{ - Clusters: clusters, - }, - }, - StatPrefix: statPrefix, - // TODO(rb/v2): can we use RDS for TCPRoute split? - }, - } - - return b.NewRouterBuilder(router) -} - -func (b *ListenerBuilder) addL7Router(routeName string, statPrefix string, protocol pbcatalog.Protocol) *RouterBuilder { - // For explicit destinations, we have no filter chain match, and filters - // are based on port protocol. - router := &pbproxystate.Router{} - - if routeName == "" { - panic("routeName is required") - } - - if statPrefix == "" { - statPrefix = "upstream." - } - - if !isProtocolHTTPLike(protocol) { - panic(fmt.Sprintf("unexpected protocol: %v", protocol)) - } - - router.Destination = &pbproxystate.Router_L7{ - L7: &pbproxystate.L7Destination{ - Route: &pbproxystate.L7DestinationRoute{ - Name: routeName, - }, - StatPrefix: statPrefix, - StaticRoute: false, - Protocol: protocolMapCatalogToL7[protocol], - }, - } - - return b.NewRouterBuilder(router) -} - -// addExplicitOutboundListener creates an outbound listener for an explicit destination. -func (b *Builder) addExplicitOutboundListener(explicit *pbmesh.Destination) *ListenerBuilder { - listener := makeExplicitListener(explicit, pbproxystate.Direction_DIRECTION_OUTBOUND) - - return b.NewListenerBuilder(listener) -} - -func makeExplicitListener(explicit *pbmesh.Destination, direction pbproxystate.Direction) *pbproxystate.Listener { - if explicit == nil { - panic("explicit upstream required") - } - - listener := &pbproxystate.Listener{ - Direction: direction, - } - - // TODO(v2): access logs, connection balancing - - // Create outbound listener address. - switch explicit.ListenAddr.(type) { - case *pbmesh.Destination_IpPort: - destinationAddr := explicit.ListenAddr.(*pbmesh.Destination_IpPort) - listener.BindAddress = &pbproxystate.Listener_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: destinationAddr.IpPort.Ip, - Port: destinationAddr.IpPort.Port, - }, - } - listener.Name = DestinationListenerName(explicit.DestinationRef, explicit.DestinationPort, destinationAddr.IpPort.Ip, destinationAddr.IpPort.Port) - case *pbmesh.Destination_Unix: - destinationAddr := explicit.ListenAddr.(*pbmesh.Destination_Unix) - listener.BindAddress = &pbproxystate.Listener_UnixSocket{ - UnixSocket: &pbproxystate.UnixSocketAddress{ - Path: destinationAddr.Unix.Path, - Mode: destinationAddr.Unix.Mode, - }, - } - listener.Name = DestinationListenerName(explicit.DestinationRef, explicit.DestinationPort, destinationAddr.Unix.Path, 0) - } - - return listener -} - -// addTransparentProxyOutboundListener creates an outbound listener for transparent proxy mode. -func (b *Builder) addTransparentProxyOutboundListener(port uint32) *ListenerBuilder { - listener := &pbproxystate.Listener{ - Name: xdscommon.OutboundListenerName, - Direction: pbproxystate.Direction_DIRECTION_OUTBOUND, - BindAddress: &pbproxystate.Listener_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "127.0.0.1", - Port: port, - }, - }, - Capabilities: []pbproxystate.Capability{pbproxystate.Capability_CAPABILITY_TRANSPARENT}, - } - - return b.NewListenerBuilder(listener) -} - -func isProtocolHTTPLike(protocol pbcatalog.Protocol) bool { - // enumcover:pbcatalog.Protocol - switch protocol { - case pbcatalog.Protocol_PROTOCOL_TCP: - return false - case pbcatalog.Protocol_PROTOCOL_HTTP2, - pbcatalog.Protocol_PROTOCOL_HTTP, - pbcatalog.Protocol_PROTOCOL_GRPC: - return true - case pbcatalog.Protocol_PROTOCOL_MESH: - fallthrough // to default - case pbcatalog.Protocol_PROTOCOL_UNSPECIFIED: - fallthrough // to default - default: - return false - } -} - -func (b *RouterBuilder) addIPMatch(vips []string) *RouterBuilder { - return b.addIPAndPortMatch(vips, 0) -} - -func (b *RouterBuilder) addIPAndPortMatch(vips []string, virtualPort uint32) *RouterBuilder { - b.router.Match = makeRouterMatchForIPAndPort(vips, virtualPort) - return b -} - -func makeRouterMatchForIPAndPort(vips []string, virtualPort uint32) *pbproxystate.Match { - match := &pbproxystate.Match{} - for _, vip := range vips { - match.PrefixRanges = append(match.PrefixRanges, &pbproxystate.CidrRange{ - AddressPrefix: vip, - PrefixLen: &wrapperspb.UInt32Value{Value: 32}, - }) - - if virtualPort > 0 { - match.DestinationPort = &wrapperspb.UInt32Value{Value: virtualPort} - } - } - return match -} - -// addCluster creates and adds a cluster to the proxyState based on the destination. -func (b *Builder) addCluster( - clusterName string, - endpointGroups []*pbproxystate.EndpointGroup, - connectTimeout *durationpb.Duration, - protocol pbproxystate.Protocol, -) { - cluster := &pbproxystate.Cluster{ - Name: clusterName, - AltStatName: clusterName, - Protocol: protocol, - } - switch len(endpointGroups) { - case 0: - panic("no endpoint groups provided") - case 1: - cluster.Group = &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: endpointGroups[0], - } - default: - cluster.Group = &pbproxystate.Cluster_FailoverGroup{ - FailoverGroup: &pbproxystate.FailoverGroup{ - EndpointGroups: endpointGroups, - Config: &pbproxystate.FailoverGroupConfig{ - UseAltStatName: true, - ConnectTimeout: connectTimeout, - }, - }, - } - } - - b.proxyStateTemplate.ProxyState.Clusters[cluster.Name] = cluster -} - -func (b *Builder) newClusterEndpointGroup( - clusterName string, - sni string, - portName string, - destinationIdentities []*pbresource.Reference, - connectTimeout *durationpb.Duration, - loadBalancer *pbmesh.LoadBalancer, -) *pbproxystate.EndpointGroup { - var spiffeIDs []string - for _, identity := range destinationIdentities { - spiffeIDs = append(spiffeIDs, connect.SpiffeIDFromIdentityRef(b.trustDomain, identity)) - } - - // TODO(v2): DestinationPolicy: circuit breakers, outlier detection - - // TODO(v2): if http2/grpc then set http2protocol options - - degConfig := &pbproxystate.DynamicEndpointGroupConfig{ - DisablePanicThreshold: true, - ConnectTimeout: connectTimeout, - } - - if loadBalancer != nil { - // enumcover:pbmesh.LoadBalancerPolicy - switch loadBalancer.Policy { - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RANDOM: - degConfig.LbPolicy = &pbproxystate.DynamicEndpointGroupConfig_Random{} - - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_ROUND_ROBIN: - degConfig.LbPolicy = &pbproxystate.DynamicEndpointGroupConfig_RoundRobin{} - - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_LEAST_REQUEST: - var choiceCount uint32 - cfg, ok := loadBalancer.Config.(*pbmesh.LoadBalancer_LeastRequestConfig) - if ok { - choiceCount = cfg.LeastRequestConfig.GetChoiceCount() - } - degConfig.LbPolicy = &pbproxystate.DynamicEndpointGroupConfig_LeastRequest{ - LeastRequest: &pbproxystate.LBPolicyLeastRequest{ - ChoiceCount: wrapperspb.UInt32(choiceCount), - }, - } - - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV: - degConfig.LbPolicy = &pbproxystate.DynamicEndpointGroupConfig_Maglev{} - - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RING_HASH: - policy := &pbproxystate.DynamicEndpointGroupConfig_RingHash{} - - cfg, ok := loadBalancer.Config.(*pbmesh.LoadBalancer_RingHashConfig) - if ok { - policy.RingHash = &pbproxystate.LBPolicyRingHash{ - MinimumRingSize: wrapperspb.UInt64(cfg.RingHashConfig.MinimumRingSize), - MaximumRingSize: wrapperspb.UInt64(cfg.RingHashConfig.MaximumRingSize), - } - } - - degConfig.LbPolicy = policy - - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_UNSPECIFIED: - // fallthrough to default - default: - // do nothing - } - } - - return &pbproxystate.EndpointGroup{ - Name: clusterName, - Group: &pbproxystate.EndpointGroup_Dynamic{ - Dynamic: &pbproxystate.DynamicEndpointGroup{ - Config: degConfig, - OutboundTls: &pbproxystate.TransportSocket{ - ConnectionTls: &pbproxystate.TransportSocket_OutboundMesh{ - OutboundMesh: &pbproxystate.OutboundMeshMTLS{ - IdentityKey: b.proxyStateTemplate.ProxyState.Identity.Name, - ValidationContext: &pbproxystate.MeshOutboundValidationContext{ - SpiffeIds: spiffeIDs, - TrustBundlePeerNameKey: b.id.Tenancy.PeerName, - }, - Sni: sni, - }, - }, - AlpnProtocols: []string{getAlpnProtocolFromPortName(portName)}, - }, - }, - }, - } -} - -func (b *Builder) addRoute(listenerName string, route *pbproxystate.Route) { - b.proxyStateTemplate.ProxyState.Routes[listenerName] = route -} - -// addEndpointsRef creates and add an endpointRef for each serviceEndpoint for a destination and -// adds it to the proxyStateTemplate so it will be processed later during reconciliation by -// the XDS controller. -func (b *Builder) addEndpointsRef(clusterName string, serviceEndpointsID *pbresource.ID, destinationPort string) { - b.proxyStateTemplate.RequiredEndpoints[clusterName] = &pbproxystate.EndpointRef{ - Id: serviceEndpointsID, - Port: destinationPort, - } -} - -func orDefault(v, def string) string { - if v != "" { - return v - } - return def -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destinations_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destinations_test.go deleted file mode 100644 index c6b5a76592549..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/destinations_test.go +++ /dev/null @@ -1,581 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/mesh/internal/types/intermediate" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/internal/testing/golden" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -var ( - endpointsData = &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "10.0.0.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 7070, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "tcp2": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - } - - serviceData = &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - VirtualPort: 7070, - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "tcp2", - VirtualPort: 8081, - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "http", - VirtualPort: 8080, - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "mesh", - VirtualPort: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - } -) - -func TestBuildExplicitDestinations(t *testing.T) { - registry := resource.NewRegistry() - types.Register(registry) - catalog.RegisterTypes(registry) - - api1Service := resourcetest.Resource(pbcatalog.ServiceType, "api-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, serviceData). - Build() - - api2Service := resourcetest.Resource(pbcatalog.ServiceType, "api-2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, serviceData). - Build() - - api3Service := resourcetest.Resource(pbcatalog.ServiceType, "api-3"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, serviceData). - Build() - - backup1Service := resourcetest.Resource(pbcatalog.ServiceType, "backup-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, serviceData). - Build() - - for _, res := range []*pbresource.Resource{ - api1Service, api2Service, api3Service, backup1Service, - } { - resourcetest.ValidateAndNormalize(t, registry, res) - } - - api1Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, endpointsData). - Build() - - api2Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, endpointsData). - Build() - - backup1Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "backup-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, endpointsData). - Build() - - for _, res := range []*pbresource.Resource{ - api1Endpoints, api2Endpoints, backup1Endpoints, - } { - resourcetest.ValidateAndNormalize(t, registry, res) - } - - api1Identity := &pbresource.Reference{ - Name: "api1-identity", - Tenancy: api1Endpoints.Id.Tenancy, - } - - api2Identity := &pbresource.Reference{ - Name: "api2-identity", - Tenancy: api2Endpoints.Id.Tenancy, - } - - backup1Identity := &pbresource.Reference{ - Name: "backup1-identity", - Tenancy: backup1Endpoints.Id.Tenancy, - } - - api1DestPolicy := resourcetest.Resource(pbmesh.DestinationPolicyType, api1Service.Id.Name). - WithTenancy(api1Service.Id.GetTenancy()). - WithData(t, &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - RequestTimeout: durationpb.New(77 * time.Second), - // LoadBalancer *LoadBalancer `protobuf:"bytes,3,opt,name=load_balancer,json=loadBalancer,proto3" json:"load_balancer,omitempty"` - }, - }, - }). - Build() - - api1HTTPRoute := resourcetest.Resource(pbmesh.HTTPRouteType, "api-1-http-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: resource.Reference(api1Service.Id, ""), - Port: "http", - }}, - Rules: []*pbmesh.HTTPRouteRule{ - { - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/split", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{ - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api2Service.Id, ""), - }, - Weight: 60, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api1Service.Id, ""), - }, - Weight: 40, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api3Service.Id, ""), - }, - Weight: 10, - }, - }, - }, - { - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api1Service.Id, ""), - }, - }}, - Timeouts: &pbmesh.HTTPRouteTimeouts{ - Request: durationpb.New(606 * time.Second), // differnet than the 77s - }, - Retries: &pbmesh.HTTPRouteRetries{ - Number: wrapperspb.UInt32(4), - OnConnectFailure: true, - }, - }, - }, - }). - Build() - resourcetest.ValidateAndNormalize(t, registry, api1HTTPRoute) - - api1FailoverPolicy := resourcetest.Resource(pbcatalog.FailoverPolicyType, "api-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.FailoverPolicy{ - PortConfigs: map[string]*pbcatalog.FailoverConfig{ - "http": { - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: resource.Reference(backup1Service.Id, ""), - Port: "http", - }}, - }, - }, - }). - Build() - resourcetest.ValidateAndNormalize(t, registry, api1FailoverPolicy) - - api1TCPRoute := resourcetest.Resource(pbmesh.TCPRouteType, "api-1-tcp-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: resource.Reference(api1Service.Id, ""), - Port: "tcp", - }}, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{ - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api2Service.Id, ""), - }, - Weight: 60, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api1Service.Id, ""), - }, - Weight: 40, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api3Service.Id, ""), - }, - Weight: 10, - }, - }, - }}, - }). - Build() - resourcetest.ValidateAndNormalize(t, registry, api1TCPRoute) - - api1TCP2Route := resourcetest.Resource(pbmesh.TCPRouteType, "api-1-tcp2-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: resource.Reference(api1Service.Id, ""), - Port: "tcp2", - }}, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{ - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api2Service.Id, ""), - }, - Weight: 60, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api1Service.Id, ""), - }, - Weight: 40, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(api3Service.Id, ""), - }, - Weight: 10, - }, - }, - }}, - }). - Build() - - api1ComputedRoutesID := resource.ReplaceType(pbmesh.ComputedRoutesType, api1Service.Id) - api1ComputedRoutes := routestest.BuildComputedRoutes(t, api1ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), - resourcetest.MustDecode[*pbcatalog.Service](t, api2Service), - resourcetest.MustDecode[*pbcatalog.Service](t, backup1Service), - // notably we do NOT include api3Service here so we trigger a null route to be generated - resourcetest.MustDecode[*pbmesh.DestinationPolicy](t, api1DestPolicy), - resourcetest.MustDecode[*pbmesh.HTTPRoute](t, api1HTTPRoute), - resourcetest.MustDecode[*pbmesh.TCPRoute](t, api1TCPRoute), - resourcetest.MustDecode[*pbcatalog.FailoverPolicy](t, api1FailoverPolicy), - resourcetest.MustDecode[*pbmesh.TCPRoute](t, api1TCP2Route), - ) - require.NotNil(t, api1ComputedRoutes) - - api2ComputedRoutesID := resource.ReplaceType(pbmesh.ComputedRoutesType, api2Service.Id) - api2ComputedRoutes := routestest.BuildComputedRoutes(t, api2ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, api2Service), - ) - require.NotNil(t, api2ComputedRoutes) - - destinationIpPort := &intermediate.Destination{ - Explicit: &pbmesh.Destination{ - DestinationRef: resource.Reference(api1Endpoints.Id, ""), - DestinationPort: "tcp", - Datacenter: "dc1", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{Ip: "1.1.1.1", Port: 1234}, - }, - }, - Service: resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), - ComputedPortRoutes: routestest.MutateTargets(t, api1ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - details.ServiceEndpointsId = api1Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api1Identity} - case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - details.ServiceEndpointsId = api2Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api2Identity} - } - }), - } - - destinationIpPort2 := &intermediate.Destination{ - Explicit: &pbmesh.Destination{ - DestinationRef: resource.Reference(api1Endpoints.Id, ""), - DestinationPort: "tcp2", - Datacenter: "dc1", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{Ip: "1.1.1.1", Port: 2345}, - }, - }, - Service: resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), - ComputedPortRoutes: routestest.MutateTargets(t, api1ComputedRoutes.Data, "tcp2", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2": - details.ServiceEndpointsId = api1Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api1Identity} - case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2": - details.ServiceEndpointsId = api2Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api2Identity} - } - }), - } - - destinationUnix := &intermediate.Destination{ - Explicit: &pbmesh.Destination{ - DestinationRef: resource.Reference(api2Endpoints.Id, ""), - DestinationPort: "tcp", - Datacenter: "dc1", - ListenAddr: &pbmesh.Destination_Unix{ - Unix: &pbmesh.UnixSocketAddress{Path: "/path/to/socket", Mode: "0666"}, - }, - }, - Service: resourcetest.MustDecode[*pbcatalog.Service](t, api2Service), - ComputedPortRoutes: routestest.MutateTargets(t, api2ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - details.ServiceEndpointsId = api2Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api2Identity} - } - }), - } - - destinationUnix2 := &intermediate.Destination{ - Explicit: &pbmesh.Destination{ - DestinationRef: resource.Reference(api2Endpoints.Id, ""), - DestinationPort: "tcp2", - Datacenter: "dc1", - ListenAddr: &pbmesh.Destination_Unix{ - Unix: &pbmesh.UnixSocketAddress{Path: "/path/to/socket", Mode: "0666"}, - }, - }, - Service: resourcetest.MustDecode[*pbcatalog.Service](t, api2Service), - ComputedPortRoutes: routestest.MutateTargets(t, api2ComputedRoutes.Data, "tcp2", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2": - details.ServiceEndpointsId = api2Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api2Identity} - } - }), - } - destinationIpPortHTTP := &intermediate.Destination{ - Explicit: &pbmesh.Destination{ - DestinationRef: resource.Reference(api1Endpoints.Id, ""), - DestinationPort: "http", - Datacenter: "dc1", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{Ip: "1.1.1.1", Port: 1234}, - }, - }, - Service: resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), - ComputedPortRoutes: routestest.MutateTargets(t, api1ComputedRoutes.Data, "http", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "http": - details.ServiceEndpointsId = api1Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api1Identity} - case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "http": - details.ServiceEndpointsId = api2Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api2Identity} - case resource.ReferenceOrIDMatch(backup1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "http": - details.ServiceEndpointsId = backup1Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{backup1Identity} - } - }), - } - _ = backup1Identity - - cases := map[string]struct { - destinations []*intermediate.Destination - }{ - "destination/l4-single-destination-ip-port-bind-address": { - destinations: []*intermediate.Destination{destinationIpPort}, - }, - "destination/l4-single-destination-unix-socket-bind-address": { - destinations: []*intermediate.Destination{destinationUnix}, - }, - "destination/l4-multi-destination": { - destinations: []*intermediate.Destination{destinationIpPort, destinationUnix, destinationIpPort2, destinationUnix2}, - }, - "destination/mixed-multi-destination": { - destinations: []*intermediate.Destination{destinationIpPort, destinationUnix, destinationIpPortHTTP}, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", false, nil). - BuildDestinations(c.destinations). - Build() - - actual := protoToJSON(t, proxyTmpl) - expected := golden.Get(t, actual, name+".golden") - - require.JSONEq(t, expected, actual) - }) - } -} - -func TestBuildImplicitDestinations(t *testing.T) { - api1Service := resourcetest.Resource(pbcatalog.ServiceType, "api-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, serviceData). - Build() - - api2Service := resourcetest.Resource(pbcatalog.ServiceType, "api-2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, serviceData). - Build() - - api1Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-1"). - WithOwner(api1Service.Id). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, endpointsData).Build() - - api2Endpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-2"). - WithOwner(api2Service.Id). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, endpointsData).Build() - - api1Identity := &pbresource.Reference{ - Name: "api1-identity", - Tenancy: api1Endpoints.Id.Tenancy, - } - - api2Identity := &pbresource.Reference{ - Name: "api2-identity", - Tenancy: api2Endpoints.Id.Tenancy, - } - - api1ComputedRoutesID := resource.ReplaceType(pbmesh.ComputedRoutesType, api1Service.Id) - api1ComputedRoutes := routestest.BuildComputedRoutes(t, api1ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), - ) - require.NotNil(t, api1ComputedRoutes) - - api2ComputedRoutesID := resource.ReplaceType(pbmesh.ComputedRoutesType, api2Service.Id) - api2ComputedRoutes := routestest.BuildComputedRoutes(t, api2ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, api2Service), - ) - require.NotNil(t, api2ComputedRoutes) - - proxyCfg := &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - TransparentProxy: &pbmesh.TransparentProxy{ - OutboundListenerPort: 15001, - }, - }, - } - - destination1 := &intermediate.Destination{ - Service: resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), - ComputedPortRoutes: routestest.MutateTargets(t, api1ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - details.ServiceEndpointsId = api1Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api1Identity} - } - }), - VirtualIPs: []string{"1.1.1.1"}, - } - - destination2 := &intermediate.Destination{ - Service: resourcetest.MustDecode[*pbcatalog.Service](t, api2Service), - ComputedPortRoutes: routestest.MutateTargets(t, api2ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - details.ServiceEndpointsId = api2Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api2Identity} - } - }), - VirtualIPs: []string{"2.2.2.2", "3.3.3.3"}, - } - - destination3 := &intermediate.Destination{ - Explicit: &pbmesh.Destination{ - DestinationRef: resource.Reference(api1Endpoints.Id, ""), - DestinationPort: "tcp", - Datacenter: "dc1", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{Ip: "1.1.1.1", Port: 1234}, - }, - }, - Service: resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), - ComputedPortRoutes: routestest.MutateTargets(t, api1ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - details.ServiceEndpointsId = api1Endpoints.Id - details.ServiceEndpoints = endpointsData - details.IdentityRefs = []*pbresource.Reference{api1Identity} - } - }), - } - - cases := map[string]struct { - destinations []*intermediate.Destination - }{ - "destination/l4-single-implicit-destination-tproxy": { - destinations: []*intermediate.Destination{destination1}, - }, - "destination/l4-multiple-implicit-destinations-tproxy": { - destinations: []*intermediate.Destination{destination1, destination2}, - }, - "destination/l4-implicit-and-explicit-destinations-tproxy": { - destinations: []*intermediate.Destination{destination2, destination3}, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", false, proxyCfg). - BuildDestinations(c.destinations). - Build() - - actual := protoToJSON(t, proxyTmpl) - expected := golden.Get(t, actual, name+".golden") - - require.JSONEq(t, expected, actual) - }) - } -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go b/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go deleted file mode 100644 index 991d6e6c7a871..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "fmt" - "regexp" - - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -func (b *Builder) buildExposePaths(workload *pbcatalog.Workload) { - if b.proxyCfg.GetDynamicConfig() != nil && b.proxyCfg.GetDynamicConfig().GetExposeConfig() != nil { - for _, exposePath := range b.proxyCfg.GetDynamicConfig().GetExposeConfig().GetExposePaths() { - clusterName := exposePathClusterName(exposePath) - - b.addExposePathsListener(workload, exposePath). - addExposePathsRouter(exposePath). - buildListener() - - var protocol pbcatalog.Protocol - switch exposePath.Protocol { - case pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP: - protocol = pbcatalog.Protocol_PROTOCOL_HTTP - case pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2: - protocol = pbcatalog.Protocol_PROTOCOL_HTTP2 - default: - panic("unsupported expose paths protocol") - } - - b.addExposePathsRoute(exposePath, clusterName). - addLocalAppCluster(clusterName, nil, pbproxystate.Protocol(protocol)). - addLocalAppStaticEndpoints(clusterName, exposePath.LocalPathPort) - } - } -} - -func (b *Builder) addExposePathsListener(workload *pbcatalog.Workload, exposePath *pbmesh.ExposePath) *ListenerBuilder { - listenerName := exposePathListenerName(exposePath) - - listener := &pbproxystate.Listener{ - Name: listenerName, - Direction: pbproxystate.Direction_DIRECTION_INBOUND, - } - - meshAddress := workload.GetFirstNonExternalMeshAddress() - if meshAddress == nil { - return b.NewListenerBuilder(nil) - } - - listener.BindAddress = &pbproxystate.Listener_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: meshAddress.Host, - Port: exposePath.ListenerPort, - }, - } - - return b.NewListenerBuilder(listener) -} - -func (b *ListenerBuilder) addExposePathsRouter(exposePath *pbmesh.ExposePath) *ListenerBuilder { - if b.listener == nil { - return b - } - destinationName := exposePathRouteName(exposePath) - - var l7Protocol pbproxystate.L7Protocol - - switch exposePath.Protocol { - case pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP: - l7Protocol = pbproxystate.L7Protocol_L7_PROTOCOL_HTTP - case pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2: - l7Protocol = pbproxystate.L7Protocol_L7_PROTOCOL_HTTP2 - default: - panic("unsupported expose paths protocol") - } - routerDestination := &pbproxystate.Router_L7{ - L7: &pbproxystate.L7Destination{ - Route: &pbproxystate.L7DestinationRoute{ - Name: destinationName, - }, - StatPrefix: destinationName, - StaticRoute: true, - Protocol: l7Protocol, - }, - } - - router := &pbproxystate.Router{ - Destination: routerDestination, - } - - b.listener.Routers = append(b.listener.Routers, router) - - return b -} - -func (b *Builder) addExposePathsRoute(exposePath *pbmesh.ExposePath, clusterName string) *Builder { - routeName := exposePathRouteName(exposePath) - routeRule := &pbproxystate.RouteRule{ - Match: &pbproxystate.RouteMatch{ - PathMatch: &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Exact{ - Exact: exposePath.Path, - }, - }, - }, - Destination: &pbproxystate.RouteDestination{ - Destination: &pbproxystate.RouteDestination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: clusterName, - }, - }, - }, - } - virtualHost := &pbproxystate.VirtualHost{ - Name: routeName, - Domains: []string{"*"}, - RouteRules: []*pbproxystate.RouteRule{routeRule}, - } - route := &pbproxystate.Route{ - VirtualHosts: []*pbproxystate.VirtualHost{virtualHost}, - } - - b.proxyStateTemplate.ProxyState.Routes[routeName] = route - return b -} - -func exposePathName(exposePath *pbmesh.ExposePath) string { - r := regexp.MustCompile(`[^a-zA-Z0-9]+`) - // The regex removes anything not a letter or number from the path. - path := r.ReplaceAllString(exposePath.Path, "") - return path -} - -func exposePathListenerName(exposePath *pbmesh.ExposePath) string { - // The path could be empty, so the unique name for this exposed path is the path and listener port. - pathPort := fmt.Sprintf("%s%d", exposePathName(exposePath), exposePath.ListenerPort) - listenerName := fmt.Sprintf("exposed_path_%s", pathPort) - return listenerName -} - -func exposePathRouteName(exposePath *pbmesh.ExposePath) string { - // The path could be empty, so the unique name for this exposed path is the path and listener port. - pathPort := fmt.Sprintf("%s%d", exposePathName(exposePath), exposePath.ListenerPort) - return fmt.Sprintf("exposed_path_route_%s", pathPort) -} - -func exposePathClusterName(exposePath *pbmesh.ExposePath) string { - return fmt.Sprintf("exposed_cluster_%d", exposePath.LocalPathPort) -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths_test.go deleted file mode 100644 index c2c9217f40932..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths_test.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "testing" - - "github.com/stretchr/testify/require" - - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/sdk/testutil" -) - -// This file contains tests only for error and edge cases cases. The happy case is tested in local_app_test.go - -func TestBuildExposePaths_NilChecks(t *testing.T) { - testutil.RunStep(t, "proxy cfg is nil", func(t *testing.T) { - b := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, nil) - require.NotPanics(t, func() { - b.buildExposePaths(nil) - }) - }) - - testutil.RunStep(t, "dynamic cfg is nil", func(t *testing.T) { - b := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, &pbmesh.ComputedProxyConfiguration{}) - require.NotPanics(t, func() { - b.buildExposePaths(nil) - }) - }) - - testutil.RunStep(t, "expose cfg is nil", func(t *testing.T) { - b := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{}, - }) - require.NotPanics(t, func() { - b.buildExposePaths(nil) - }) - }) -} - -func TestBuildExposePaths_NoExternalMeshWorkloadAddress(t *testing.T) { - workload := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1", External: true}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - "mesh": {Port: 20000}, - }, - } - - proxycfg := &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - ExposeConfig: &pbmesh.ExposeConfig{ - ExposePaths: []*pbmesh.ExposePath{ - { - ListenerPort: 1234, - LocalPathPort: 9090, - Path: "/health", - }, - }, - }, - }, - } - - b := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, proxycfg) - b.buildExposePaths(workload) - require.Empty(t, b.proxyStateTemplate.ProxyState.Listeners) -} - -func TestBuildExposePaths_InvalidProtocol(t *testing.T) { - workload := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "1.1.1.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - - proxycfg := &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - ExposeConfig: &pbmesh.ExposeConfig{ - ExposePaths: []*pbmesh.ExposePath{ - { - ListenerPort: 1234, - LocalPathPort: 9090, - Path: "/health", - Protocol: 3, - }, - }, - }, - }, - } - - b := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, proxycfg) - require.PanicsWithValue(t, "unsupported expose paths protocol", func() { - b.buildExposePaths(workload) - }) -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go deleted file mode 100644 index 871cb444bd5d5..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go +++ /dev/null @@ -1,500 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "fmt" - - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/agent/connect" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -func (b *Builder) BuildLocalApp(workload *pbcatalog.Workload, ctp *pbauth.ComputedTrafficPermissions) *Builder { - // Add the public listener. - lb := b.addInboundListener(xdscommon.PublicListenerName, workload) - lb.buildListener() - - trafficPermissions := buildTrafficPermissions(b.defaultAllow, b.trustDomain, workload, ctp) - - // Go through workload ports and add the routers, clusters, endpoints, and TLS. - // Note that the order of ports is non-deterministic here but the xds generation - // code should make sure to send it in the same order to Envoy to avoid unnecessary - // updates. - foundInboundNonMeshPorts := false - for portName, port := range workload.Ports { - clusterName := fmt.Sprintf("%s:%s", xdscommon.LocalAppClusterName, portName) - routeName := fmt.Sprintf("%s:%s", lb.listener.Name, portName) - - if port.Protocol != pbcatalog.Protocol_PROTOCOL_MESH { - foundInboundNonMeshPorts = true - lb.addInboundRouter(clusterName, routeName, port, portName, trafficPermissions[portName], b.proxyCfg.GetDynamicConfig().GetInboundConnections()). - addInboundTLS() - - if isL7(port.Protocol) { - b.addLocalAppRoute(routeName, clusterName, portName) - } - b.addLocalAppCluster(clusterName, &portName, pbproxystate.Protocol(port.Protocol)). - addLocalAppStaticEndpoints(clusterName, port.GetPort()) - } - } - - b.buildExposePaths(workload) - - // If there are no inbound ports other than the mesh port, we black-hole all inbound traffic. - if !foundInboundNonMeshPorts { - lb.addBlackHoleRouter() - b.addBlackHoleCluster() - } - - return b -} - -func buildTrafficPermissions(globalDefaultAllow bool, trustDomain string, workload *pbcatalog.Workload, computed *pbauth.ComputedTrafficPermissions) map[string]*pbproxystate.TrafficPermissions { - portsWithProtocol := workload.GetPortsByProtocol() - var defaultAllow bool - // If the computed traffic permissions don't exist yet, use default deny just to be safe. - // When it exists, use default deny unless no traffic permissions exist and default allow - // is configured globally. - if computed != nil && computed.IsDefault && globalDefaultAllow { - defaultAllow = true - } - - out := make(map[string]*pbproxystate.TrafficPermissions) - portToProtocol := make(map[string]pbcatalog.Protocol) - var allPorts []string - for protocol, ports := range portsWithProtocol { - if protocol == pbcatalog.Protocol_PROTOCOL_MESH { - continue - } - - for _, p := range ports { - allPorts = append(allPorts, p) - portToProtocol[p] = protocol - out[p] = &pbproxystate.TrafficPermissions{ - DefaultAllow: defaultAllow, - } - } - } - - if computed == nil { - return out - } - - for _, p := range computed.DenyPermissions { - drsByPort := destinationRulesByPort(allPorts, p.DestinationRules) - principals := makePrincipals(trustDomain, p) - for port := range drsByPort { - out[port].DenyPermissions = append(out[port].DenyPermissions, &pbproxystate.Permission{ - Principals: principals, - }) - } - } - - for _, p := range computed.AllowPermissions { - drsByPort := destinationRulesByPort(allPorts, p.DestinationRules) - principals := makePrincipals(trustDomain, p) - for port := range drsByPort { - if _, ok := out[port]; !ok { - continue - } - - out[port].AllowPermissions = append(out[port].AllowPermissions, &pbproxystate.Permission{ - Principals: principals, - }) - } - } - - return out -} - -// TODO this is a placeholder until we add them to the IR. -type DestinationRule struct{} - -func destinationRulesByPort(allPorts []string, destinationRules []*pbauth.DestinationRule) map[string][]DestinationRule { - out := make(map[string][]DestinationRule) - - if len(destinationRules) == 0 { - for _, p := range allPorts { - out[p] = nil - } - - return out - } - - for _, destinationRule := range destinationRules { - ports, dr := convertDestinationRule(allPorts, destinationRule) - for _, p := range ports { - out[p] = append(out[p], dr) - } - } - - return out -} - -func convertDestinationRule(allPorts []string, dr *pbauth.DestinationRule) ([]string, DestinationRule) { - ports := make(map[string]struct{}) - if len(dr.PortNames) > 0 { - for _, p := range dr.PortNames { - ports[p] = struct{}{} - } - } else { - for _, p := range allPorts { - ports[p] = struct{}{} - } - } - - for _, exclude := range dr.Exclude { - for _, p := range exclude.PortNames { - delete(ports, p) - } - } - - var out []string - for p := range ports { - out = append(out, p) - } - - return out, DestinationRule{} -} - -func makePrincipals(trustDomain string, perm *pbauth.Permission) []*pbproxystate.Principal { - var principals []*pbproxystate.Principal - for _, s := range perm.Sources { - principals = append(principals, makePrincipal(trustDomain, s)) - } - - return principals -} - -func makePrincipal(trustDomain string, s *pbauth.Source) *pbproxystate.Principal { - excludes := make([]*pbproxystate.Spiffe, 0, len(s.Exclude)) - for _, es := range s.Exclude { - excludes = append(excludes, sourceToSpiffe(trustDomain, es)) - } - - return &pbproxystate.Principal{ - Spiffe: sourceToSpiffe(trustDomain, s), - ExcludeSpiffes: excludes, - } -} - -const ( - anyPath = `[^/]+` -) - -func sourceToSpiffe(trustDomain string, s pbauth.SourceToSpiffe) *pbproxystate.Spiffe { - var ( - name = s.GetIdentityName() - ns = s.GetNamespace() - ap = s.GetPartition() - ) - - if ns == "" && name != "" { - panic(fmt.Sprintf("not possible to have a wildcarded namespace %q but an exact identity %q", ns, name)) - } - - if ap == "" { - panic("not possible to have a wildcarded source partition") - } - - if ns == "" { - ns = anyPath - } - if name == "" { - name = anyPath - } - - spiffeURI := connect.SpiffeIDWorkloadIdentity{ - TrustDomain: trustDomain, - Partition: ap, - Namespace: ns, - WorkloadIdentity: name, - }.URI() - - matcher := fmt.Sprintf(`^%s://%s%s$`, spiffeURI.Scheme, spiffeURI.Host, spiffeURI.Path) - - return &pbproxystate.Spiffe{ - Regex: matcher, - } -} - -func (b *Builder) addInboundListener(name string, workload *pbcatalog.Workload) *ListenerBuilder { - listener := &pbproxystate.Listener{ - Name: name, - Direction: pbproxystate.Direction_DIRECTION_INBOUND, - } - - // We will take listener bind port from the workload. - // Find mesh port. - meshPort, ok := workload.GetMeshPortName() - if !ok { - // At this point, we should only get workloads that have mesh ports. - return &ListenerBuilder{ - builder: b, - } - } - - // Check if the workload has a specific address for the mesh port. - meshAddresses := workload.GetNonExternalAddressesForPort(meshPort) - - // If there are no mesh addresses, return. This should be impossible. - if len(meshAddresses) == 0 { - return &ListenerBuilder{ - builder: b, - } - } - - // If there are more than one mesh address, use the first one in the list. - var meshAddress string - if len(meshAddresses) > 0 { - meshAddress = meshAddresses[0].Host - } - - listener.BindAddress = &pbproxystate.Listener_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: meshAddress, - Port: workload.Ports[meshPort].Port, - }, - } - - // Add TLS inspection capability to be able to parse ALPN and/or SNI information from inbound connections. - listener.Capabilities = append(listener.Capabilities, pbproxystate.Capability_CAPABILITY_L4_TLS_INSPECTION) - - if b.proxyCfg.GetDynamicConfig() != nil && b.proxyCfg.GetDynamicConfig().InboundConnections != nil { - listener.BalanceConnections = pbproxystate.BalanceConnections(b.proxyCfg.DynamicConfig.InboundConnections.BalanceInboundConnections) - } - return b.NewListenerBuilder(listener) -} - -func (l *ListenerBuilder) addInboundRouter(clusterName string, routeName string, - port *pbcatalog.WorkloadPort, portName string, tp *pbproxystate.TrafficPermissions, - ic *pbmesh.InboundConnectionsConfig) *ListenerBuilder { - - if l.listener == nil { - return l - } - - if port.Protocol == pbcatalog.Protocol_PROTOCOL_TCP { - r := &pbproxystate.Router{ - Destination: &pbproxystate.Router_L4{ - L4: &pbproxystate.L4Destination{ - Destination: &pbproxystate.L4Destination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: clusterName, - }, - }, - StatPrefix: l.listener.Name, - TrafficPermissions: tp, - }, - }, - Match: &pbproxystate.Match{ - AlpnProtocols: []string{getAlpnProtocolFromPortName(portName)}, - }, - } - - if ic != nil { - // MaxInboundConnections is uint32 that is used on: - // - router destinations MaxInboundConnection (uint64). - // - cluster circuit breakers UpstreamLimits.MaxConnections (uint32). - // It is cast to a uint64 here similarly as it is to the proxystateconverter code. - r.GetL4().MaxInboundConnections = uint64(ic.MaxInboundConnections) - } - - l.listener.Routers = append(l.listener.Routers, r) - } else if isL7(port.Protocol) { - r := &pbproxystate.Router{ - Destination: &pbproxystate.Router_L7{ - L7: &pbproxystate.L7Destination{ - StatPrefix: l.listener.Name, - Protocol: protocolMapCatalogToL7[port.Protocol], - TrafficPermissions: tp, - StaticRoute: true, - // Route name for l7 local app destinations differentiates between routes for each port. - Route: &pbproxystate.L7DestinationRoute{ - Name: routeName, - }, - }, - }, - Match: &pbproxystate.Match{ - AlpnProtocols: []string{getAlpnProtocolFromPortName(portName)}, - }, - } - - if ic != nil { - // MaxInboundConnections is cast to a uint64 here similarly as it is to the - // as the L4 case statement above and in proxystateconverter code. - r.GetL7().MaxInboundConnections = uint64(ic.MaxInboundConnections) - } - - l.listener.Routers = append(l.listener.Routers, r) - } - return l -} - -func (l *ListenerBuilder) addBlackHoleRouter() *ListenerBuilder { - if l.listener == nil { - return l - } - - r := &pbproxystate.Router{ - Destination: &pbproxystate.Router_L4{ - L4: &pbproxystate.L4Destination{ - Destination: &pbproxystate.L4Destination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: xdscommon.BlackHoleClusterName, - }, - }, - StatPrefix: l.listener.Name, - }, - }, - } - l.listener.Routers = append(l.listener.Routers, r) - - return l -} - -func getAlpnProtocolFromPortName(portName string) string { - return fmt.Sprintf("consul~%s", portName) -} - -func (b *Builder) addLocalAppRoute(routeName, clusterName, portName string) { - proxyRouteRule := &pbproxystate.RouteRule{ - Match: &pbproxystate.RouteMatch{ - PathMatch: &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: "/", - }, - }, - }, - Destination: &pbproxystate.RouteDestination{ - Destination: &pbproxystate.RouteDestination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: clusterName, - }, - }, - }, - } - if b.proxyCfg.GetDynamicConfig() != nil && b.proxyCfg.GetDynamicConfig().LocalConnection != nil { - lc, lcOK := b.proxyCfg.GetDynamicConfig().LocalConnection[portName] - if lcOK { - proxyRouteRule.Destination.DestinationConfiguration = - &pbproxystate.DestinationConfiguration{ - TimeoutConfig: &pbproxystate.TimeoutConfig{ - Timeout: lc.RequestTimeout, - }, - } - } - } - - // Each route name for the local app is listenerName:port since there is a route per port on the local app listener. - b.addRoute(routeName, &pbproxystate.Route{ - VirtualHosts: []*pbproxystate.VirtualHost{{ - Name: routeName, - Domains: []string{"*"}, - RouteRules: []*pbproxystate.RouteRule{proxyRouteRule}, - }}, - }) -} - -func isL7(protocol pbcatalog.Protocol) bool { - if protocol == pbcatalog.Protocol_PROTOCOL_HTTP || protocol == pbcatalog.Protocol_PROTOCOL_HTTP2 || protocol == pbcatalog.Protocol_PROTOCOL_GRPC { - return true - } - return false -} - -func (b *Builder) addLocalAppCluster(clusterName string, portName *string, protocol pbproxystate.Protocol) *Builder { - // Make cluster for this router destination. - cluster := &pbproxystate.Cluster{ - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Static{ - Static: &pbproxystate.StaticEndpointGroup{}, - }, - }, - }, - Protocol: protocol, - } - - // configure inbound connections or connection timeout if either is defined - if b.proxyCfg.GetDynamicConfig() != nil && portName != nil { - lc, lcOK := b.proxyCfg.DynamicConfig.LocalConnection[*portName] - - if lcOK || b.proxyCfg.DynamicConfig.InboundConnections != nil { - cluster.GetEndpointGroup().GetStatic().Config = &pbproxystate.StaticEndpointGroupConfig{} - - if lcOK { - cluster.GetEndpointGroup().GetStatic().GetConfig().ConnectTimeout = lc.ConnectTimeout - } - - if b.proxyCfg.DynamicConfig.InboundConnections != nil { - cluster.GetEndpointGroup().GetStatic().GetConfig().CircuitBreakers = &pbproxystate.CircuitBreakers{ - UpstreamLimits: &pbproxystate.UpstreamLimits{ - MaxConnections: &wrapperspb.UInt32Value{Value: b.proxyCfg.DynamicConfig.InboundConnections.MaxInboundConnections}, - }, - } - } - } - } - - b.proxyStateTemplate.ProxyState.Clusters[clusterName] = cluster - return b -} - -func (b *Builder) addBlackHoleCluster() *Builder { - return b.addLocalAppCluster(xdscommon.BlackHoleClusterName, nil, pbproxystate.Protocol_PROTOCOL_TCP) -} - -func (b *Builder) addLocalAppStaticEndpoints(clusterName string, port uint32) { - // We're adding endpoints statically as opposed to creating an endpoint ref - // because this endpoint is less likely to change as we're not tracking the health. - endpoint := &pbproxystate.Endpoint{ - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "127.0.0.1", - Port: port, - }, - }, - } - b.proxyStateTemplate.ProxyState.Endpoints[clusterName] = &pbproxystate.Endpoints{ - Endpoints: []*pbproxystate.Endpoint{endpoint}, - } -} - -func (l *ListenerBuilder) addInboundTLS() *ListenerBuilder { - if l.listener == nil { - return nil - } - - // For inbound TLS, we want to use this proxy's identity. - workloadIdentity := l.builder.proxyStateTemplate.ProxyState.Identity.Name - - inboundTLS := &pbproxystate.TransportSocket{ - ConnectionTls: &pbproxystate.TransportSocket_InboundMesh{ - InboundMesh: &pbproxystate.InboundMeshMTLS{ - IdentityKey: workloadIdentity, - ValidationContext: &pbproxystate.MeshInboundValidationContext{ - TrustBundlePeerNameKeys: []string{l.builder.id.Tenancy.PeerName}, - }, - }, - }, - } - - for i := range l.listener.Routers { - l.listener.Routers[i].InboundTls = inboundTLS - } - return l -} - -var protocolMapCatalogToL7 = map[pbcatalog.Protocol]pbproxystate.L7Protocol{ - pbcatalog.Protocol_PROTOCOL_HTTP: pbproxystate.L7Protocol_L7_PROTOCOL_HTTP, - pbcatalog.Protocol_PROTOCOL_HTTP2: pbproxystate.L7Protocol_L7_PROTOCOL_HTTP2, - pbcatalog.Protocol_PROTOCOL_GRPC: pbproxystate.L7Protocol_L7_PROTOCOL_GRPC, -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_multiport_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_multiport_test.go deleted file mode 100644 index 12cbb387af3a0..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_multiport_test.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "sort" - "testing" - - "github.com/hashicorp/consul/internal/testing/golden" - - "github.com/stretchr/testify/require" - - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" -) - -func TestBuildLocalApp_Multiport(t *testing.T) { - cases := map[string]struct { - workload *pbcatalog.Workload - }{ - "source/multiport-l7-single-workload-address-without-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - "grpc-port": {Port: 9091, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - "source/multiport-l7-multiple-workload-addresses-without-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - { - Host: "10.0.0.2", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - "grpc-port": {Port: 9091, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - "source/multiport-l7-multiple-workload-addresses-with-specific-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - Ports: []string{"admin-port"}, - }, - { - Host: "10.0.0.2", - Ports: []string{"api-port"}, - }, - { - Host: "10.0.0.3", - Ports: []string{"mesh"}, - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - "source/multiport-l4-single-workload-address-without-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - "source/multiport-l4-multiple-workload-addresses-without-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - { - Host: "10.0.0.2", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - "source/multiport-l4-multiple-workload-addresses-with-specific-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - Ports: []string{"admin-port"}, - }, - { - Host: "10.0.0.2", - Ports: []string{"api-port"}, - }, - { - Host: "10.0.0.3", - Ports: []string{"mesh"}, - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "admin-port": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "api-port": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - "source/multiport-l4-workload-with-only-mesh-port": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", false, nil). - BuildLocalApp(c.workload, nil). - Build() - - // sort routers because of test flakes where order was flip flopping. - actualRouters := proxyTmpl.ProxyState.Listeners[0].Routers - sort.Slice(actualRouters, func(i, j int) bool { - return actualRouters[i].String() < actualRouters[j].String() - }) - - actual := protoToJSON(t, proxyTmpl) - expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+".golden")) - - // sort routers on listener from golden file - expectedRouters := expected.ProxyState.Listeners[0].Routers - sort.Slice(expectedRouters, func(i, j int) bool { - return expectedRouters[i].String() < expectedRouters[j].String() - }) - - // convert back to json after sorting so that test output does not contain extraneous fields. - require.Equal(t, protoToJSON(t, expected), protoToJSON(t, proxyTmpl)) - }) - } -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go deleted file mode 100644 index 33dcab7155228..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "google.golang.org/protobuf/types/known/durationpb" - "sort" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/internal/testing/golden" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestBuildLocalApp(t *testing.T) { - cases := map[string]struct { - workload *pbcatalog.Workload - ctp *pbauth.ComputedTrafficPermissions - defaultAllow bool - }{ - "source/l4-single-workload-address-without-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - "source/l4-multiple-workload-addresses-without-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - { - Host: "10.0.0.2", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - }, - "source/l4-multiple-workload-addresses-with-specific-ports": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "127.0.0.1", - Ports: []string{"port1"}, - }, - { - Host: "10.0.0.2", - Ports: []string{"port2"}, - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - ctp: &pbauth.ComputedTrafficPermissions{ - AllowPermissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Namespace: "default", - Partition: "default", - }, - }, - }, - }, - }, - defaultAllow: true, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", c.defaultAllow, nil). - BuildLocalApp(c.workload, c.ctp). - Build() - actual := protoToJSON(t, proxyTmpl) - expected := golden.Get(t, actual, name+".golden") - - require.JSONEq(t, expected, actual) - }) - } -} - -func TestBuildLocalApp_WithProxyConfiguration(t *testing.T) { - cases := map[string]struct { - workload *pbcatalog.Workload - proxyCfg *pbmesh.ComputedProxyConfiguration - }{ - "source/l7-expose-paths": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }, - proxyCfg: &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - ExposeConfig: &pbmesh.ExposeConfig{ - ExposePaths: []*pbmesh.ExposePath{ - { - ListenerPort: 1234, - Path: "/health", - LocalPathPort: 9090, - Protocol: pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP, - }, - { - ListenerPort: 1235, - Path: "GetHealth", - LocalPathPort: 9091, - Protocol: pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2, - }, - }, - }, - }, - }, - }, - // source/local-and-inbound-connections shows that configuring LocalCOnnection - // and InboundConnections in DynamicConfig will set fields on standard clusters and routes, - // but will not set fields on exposed path clusters and routes. - "source/local-and-inbound-connections": { - workload: &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - "port3": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - }, - proxyCfg: &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - LocalConnection: map[string]*pbmesh.ConnectionConfig{ - "port1": { - ConnectTimeout: durationpb.New(6 * time.Second), - RequestTimeout: durationpb.New(7 * time.Second)}, - "port3": { - ConnectTimeout: durationpb.New(8 * time.Second), - RequestTimeout: durationpb.New(9 * time.Second)}, - }, - InboundConnections: &pbmesh.InboundConnectionsConfig{ - MaxInboundConnections: 123, - BalanceInboundConnections: pbmesh.BalanceConnections(pbproxystate.BalanceConnections_BALANCE_CONNECTIONS_EXACT), - }, - ExposeConfig: &pbmesh.ExposeConfig{ - ExposePaths: []*pbmesh.ExposePath{ - { - ListenerPort: 1234, - Path: "/health", - LocalPathPort: 9090, - Protocol: pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP, - }, - { - ListenerPort: 1235, - Path: "GetHealth", - LocalPathPort: 9091, - Protocol: pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2, - }, - }, - }, - }, - }, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, c.proxyCfg). - BuildLocalApp(c.workload, nil). - Build() - - // sort routers because of test flakes where order was flip flopping. - actualRouters := proxyTmpl.ProxyState.Listeners[0].Routers - sort.Slice(actualRouters, func(i, j int) bool { - return actualRouters[i].String() < actualRouters[j].String() - }) - - actual := protoToJSON(t, proxyTmpl) - expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+".golden")) - - // sort routers on listener from golden file - expectedRouters := expected.ProxyState.Listeners[0].Routers - sort.Slice(expectedRouters, func(i, j int) bool { - return expectedRouters[i].String() < expectedRouters[j].String() - }) - - // convert back to json after sorting so that test output does not contain extraneous fields. - require.Equal(t, protoToJSON(t, expected), protoToJSON(t, proxyTmpl)) - }) - } -} - -func TestBuildL4TrafficPermissions(t *testing.T) { - testTrustDomain := "test.consul" - - cases := map[string]struct { - defaultAllow bool - workloadPorts map[string]*pbcatalog.WorkloadPort - ctp *pbauth.ComputedTrafficPermissions - expected map[string]*pbproxystate.TrafficPermissions - }{ - "empty": { - defaultAllow: true, - workloadPorts: map[string]*pbcatalog.WorkloadPort{ - "p1": { - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "p2": { - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - "p3": {}, - "mesh": { - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - expected: map[string]*pbproxystate.TrafficPermissions{ - "p1": { - DefaultAllow: false, - }, - "p2": { - DefaultAllow: false, - }, - "p3": { - DefaultAllow: false, - }, - }, - }, - "default allow everywhere": { - defaultAllow: true, - workloadPorts: map[string]*pbcatalog.WorkloadPort{ - "p1": { - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "p2": { - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - "p3": {}, - "mesh": { - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - ctp: &pbauth.ComputedTrafficPermissions{ - IsDefault: true, - }, - expected: map[string]*pbproxystate.TrafficPermissions{ - "p1": { - DefaultAllow: true, - }, - "p2": { - DefaultAllow: true, - }, - "p3": { - DefaultAllow: true, - }, - }, - }, - "preserves default deny": { - defaultAllow: false, - workloadPorts: map[string]*pbcatalog.WorkloadPort{ - "p1": { - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "p2": { - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - ctp: &pbauth.ComputedTrafficPermissions{ - AllowPermissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Partition: "default", - Namespace: "default", - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - { - PortNames: []string{"p1"}, - }, - }, - }, - }, - }, - expected: map[string]*pbproxystate.TrafficPermissions{ - "p1": { - DefaultAllow: false, - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/foo$"}, - }, - }, - }, - }, - }, - "p2": { - DefaultAllow: false, - }, - }, - }, - "default allow with a non-empty ctp becomes default deny on all ports": { - defaultAllow: true, - workloadPorts: map[string]*pbcatalog.WorkloadPort{ - "p1": { - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "p2": { - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - ctp: &pbauth.ComputedTrafficPermissions{ - AllowPermissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "baz", - Partition: "default", - Namespace: "default", - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - { - PortNames: []string{"no-match"}, - }, - }, - }, - }, - }, - expected: map[string]*pbproxystate.TrafficPermissions{ - "p1": { - DefaultAllow: false, - }, - "p2": { - DefaultAllow: false, - }, - }, - }, - "kitchen sink": { - defaultAllow: true, - workloadPorts: map[string]*pbcatalog.WorkloadPort{ - "p1": { - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "p2": { - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - ctp: &pbauth.ComputedTrafficPermissions{ - AllowPermissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Partition: "default", - Namespace: "default", - }, - { - IdentityName: "", - Partition: "default", - Namespace: "default", - Exclude: []*pbauth.ExcludeSource{ - { - IdentityName: "bar", - Namespace: "default", - Partition: "default", - }, - }, - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - // This should be p2. - { - Exclude: []*pbauth.ExcludePermissionRule{ - { - PortNames: []string{"p1"}, - }, - }, - }, - }, - }, - { - Sources: []*pbauth.Source{ - { - IdentityName: "baz", - Partition: "default", - Namespace: "default", - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - { - PortNames: []string{"p1"}, - }, - }, - }, - }, - DenyPermissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "qux", - Partition: "default", - Namespace: "default", - }, - }, - }, - { - Sources: []*pbauth.Source{ - { - IdentityName: "", - Namespace: "default", - Partition: "default", - Exclude: []*pbauth.ExcludeSource{ - { - IdentityName: "quux", - Partition: "default", - Namespace: "default", - }, - }, - }, - }, - }, - }, - }, - expected: map[string]*pbproxystate.TrafficPermissions{ - "p1": { - DefaultAllow: false, - DenyPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/qux$"}, - }, - }, - }, - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: &pbproxystate.Spiffe{Regex: `^spiffe://test.consul/ap/default/ns/default/identity/[^/]+$`}, - ExcludeSpiffes: []*pbproxystate.Spiffe{ - {Regex: "^spiffe://test.consul/ap/default/ns/default/identity/quux$"}, - }, - }, - }, - }, - }, - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/baz$"}, - }, - }, - }, - }, - }, - "p2": { - DefaultAllow: false, - DenyPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/qux$"}, - }, - }, - }, - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: &pbproxystate.Spiffe{Regex: `^spiffe://test.consul/ap/default/ns/default/identity/[^/]+$`}, - ExcludeSpiffes: []*pbproxystate.Spiffe{ - {Regex: "^spiffe://test.consul/ap/default/ns/default/identity/quux$"}, - }, - }, - }, - }, - }, - AllowPermissions: []*pbproxystate.Permission{ - { - Principals: []*pbproxystate.Principal{ - { - Spiffe: &pbproxystate.Spiffe{Regex: "^spiffe://test.consul/ap/default/ns/default/identity/foo$"}, - }, - { - Spiffe: &pbproxystate.Spiffe{Regex: `^spiffe://test.consul/ap/default/ns/default/identity/[^/]+$`}, - ExcludeSpiffes: []*pbproxystate.Spiffe{ - {Regex: "^spiffe://test.consul/ap/default/ns/default/identity/bar$"}, - }, - }, - }, - }, - }, - }, - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - workload := &pbcatalog.Workload{ - Ports: tc.workloadPorts, - } - permissions := buildTrafficPermissions(tc.defaultAllow, testTrustDomain, workload, tc.ctp) - require.Equal(t, len(tc.expected), len(permissions)) - for k, v := range tc.expected { - prototest.AssertDeepEqual(t, v, permissions[k]) - } - }) - } -} - -func testProxyStateTemplateID() *pbresource.ID { - return resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ID() -} - -func testIdentityRef() *pbresource.Reference { - return &pbresource.Reference{ - Name: "test-identity", - Tenancy: &pbresource.Tenancy{ - Namespace: "default", - Partition: "default", - PeerName: "local", - }, - Type: pbauth.WorkloadIdentityType, - } -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/naming.go b/internal/mesh/internal/controllers/sidecarproxy/builder/naming.go deleted file mode 100644 index 13a21e4e597d8..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/naming.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "fmt" - - "github.com/hashicorp/consul/agent/connect" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func DestinationSNI(serviceRef *pbresource.Reference, datacenter, trustDomain string) string { - return connect.ServiceSNI(serviceRef.Name, - "", - serviceRef.Tenancy.Namespace, - serviceRef.Tenancy.Partition, - datacenter, - trustDomain) -} - -func DestinationStatPrefix(serviceRef *pbresource.Reference, portName, datacenter string) string { - return fmt.Sprintf("upstream.%s.%s.%s.%s.%s", - portName, - serviceRef.Name, - serviceRef.Tenancy.Namespace, - serviceRef.Tenancy.Partition, - datacenter) -} - -func DestinationListenerName(destinationRef *pbresource.Reference, portName string, address string, port uint32) string { - name := fmt.Sprintf("%s:%s", DestinationResourceID(destinationRef, portName), address) - if port != 0 { - return fmt.Sprintf("%s:%d", name, port) - } - - return name -} - -// DestinationResourceID returns a string representation that uniquely identifies the -// upstream in a canonical but human readable way. -func DestinationResourceID(destinationRef *pbresource.Reference, port string) string { - tenancyPrefix := fmt.Sprintf("%s/%s/%s", destinationRef.Tenancy.Partition, - destinationRef.Tenancy.PeerName, destinationRef.Tenancy.Namespace) - return fmt.Sprintf("%s/%s:%s", tenancyPrefix, destinationRef.Name, port) -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/routes.go b/internal/mesh/internal/controllers/sidecarproxy/builder/routes.go deleted file mode 100644 index 03d68bdf081a4..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/routes.go +++ /dev/null @@ -1,595 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package builder - -import ( - "fmt" - "strings" - "time" - - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/internal/mesh/internal/types" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -func (b *Builder) backendTargetToClusterName( - backendTarget string, - targets map[string]*pbmesh.BackendTargetDetails, - defaultDC func(string) string, -) string { - if backendTarget == types.NullRouteBackend { - return NullRouteClusterName - } - - details, ok := targets[backendTarget] - if !ok { - panic("dangling reference") - } - - backendRef := details.BackendRef - - dc := defaultDC(backendRef.Datacenter) - - sni := DestinationSNI( - details.BackendRef.Ref, - dc, - b.trustDomain, - ) - - return fmt.Sprintf("%s.%s", details.BackendRef.Port, sni) -} - -func (b *Builder) makeHTTPRouteDestination( - computedBackendRefs []*pbmesh.ComputedHTTPBackendRef, - destConfig *pbproxystate.DestinationConfiguration, - targets map[string]*pbmesh.BackendTargetDetails, - defaultDC func(string) string, -) *pbproxystate.RouteDestination { - switch len(computedBackendRefs) { - case 0: - panic("not possible to have a route rule with no backend refs") - case 1: - return b.makeRouteDestinationForDirect(computedBackendRefs[0].BackendTarget, destConfig, targets, defaultDC) - default: - clusters := make([]*pbproxystate.L7WeightedDestinationCluster, 0, len(computedBackendRefs)) - for _, computedBackendRef := range computedBackendRefs { - clusterName := b.backendTargetToClusterName(computedBackendRef.BackendTarget, targets, defaultDC) - - clusters = append(clusters, &pbproxystate.L7WeightedDestinationCluster{ - Name: clusterName, - Weight: &wrapperspb.UInt32Value{ - Value: computedBackendRef.Weight, - }, - }) - } - return b.makeRouteDestinationForSplit(clusters, destConfig) - } -} - -func (b *Builder) makeGRPCRouteDestination( - computedBackendRefs []*pbmesh.ComputedGRPCBackendRef, - destConfig *pbproxystate.DestinationConfiguration, - targets map[string]*pbmesh.BackendTargetDetails, - defaultDC func(string) string, -) *pbproxystate.RouteDestination { - switch len(computedBackendRefs) { - case 0: - panic("not possible to have a route rule with no backend refs") - case 1: - return b.makeRouteDestinationForDirect(computedBackendRefs[0].BackendTarget, destConfig, targets, defaultDC) - default: - clusters := make([]*pbproxystate.L7WeightedDestinationCluster, 0, len(computedBackendRefs)) - for _, computedBackendRef := range computedBackendRefs { - clusterName := b.backendTargetToClusterName(computedBackendRef.BackendTarget, targets, defaultDC) - - clusters = append(clusters, &pbproxystate.L7WeightedDestinationCluster{ - Name: clusterName, - Weight: &wrapperspb.UInt32Value{ - Value: computedBackendRef.Weight, - }, - }) - } - return b.makeRouteDestinationForSplit(clusters, destConfig) - } -} - -func (b *Builder) makeRouteDestinationForDirect( - backendTarget string, - destConfig *pbproxystate.DestinationConfiguration, - targets map[string]*pbmesh.BackendTargetDetails, - defaultDC func(string) string, -) *pbproxystate.RouteDestination { - clusterName := b.backendTargetToClusterName(backendTarget, targets, defaultDC) - - return &pbproxystate.RouteDestination{ - Destination: &pbproxystate.RouteDestination_Cluster{ - Cluster: &pbproxystate.DestinationCluster{ - Name: clusterName, - }, - }, - DestinationConfiguration: destConfig, - } -} - -func (b *Builder) makeRouteDestinationForSplit( - clusters []*pbproxystate.L7WeightedDestinationCluster, - destConfig *pbproxystate.DestinationConfiguration, -) *pbproxystate.RouteDestination { - return &pbproxystate.RouteDestination{ - Destination: &pbproxystate.RouteDestination_WeightedClusters{ - WeightedClusters: &pbproxystate.L7WeightedClusterGroup{ - Clusters: clusters, - }, - }, - DestinationConfiguration: destConfig, - } -} - -func (b *Builder) makeDestinationConfiguration( - timeouts *pbmesh.HTTPRouteTimeouts, - retries *pbmesh.HTTPRouteRetries, -) *pbproxystate.DestinationConfiguration { - cfg := &pbproxystate.DestinationConfiguration{ - TimeoutConfig: translateTimeouts(timeouts), - RetryPolicy: translateRetries(retries), - } - if cfg.TimeoutConfig == nil && cfg.RetryPolicy == nil { - return nil - } - - return cfg -} - -func applyRouteFilters[V interface { - GetRequestHeaderModifier() *pbmesh.HTTPHeaderFilter - GetResponseHeaderModifier() *pbmesh.HTTPHeaderFilter - GetUrlRewrite() *pbmesh.HTTPURLRewriteFilter -}]( - psDestConfig *pbproxystate.DestinationConfiguration, - filters []V, -) []*pbproxystate.HeaderMutation { - var headerMutations []*pbproxystate.HeaderMutation - for _, filter := range filters { - switch { - case filter.GetRequestHeaderModifier() != nil: - mod := filter.GetRequestHeaderModifier() - - for _, hdr := range mod.Set { - headerMutations = append(headerMutations, &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_RequestHeaderAdd{ - RequestHeaderAdd: &pbproxystate.RequestHeaderAdd{ - Header: &pbproxystate.Header{ - Key: hdr.Name, - Value: hdr.Value, - }, - AppendAction: pbproxystate.AppendAction_APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD, - }, - }, - }) - } - for _, hdr := range mod.Add { - headerMutations = append(headerMutations, &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_RequestHeaderAdd{ - RequestHeaderAdd: &pbproxystate.RequestHeaderAdd{ - Header: &pbproxystate.Header{ - Key: hdr.Name, - Value: hdr.Value, - }, - AppendAction: pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD, - }, - }, - }) - } - - if len(mod.Remove) > 0 { - headerMutations = append(headerMutations, &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_RequestHeaderRemove{ - RequestHeaderRemove: &pbproxystate.RequestHeaderRemove{ - HeaderKeys: mod.Remove, - }, - }, - }) - } - - case filter.GetResponseHeaderModifier() != nil: - mod := filter.GetResponseHeaderModifier() - - for _, hdr := range mod.Set { - headerMutations = append(headerMutations, &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_ResponseHeaderAdd{ - ResponseHeaderAdd: &pbproxystate.ResponseHeaderAdd{ - Header: &pbproxystate.Header{ - Key: hdr.Name, - Value: hdr.Value, - }, - AppendAction: pbproxystate.AppendAction_APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD, - }, - }, - }) - } - for _, hdr := range mod.Add { - headerMutations = append(headerMutations, &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_ResponseHeaderAdd{ - ResponseHeaderAdd: &pbproxystate.ResponseHeaderAdd{ - Header: &pbproxystate.Header{ - Key: hdr.Name, - Value: hdr.Value, - }, - AppendAction: pbproxystate.AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD, - }, - }, - }) - } - - if len(mod.Remove) > 0 { - headerMutations = append(headerMutations, &pbproxystate.HeaderMutation{ - Action: &pbproxystate.HeaderMutation_ResponseHeaderRemove{ - ResponseHeaderRemove: &pbproxystate.ResponseHeaderRemove{ - HeaderKeys: mod.Remove, - }, - }, - }) - } - - case filter.GetUrlRewrite() != nil: - prefix := filter.GetUrlRewrite().PathPrefix - if prefix != "" { - psDestConfig.PrefixRewrite = prefix - } - } - } - return headerMutations -} - -func applyLoadBalancerPolicy[V interface { - GetBackendTarget() string -}]( - psDestConfig *pbproxystate.DestinationConfiguration, - cpr *pbmesh.ComputedPortRoutes, - backendRefs []V, -) { - var lb *pbmesh.LoadBalancer - - // If there are multiple targets, just pick the lb policy from - // the first one configured. - for _, backendRef := range backendRefs { - if backendRef.GetBackendTarget() == types.NullRouteBackend { - continue - } - details, ok := cpr.Targets[backendRef.GetBackendTarget()] - if !ok { - continue - } - thisLB := details.DestinationConfig.LoadBalancer - if thisLB != nil { - lb = thisLB - break - } - } - - if lb == nil { - return - } - - for _, policy := range lb.HashPolicies { - if policy.SourceIp { - psDestConfig.HashPolicies = append(psDestConfig.HashPolicies, &pbproxystate.LoadBalancerHashPolicy{ - Policy: &pbproxystate.LoadBalancerHashPolicy_ConnectionProperties{ - ConnectionProperties: &pbproxystate.ConnectionPropertiesPolicy{ - SourceIp: true, - Terminal: policy.Terminal, - }, - }, - }) - - continue - } - - // enumcover:pbmesh.HashPolicyField - switch policy.Field { - case pbmesh.HashPolicyField_HASH_POLICY_FIELD_HEADER: - psDestConfig.HashPolicies = append(psDestConfig.HashPolicies, &pbproxystate.LoadBalancerHashPolicy{ - Policy: &pbproxystate.LoadBalancerHashPolicy_Header{ - Header: &pbproxystate.HeaderPolicy{ - Name: policy.FieldValue, - Terminal: policy.Terminal, - }, - }, - }) - case pbmesh.HashPolicyField_HASH_POLICY_FIELD_COOKIE: - cookie := &pbproxystate.CookiePolicy{ - Name: policy.FieldValue, - Terminal: policy.Terminal, - } - if policy.CookieConfig != nil { - cookie.Path = policy.CookieConfig.Path - - if policy.CookieConfig.Ttl != nil { - if policy.CookieConfig.Ttl.AsDuration() != 0 { - cookie.Ttl = policy.CookieConfig.Ttl - } - } - - // Envoy will generate a session cookie if the ttl is present and zero. - if policy.CookieConfig.Session { - cookie.Ttl = durationpb.New(0 * time.Second) - } - } - - psDestConfig.HashPolicies = append(psDestConfig.HashPolicies, &pbproxystate.LoadBalancerHashPolicy{ - Policy: &pbproxystate.LoadBalancerHashPolicy_Cookie{ - Cookie: cookie, - }, - }) - case pbmesh.HashPolicyField_HASH_POLICY_FIELD_QUERY_PARAMETER: - psDestConfig.HashPolicies = append(psDestConfig.HashPolicies, &pbproxystate.LoadBalancerHashPolicy{ - Policy: &pbproxystate.LoadBalancerHashPolicy_QueryParameter{ - QueryParameter: &pbproxystate.QueryParameterPolicy{ - Name: policy.FieldValue, - Terminal: policy.Terminal, - }, - }, - }) - case pbmesh.HashPolicyField_HASH_POLICY_FIELD_UNSPECIFIED: - // fallthrough to default - default: - // not possible from validation - } - } -} - -func makeHTTPRouteMatch(match *pbmesh.HTTPRouteMatch) *pbproxystate.RouteMatch { - em := &pbproxystate.RouteMatch{} - - if match.Path != nil { - // enumcover:pbmesh.PathMatchType - switch match.Path.Type { - case pbmesh.PathMatchType_PATH_MATCH_TYPE_EXACT: - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Exact{ - Exact: match.Path.Value, - }, - } - case pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX: - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: match.Path.Value, - }, - } - case pbmesh.PathMatchType_PATH_MATCH_TYPE_REGEX: - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Regex{ - Regex: match.Path.Value, - }, - } - case pbmesh.PathMatchType_PATH_MATCH_TYPE_UNSPECIFIED: - fallthrough // to default - default: - panic(fmt.Sprintf("unknown path match type: %v", match.Path.Type)) - } - } else { - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: "/", - }, - } - } - - em.HeaderMatches = translateHeaderMatches(match.Headers, (*pbmesh.HTTPHeaderMatch).GetInvert) - - if match.Method != "" { - em.MethodMatches = []string{match.Method} - } - - if len(match.QueryParams) > 0 { - em.QueryParameterMatches = make([]*pbproxystate.QueryParameterMatch, 0, len(match.QueryParams)) - for _, qm := range match.QueryParams { - eq := &pbproxystate.QueryParameterMatch{ - Name: qm.Name, - } - - // *QueryParameterMatch_Exact - // enumcover:pbmesh.QueryParamMatchType - switch qm.Type { - case pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT: - eq.Match = &pbproxystate.QueryParameterMatch_Exact{ - Exact: qm.Value, - } - case pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_REGEX: - eq.Match = &pbproxystate.QueryParameterMatch_Regex{ - Regex: qm.Value, - } - case pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_PRESENT: - eq.Match = &pbproxystate.QueryParameterMatch_Present{ - Present: true, - } - case pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_UNSPECIFIED: - fallthrough // to default - default: - panic(fmt.Sprintf("unknown query param match type: %v", qm.Type)) - } - - em.QueryParameterMatches = append(em.QueryParameterMatches, eq) - } - } - - return em -} - -func makeGRPCRouteMatch(match *pbmesh.GRPCRouteMatch) *pbproxystate.RouteMatch { - em := &pbproxystate.RouteMatch{} - - if match.Method != nil { - mm := match.Method - switch mm.Type { - case pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT: - switch { - case mm.Method == "": - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: fmt.Sprintf("/%s/", mm.Service), - }, - } - case mm.Service == "": - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Regex{ - Regex: fmt.Sprintf("/[^/]+/%s", mm.Method), - }, - } - default: - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Exact{ - Exact: fmt.Sprintf("/%s/%s", mm.Service, mm.Method), - }, - } - } - case pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_REGEX: - switch { - case mm.Method == "": - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Regex{ - Regex: fmt.Sprintf("/%s/.+", mm.Service), - }, - } - case mm.Service == "": - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Regex{ - Regex: fmt.Sprintf("/[^/]+/%s", mm.Method), - }, - } - default: - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Regex{ - Regex: fmt.Sprintf("/%s/%s", mm.Service, mm.Method), - }, - } - } - case pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_UNSPECIFIED: - fallthrough // to default - default: - panic(fmt.Sprintf("unknown method match type: %v", match.Method.Type)) - } - } else { - em.PathMatch = &pbproxystate.PathMatch{ - PathMatch: &pbproxystate.PathMatch_Prefix{ - Prefix: "/", - }, - } - } - - em.HeaderMatches = translateHeaderMatches(match.Headers, nil) - - return em -} - -func translateHeaderMatches[V interface { - GetType() pbmesh.HeaderMatchType - GetName() string - GetValue() string -}]( - headers []V, - getInvert func(v V) bool, -) []*pbproxystate.HeaderMatch { - if len(headers) == 0 { - return nil - } - var out []*pbproxystate.HeaderMatch - out = make([]*pbproxystate.HeaderMatch, 0, len(headers)) - for _, hdr := range headers { - eh := &pbproxystate.HeaderMatch{ - Name: hdr.GetName(), - } - - // enumcover:pbmesh.HeaderMatchType - switch hdr.GetType() { - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT: - eh.Match = &pbproxystate.HeaderMatch_Exact{ - Exact: hdr.GetValue(), - } - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_REGEX: - eh.Match = &pbproxystate.HeaderMatch_Regex{ - Regex: hdr.GetValue(), - } - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_PREFIX: - eh.Match = &pbproxystate.HeaderMatch_Prefix{ - Prefix: hdr.GetValue(), - } - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_SUFFIX: - eh.Match = &pbproxystate.HeaderMatch_Suffix{ - Suffix: hdr.GetValue(), - } - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_PRESENT: - eh.Match = &pbproxystate.HeaderMatch_Present{ - Present: true, - } - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_UNSPECIFIED: - fallthrough // to default - default: - panic(fmt.Sprintf("unknown header match type: %v", hdr.GetType())) - } - - // HTTPHeaderMatch only - if getInvert != nil && getInvert(hdr) { - eh.InvertMatch = true - } - - out = append(out, eh) - } - return out -} - -func translateTimeouts(timeouts *pbmesh.HTTPRouteTimeouts) *pbproxystate.TimeoutConfig { - if timeouts == nil || (timeouts.Request == nil && timeouts.Idle == nil) { - return nil - } - - return &pbproxystate.TimeoutConfig{ - Timeout: timeouts.Request, - IdleTimeout: timeouts.Idle, - } -} - -func translateRetries(retries *pbmesh.HTTPRouteRetries) *pbproxystate.RetryPolicy { - if retries == nil { - return nil - } - - retryPolicy := &pbproxystate.RetryPolicy{} - if retries.Number != nil { - retryPolicy.NumRetries = retries.Number - } - - // The RetryOn magic values come from: https://www.envoyproxy.io/docs/envoy/v1.10.0/configuration/http_filters/router_filter#config-http-filters-router-x-envoy-retry-on - var retryStrings []string - - if len(retries.OnConditions) > 0 { - retryStrings = append(retryStrings, retries.OnConditions...) - } - - if retries.OnConnectFailure { - // connect-failure can be enabled by either adding connect-failure to the RetryOn list or by using the legacy RetryOnConnectFailure option - // Check that it's not already in the RetryOn list, so we don't set it twice - connectFailureExists := false - for _, r := range retryStrings { - if r == "connect-failure" { - connectFailureExists = true - } - } - if !connectFailureExists { - retryStrings = append(retryStrings, "connect-failure") - } - } - - if len(retries.OnStatusCodes) > 0 { - retryStrings = append(retryStrings, "retriable-status-codes") - retryPolicy.RetriableStatusCodes = retries.OnStatusCodes - } - - retryPolicy.RetryOn = strings.Join(retryStrings, ",") - - return retryPolicy -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden deleted file mode 100644 index 098beac1af9bb..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden +++ /dev/null @@ -1,194 +0,0 @@ -{ - "proxyState": { - "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-1.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-1.default.default.dc1" - } - } - ] - }, - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - } - ] - } - ] - }, - "requiredEndpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden deleted file mode 100644 index 1f925e4b5a2b7..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden +++ /dev/null @@ -1,320 +0,0 @@ -{ - "proxyState": { - "clusters": { - "null_route_cluster": { - "endpointGroup": { - "static": { - "config": { - "connectTimeout": "10s" - } - } - }, - "name": "null_route_cluster", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "routers": [ - { - "l4": { - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - }, - { - "direction": "DIRECTION_OUTBOUND", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - } - } - ], - "unixSocket": { - "mode": "0666", - "path": "/path/to/socket" - } - }, - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 2345 - }, - "name": "default/local/default/api-1:tcp2:1.1.1.1:2345", - "routers": [ - { - "l4": { - "statPrefix": "upstream.tcp2.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp2.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp2.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - }, - { - "direction": "DIRECTION_OUTBOUND", - "name": "default/local/default/api-2:tcp2:/path/to/socket", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp2.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-2.default.default.dc1" - } - } - ], - "unixSocket": { - "mode": "0666", - "path": "/path/to/socket" - } - } - ] - }, - "requiredEndpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp2.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp2.api-2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index e00c9d08e0105..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,193 +0,0 @@ -{ - "proxyState": { - "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-1.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-1.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - } - ] - } - ] - }, - "requiredEndpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address.golden deleted file mode 100644 index ae2d99c942619..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address.golden +++ /dev/null @@ -1,165 +0,0 @@ -{ - "proxyState": { - "clusters": { - "null_route_cluster": { - "endpointGroup": { - "static": { - "config": { - "connectTimeout": "10s" - } - } - }, - "name": "null_route_cluster", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "routers": [ - { - "l4": { - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - } - ] - }, - "requiredEndpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address.golden deleted file mode 100644 index 2af48e9f29e31..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address.golden +++ /dev/null @@ -1,97 +0,0 @@ -{ - "proxyState": { - "clusters": { - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - } - } - ], - "unixSocket": { - "mode": "0666", - "path": "/path/to/socket" - } - } - ] - }, - "requiredEndpoints": { - "tcp.api-2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy.golden deleted file mode 100644 index 50e871481174c..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,128 +0,0 @@ -{ - "proxyState": { - "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-1.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-1.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - } - ] - } - ] - }, - "requiredEndpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination.golden deleted file mode 100644 index ca69db7dfcb0d..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination.golden +++ /dev/null @@ -1,415 +0,0 @@ -{ - "proxyState": { - "clusters": { - "http.api-1.default.dc1.internal.foo.consul": { - "altStatName": "http.api-1.default.dc1.internal.foo.consul", - "failoverGroup": { - "config": { - "connectTimeout": "55s", - "useAltStatName": true - }, - "endpointGroups": [ - { - "dynamic": { - "config": { - "connectTimeout": "55s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - }, - "name": "failover-target~0~http.api-1.default.dc1.internal.foo.consul" - }, - { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "backup-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/backup1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - }, - "name": "failover-target~1~http.api-1.default.dc1.internal.foo.consul" - } - ] - }, - "name": "http.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "http.api-2.default.dc1.internal.foo.consul": { - "altStatName": "http.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "null_route_cluster": { - "endpointGroup": { - "static": { - "config": { - "connectTimeout": "10s" - } - } - }, - "name": "null_route_cluster", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "routers": [ - { - "l4": { - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - }, - { - "direction": "DIRECTION_OUTBOUND", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - } - } - ], - "unixSocket": { - "mode": "0666", - "path": "/path/to/socket" - } - }, - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:http:1.1.1.1:1234", - "routers": [ - { - "l7": { - "route": { - "name": "default/local/default/api-1:http:1.1.1.1:1234" - }, - "statPrefix": "upstream." - } - } - ] - } - ], - "routes": { - "default/local/default/api-1:http:1.1.1.1:1234": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-1:http:1.1.1.1:1234", - "routeRules": [ - { - "destination": { - "destinationConfiguration": { - "timeoutConfig": { - "timeout": "77s" - } - }, - "weightedClusters": { - "clusters": [ - { - "name": "http.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "http.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - }, - "match": { - "pathMatch": { - "prefix": "/split" - } - } - }, - { - "destination": { - "cluster": { - "name": "http.api-1.default.dc1.internal.foo.consul" - }, - "destinationConfiguration": { - "retryPolicy": { - "numRetries": 4, - "retryOn": "connect-failure" - }, - "timeoutConfig": { - "timeout": "606s" - } - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - }, - { - "destination": { - "cluster": { - "name": "null_route_cluster" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredEndpoints": { - "failover-target~1~http.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "backup-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "http.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "http.api-2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index 3192629710d92..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,495 +0,0 @@ -{ - "proxyState": { - "clusters": { - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-app2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "http.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-app2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-app2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp.api-app2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-app2.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - }, - { - "l7": { - "route": { - "name": "default/local/default/api-app:http" - }, - "statPrefix": "upstream." - }, - "match": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l7": { - "route": { - "name": "default/local/default/api-app2:http" - }, - "statPrefix": "upstream." - }, - "match": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp2.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp2.api-app2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-app2.default.default.dc1" - }, - "match": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "routes": { - "default/local/default/api-app2:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-app2:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "http.api-app2.default.dc1.internal.foo.consul" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "default/local/default/api-app:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-app:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "http.api-app.default.dc1.internal.foo.consul" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredEndpoints": { - "tcp2.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp2.api-app2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "http.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "http.api-app2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-app2.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app2", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden deleted file mode 100644 index 2ab840e3da9bd..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,276 +0,0 @@ -{ - "proxyState": { - "clusters": { - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l7": { - "route": { - "name": "default/local/default/api-app:http" - }, - "statPrefix": "upstream." - }, - "match": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp2.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "routes": { - "default/local/default/api-app:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-app:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "http.api-app.default.dc1.internal.foo.consul" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredEndpoints": { - "tcp2.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "http.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden deleted file mode 100644 index 2ab840e3da9bd..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ /dev/null @@ -1,276 +0,0 @@ -{ - "proxyState": { - "clusters": { - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l7": { - "route": { - "name": "default/local/default/api-app:http" - }, - "statPrefix": "upstream." - }, - "match": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp2.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "routes": { - "default/local/default/api-app:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-app:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "http.api-app.default.dc1.internal.foo.consul" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredEndpoints": { - "tcp2.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "http.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "id": { - "name": "api-app", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "catalog", - "groupVersion": "v2beta1", - "kind": "ServiceEndpoints" - } - }, - "port": "mesh" - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 95ee222f3d26d..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,101 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:port1": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.2", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "statPrefix": "public_listener", - "trafficPermissions": { - "allowPermissions": [ - { - "principals": [ - { - "spiffe": { - "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" - } - } - ] - } - ] - } - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - } - ] - } - ] - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 0cb52d9921557..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,89 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:port1": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - } - ] - } - ] - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-single-workload-address-without-ports.golden deleted file mode 100644 index 0cb52d9921557..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-single-workload-address-without-ports.golden +++ /dev/null @@ -1,89 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:port1": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - } - ] - } - ] - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden deleted file mode 100644 index 2af5ce9c06d43..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden +++ /dev/null @@ -1,212 +0,0 @@ -{ - "proxyState": { - "clusters": { - "exposed_cluster_9090": { - "endpointGroup": { - "static": {} - }, - "name": "exposed_cluster_9090", - "protocol": "PROTOCOL_HTTP" - }, - "exposed_cluster_9091": { - "endpointGroup": { - "static": {} - }, - "name": "exposed_cluster_9091", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:port1": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "exposed_cluster_9090": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - }, - "exposed_cluster_9091": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9091 - } - } - ] - }, - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - } - ] - }, - { - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 1234 - }, - "name": "exposed_path_health1234", - "routers": [ - { - "l7": { - "route": { - "name": "exposed_path_route_health1234" - }, - "statPrefix": "exposed_path_route_health1234", - "staticRoute": true - } - } - ] - }, - { - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 1235 - }, - "name": "exposed_path_GetHealth1235", - "routers": [ - { - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "exposed_path_route_GetHealth1235" - }, - "statPrefix": "exposed_path_route_GetHealth1235", - "staticRoute": true - } - } - ] - } - ], - "routes": { - "exposed_path_route_GetHealth1235": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_route_GetHealth1235", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "exposed_cluster_9091" - } - }, - "match": { - "pathMatch": { - "exact": "GetHealth" - } - } - } - ] - } - ] - }, - "exposed_path_route_health1234": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_route_health1234", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "exposed_cluster_9090" - } - }, - "match": { - "pathMatch": { - "exact": "/health" - } - } - } - ] - } - ] - } - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections.golden deleted file mode 100644 index 299b051ef69d4..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections.golden +++ /dev/null @@ -1,304 +0,0 @@ -{ - "proxyState": { - "clusters": { - "exposed_cluster_9090": { - "endpointGroup": { - "static": {} - }, - "name": "exposed_cluster_9090", - "protocol": "PROTOCOL_HTTP" - }, - "exposed_cluster_9091": { - "endpointGroup": { - "static": {} - }, - "name": "exposed_cluster_9091", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:port1": { - "endpointGroup": { - "static": { - "config": { - "circuitBreakers": { - "upstreamLimits": { - "maxConnections": 123 - } - }, - "connectTimeout": "6s" - } - } - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - }, - "local_app:port3": { - "endpointGroup": { - "static": { - "config": { - "circuitBreakers": { - "upstreamLimits": { - "maxConnections": 123 - } - }, - "connectTimeout": "8s" - } - } - }, - "name": "local_app:port3", - "protocol": "PROTOCOL_HTTP" - } - }, - "endpoints": { - "exposed_cluster_9090": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - }, - "exposed_cluster_9091": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9091 - } - } - ] - }, - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:port3": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8081 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "balanceConnections": "BALANCE_CONNECTIONS_EXACT", - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "maxInboundConnections": "123", - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "maxInboundConnections": "123", - "route": { - "name": "public_listener:port3" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port3" - ] - } - } - ] - }, - { - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 1234 - }, - "name": "exposed_path_health1234", - "routers": [ - { - "l7": { - "route": { - "name": "exposed_path_route_health1234" - }, - "statPrefix": "exposed_path_route_health1234", - "staticRoute": true - } - } - ] - }, - { - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 1235 - }, - "name": "exposed_path_GetHealth1235", - "routers": [ - { - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "exposed_path_route_GetHealth1235" - }, - "statPrefix": "exposed_path_route_GetHealth1235", - "staticRoute": true - } - } - ] - } - ], - "routes": { - "exposed_path_route_GetHealth1235": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_route_GetHealth1235", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "exposed_cluster_9091" - } - }, - "match": { - "pathMatch": { - "exact": "GetHealth" - } - } - } - ] - } - ] - }, - "exposed_path_route_health1234": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_route_health1234", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "exposed_cluster_9090" - } - }, - "match": { - "pathMatch": { - "exact": "/health" - } - } - } - ] - } - ] - }, - "public_listener:port3": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:port3", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:port3" - }, - "destinationConfiguration": { - "timeoutConfig": { - "timeout": "9s" - } - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 93a69b2bb033a..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,130 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_TCP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.3", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:admin-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:api-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - } - ] - } - ] - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 3831349ccdbd5..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,130 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_TCP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:admin-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:api-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - } - ] - } - ] - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports.golden deleted file mode 100644 index 3831349ccdbd5..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports.golden +++ /dev/null @@ -1,130 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_TCP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:admin-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:api-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - } - ] - } - ] - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port.golden deleted file mode 100644 index dc9afc44fa43d..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port.golden +++ /dev/null @@ -1,61 +0,0 @@ -{ - "proxyState": { - "clusters": { - "black-hole-cluster": { - "endpointGroup": { - "static": {} - }, - "name": "black-hole-cluster", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "black-hole-cluster" - }, - "statPrefix": "public_listener" - } - } - ] - } - ] - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index dcba1dc58150a..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,183 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_HTTP2" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.3", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:admin-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:api-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - } - ] - } - ], - "routes": { - "public_listener:admin-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:admin-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:admin-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:api-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:api-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:api-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 08d9faa234ea6..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,250 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:grpc-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc-port", - "protocol": "PROTOCOL_GRPC" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - }, - "local_app:grpc-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9091 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:admin-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:api-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc-port" - ] - } - } - ] - } - ], - "routes": { - "public_listener:admin-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:admin-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:admin-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:api-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:api-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:api-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:grpc-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports.golden deleted file mode 100644 index 08d9faa234ea6..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports.golden +++ /dev/null @@ -1,250 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:grpc-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc-port", - "protocol": "PROTOCOL_GRPC" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - }, - "local_app:grpc-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9091 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:admin-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:api-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc-port" - ] - } - } - ] - } - ], - "routes": { - "public_listener:admin-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:admin-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:admin-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:api-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:api-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:api-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:grpc-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/cache/cache.go b/internal/mesh/internal/controllers/sidecarproxy/cache/cache.go deleted file mode 100644 index b2007d5b0d43e..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/cache/cache.go +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package cache - -import ( - "context" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - "github.com/hashicorp/consul/internal/resource/mappers/selectiontracker" - "github.com/hashicorp/consul/internal/storage" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type Cache struct { - // computedRoutes keeps track of computed routes IDs to service references it applies to. - computedRoutes *bimapper.Mapper - - // identities keeps track of which identity a workload is mapped to. - identities *bimapper.Mapper - - // computedDestinations keeps track of the computed explicit destinations IDs to service references that are - // referenced in that resource. - computedDestinations *bimapper.Mapper - - // serviceSelectorTracker keeps track of which workload selectors a service is currently using. - serviceSelectorTracker *selectiontracker.WorkloadSelectionTracker -} - -func New() *Cache { - return &Cache{ - computedRoutes: bimapper.New(pbmesh.ComputedRoutesType, pbcatalog.ServiceType), - identities: bimapper.New(pbcatalog.WorkloadType, pbauth.WorkloadIdentityType), - computedDestinations: bimapper.New(pbmesh.ComputedExplicitDestinationsType, pbcatalog.ServiceType), - serviceSelectorTracker: selectiontracker.New(), - } -} - -func (c *Cache) TrackComputedDestinations(computedDestinations *types.DecodedComputedDestinations) { - var serviceRefs []resource.ReferenceOrID - - for _, dest := range computedDestinations.Data.Destinations { - serviceRefs = append(serviceRefs, dest.DestinationRef) - } - - c.computedDestinations.TrackItem(computedDestinations.Resource.Id, serviceRefs) -} - -func (c *Cache) UntrackComputedDestinations(computedDestinationsID *pbresource.ID) { - c.computedDestinations.UntrackItem(computedDestinationsID) -} - -func (c *Cache) UntrackComputedRoutes(computedRoutesID *pbresource.ID) { - c.computedRoutes.UntrackItem(computedRoutesID) -} - -func (c *Cache) TrackWorkload(workload *types.DecodedWorkload) { - identityID := &pbresource.ID{ - Name: workload.GetData().Identity, - Tenancy: workload.GetResource().Id.Tenancy, - Type: pbauth.WorkloadIdentityType, - } - c.identities.TrackItem(workload.GetResource().GetId(), []resource.ReferenceOrID{identityID}) -} - -// UntrackWorkload removes tracking for the given workload ID. -func (c *Cache) UntrackWorkload(wID *pbresource.ID) { - c.identities.UntrackItem(wID) -} - -func (c *Cache) ComputedDestinationsByService(id resource.ReferenceOrID) []*pbresource.ID { - return c.computedDestinations.ItemIDsForLink(id) -} - -func (c *Cache) trackComputedRoutes(computedRoutes *types.DecodedComputedRoutes) { - var serviceRefs []resource.ReferenceOrID - - for _, pcr := range computedRoutes.Data.PortedConfigs { - for _, details := range pcr.Targets { - serviceRefs = append(serviceRefs, details.BackendRef.Ref) - } - } - - c.computedRoutes.TrackItem(computedRoutes.Resource.Id, serviceRefs) -} - -func (c *Cache) computedRoutesByService(id resource.ReferenceOrID) []*pbresource.ID { - return c.computedRoutes.ItemIDsForLink(id) -} - -func (c *Cache) WorkloadsByWorkloadIdentity(id *pbresource.ID) []*pbresource.ID { - return c.identities.ItemIDsForLink(id) -} - -func (c *Cache) ServicesForWorkload(id *pbresource.ID) []*pbresource.ID { - return c.serviceSelectorTracker.GetIDsForWorkload(id) -} - -func (c *Cache) UntrackService(id *pbresource.ID) { - c.serviceSelectorTracker.UntrackID(id) -} - -func (c *Cache) MapComputedRoutes(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - computedRoutes, err := resource.Decode[*pbmesh.ComputedRoutes](res) - if err != nil { - return nil, err - } - - ids, err := c.mapComputedRoutesToProxyStateTemplate(ctx, rt, res.Id) - if err != nil { - return nil, err - } - - c.trackComputedRoutes(computedRoutes) - - return controller.MakeRequests(pbmesh.ProxyStateTemplateType, ids), nil -} - -func (c *Cache) mapComputedRoutesToProxyStateTemplate(ctx context.Context, rt controller.Runtime, computedRoutesID *pbresource.ID) ([]*pbresource.ID, error) { - // Each Destination gets a single ComputedRoutes. - serviceID := resource.ReplaceType(pbcatalog.ServiceType, computedRoutesID) - serviceRef := resource.Reference(serviceID, "") - - return c.mapServiceThroughDestinations(ctx, rt, serviceRef) -} - -func (c *Cache) TrackService(svc *types.DecodedService) { - c.serviceSelectorTracker.TrackIDForSelector(svc.Resource.GetId(), svc.GetData().GetWorkloads()) -} - -func (c *Cache) MapService(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - // Record workload selector in the cache every time we see an event for a service. - decodedService, err := resource.Decode[*pbcatalog.Service](res) - if err != nil { - return nil, err - } - c.TrackService(decodedService) - - serviceRef := resource.Reference(res.Id, "") - - pstIDs, err := c.mapServiceThroughDestinations(ctx, rt, serviceRef) - if err != nil { - return nil, err - } - - // Now walk the mesh configuration information backwards because - // we need to find any PST that needs to DISCOVER endpoints for this - // service as a part of mesh configuration and traffic routing. - - // Find all ComputedRoutes that reference this service. - routeIDs := c.computedRoutesByService(serviceRef) - for _, routeID := range routeIDs { - // Find all Upstreams that reference a Service aligned with this ComputedRoutes. - // Afterwards, find all Workloads selected by the Upstreams, and align a PST with those. - ids, err := c.mapComputedRoutesToProxyStateTemplate(ctx, rt, routeID) - if err != nil { - return nil, err - } - - pstIDs = append(pstIDs, ids...) - } - - return controller.MakeRequests(pbmesh.ProxyStateTemplateType, pstIDs), nil -} - -// mapServiceThroughDestinations takes an explicit -// Service and traverses back through Destinations to Workloads to -// ProxyStateTemplates. -// -// This is in a separate function so it can be chained for more complicated -// relationships. -func (c *Cache) mapServiceThroughDestinations( - ctx context.Context, - rt controller.Runtime, - serviceRef *pbresource.Reference, -) ([]*pbresource.ID, error) { - - // The relationship is: - // - // - PST (replace type) Workload - // - Workload (name-aligned) ComputedDestinations - // - ComputedDestinations (contains) Service - // - // When we wake up for Service we should: - // - // - look up computed destinations for the service - // - rewrite computed destination types to PST - - var pstIDs []*pbresource.ID - - // Get all source proxies if they're referenced in any explicit destinations from computed destinations (name-aligned with workload/PST). - sources := c.ComputedDestinationsByService(serviceRef) - for _, cdID := range sources { - pstIDs = append(pstIDs, resource.ReplaceType(pbmesh.ProxyStateTemplateType, cdID)) - } - - // TODO(v2): remove this after we can do proper performant implicit upstream determination - // - // TODO(rb): shouldn't this instead list all Workloads that have a mesh port? - allIDs, err := c.listAllProxyStateTemplatesTemporarily(ctx, rt, serviceRef.Tenancy) - if err != nil { - return nil, err - } - - pstIDs = append(pstIDs, allIDs...) - - return pstIDs, nil -} - -func (c *Cache) listAllProxyStateTemplatesTemporarily(ctx context.Context, rt controller.Runtime, tenancy *pbresource.Tenancy) ([]*pbresource.ID, error) { - // todo (ishustava): this is a stub for now until we implement implicit destinations. - // For tproxy, we generate requests for all proxy states in the cluster. - // This will generate duplicate events for proxies already added above, - // however, we expect that the controller runtime will de-dup for us. - rsp, err := rt.Client.List(ctx, &pbresource.ListRequest{ - Type: pbmesh.ProxyStateTemplateType, - Tenancy: &pbresource.Tenancy{ - Namespace: storage.Wildcard, - Partition: tenancy.Partition, - PeerName: tenancy.PeerName, - }, - }) - if err != nil { - return nil, err - } - - result := make([]*pbresource.ID, 0, len(rsp.Resources)) - for _, r := range rsp.Resources { - result = append(result, r.Id) - } - return result, nil -} - -func (c *Cache) MapComputedTrafficPermissions(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - var ctp pbauth.ComputedTrafficPermissions - err := res.Data.UnmarshalTo(&ctp) - if err != nil { - return nil, err - } - - workloadIdentityID := resource.ReplaceType(pbauth.WorkloadIdentityType, res.Id) - ids := c.WorkloadsByWorkloadIdentity(workloadIdentityID) - - return controller.MakeRequests(pbmesh.ProxyStateTemplateType, ids), nil -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/cache/cache_test.go b/internal/mesh/internal/controllers/sidecarproxy/cache/cache_test.go deleted file mode 100644 index 2aa5484db498e..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/cache/cache_test.go +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package cache - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestIdentities(t *testing.T) { - cache := New() - - identityID1 := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-1"). - WithTenancy(resource.DefaultNamespacedTenancy()).ID() - identityID2 := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-2"). - WithTenancy(resource.DefaultNamespacedTenancy()).ID() - - w1 := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-1"). - WithData(t, &pbcatalog.Workload{ - Identity: identityID1.Name, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - decW1 := resourcetest.MustDecode[*pbcatalog.Workload](t, w1) - w2 := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-2"). - WithData(t, &pbcatalog.Workload{ - Identity: identityID2.Name, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - decW2 := resourcetest.MustDecode[*pbcatalog.Workload](t, w2) - - // Empty cache - require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID1)) - require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID2)) - - // Insert value and fetch it. - cache.TrackWorkload(decW1) - require.Equal(t, []*pbresource.ID{w1.Id}, cache.WorkloadsByWorkloadIdentity(identityID1)) - require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID2)) - - // Insert another value referencing the same identity. - decW2.GetData().Identity = identityID1.Name - cache.TrackWorkload(decW2) - require.ElementsMatch(t, []*pbresource.ID{w1.Id, w2.Id}, cache.WorkloadsByWorkloadIdentity(identityID1)) - require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID2)) - - // Now workload 1 uses identity 2 - decW1.GetData().Identity = identityID2.Name - cache.TrackWorkload(decW1) - require.Equal(t, []*pbresource.ID{w1.Id}, cache.WorkloadsByWorkloadIdentity(identityID2)) - require.Equal(t, []*pbresource.ID{w2.Id}, cache.WorkloadsByWorkloadIdentity(identityID1)) - - // Untrack workload 2 - cache.UntrackWorkload(w2.Id) - require.Equal(t, []*pbresource.ID{w1.Id}, cache.WorkloadsByWorkloadIdentity(identityID2)) - require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID1)) - - // Untrack workload 1 - cache.UntrackWorkload(w1.Id) - require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID2)) - require.Nil(t, cache.WorkloadsByWorkloadIdentity(identityID1)) -} - -func TestMapComputedTrafficPermissions(t *testing.T) { - client := svctest.RunResourceService(t, types.Register, catalog.RegisterTypes) - ctp := resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, "workload-identity-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbauth.ComputedTrafficPermissions{}). - Build() - - c := New() - - // Empty results when the cache isn't populated. - requests, err := c.MapComputedTrafficPermissions(context.Background(), controller.Runtime{Client: client}, ctp) - require.NoError(t, err) - require.Len(t, requests, 0) - - identityID1 := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-1"). - WithTenancy(resource.DefaultNamespacedTenancy()).ID() - - w1 := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-1"). - WithData(t, &pbcatalog.Workload{ - Identity: identityID1.Name, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - decW1 := resourcetest.MustDecode[*pbcatalog.Workload](t, w1) - w2 := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-2"). - WithData(t, &pbcatalog.Workload{ - Identity: identityID1.Name, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - decW2 := resourcetest.MustDecode[*pbcatalog.Workload](t, w2) - - c.TrackWorkload(decW1) - - // Empty results when the cache isn't populated. - requests, err = c.MapComputedTrafficPermissions(context.Background(), controller.Runtime{Client: client}, ctp) - require.NoError(t, err) - prototest.AssertElementsMatch(t, - []controller.Request{{ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w1.Id)}}, requests) - - c.TrackWorkload(decW2) - - // Empty results when the cache isn't populated. - requests, err = c.MapComputedTrafficPermissions(context.Background(), controller.Runtime{Client: client}, ctp) - require.NoError(t, err) - prototest.AssertElementsMatch(t, []controller.Request{ - {ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w1.Id)}, - {ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w2.Id)}, - }, requests) -} - -func TestUnified_AllMappingsToProxyStateTemplate(t *testing.T) { - var ( - cache = New() - client = svctest.RunResourceService(t, types.Register, catalog.RegisterTypes) - ) - - anyServiceData := &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"src-workload"}, - }, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp1", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "tcp2", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "mesh", - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - } - - // The thing we link through Destinations. - destService := resourcetest.Resource(pbcatalog.ServiceType, "web"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, anyServiceData). - Build() - destServiceRef := resource.Reference(destService.Id, "") - - // The thing we reach through the mesh config. - targetService := resourcetest.Resource(pbcatalog.ServiceType, "db"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, anyServiceData). - Build() - targetServiceRef := resource.Reference(targetService.Id, "") - - backupTargetService := resourcetest.Resource(pbcatalog.ServiceType, "db-backup"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, anyServiceData). - Build() - backupTargetServiceRef := resource.Reference(backupTargetService.Id, "") - - // The way we make 'web' actually route traffic to 'db'. - tcpRoute := resourcetest.Resource(pbmesh.TCPRouteType, "tcp-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: destServiceRef, - }}, - Rules: []*pbmesh.TCPRouteRule{{ - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: &pbmesh.BackendReference{ - Ref: targetServiceRef, - }, - }}, - }}, - }). - Build() - failoverPolicy := resourcetest.ResourceID(resource.ReplaceType(pbcatalog.FailoverPolicyType, targetService.Id)). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{{ - Ref: backupTargetServiceRef, - }}, - }, - }). - Build() - webRoutes := routestest.BuildComputedRoutes(t, resource.ReplaceType(pbmesh.ComputedRoutesType, destService.Id), - resourcetest.MustDecode[*pbcatalog.Service](t, destService), - resourcetest.MustDecode[*pbcatalog.Service](t, targetService), - resourcetest.MustDecode[*pbcatalog.Service](t, backupTargetService), - resourcetest.MustDecode[*pbmesh.TCPRoute](t, tcpRoute), - resourcetest.MustDecode[*pbcatalog.FailoverPolicy](t, failoverPolicy), - ) - - var ( - sourceProxy1 = newID(pbmesh.ProxyStateTemplateType, "src-workload-1") - sourceProxy2 = newID(pbmesh.ProxyStateTemplateType, "src-workload-2") - sourceProxy3 = newID(pbmesh.ProxyStateTemplateType, "src-workload-3") - sourceProxy4 = newID(pbmesh.ProxyStateTemplateType, "src-workload-4") - sourceProxy5 = newID(pbmesh.ProxyStateTemplateType, "src-workload-5") - sourceProxy6 = newID(pbmesh.ProxyStateTemplateType, "src-workload-6") - ) - - compDestProxy1 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy1.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: destServiceRef, - DestinationPort: "tcp1", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - - compDestProxy2 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy2.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: destServiceRef, - DestinationPort: "tcp1", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - - compDestProxy3 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy3.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: destServiceRef, - DestinationPort: "tcp2", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - - compDestProxy4 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy4.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: destServiceRef, - DestinationPort: "tcp2", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - - compDestProxy5 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy5.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: destServiceRef, - DestinationPort: "mesh", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - - compDestProxy6 := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, sourceProxy6.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: destServiceRef, - DestinationPort: "mesh", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - - cache.trackComputedRoutes(webRoutes) - cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy1)) - cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy2)) - cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy3)) - cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy4)) - cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy5)) - cache.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDestProxy6)) - - t.Run("Service", func(t *testing.T) { - t.Run("map dest service", func(t *testing.T) { - requests, err := cache.MapService( - context.Background(), - controller.Runtime{Client: client}, - destService, - ) - require.NoError(t, err) - - // Only wake up things with dest as an upstream. - expRequests := []controller.Request{ - {ID: sourceProxy1}, - {ID: sourceProxy2}, - {ID: sourceProxy3}, - {ID: sourceProxy4}, - {ID: sourceProxy5}, - {ID: sourceProxy6}, - } - - prototest.AssertElementsMatch(t, expRequests, requests) - - // Check that service's workload selector is tracked. - prototest.AssertElementsMatch(t, - []*pbresource.ID{destService.Id}, - cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy1))) - prototest.AssertElementsMatch(t, - []*pbresource.ID{destService.Id}, - cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy2))) - prototest.AssertElementsMatch(t, - []*pbresource.ID{destService.Id}, - cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy3))) - prototest.AssertElementsMatch(t, - []*pbresource.ID{destService.Id}, - cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy4))) - prototest.AssertElementsMatch(t, - []*pbresource.ID{destService.Id}, - cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy5))) - prototest.AssertElementsMatch(t, - []*pbresource.ID{destService.Id}, - cache.serviceSelectorTracker.GetIDsForWorkload(resource.ReplaceType(pbcatalog.WorkloadType, sourceProxy6))) - }) - - t.Run("map target endpoints (TCPRoute)", func(t *testing.T) { - requests, err := cache.MapService( - context.Background(), - controller.Runtime{Client: client}, - targetService, - ) - require.NoError(t, err) - - requests = testDeduplicateRequests(requests) - - expRequests := []controller.Request{ - // Wakeup things that have destService as a destination b/c of the TCPRoute reference. - {ID: sourceProxy1}, - {ID: sourceProxy2}, - {ID: sourceProxy3}, - {ID: sourceProxy4}, - {ID: sourceProxy5}, - {ID: sourceProxy6}, - } - - prototest.AssertElementsMatch(t, expRequests, requests) - }) - - t.Run("map backup target endpoints (FailoverPolicy)", func(t *testing.T) { - requests, err := cache.MapService( - context.Background(), - controller.Runtime{Client: client}, - backupTargetService, - ) - require.NoError(t, err) - - requests = testDeduplicateRequests(requests) - - expRequests := []controller.Request{ - // Wakeup things that have destService as a destination b/c of the FailoverPolicy reference. - {ID: sourceProxy1}, - {ID: sourceProxy2}, - {ID: sourceProxy3}, - {ID: sourceProxy4}, - {ID: sourceProxy5}, - {ID: sourceProxy6}, - } - - prototest.AssertElementsMatch(t, expRequests, requests) - }) - }) - - t.Run("ComputedRoutes", func(t *testing.T) { - t.Run("map web routes", func(t *testing.T) { - requests, err := cache.MapComputedRoutes( - context.Background(), - controller.Runtime{Client: client}, - webRoutes.Resource, - ) - require.NoError(t, err) - - // Only wake up things with dest as an upstream. - expRequests := []controller.Request{ - {ID: sourceProxy1}, - {ID: sourceProxy2}, - {ID: sourceProxy3}, - {ID: sourceProxy4}, - {ID: sourceProxy5}, - {ID: sourceProxy6}, - } - - prototest.AssertElementsMatch(t, expRequests, requests) - }) - }) -} - -func newID(typ *pbresource.Type, name string) *pbresource.ID { - return &pbresource.ID{ - Type: typ, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: name, - } -} - -func testDeduplicateRequests(reqs []controller.Request) []controller.Request { - type resID struct { - resource.ReferenceKey - UID string - } - - out := make([]controller.Request, 0, len(reqs)) - seen := make(map[resID]struct{}) - - for _, req := range reqs { - rid := resID{ - ReferenceKey: resource.NewReferenceKey(req.ID), - UID: req.ID.Uid, - } - if _, ok := seen[rid]; !ok { - out = append(out, req) - seen[rid] = struct{}{} - } - } - - return out -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/controller.go b/internal/mesh/internal/controllers/sidecarproxy/controller.go deleted file mode 100644 index 6b81b04b8c0ff..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/controller.go +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sidecarproxy - -import ( - "context" - - "github.com/hashicorp/go-hclog" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/builder" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/fetcher" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// ControllerName is the name for this controller. It's used for logging or status keys. -const ControllerName = "consul.io/sidecar-proxy-controller" - -type TrustDomainFetcher func() (string, error) - -func Controller( - cache *cache.Cache, - trustDomainFetcher TrustDomainFetcher, - dc string, - defaultAllow bool, -) controller.Controller { - if cache == nil || trustDomainFetcher == nil { - panic("cache and trust domain fetcher are required") - } - - /* - Workload PST - ComputedDestinations PST(==Workload) - ComputedDestinations Service(destinations) - ComputedProxyConfiguration PST(==Workload) - ComputedRoutes Service(upstream) - ComputedRoutes Service(disco) - ComputedTrafficPermissions WorkloadIdentity - Workload WorkloadIdentity - - These relationships then dictate the following reconcile logic. - - controller: read workload for PST - controller: read previous PST - controller: read ComputedProxyConfiguration for Workload - controller: read ComputedDestinations for workload to walk explicit upstreams - controller: read ComputedTrafficPermissions for workload using workload.identity field. - - fetcher: read Service(Destination) - fetcher: read ComputedRoutes - - fetcher: read ServiceEndpoints - - - - fetcher: list ALL ComputedRoutes - - fetcher: read Service(upstream) - - fetcher: read ServiceEndpoints - - - - */ - - /* - Which means for equivalence, the following mapper relationships should exist: - - Service: find destinations with Service; Recurse(ComputedDestinations); - find ComputedRoutes with this in a Target or FailoverConfig; Recurse(ComputedRoutes) - ComputedDestinations: replace type CED=>PST - ComputedProxyConfiguration: replace type CPC=>PST - ComputedRoutes: CR=>Service; find destinations with Service; Recurse(Destinations) - [implicit/temp]: trigger all - ComputedTrafficPermissions: find workloads in cache stored for this CTP=Workload, workloads=>PST reconcile requests - */ - - return controller.ForType(pbmesh.ProxyStateTemplateType). - WithWatch(pbcatalog.ServiceType, cache.MapService). - WithWatch(pbcatalog.WorkloadType, controller.ReplaceType(pbmesh.ProxyStateTemplateType)). - WithWatch(pbmesh.ComputedExplicitDestinationsType, controller.ReplaceType(pbmesh.ProxyStateTemplateType)). - WithWatch(pbmesh.ComputedProxyConfigurationType, controller.ReplaceType(pbmesh.ProxyStateTemplateType)). - WithWatch(pbmesh.ComputedRoutesType, cache.MapComputedRoutes). - WithWatch(pbauth.ComputedTrafficPermissionsType, cache.MapComputedTrafficPermissions). - WithReconciler(&reconciler{ - cache: cache, - getTrustDomain: trustDomainFetcher, - dc: dc, - defaultAllow: defaultAllow, - }) -} - -type reconciler struct { - cache *cache.Cache - getTrustDomain TrustDomainFetcher - defaultAllow bool - dc string -} - -func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error { - rt.Logger = rt.Logger.With("resource-id", req.ID, "controller", ControllerName) - - rt.Logger.Trace("reconciling proxy state template") - - // Instantiate a data fetcher to fetch all reconciliation data. - dataFetcher := fetcher.New(rt.Client, r.cache) - - // Check if the workload exists. - workloadID := resource.ReplaceType(pbcatalog.WorkloadType, req.ID) - workload, err := dataFetcher.FetchWorkload(ctx, workloadID) - if err != nil { - rt.Logger.Error("error reading the associated workload", "error", err) - return err - } - if workload == nil { - // If workload has been deleted, then return as ProxyStateTemplate should be cleaned up - // by the garbage collector because of the owner reference. - rt.Logger.Trace("workload doesn't exist; skipping reconciliation", "workload", workloadID) - return nil - } - - proxyStateTemplate, err := dataFetcher.FetchProxyStateTemplate(ctx, req.ID) - if err != nil { - rt.Logger.Error("error reading proxy state template", "error", err) - return nil - } - - if proxyStateTemplate == nil { - // If proxy state template has been deleted, we will need to generate a new one. - rt.Logger.Trace("proxy state template for this workload doesn't yet exist; generating a new one") - } - - if !workload.GetData().IsMeshEnabled() { - // Skip non-mesh workloads. - - // If there's existing proxy state template, delete it. - if proxyStateTemplate != nil { - rt.Logger.Trace("deleting existing proxy state template because workload is no longer on the mesh") - _, err = rt.Client.Delete(ctx, &pbresource.DeleteRequest{Id: req.ID}) - if err != nil { - rt.Logger.Error("error deleting existing proxy state template", "error", err) - return err - } - } - rt.Logger.Trace("skipping proxy state template generation because workload is not on the mesh", "workload", workload.Resource.Id) - return nil - } - - // First get the trust domain. - trustDomain, err := r.getTrustDomain() - if err != nil { - rt.Logger.Error("error fetching trust domain to compute proxy state template", "error", err) - return err - } - - // Fetch proxy configuration. - proxyCfg, err := dataFetcher.FetchComputedProxyConfiguration(ctx, req.ID) - if err != nil { - rt.Logger.Error("error fetching proxy and merging proxy configurations", "error", err) - return err - } - - trafficPermissions, err := dataFetcher.FetchComputedTrafficPermissions(ctx, computedTrafficPermissionsIDFromWorkload(workload)) - if err != nil { - rt.Logger.Error("error fetching computed traffic permissions to compute proxy state template", "error", err) - return err - } - - var ctp *pbauth.ComputedTrafficPermissions - if trafficPermissions != nil { - ctp = trafficPermissions.Data - } - - workloadPorts, err := r.workloadPortProtocolsFromService(ctx, dataFetcher, workload, rt.Logger) - if err != nil { - rt.Logger.Error("error determining workload ports", "error", err) - return err - } - workloadDataWithInheritedPorts := proto.Clone(workload.Data).(*pbcatalog.Workload) - workloadDataWithInheritedPorts.Ports = workloadPorts - - b := builder.New(req.ID, identityRefFromWorkload(workload), trustDomain, r.dc, r.defaultAllow, proxyCfg.GetData()). - BuildLocalApp(workloadDataWithInheritedPorts, ctp) - - // Get all destinationsData. - destinationsData, err := dataFetcher.FetchExplicitDestinationsData(ctx, req.ID) - if err != nil { - rt.Logger.Error("error fetching explicit destinations for this proxy", "error", err) - return err - } - - if proxyCfg.GetData() != nil && proxyCfg.GetData().IsTransparentProxy() { - rt.Logger.Trace("transparent proxy is enabled; fetching implicit destinations") - destinationsData, err = dataFetcher.FetchImplicitDestinationsData(ctx, req.ID, destinationsData) - if err != nil { - rt.Logger.Error("error fetching implicit destinations for this proxy", "error", err) - return err - } - } - - b.BuildDestinations(destinationsData) - - newProxyTemplate := b.Build() - - if proxyStateTemplate == nil || !proto.Equal(proxyStateTemplate.Data, newProxyTemplate) { - if proxyStateTemplate == nil { - req.ID.Uid = "" - } - proxyTemplateData, err := anypb.New(newProxyTemplate) - if err != nil { - rt.Logger.Error("error creating proxy state template data", "error", err) - return err - } - rt.Logger.Trace("updating proxy state template") - _, err = rt.Client.Write(ctx, &pbresource.WriteRequest{ - Resource: &pbresource.Resource{ - Id: req.ID, - Owner: workload.Resource.Id, - Data: proxyTemplateData, - }, - }) - if err != nil { - rt.Logger.Error("error writing proxy state template", "error", err) - return err - } - } else { - rt.Logger.Trace("proxy state template data has not changed, skipping update") - } - - return nil -} - -func (r *reconciler) workloadPortProtocolsFromService( - ctx context.Context, - fetcher *fetcher.Fetcher, - workload *types.DecodedWorkload, - logger hclog.Logger, -) (map[string]*pbcatalog.WorkloadPort, error) { - - // Fetch all services for this workload. - serviceIDs := r.cache.ServicesForWorkload(workload.GetResource().GetId()) - - var services []*types.DecodedService - - for _, serviceID := range serviceIDs { - svc, err := fetcher.FetchService(ctx, serviceID) - if err != nil { - return nil, err - } - - // If service is not found, we should untrack it. - if svc == nil { - r.cache.UntrackService(serviceID) - continue - } - - services = append(services, svc) - } - - // Now walk through all workload ports. - // For ports that don't have a protocol explicitly specified, inherit it from the service. - - result := make(map[string]*pbcatalog.WorkloadPort) - - for portName, port := range workload.GetData().GetPorts() { - if port.GetProtocol() != pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { - // Add any specified protocols as is. - result[portName] = port - continue - } - - // Check if we have any service IDs or fetched services. - if len(serviceIDs) == 0 || len(services) == 0 { - logger.Trace("found no services for this workload's port; using default TCP protocol", "port", portName) - result[portName] = &pbcatalog.WorkloadPort{ - Port: port.GetPort(), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - } - continue - } - - // Otherwise, look for port protocol in the service. - inheritedProtocol := pbcatalog.Protocol_PROTOCOL_UNSPECIFIED - for _, svc := range services { - // Find workload's port as the target port. - svcPort := svc.GetData().FindServicePort(portName) - - // If this service doesn't select this port, go to the next service. - if svcPort == nil { - continue - } - - // Check for conflicts. - // If protocols between services selecting this workload on this port do not match, - // we use the default protocol (tcp) instead. - if inheritedProtocol != pbcatalog.Protocol_PROTOCOL_UNSPECIFIED && - svcPort.GetProtocol() != inheritedProtocol { - - logger.Trace("found conflicting service protocols that select this workload port; using default TCP protocol", "port", portName) - inheritedProtocol = pbcatalog.Protocol_PROTOCOL_TCP - - // We won't check any remaining services as there's already a conflict. - break - } - - inheritedProtocol = svcPort.GetProtocol() - } - - // If after going through all services, we haven't found a protocol, use the default. - if inheritedProtocol == pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { - logger.Trace("no services select this workload port; using default TCP protocol", "port", portName) - result[portName] = &pbcatalog.WorkloadPort{ - Port: port.GetPort(), - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - } - } else { - result[portName] = &pbcatalog.WorkloadPort{ - Port: port.GetPort(), - Protocol: inheritedProtocol, - } - } - } - - return result, nil -} - -func identityRefFromWorkload(w *types.DecodedWorkload) *pbresource.Reference { - return &pbresource.Reference{ - Name: w.Data.Identity, - Tenancy: w.Resource.Id.Tenancy, - Type: pbauth.WorkloadIdentityType, - } -} - -func computedTrafficPermissionsIDFromWorkload(w *types.DecodedWorkload) *pbresource.ID { - return &pbresource.ID{ - Type: pbauth.ComputedTrafficPermissionsType, - Name: w.Data.Identity, - Tenancy: w.Resource.Id.Tenancy, - } -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/controller_test.go b/internal/mesh/internal/controllers/sidecarproxy/controller_test.go deleted file mode 100644 index 0d6684f0ef544..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/controller_test.go +++ /dev/null @@ -1,921 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sidecarproxy - -import ( - "context" - "strings" - "testing" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/envoyextensions/xdscommon" - "github.com/hashicorp/consul/internal/auth" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/builder" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/fetcher" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" -) - -type controllerTestSuite struct { - suite.Suite - - client *resourcetest.Client - runtime controller.Runtime - - ctl *reconciler - ctx context.Context - - apiWorkloadID *pbresource.ID - apiWorkload *pbcatalog.Workload - apiComputedTrafficPermissions *pbresource.Resource - apiComputedTrafficPermissionsData *pbauth.ComputedTrafficPermissions - apiService *pbresource.Resource - apiServiceData *pbcatalog.Service - apiEndpoints *pbresource.Resource - apiEndpointsData *pbcatalog.ServiceEndpoints - webWorkload *pbresource.Resource - - dbWorkloadID *pbresource.ID - dbWorkload *pbcatalog.Workload - dbService *pbresource.Resource - dbEndpoints *pbresource.Resource - dbEndpointsData *pbcatalog.ServiceEndpoints - - proxyStateTemplate *pbmesh.ProxyStateTemplate -} - -func (suite *controllerTestSuite) SetupTest() { - resourceClient := svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes, auth.RegisterTypes) - suite.client = resourcetest.NewClient(resourceClient) - suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())} - suite.ctx = testutil.TestContext(suite.T()) - - suite.ctl = &reconciler{ - cache: cache.New(), - getTrustDomain: func() (string, error) { - return "test.consul", nil - }, - } - - { - // DB will be a service with a single workload, IN the mesh that will - // be a destination of web. - - suite.dbWorkload = &pbcatalog.Workload{ - Identity: "db-identity", - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: "10.0.4.1"}, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - suite.dbWorkloadID = resourcetest.Resource(pbcatalog.WorkloadType, "db-abc"). - WithData(suite.T(), suite.dbWorkload). - Write(suite.T(), resourceClient).Id - - suite.dbService = resourcetest.Resource(pbcatalog.ServiceType, "db-service"). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"db-abc"}}, - VirtualIps: []string{"1.1.1.1"}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }}). - Write(suite.T(), suite.client) - - suite.dbEndpointsData = &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: suite.dbWorkloadID, - Addresses: suite.dbWorkload.Addresses, - Ports: suite.dbWorkload.Ports, - Identity: "db-identity", - }, - }, - } - suite.dbEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "db-service"). - WithData(suite.T(), suite.dbEndpointsData). - Write(suite.T(), suite.client) - - } - - suite.apiWorkload = &pbcatalog.Workload{ - Identity: "api-identity", - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - - suite.apiWorkloadID = resourcetest.Resource(pbcatalog.WorkloadType, "api-abc"). - WithData(suite.T(), suite.apiWorkload). - Write(suite.T(), resourceClient).Id - - suite.apiServiceData = &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"api-abc"}}, - VirtualIps: []string{"1.1.1.1"}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - - suite.apiComputedTrafficPermissionsData = &pbauth.ComputedTrafficPermissions{ - IsDefault: false, - AllowPermissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "foo", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - } - - suite.apiComputedTrafficPermissions = resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, suite.apiWorkload.Identity). - WithData(suite.T(), suite.apiComputedTrafficPermissionsData). - Write(suite.T(), resourceClient) - - suite.apiService = resourcetest.Resource(pbcatalog.ServiceType, "api-service"). - WithData(suite.T(), suite.apiServiceData). - Write(suite.T(), suite.client.ResourceServiceClient) - - suite.apiEndpointsData = &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: suite.apiWorkloadID, - Addresses: suite.apiWorkload.Addresses, - Ports: suite.apiWorkload.Ports, - Identity: "api-identity", - }, - }, - } - suite.apiEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service"). - WithData(suite.T(), suite.apiEndpointsData). - Write(suite.T(), suite.client.ResourceServiceClient) - - webWorkloadData := &pbcatalog.Workload{ - Identity: "web-identity", - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.2", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - suite.webWorkload = resourcetest.Resource(pbcatalog.WorkloadType, "web-def"). - WithData(suite.T(), webWorkloadData). - Write(suite.T(), suite.client) - - resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, webWorkloadData.Identity). - WithData(suite.T(), &pbauth.ComputedTrafficPermissions{IsDefault: true}). - Write(suite.T(), resourceClient) - - resourcetest.Resource(pbcatalog.ServiceType, "web"). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"web-def"}}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }}). - Write(suite.T(), suite.client) - - resourcetest.Resource(pbcatalog.ServiceEndpointsType, "web"). - WithData(suite.T(), &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: suite.webWorkload.Id, - Addresses: webWorkloadData.Addresses, - Ports: webWorkloadData.Ports, - Identity: "web-identity", - }, - }, - }).Write(suite.T(), suite.client) - - identityRef := &pbresource.Reference{ - Name: suite.apiWorkload.Identity, - Tenancy: suite.apiWorkloadID.Tenancy, - Type: pbauth.WorkloadIdentityType, - } - - suite.proxyStateTemplate = builder.New(resource.ReplaceType(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID), - identityRef, "test.consul", "dc1", false, nil). - BuildLocalApp(suite.apiWorkload, suite.apiComputedTrafficPermissionsData). - Build() -} - -func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_NoServicesInCache() { - dataFetcher := fetcher.New(suite.client, suite.ctl.cache) - - workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-workload"). - WithData(suite.T(), &pbcatalog.Workload{ - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - }). - Build() - - decWorkload := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload) - workloadPorts, err := suite.ctl.workloadPortProtocolsFromService(suite.ctx, dataFetcher, decWorkload, suite.runtime.Logger) - require.NoError(suite.T(), err) - prototest.AssertDeepEqual(suite.T(), pbcatalog.Protocol_PROTOCOL_TCP, workloadPorts["tcp"].GetProtocol()) -} - -func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService_ServiceNotFound() { - c := cache.New() - dataFetcher := fetcher.New(suite.client, c) - ctrl := &reconciler{ - cache: c, - getTrustDomain: func() (string, error) { - return "test.consul", nil - }, - } - svc := resourcetest.Resource(pbcatalog.ServiceType, "not-found"). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"api-workload"}, - }, - }). - Build() - - decSvc := resourcetest.MustDecode[*pbcatalog.Service](suite.T(), svc) - c.TrackService(decSvc) - - workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-workload"). - WithData(suite.T(), &pbcatalog.Workload{ - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080}, - }, - }). - Build() - - decWorkload := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload) - - workloadPorts, err := ctrl.workloadPortProtocolsFromService(suite.ctx, dataFetcher, decWorkload, suite.runtime.Logger) - require.NoError(suite.T(), err) - prototest.AssertDeepEqual(suite.T(), pbcatalog.Protocol_PROTOCOL_TCP, workloadPorts["tcp"].GetProtocol()) - // Check that the service is no longer in cache. - require.Nil(suite.T(), c.ServicesForWorkload(workload.Id)) -} - -func (suite *controllerTestSuite) TestWorkloadPortProtocolsFromService() { - c := cache.New() - dataFetcher := fetcher.New(suite.client, c) - ctrl := &reconciler{ - cache: c, - getTrustDomain: func() (string, error) { - return "test.consul", nil - }, - } - svc1 := resourcetest.Resource(pbcatalog.ServiceType, "api-1"). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"api-workload"}, - }, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "http1", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "conflict", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - }). - Write(suite.T(), suite.client) - - decSvc := resourcetest.MustDecode[*pbcatalog.Service](suite.T(), svc1) - c.TrackService(decSvc) - - svc2 := resourcetest.Resource(pbcatalog.ServiceType, "api-2"). - WithData(suite.T(), &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"api-workload"}, - }, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "http2", - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, - }, - { - TargetPort: "conflict", - Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, - }, - }, - }). - Write(suite.T(), suite.client) - - decSvc = resourcetest.MustDecode[*pbcatalog.Service](suite.T(), svc2) - c.TrackService(decSvc) - - workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-workload"). - WithData(suite.T(), &pbcatalog.Workload{ - Ports: map[string]*pbcatalog.WorkloadPort{ - "http1": {Port: 8080}, - "http2": {Port: 9090}, - "conflict": {Port: 9091}, - "not-selected": {Port: 8081}, - "specified-protocol": {Port: 8082, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - - decWorkload := resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload) - - expWorkloadPorts := map[string]*pbcatalog.WorkloadPort{ - // This protocol should be inherited from service 1. - "http1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - - // this protocol should be inherited from service 2. - "http2": {Port: 9090, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - - // This port is not selected by the service and should default to tcp. - "not-selected": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - - // This port has conflicting protocols in each service and so it should default to tcp. - "conflict": {Port: 9091, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - - // These port should keep its existing protocol. - "specified-protocol": {Port: 8082, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - } - - workloadPorts, err := ctrl.workloadPortProtocolsFromService(suite.ctx, dataFetcher, decWorkload, suite.runtime.Logger) - require.NoError(suite.T(), err) - - prototest.AssertDeepEqual(suite.T(), expWorkloadPorts, workloadPorts) -} - -func (suite *controllerTestSuite) TestReconcile_NoWorkload() { - // This test ensures that removed workloads are ignored and don't result - // in the creation of the proxy state template. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: resourceID(pbmesh.ProxyStateTemplateType, "not-found"), - }) - require.NoError(suite.T(), err) - - suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "not-found")) -} - -func (suite *controllerTestSuite) TestReconcile_NonMeshWorkload() { - // This test ensures that non-mesh workloads are ignored by the controller. - - nonMeshWorkload := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - }, - } - - resourcetest.Resource(pbcatalog.WorkloadType, "test-non-mesh-api-workload"). - WithData(suite.T(), nonMeshWorkload). - Write(suite.T(), suite.client.ResourceServiceClient) - - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload"), - }) - - require.NoError(suite.T(), err) - suite.client.RequireResourceNotFound(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, "test-non-mesh-api-workload")) -} - -func (suite *controllerTestSuite) TestReconcile_NoExistingProxyStateTemplate() { - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name), - }) - require.NoError(suite.T(), err) - - res := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name)) - require.NoError(suite.T(), err) - require.NotNil(suite.T(), res.Data) - prototest.AssertDeepEqual(suite.T(), suite.apiWorkloadID, res.Owner) -} - -func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_WithUpdates() { - // This test ensures that we write a new proxy state template when there are changes. - - // Write the original. - resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc"). - WithData(suite.T(), suite.proxyStateTemplate). - WithOwner(suite.apiWorkloadID). - Write(suite.T(), suite.client.ResourceServiceClient) - - // Update the apiWorkload and check that we default the port to tcp if it's unspecified. - suite.apiWorkload.Ports["tcp"].Protocol = pbcatalog.Protocol_PROTOCOL_UNSPECIFIED - - updatedWorkloadID := resourcetest.Resource(pbcatalog.WorkloadType, "api-abc"). - WithData(suite.T(), suite.apiWorkload). - Write(suite.T(), suite.client.ResourceServiceClient).Id - - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name), - }) - require.NoError(suite.T(), err) - - res := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name)) - require.NoError(suite.T(), err) - require.NotNil(suite.T(), res.Data) - prototest.AssertDeepEqual(suite.T(), updatedWorkloadID, res.Owner) - - var updatedProxyStateTemplate pbmesh.ProxyStateTemplate - err = res.Data.UnmarshalTo(&updatedProxyStateTemplate) - require.NoError(suite.T(), err) - - // Check that our value is updated in the proxy state template. - require.Len(suite.T(), updatedProxyStateTemplate.ProxyState.Listeners, 1) - require.Len(suite.T(), updatedProxyStateTemplate.ProxyState.Listeners[0].Routers, 1) - - l4InboundRouter := updatedProxyStateTemplate.ProxyState.Listeners[0]. - Routers[0].GetL4() - require.NotNil(suite.T(), l4InboundRouter) -} - -func (suite *controllerTestSuite) TestReconcile_ExistingProxyStateTemplate_NoUpdates() { - // This test ensures that we skip writing of the proxy state template when there are no changes to it. - - // Write the original. - originalProxyState := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc"). - WithData(suite.T(), suite.proxyStateTemplate). - WithOwner(suite.apiWorkloadID). - Write(suite.T(), suite.client.ResourceServiceClient) - - // Update the metadata on the apiWorkload which should result in no changes. - updatedWorkloadID := resourcetest.Resource(pbcatalog.WorkloadType, "api-abc"). - WithData(suite.T(), suite.apiWorkload). - WithMeta("some", "meta"). - Write(suite.T(), suite.client.ResourceServiceClient).Id - - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: resourceID(pbmesh.ProxyStateTemplateType, updatedWorkloadID.Name), - }) - require.NoError(suite.T(), err) - - updatedProxyState := suite.client.RequireResourceExists(suite.T(), resourceID(pbmesh.ProxyStateTemplateType, suite.apiWorkloadID.Name)) - resourcetest.RequireVersionUnchanged(suite.T(), updatedProxyState, originalProxyState.Version) -} - -func (suite *controllerTestSuite) TestController() { - // This is a comprehensive test that checks the overall controller behavior as various resources change state. - // This should test interactions between the reconciler, the mappers, and the destinationsCache to ensure they work - // together and produce expected result. - - // Run the controller manager - mgr := controller.NewManager(suite.client, suite.runtime.Logger) - - // Initialize controller dependencies. - c := cache.New() - trustDomainFetcher := func() (string, error) { return "test.consul", nil } - - mgr.Register(Controller(c, trustDomainFetcher, "dc1", false)) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - var ( - // Create proxy state template IDs to check against in this test. - apiProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc").ID() - webProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "web-def").ID() - - apiComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, suite.apiService.Id) - dbComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, suite.dbService.Id) - - apiProxyStateTemplate *pbresource.Resource - webProxyStateTemplate *pbresource.Resource - webComputedDestinations *pbresource.Resource - ) - - testutil.RunStep(suite.T(), "proxy state template generation", func(t *testing.T) { - // Check that proxy state template resource is generated for both the api and web workloads. - retry.Run(t, func(r *retry.R) { - suite.client.RequireResourceExists(r, apiProxyStateTemplateID) - webProxyStateTemplate = suite.client.RequireResourceExists(r, webProxyStateTemplateID) - apiProxyStateTemplate = suite.client.RequireResourceExists(r, apiProxyStateTemplateID) - }) - }) - - // Write a default ComputedRoutes for api. - routestest.ReconcileComputedRoutes(suite.T(), suite.client, apiComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.apiService), - ) - - // Add a source service and check that a new proxy state is generated. - webComputedDestinations = resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webWorkload.Id.Name). - WithData(suite.T(), &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: resource.Reference(suite.apiService.Id, ""), - DestinationPort: "tcp", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1234, - }, - }, - }, - }, - }).Write(suite.T(), suite.client) - - testutil.RunStep(suite.T(), "add explicit destinations and check that new proxy state is generated", func(t *testing.T) { - webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) - - requireExplicitDestinationsFound(t, "api", webProxyStateTemplate) - }) - - testutil.RunStep(suite.T(), "update api's ports to be non-mesh", func(t *testing.T) { - // Update destination's service endpoints and workload to be non-mesh - // and check that: - // * api's proxy state template is deleted - // * we get a new web proxy resource re-generated - // * the status on Upstreams resource is updated with a validation error - nonMeshPorts := map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - } - - // Note: the order matters here because in reality service endpoints will only - // be reconciled after the workload has been updated, and so we need to write the - // workload and service before we write service endpoints. - resourcetest.Resource(pbcatalog.WorkloadType, "api-abc"). - WithData(suite.T(), &pbcatalog.Workload{ - Identity: "api-identity", - Addresses: suite.apiWorkload.Addresses, - Ports: nonMeshPorts}). - Write(suite.T(), suite.client) - - suite.apiService = resourcetest.ResourceID(suite.apiService.Id). - WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"api-abc"}}, - VirtualIps: []string{"1.1.1.1"}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - // {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }). - Write(suite.T(), suite.client) - - resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service"). - WithData(suite.T(), &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: suite.apiWorkloadID, - Addresses: suite.apiWorkload.Addresses, - Ports: nonMeshPorts, - Identity: "api-identity", - }, - }, - }). - Write(suite.T(), suite.client.ResourceServiceClient) - - // Refresh the computed routes in light of api losing a mesh port. - routestest.ReconcileComputedRoutes(suite.T(), suite.client, apiComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, suite.apiService), - ) - - // Check that api proxy template is gone. - retry.Run(t, func(r *retry.R) { - suite.client.RequireResourceNotFound(r, apiProxyStateTemplateID) - }) - - // We should get a new web proxy template resource because this destination should be removed. - webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) - - requireExplicitDestinationsNotFound(t, "api", webProxyStateTemplate) - }) - - testutil.RunStep(suite.T(), "update ports to be mesh again", func(t *testing.T) { - // Update destination's service endpoints back to mesh and check that we get a new web proxy resource re-generated - // and that the status on Upstreams resource is updated to be empty. - suite.runtime.Logger.Trace("updating ports to mesh") - - resourcetest.Resource(pbcatalog.WorkloadType, "api-abc"). - WithData(suite.T(), suite.apiWorkload). - Write(suite.T(), suite.client) - - suite.apiService = resourcetest.Resource(pbcatalog.ServiceType, "api-service"). - WithData(suite.T(), suite.apiServiceData). - Write(suite.T(), suite.client.ResourceServiceClient) - - resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-service"). - WithData(suite.T(), suite.apiEndpointsData). - Write(suite.T(), suite.client.ResourceServiceClient) - - // Refresh the computed routes in light of api losing a mesh port. - routestest.ReconcileComputedRoutes(suite.T(), suite.client, apiComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, suite.apiService), - ) - - // We should also get a new web proxy template resource as this destination should be added again. - webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) - - requireExplicitDestinationsFound(t, "api", webProxyStateTemplate) - }) - - testutil.RunStep(suite.T(), "delete the proxy state template and check re-generation", func(t *testing.T) { - // Delete the proxy state template resource and check that it gets regenerated. - suite.runtime.Logger.Trace("deleting web proxy") - _, err := suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: webProxyStateTemplateID}) - require.NoError(suite.T(), err) - - webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) - requireExplicitDestinationsFound(t, "api", webProxyStateTemplate) - }) - - testutil.RunStep(suite.T(), "add implicit upstream and enable tproxy", func(t *testing.T) { - // Delete explicit destinations resource. - suite.runtime.Logger.Trace("deleting web destinations") - _, err := suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: webComputedDestinations.Id}) - require.NoError(t, err) - - webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) - - // Write a default ComputedRoutes for db, so it's eligible. - dbCR := routestest.ReconcileComputedRoutes(suite.T(), suite.client, dbComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](t, suite.dbService), - ) - require.NotNil(t, dbCR) - - // Enable transparent proxy for the web proxy. - resourcetest.Resource(pbmesh.ComputedProxyConfigurationType, suite.webWorkload.Id.Name). - WithData(t, &pbmesh.ComputedProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - TransparentProxy: &pbmesh.TransparentProxy{ - OutboundListenerPort: 15001, - }, - }, - }).Write(suite.T(), suite.client) - - webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) - apiProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), apiProxyStateTemplateID, apiProxyStateTemplate.Version) - - requireImplicitDestinationsFound(t, "api", webProxyStateTemplate) - requireImplicitDestinationsFound(t, "db", webProxyStateTemplate) - }) - - testutil.RunStep(suite.T(), "traffic permissions", func(t *testing.T) { - // Global default deny applies to all identities. - assertTrafficPermissionDefaultPolicy(t, false, apiProxyStateTemplate) - assertTrafficPermissionDefaultPolicy(t, false, webProxyStateTemplate) - - suite.runtime.Logger.Trace("deleting computed traffic permissions") - _, err := suite.client.Delete(suite.ctx, &pbresource.DeleteRequest{Id: suite.apiComputedTrafficPermissions.Id}) - require.NoError(t, err) - suite.client.WaitForDeletion(t, suite.apiComputedTrafficPermissions.Id) - - apiProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), apiProxyStateTemplateID, apiProxyStateTemplate.Version) - - suite.runtime.Logger.Trace("creating computed traffic permissions") - resourcetest.Resource(pbauth.ComputedTrafficPermissionsType, suite.apiWorkload.Identity). - WithData(t, suite.apiComputedTrafficPermissionsData). - Write(t, suite.client) - - suite.client.WaitForNewVersion(t, apiProxyStateTemplateID, apiProxyStateTemplate.Version) - }) - - testutil.RunStep(suite.T(), "add an HTTPRoute with a simple split on the tcp port", func(t *testing.T) { - // NOTE: because at this point we have tproxy in all-to-all mode, we will get an - // implicit upstream on 'db' - - // Create a route NOT in the state store, only to more easily feed - // into the generator. - routeData := &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{{ - Ref: resource.Reference(suite.dbService.Id, ""), - Port: "", // implicitly applies to 'http' - }}, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{ - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(suite.apiService.Id, ""), - Port: "tcp", - }, - Weight: 60, - }, - { - BackendRef: &pbmesh.BackendReference{ - Ref: resource.Reference(suite.dbService.Id, ""), - Port: "", // assumed to be 'http' - }, - Weight: 40, - }, - }, - }}, - } - route := resourcetest.Resource(pbmesh.HTTPRouteType, "db-http-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, routeData). - Build() - require.NoError(t, types.MutateHTTPRoute(route)) - require.NoError(t, types.ValidateHTTPRoute(route)) - - dbCRID := resource.ReplaceType(pbmesh.ComputedRoutesType, suite.dbService.Id) - - dbCR := routestest.ReconcileComputedRoutes(suite.T(), suite.client, dbCRID, - resourcetest.MustDecode[*pbmesh.HTTPRoute](t, route), - resourcetest.MustDecode[*pbcatalog.Service](t, suite.dbService), - resourcetest.MustDecode[*pbcatalog.Service](t, suite.apiService), - ) - require.NotNil(t, dbCR, "computed routes for db was deleted instead of created") - - webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) - - requireImplicitDestinationsFound(t, "api", webProxyStateTemplate) - requireImplicitDestinationsFound(t, "db", webProxyStateTemplate) - }) -} - -func (suite *controllerTestSuite) TestControllerDefaultAllow() { - // Run the controller manager - mgr := controller.NewManager(suite.client, suite.runtime.Logger) - - // Initialize controller dependencies. - c := cache.New() - trustDomainFetcher := func() (string, error) { return "test.consul", nil } - - mgr.Register(Controller(c, trustDomainFetcher, "dc1", true)) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - var ( - // Create proxy state template IDs to check against in this test. - apiProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api-abc").ID() - webProxyStateTemplateID = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "web-def").ID() - ) - - retry.Run(suite.T(), func(r *retry.R) { - webProxyStateTemplate := suite.client.RequireResourceExists(r, webProxyStateTemplateID) - apiProxyStateTemplate := suite.client.RequireResourceExists(r, apiProxyStateTemplateID) - - // Default deny because api has non-empty computed traffic permissions. - assertTrafficPermissionDefaultPolicy(r, false, apiProxyStateTemplate) - assertTrafficPermissionDefaultPolicy(r, true, webProxyStateTemplate) - }) -} - -func TestMeshController(t *testing.T) { - suite.Run(t, new(controllerTestSuite)) -} - -func requireExplicitDestinationsFound(t *testing.T, name string, tmplResource *pbresource.Resource) { - requireExplicitDestinations(t, name, tmplResource, true) -} - -func requireExplicitDestinationsNotFound(t *testing.T, name string, tmplResource *pbresource.Resource) { - requireExplicitDestinations(t, name, tmplResource, false) -} - -func requireExplicitDestinations(t *testing.T, name string, tmplResource *pbresource.Resource, found bool) { - t.Helper() - - var tmpl pbmesh.ProxyStateTemplate - err := tmplResource.Data.UnmarshalTo(&tmpl) - require.NoError(t, err) - - // Check outbound listener. - var foundListener bool - for _, l := range tmpl.ProxyState.Listeners { - if strings.Contains(l.Name, name) && l.Direction == pbproxystate.Direction_DIRECTION_OUTBOUND { - foundListener = true - break - } - } - - require.Equal(t, found, foundListener) - - requireClustersAndEndpoints(t, name, &tmpl, found) -} - -func requireImplicitDestinationsFound(t *testing.T, name string, tmplResource *pbresource.Resource) { - t.Helper() - - var tmpl pbmesh.ProxyStateTemplate - err := tmplResource.Data.UnmarshalTo(&tmpl) - require.NoError(t, err) - - // Check outbound listener. - var foundListener bool - for _, l := range tmpl.ProxyState.Listeners { - if strings.Contains(l.Name, xdscommon.OutboundListenerName) && l.Direction == pbproxystate.Direction_DIRECTION_OUTBOUND { - foundListener = true - - // Check the listener filter chain - for _, r := range l.Routers { - foundByName := false - switch x := r.Destination.(type) { - case *pbproxystate.Router_L4: - // TcpProxy is easy, so just having this exist is - // sufficient. We don't have to deep inspect it. We care - // that there IS a listener matching the destination. If - // there is a TCPRoute with a split or a rename we don't - // care here. - foundByName = true - case *pbproxystate.Router_L7: - require.NotNil(t, x.L7.Route) - routerName := x.L7.Route.Name - foundByName = strings.Contains(routerName, name) - default: - t.Fatalf("unexpected type of destination: %T", r.Destination) - } - - if foundByName { - // We expect that there is a filter chain match for transparent proxy destinations. - require.NotNil(t, r.Match) - require.NotEmpty(t, r.Match.PrefixRanges) - break - } - } - break - } - } - require.True(t, foundListener) - - requireClustersAndEndpoints(t, name, &tmpl, true) -} - -func requireClustersAndEndpoints(t *testing.T, name string, tmpl *pbmesh.ProxyStateTemplate, found bool) { - t.Helper() - - var foundCluster bool - for c := range tmpl.ProxyState.Clusters { - if strings.Contains(c, name) { - foundCluster = true - break - } - } - - require.Equal(t, found, foundCluster) - - var foundEndpoints bool - for c := range tmpl.RequiredEndpoints { - if strings.Contains(c, name) { - foundEndpoints = true - break - } - } - - require.Equal(t, found, foundEndpoints) -} - -func resourceID(rtype *pbresource.Type, name string) *pbresource.ID { - return &pbresource.ID{ - Type: rtype, - Tenancy: &pbresource.Tenancy{ - Partition: "default", - Namespace: "default", - PeerName: "local", - }, - Name: name, - } -} - -func assertTrafficPermissionDefaultPolicy(t resourcetest.T, defaultAllow bool, resource *pbresource.Resource) { - dec := resourcetest.MustDecode[*pbmesh.ProxyStateTemplate](t, resource) - var listener *pbproxystate.Listener - for _, l := range dec.Data.ProxyState.Listeners { - if l.Name == "public_listener" { - listener = l - break - } - } - require.Len(t, listener.Routers, 1) - l4 := listener.Routers[0].GetL4() - require.NotNil(t, l4) - require.Equal(t, defaultAllow, l4.TrafficPermissions.DefaultAllow) -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/fetcher/data_fetcher.go b/internal/mesh/internal/controllers/sidecarproxy/fetcher/data_fetcher.go deleted file mode 100644 index 7a31798a244b5..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/fetcher/data_fetcher.go +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package fetcher - -import ( - "context" - "fmt" - "strings" - - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache" - "github.com/hashicorp/consul/internal/mesh/internal/types" - intermediateTypes "github.com/hashicorp/consul/internal/mesh/internal/types/intermediate" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/storage" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type Fetcher struct { - client pbresource.ResourceServiceClient - cache *cache.Cache -} - -func New(client pbresource.ResourceServiceClient, cache *cache.Cache) *Fetcher { - return &Fetcher{ - client: client, - cache: cache, - } -} - -func (f *Fetcher) FetchWorkload(ctx context.Context, id *pbresource.ID) (*types.DecodedWorkload, error) { - dec, err := resource.GetDecodedResource[*pbcatalog.Workload](ctx, f.client, id) - if err != nil { - return nil, err - } else if dec == nil { - // We also need to make sure to delete the associated proxy from cache. - f.cache.UntrackWorkload(id) - return nil, nil - } - - f.cache.TrackWorkload(dec) - - return dec, err -} - -func (f *Fetcher) FetchProxyStateTemplate(ctx context.Context, id *pbresource.ID) (*types.DecodedProxyStateTemplate, error) { - return resource.GetDecodedResource[*pbmesh.ProxyStateTemplate](ctx, f.client, id) -} - -func (f *Fetcher) FetchComputedTrafficPermissions(ctx context.Context, id *pbresource.ID) (*types.DecodedComputedTrafficPermissions, error) { - return resource.GetDecodedResource[*pbauth.ComputedTrafficPermissions](ctx, f.client, id) -} - -func (f *Fetcher) FetchServiceEndpoints(ctx context.Context, id *pbresource.ID) (*types.DecodedServiceEndpoints, error) { - return resource.GetDecodedResource[*pbcatalog.ServiceEndpoints](ctx, f.client, id) -} - -func (f *Fetcher) FetchService(ctx context.Context, id *pbresource.ID) (*types.DecodedService, error) { - return resource.GetDecodedResource[*pbcatalog.Service](ctx, f.client, id) -} - -func (f *Fetcher) FetchDestinations(ctx context.Context, id *pbresource.ID) (*types.DecodedDestinations, error) { - return resource.GetDecodedResource[*pbmesh.Destinations](ctx, f.client, id) -} - -func (f *Fetcher) FetchComputedRoutes(ctx context.Context, id *pbresource.ID) (*types.DecodedComputedRoutes, error) { - if !types.IsComputedRoutesType(id.Type) { - return nil, fmt.Errorf("id must be a ComputedRoutes type") - } - - dec, err := resource.GetDecodedResource[*pbmesh.ComputedRoutes](ctx, f.client, id) - if err != nil { - return nil, err - } else if dec == nil { - f.cache.UntrackComputedRoutes(id) - } - - return dec, err -} - -func (f *Fetcher) FetchExplicitDestinationsData( - ctx context.Context, - proxyID *pbresource.ID, -) ([]*intermediateTypes.Destination, error) { - - var destinations []*intermediateTypes.Destination - - // Fetch computed explicit destinations first. - cdID := resource.ReplaceType(pbmesh.ComputedExplicitDestinationsType, proxyID) - cd, err := resource.GetDecodedResource[*pbmesh.ComputedExplicitDestinations](ctx, f.client, cdID) - if err != nil { - return nil, err - } - if cd == nil { - f.cache.UntrackComputedDestinations(cdID) - return nil, nil - } - - // Otherwise, track this resource in the destinations cache. - f.cache.TrackComputedDestinations(cd) - - for _, dest := range cd.GetData().GetDestinations() { - d := &intermediateTypes.Destination{} - - var ( - serviceID = resource.IDFromReference(dest.DestinationRef) - ) - - // Fetch Service - svc, err := f.FetchService(ctx, serviceID) - if err != nil { - return nil, err - } - - if svc == nil { - // If the Service resource is not found, skip this destination. - continue - } - - d.Service = svc - - // Check if this service is mesh-enabled. If not, update the status. - if !svc.GetData().IsMeshEnabled() { - // This error should not cause the execution to stop, as we want to make sure that this non-mesh destination - // service gets removed from the proxy state. - continue - } - - // Check if the desired port exists on the service and skip it doesn't. - if svc.GetData().FindServicePort(dest.DestinationPort) == nil { - continue - } - - // No destination port should point to a port with "mesh" protocol, - // so check if destination port has the mesh protocol and skip it if it does. - if svc.GetData().FindServicePort(dest.DestinationPort).GetProtocol() == pbcatalog.Protocol_PROTOCOL_MESH { - continue - } - - // Fetch ComputedRoutes. - cr, err := f.FetchComputedRoutes(ctx, resource.ReplaceType(pbmesh.ComputedRoutesType, serviceID)) - if err != nil { - return nil, err - } else if cr == nil { - // This is required, so wait until it exists. - continue - } - - portConfig, ok := cr.Data.PortedConfigs[dest.DestinationPort] - if !ok { - // This is required, so wait until it exists. - continue - } - - // Copy this so we can mutate the targets. - d.ComputedPortRoutes = proto.Clone(portConfig).(*pbmesh.ComputedPortRoutes) - - // As Destinations resource contains a list of destinations, - // we need to find the one that references our service and port. - d.Explicit = dest - - // NOTE: we collect both DIRECT and INDIRECT target information here. - for _, routeTarget := range d.ComputedPortRoutes.Targets { - targetServiceID := resource.IDFromReference(routeTarget.BackendRef.Ref) - - // Fetch ServiceEndpoints. - se, err := f.FetchServiceEndpoints(ctx, resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID)) - if err != nil { - return nil, err - } - - if se != nil { - routeTarget.ServiceEndpointsId = se.Resource.Id - routeTarget.ServiceEndpoints = se.Data - - // Gather all identities. - var identities []*pbresource.Reference - for _, identity := range se.GetData().GetIdentities() { - identities = append(identities, &pbresource.Reference{ - Name: identity, - Tenancy: se.Resource.Id.Tenancy, - }) - } - routeTarget.IdentityRefs = identities - } - } - - destinations = append(destinations, d) - } - - return destinations, nil -} - -type PortReferenceKey struct { - resource.ReferenceKey - Port string -} - -// FetchImplicitDestinationsData fetches all implicit destinations and adds them to existing destinations. -// If the implicit destination is already in addToDestinations, it will be skipped. -// todo (ishustava): this function will eventually need to fetch implicit destinations from the ImplicitDestinations resource instead. -func (f *Fetcher) FetchImplicitDestinationsData( - ctx context.Context, - proxyID *pbresource.ID, - addToDestinations []*intermediateTypes.Destination, -) ([]*intermediateTypes.Destination, error) { - // First, convert existing destinations to a map so we can de-dup. - // - // This is keyed by the serviceID+port of the upstream, which is effectively - // the same as the id of the computed routes for the service. - destinations := make(map[PortReferenceKey]*intermediateTypes.Destination) - for _, d := range addToDestinations { - prk := PortReferenceKey{ - ReferenceKey: resource.NewReferenceKey(d.Service.Resource.Id), - Port: d.ComputedPortRoutes.ParentRef.Port, - } - destinations[prk] = d - } - - // For now we need to look up all computed routes within a partition. - rsp, err := f.client.List(ctx, &pbresource.ListRequest{ - Type: pbmesh.ComputedRoutesType, - Tenancy: &pbresource.Tenancy{ - Namespace: storage.Wildcard, - Partition: proxyID.Tenancy.Partition, - PeerName: proxyID.Tenancy.PeerName, - }, - }) - if err != nil { - return nil, err - } - - for _, r := range rsp.Resources { - svcID := resource.ReplaceType(pbcatalog.ServiceType, r.Id) - computedRoutes, err := resource.Decode[*pbmesh.ComputedRoutes](r) - if err != nil { - return nil, err - } - - if computedRoutes == nil { - // the routes-controller doesn't deem this worthy of the mesh - continue - } - - // Fetch the service. - // todo (ishustava): this should eventually grab virtual IPs resource. - svc, err := f.FetchService(ctx, resource.ReplaceType(pbcatalog.ServiceType, r.Id)) - if err != nil { - return nil, err - } - if svc == nil { - // If service no longer exists, skip. - continue - } - - // If this proxy is a part of this service, ignore it. - if isPartOfService(resource.ReplaceType(pbcatalog.WorkloadType, proxyID), svc) { - continue - } - - inMesh := false - for _, port := range svc.Data.Ports { - if port.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { - inMesh = true - break - } - } - - if !inMesh { - // If a service is no longer in the mesh, skip. - continue - } - - // Fetch the resources that may show up duplicated. - // - // NOTE: we collect both DIRECT and INDIRECT target information here. - endpointsMap := make(map[resource.ReferenceKey]*types.DecodedServiceEndpoints) - for _, portConfig := range computedRoutes.Data.PortedConfigs { - for _, routeTarget := range portConfig.Targets { - targetServiceID := resource.IDFromReference(routeTarget.BackendRef.Ref) - - seID := resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID) - seRK := resource.NewReferenceKey(seID) - - if _, ok := endpointsMap[seRK]; !ok { - se, err := f.FetchServiceEndpoints(ctx, seID) - if err != nil { - return nil, err - } - // We only add the endpoint to the map if it's not nil. If it's missing on lookup now, the - // controller should get triggered when the endpoint exists again since it watches service - // endpoints. - if se != nil { - endpointsMap[seRK] = se - } - } - } - } - - for portName, portConfig := range computedRoutes.Data.PortedConfigs { - // If it's already in destinations, ignore it. - prk := PortReferenceKey{ - ReferenceKey: resource.NewReferenceKey(svcID), - Port: portName, - } - if _, ok := destinations[prk]; ok { - continue - } - - // Copy this so we can mutate the targets. - portConfig = proto.Clone(portConfig).(*pbmesh.ComputedPortRoutes) - - d := &intermediateTypes.Destination{ - Service: svc, - ComputedPortRoutes: portConfig, - VirtualIPs: svc.Data.VirtualIps, - } - for _, routeTarget := range portConfig.Targets { - targetServiceID := resource.IDFromReference(routeTarget.BackendRef.Ref) - seID := resource.ReplaceType(pbcatalog.ServiceEndpointsType, targetServiceID) - - // Fetch ServiceEndpoints. - se, ok := endpointsMap[resource.NewReferenceKey(seID)] - if ok { - routeTarget.ServiceEndpointsId = se.Resource.Id - routeTarget.ServiceEndpoints = se.Data - - // Gather all identities. - var identities []*pbresource.Reference - for _, ep := range se.Data.Endpoints { - identities = append(identities, &pbresource.Reference{ - Name: ep.Identity, - Tenancy: se.Resource.Id.Tenancy, - }) - } - routeTarget.IdentityRefs = identities - } - } - addToDestinations = append(addToDestinations, d) - } - } - return addToDestinations, err -} - -// FetchComputedProxyConfiguration fetches proxy configurations for the proxy state template provided by id -// and merges them into one object. -func (f *Fetcher) FetchComputedProxyConfiguration(ctx context.Context, id *pbresource.ID) (*types.DecodedComputedProxyConfiguration, error) { - compProxyCfgID := resource.ReplaceType(pbmesh.ComputedProxyConfigurationType, id) - - return resource.GetDecodedResource[*pbmesh.ComputedProxyConfiguration](ctx, f.client, compProxyCfgID) -} - -func isPartOfService(workloadID *pbresource.ID, svc *types.DecodedService) bool { - if !resource.EqualTenancy(workloadID.GetTenancy(), svc.Resource.Id.GetTenancy()) { - return false - } - sel := svc.Data.Workloads - for _, exact := range sel.GetNames() { - if workloadID.GetName() == exact { - return true - } - } - for _, prefix := range sel.GetPrefixes() { - if strings.HasPrefix(workloadID.GetName(), prefix) { - return true - } - } - return false -} diff --git a/internal/mesh/internal/controllers/sidecarproxy/fetcher/data_fetcher_test.go b/internal/mesh/internal/controllers/sidecarproxy/fetcher/data_fetcher_test.go deleted file mode 100644 index 457fa393b43f1..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/fetcher/data_fetcher_test.go +++ /dev/null @@ -1,598 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package fetcher - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/routes/routestest" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/sidecarproxy/cache" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/mesh/internal/types/intermediate" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -type dataFetcherSuite struct { - suite.Suite - - ctx context.Context - client pbresource.ResourceServiceClient - rt controller.Runtime - - api1Service *pbresource.Resource - api1ServiceData *pbcatalog.Service - api2Service *pbresource.Resource - api2ServiceData *pbcatalog.Service - api1ServiceEndpoints *pbresource.Resource - api1ServiceEndpointsData *pbcatalog.ServiceEndpoints - api2ServiceEndpoints *pbresource.Resource - api2ServiceEndpointsData *pbcatalog.ServiceEndpoints - webComputedDestinationsData *pbmesh.ComputedExplicitDestinations - webProxy *pbresource.Resource - webWorkload *pbresource.Resource -} - -func (suite *dataFetcherSuite) SetupTest() { - suite.ctx = testutil.TestContext(suite.T()) - suite.client = svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes) - suite.rt = controller.Runtime{ - Client: suite.client, - Logger: testutil.Logger(suite.T()), - } - - suite.api1ServiceData = &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", VirtualPort: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - suite.api1Service = resourcetest.Resource(pbcatalog.ServiceType, "api-1"). - WithData(suite.T(), suite.api1ServiceData). - Write(suite.T(), suite.client) - - suite.api1ServiceEndpointsData = &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - Addresses: []*pbcatalog.WorkloadAddress{{Host: "10.0.0.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - Identity: "api-1-identity", - }, - }, - } - suite.api1ServiceEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-1"). - WithData(suite.T(), suite.api1ServiceEndpointsData). - Write(suite.T(), suite.client) - - suite.api2ServiceData = &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp1", VirtualPort: 9080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "tcp2", VirtualPort: 9081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", VirtualPort: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - suite.api2Service = resourcetest.Resource(pbcatalog.ServiceType, "api-2"). - WithData(suite.T(), suite.api2ServiceData). - Write(suite.T(), suite.client) - - suite.api2ServiceEndpointsData = &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - Addresses: []*pbcatalog.WorkloadAddress{{Host: "10.0.0.2"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp1": {Port: 9080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "tcp2": {Port: 9081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - Identity: "api-2-identity", - }, - }, - } - suite.api2ServiceEndpoints = resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-2"). - WithData(suite.T(), suite.api2ServiceEndpointsData). - Write(suite.T(), suite.client) - - suite.webComputedDestinationsData = &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: resource.Reference(suite.api1Service.Id, ""), - DestinationPort: "tcp", - }, - { - DestinationRef: resource.Reference(suite.api2Service.Id, ""), - DestinationPort: "tcp1", - }, - { - DestinationRef: resource.Reference(suite.api2Service.Id, ""), - DestinationPort: "tcp2", - }, - }, - } - - suite.webProxy = resourcetest.Resource(pbmesh.ProxyStateTemplateType, "web-abc"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{}). - Write(suite.T(), suite.client) - - suite.webWorkload = resourcetest.Resource(pbcatalog.WorkloadType, "web-abc"). - WithData(suite.T(), &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "10.0.0.2"}}, - Ports: map[string]*pbcatalog.WorkloadPort{"tcp": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}}, - }). - Write(suite.T(), suite.client) -} - -func (suite *dataFetcherSuite) TestFetcher_FetchWorkload_WorkloadNotFound() { - identityID := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-abc").ID() - - // Create cache and pre-populate it. - c := cache.New() - - f := Fetcher{ - cache: c, - client: suite.client, - } - - workloadID := resourcetest.Resource(pbcatalog.WorkloadType, "not-found").ID() - - // Track workload with its identity. - workload := resourcetest.Resource(pbcatalog.WorkloadType, workloadID.GetName()). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), &pbcatalog.Workload{ - Identity: identityID.Name, - }).Build() - - c.TrackWorkload(resourcetest.MustDecode[*pbcatalog.Workload](suite.T(), workload)) - - // Now fetch the workload so that we can check that it's been removed from cache. - _, err := f.FetchWorkload(context.Background(), workloadID) - require.NoError(suite.T(), err) - require.Nil(suite.T(), c.WorkloadsByWorkloadIdentity(identityID)) -} - -func (suite *dataFetcherSuite) TestFetcher_FetchWorkload_WorkloadFound() { - identityID := resourcetest.Resource(pbauth.WorkloadIdentityType, "workload-identity-abc").ID() - - // Create cache and pre-populate it. - c := cache.New() - - f := Fetcher{ - cache: c, - client: suite.client, - } - - workload := resourcetest.Resource(pbcatalog.WorkloadType, "service-workload-abc"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), &pbcatalog.Workload{ - Identity: identityID.Name, - Ports: map[string]*pbcatalog.WorkloadPort{ - "foo": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.0.0.1", - Ports: []string{"foo"}, - }, - }, - }).Write(suite.T(), suite.client) - - // This call should track the workload's identity - _, err := f.FetchWorkload(context.Background(), workload.Id) - require.NoError(suite.T(), err) - - // Check that the workload is tracked - workload.Id.Uid = "" - prototest.AssertElementsMatch(suite.T(), []*pbresource.ID{workload.Id}, c.WorkloadsByWorkloadIdentity(identityID)) -} - -func (suite *dataFetcherSuite) TestFetcher_FetchExplicitDestinationsData() { - c := cache.New() - - var ( - api1ServiceRef = resource.Reference(suite.api1Service.Id, "") - ) - - f := Fetcher{ - cache: c, - client: suite.client, - } - - testutil.RunStep(suite.T(), "computed destinations not found", func(t *testing.T) { - // First add computed destination to cache so we can check if it's untracked later. - compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: api1ServiceRef, - DestinationPort: "tcp1", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - c.TrackComputedDestinations(resourcetest.MustDecode[*pbmesh.ComputedExplicitDestinations](t, compDest)) - - // We will try to fetch explicit destinations for a proxy that doesn't have one. - destinations, err := f.FetchExplicitDestinationsData(suite.ctx, suite.webProxy.Id) - require.NoError(t, err) - require.Nil(t, destinations) - - // Check that cache no longer has this destination. - require.Nil(t, c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef))) - }) - - testutil.RunStep(suite.T(), "invalid destinations: service not found", func(t *testing.T) { - notFoundServiceRef := resourcetest.Resource(pbcatalog.ServiceType, "not-found"). - WithTenancy(resource.DefaultNamespacedTenancy()). - ReferenceNoSection() - - compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: notFoundServiceRef, - DestinationPort: "tcp", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Write(t, suite.client) - - destinations, err := f.FetchExplicitDestinationsData(suite.ctx, suite.webProxy.Id) - require.NoError(t, err) - require.Nil(t, destinations) - cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(notFoundServiceRef)) - compDest.Id.Uid = "" - prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs) - }) - - testutil.RunStep(suite.T(), "invalid destinations: service not on mesh", func(t *testing.T) { - apiNonMeshServiceData := &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - }, - } - resourcetest.ResourceID(suite.api1Service.Id). - WithData(t, apiNonMeshServiceData). - Write(t, suite.client) - compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: api1ServiceRef, - DestinationPort: "tcp", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Write(t, suite.client) - - destinations, err := f.FetchExplicitDestinationsData(suite.ctx, suite.webProxy.Id) - require.NoError(t, err) - require.Nil(t, destinations) - cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef)) - compDest.Id.Uid = "" - prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs) - }) - - testutil.RunStep(suite.T(), "invalid destinations: destination port not found", func(t *testing.T) { - resourcetest.ResourceID(suite.api1Service.Id). - WithData(t, &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "some-other-port", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }). - Write(t, suite.client) - compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: api1ServiceRef, - DestinationPort: "tcp", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Write(t, suite.client) - - destinations, err := f.FetchExplicitDestinationsData(suite.ctx, suite.webProxy.Id) - require.NoError(t, err) - require.Nil(t, destinations) - cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef)) - compDest.Id.Uid = "" - prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs) - }) - - suite.api1Service = resourcetest.ResourceID(suite.api1Service.Id). - WithData(suite.T(), suite.api1ServiceData). - Write(suite.T(), suite.client) - - suite.api2Service = resourcetest.ResourceID(suite.api2Service.Id). - WithData(suite.T(), suite.api2ServiceData). - Write(suite.T(), suite.client) - - testutil.RunStep(suite.T(), "invalid destinations: destination is pointing to a mesh port", func(t *testing.T) { - // Create a computed destinations resource pointing to the mesh port. - compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name). - WithData(t, &pbmesh.ComputedExplicitDestinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: api1ServiceRef, - DestinationPort: "mesh", - }, - }, - }). - WithTenancy(resource.DefaultNamespacedTenancy()). - Write(t, suite.client) - - destinations, err := f.FetchExplicitDestinationsData(suite.ctx, suite.webProxy.Id) - require.NoError(t, err) - require.Empty(t, destinations) - - cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef)) - compDest.Id.Uid = "" - prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs) - }) - - compDest := resourcetest.Resource(pbmesh.ComputedExplicitDestinationsType, suite.webProxy.Id.Name). - WithData(suite.T(), suite.webComputedDestinationsData). - WithTenancy(resource.DefaultNamespacedTenancy()). - Write(suite.T(), suite.client) - - testutil.RunStep(suite.T(), "invalid destinations: destination is pointing to a port but computed routes is not aware of it yet", func(t *testing.T) { - apiNonTCPServiceData := &pbcatalog.Service{ - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "http", Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - } - apiNonTCPService := resourcetest.ResourceID(suite.api1Service.Id). - WithData(t, apiNonTCPServiceData). - Build() - - api1ComputedRoutesID := resource.ReplaceType(pbmesh.ComputedRoutesType, suite.api1Service.Id) - api1ComputedRoutes := routestest.ReconcileComputedRoutes(suite.T(), suite.client, api1ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), apiNonTCPService), - ) - require.NotNil(suite.T(), api1ComputedRoutes) - - // This destination points to TCP, but the computed routes is stale and only knows about HTTP. - destinations, err := f.FetchExplicitDestinationsData(suite.ctx, suite.webProxy.Id) - require.NoError(t, err) - - // Check that we didn't return any destinations. - require.Nil(t, destinations) - - // Check that destination service is still in cache because it's still referenced from the pbmesh.Destinations - // resource. - cachedCompDestIDs := c.ComputedDestinationsByService(resource.IDFromReference(api1ServiceRef)) - compDest.Id.Uid = "" - prototest.AssertElementsMatch(t, []*pbresource.ID{compDest.Id}, cachedCompDestIDs) - }) - - testutil.RunStep(suite.T(), "happy path", func(t *testing.T) { - // Write a default ComputedRoutes for api1 and api2. - var ( - api1ComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, suite.api1Service.Id) - api2ComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, suite.api2Service.Id) - ) - api1ComputedRoutes := routestest.ReconcileComputedRoutes(suite.T(), suite.client, api1ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api1Service), - ) - require.NotNil(suite.T(), api1ComputedRoutes) - api2ComputedRoutes := routestest.ReconcileComputedRoutes(suite.T(), suite.client, api2ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api2Service), - ) - require.NotNil(suite.T(), api2ComputedRoutes) - - resourcetest.ResourceID(suite.api1Service.Id) - - expectedDestinations := []*intermediate.Destination{ - { - Explicit: suite.webComputedDestinationsData.Destinations[0], - Service: resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api1Service), - ComputedPortRoutes: routestest.MutateTargets(suite.T(), api1ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(suite.api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api1ServiceEndpoints) - details.ServiceEndpointsId = se.Resource.Id - details.ServiceEndpoints = se.Data - details.IdentityRefs = []*pbresource.Reference{{ - Name: "api-1-identity", - Tenancy: suite.api1Service.Id.Tenancy, - }} - } - }), - }, - { - Explicit: suite.webComputedDestinationsData.Destinations[1], - Service: resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api2Service), - ComputedPortRoutes: routestest.MutateTargets(suite.T(), api2ComputedRoutes.Data, "tcp1", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(suite.api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp1": - se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api2ServiceEndpoints) - details.ServiceEndpointsId = se.Resource.Id - details.ServiceEndpoints = se.Data - details.IdentityRefs = []*pbresource.Reference{{ - Name: "api-2-identity", - Tenancy: suite.api2Service.Id.Tenancy, - }} - } - }), - }, - { - Explicit: suite.webComputedDestinationsData.Destinations[2], - Service: resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api2Service), - ComputedPortRoutes: routestest.MutateTargets(suite.T(), api2ComputedRoutes.Data, "tcp2", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(suite.api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2": - se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api2ServiceEndpoints) - details.ServiceEndpointsId = se.Resource.Id - details.ServiceEndpoints = se.Data - details.IdentityRefs = []*pbresource.Reference{{ - Name: "api-2-identity", - Tenancy: suite.api2Service.Id.Tenancy, - }} - } - }), - }, - } - - actualDestinations, err := f.FetchExplicitDestinationsData(suite.ctx, suite.webProxy.Id) - require.NoError(t, err) - - // Check that we've computed expanded destinations correctly. - prototest.AssertElementsMatch(t, expectedDestinations, actualDestinations) - }) -} - -func (suite *dataFetcherSuite) TestFetcher_FetchImplicitDestinationsData() { - // Create a few other services to be implicit upstreams. - api3Service := resourcetest.Resource(pbcatalog.ServiceType, "api-3"). - WithData(suite.T(), &pbcatalog.Service{ - VirtualIps: []string{"192.1.1.1"}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", VirtualPort: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", VirtualPort: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }). - Write(suite.T(), suite.client) - - api3ServiceEndpointsData := &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - TargetRef: &pbresource.ID{ - Name: "api-3-abc", - Tenancy: api3Service.Id.Tenancy, - Type: pbcatalog.WorkloadType, - }, - Addresses: []*pbcatalog.WorkloadAddress{{Host: "10.0.0.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - Identity: "api-3-identity", - }, - }, - } - api3ServiceEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "api-3"). - WithData(suite.T(), api3ServiceEndpointsData). - Write(suite.T(), suite.client) - - // Write a default ComputedRoutes for api1, api2, and api3. - var ( - api1ComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, suite.api1Service.Id) - api2ComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, suite.api2Service.Id) - api3ComputedRoutesID = resource.ReplaceType(pbmesh.ComputedRoutesType, api3Service.Id) - ) - api1ComputedRoutes := routestest.ReconcileComputedRoutes(suite.T(), suite.client, api1ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api1Service), - ) - require.NotNil(suite.T(), api1ComputedRoutes) - api2ComputedRoutes := routestest.ReconcileComputedRoutes(suite.T(), suite.client, api2ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api2Service), - ) - require.NotNil(suite.T(), api2ComputedRoutes) - api3ComputedRoutes := routestest.ReconcileComputedRoutes(suite.T(), suite.client, api3ComputedRoutesID, - resourcetest.MustDecode[*pbcatalog.Service](suite.T(), api3Service), - ) - require.NotNil(suite.T(), api3ComputedRoutes) - - existingDestinations := []*intermediate.Destination{ - { - Explicit: suite.webComputedDestinationsData.Destinations[0], - Service: resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api1Service), - ComputedPortRoutes: routestest.MutateTargets(suite.T(), api1ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(suite.api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api1ServiceEndpoints) - details.ServiceEndpointsId = se.Resource.Id - details.ServiceEndpoints = se.Data - details.IdentityRefs = []*pbresource.Reference{{ - Name: "api-1-identity", - Tenancy: suite.api1Service.Id.Tenancy, - }} - } - }), - }, - { - Explicit: suite.webComputedDestinationsData.Destinations[1], - Service: resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api2Service), - ComputedPortRoutes: routestest.MutateTargets(suite.T(), api2ComputedRoutes.Data, "tcp1", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(suite.api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp1": - se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api2ServiceEndpoints) - details.ServiceEndpointsId = se.Resource.Id - details.ServiceEndpoints = se.Data - details.IdentityRefs = []*pbresource.Reference{{ - Name: "api-2-identity", - Tenancy: suite.api1Service.Id.Tenancy, - }} - } - }), - }, - { - Explicit: suite.webComputedDestinationsData.Destinations[2], - Service: resourcetest.MustDecode[*pbcatalog.Service](suite.T(), suite.api2Service), - ComputedPortRoutes: routestest.MutateTargets(suite.T(), api2ComputedRoutes.Data, "tcp2", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(suite.api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2": - se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), suite.api2ServiceEndpoints) - details.ServiceEndpointsId = se.Resource.Id - details.ServiceEndpoints = se.Data - details.IdentityRefs = []*pbresource.Reference{{ - Name: "api-2-identity", - Tenancy: suite.api1Service.Id.Tenancy, - }} - } - }), - }, - { - // implicit - Service: resourcetest.MustDecode[*pbcatalog.Service](suite.T(), api3Service), - ComputedPortRoutes: routestest.MutateTargets(suite.T(), api3ComputedRoutes.Data, "tcp", func(t *testing.T, details *pbmesh.BackendTargetDetails) { - switch { - case resource.ReferenceOrIDMatch(api3Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp": - se := resourcetest.MustDecode[*pbcatalog.ServiceEndpoints](suite.T(), api3ServiceEndpoints) - details.ServiceEndpointsId = se.Resource.Id - details.ServiceEndpoints = se.Data - details.IdentityRefs = []*pbresource.Reference{{ - Name: "api-3-identity", - Tenancy: suite.api1Service.Id.Tenancy, - }} - } - }), - VirtualIPs: []string{"192.1.1.1"}, - }, - } - - f := Fetcher{ - client: suite.client, - } - - actualDestinations, err := f.FetchImplicitDestinationsData(context.Background(), suite.webProxy.Id, existingDestinations) - require.NoError(suite.T(), err) - - prototest.AssertElementsMatch(suite.T(), existingDestinations, actualDestinations) -} - -func TestDataFetcher(t *testing.T) { - suite.Run(t, new(dataFetcherSuite)) -} diff --git a/internal/mesh/internal/controllers/xds/controller.go b/internal/mesh/internal/controllers/xds/controller.go deleted file mode 100644 index 678cfd0539d8d..0000000000000 --- a/internal/mesh/internal/controllers/xds/controller.go +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "context" - "fmt" - "time" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/cacheshim" - "github.com/hashicorp/consul/agent/leafcert" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/xds/status" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - "github.com/hashicorp/consul/lib" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ControllerName = "consul.io/xds-controller" - -const defaultTenancy = "default" - -func Controller(endpointsMapper *bimapper.Mapper, updater ProxyUpdater, fetcher TrustBundleFetcher, leafCertManager *leafcert.Manager, leafMapper *LeafMapper, leafCancels *LeafCancels, datacenter string) controller.Controller { - leafCertEvents := make(chan controller.Event, 1000) - if endpointsMapper == nil || fetcher == nil || leafCertManager == nil || leafMapper == nil || datacenter == "" { - panic("endpointsMapper, updater, fetcher, leafCertManager, leafMapper, and datacenter are required") - } - - return controller.ForType(pbmesh.ProxyStateTemplateType). - WithWatch(pbcatalog.ServiceEndpointsType, endpointsMapper.MapLink). - WithCustomWatch(proxySource(updater), proxyMapper). - WithCustomWatch(&controller.Source{Source: leafCertEvents}, leafMapper.EventMapLink). - WithPlacement(controller.PlacementEachServer). - WithReconciler(&xdsReconciler{endpointsMapper: endpointsMapper, updater: updater, fetchTrustBundle: fetcher, leafCertManager: leafCertManager, leafCancels: leafCancels, leafCertEvents: leafCertEvents, leafMapper: leafMapper, datacenter: datacenter}) -} - -type xdsReconciler struct { - // Fields for fetching and watching endpoints. - endpointsMapper *bimapper.Mapper - // Fields for proxy management. - updater ProxyUpdater - // Fields for fetching and watching trust bundles. - fetchTrustBundle TrustBundleFetcher - // Fields for fetching and watching leaf certificates. - leafCertManager *leafcert.Manager - leafMapper *LeafMapper - leafCancels *LeafCancels - leafCertEvents chan controller.Event - datacenter string -} - -type TrustBundleFetcher func() (*pbproxystate.TrustBundle, error) - -// ProxyUpdater is an interface that defines the ability to push proxy updates to the updater -// and also check its connectivity to the server. -type ProxyUpdater interface { - // PushChange allows pushing a computed ProxyState to xds for xds resource generation to send to a proxy. - PushChange(id *pbresource.ID, snapshot proxysnapshot.ProxySnapshot) error - - // ProxyConnectedToServer returns whether this id is connected to this server. - ProxyConnectedToServer(id *pbresource.ID) (string, bool) - - // EventChannel returns a channel of events that are consumed by the Custom Watcher. - EventChannel() chan controller.Event -} - -func (r *xdsReconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error { - rt.Logger = rt.Logger.With("resource-id", req.ID, "controller", ControllerName) - - rt.Logger.Trace("reconciling proxy state template", "id", req.ID) - - // Get the ProxyStateTemplate. - proxyStateTemplate, err := getProxyStateTemplate(ctx, rt, req.ID) - if err != nil { - rt.Logger.Error("error reading proxy state template", "error", err) - return err - } - - token, proxyConnected := r.updater.ProxyConnectedToServer(req.ID) - - if proxyStateTemplate == nil || proxyStateTemplate.Template == nil || !proxyConnected { - rt.Logger.Trace("proxy state template has been deleted or this controller is not responsible for this proxy state template", "id", req.ID) - - // If the proxy state template (PST) was deleted, we should: - // 1. Remove references from endpoints mapper. - // 2. Remove references from leaf mapper. - // 3. Cancel all leaf watches. - - // 1. Remove PST from endpoints mapper. - r.endpointsMapper.UntrackItem(req.ID) - // Grab the leafs related to this PST before untracking the PST so we know which ones to cancel. - leafLinks := r.leafMapper.LinkRefsForItem(req.ID) - // 2. Remove PST from leaf mapper. - r.leafMapper.UntrackItem(req.ID) - - // 3. Cancel watches for leafs that were related to this PST as long as it's not referenced by any other PST. - r.cancelWatches(leafLinks) - - return nil - } - - var ( - statusCondition *pbresource.Condition - pstResource *pbresource.Resource - ) - pstResource = proxyStateTemplate.Resource - - if proxyStateTemplate.Template.ProxyState == nil { - rt.Logger.Error("proxy state was missing from proxy state template") - // Set the status. - statusCondition = status.ConditionRejectedNilProxyState(status.KeyFromID(req.ID)) - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - - return err - } - - // TODO: Fetch trust bundles for all peers when peering is supported. - trustBundle, err := r.fetchTrustBundle() - if err != nil { - rt.Logger.Error("error fetching root trust bundle", "error", err) - // Set the status. - statusCondition = status.ConditionRejectedTrustBundleFetchFailed(status.KeyFromID(req.ID)) - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - return err - } - - // Initialize ProxyState maps. - if proxyStateTemplate.Template.ProxyState.TrustBundles == nil { - proxyStateTemplate.Template.ProxyState.TrustBundles = make(map[string]*pbproxystate.TrustBundle) - } - // TODO: Figure out the correct key for the default trust bundle. - proxyStateTemplate.Template.ProxyState.TrustBundles["local"] = trustBundle - - if proxyStateTemplate.Template.ProxyState.Endpoints == nil { - proxyStateTemplate.Template.ProxyState.Endpoints = make(map[string]*pbproxystate.Endpoints) - } - if proxyStateTemplate.Template.ProxyState.LeafCertificates == nil { - proxyStateTemplate.Template.ProxyState.LeafCertificates = make(map[string]*pbproxystate.LeafCertificate) - } - - // Iterate through the endpoint references. - // For endpoints, the controller should: - // 1. Resolve ServiceEndpoint references - // 2. Translate them into pbproxystate.Endpoints - // 3. Add the pbproxystate.Endpoints to the ProxyState endpoints map. - // 4. Track relationships between ProxyState and ServiceEndpoints, such that we can look up ServiceEndpoints and - // figure out which ProxyStates are associated with it (for mapping watches) and vice versa (for looking up - // references). The bimapper package is useful for tracking these relationships. - endpointReferencesMap := proxyStateTemplate.Template.RequiredEndpoints - var endpointsInProxyStateTemplate []resource.ReferenceOrID - for xdsClusterName, endpointRef := range endpointReferencesMap { - - // Step 1: Resolve the reference by looking up the ServiceEndpoints. - // serviceEndpoints will not be nil unless there is an error. - // - // TODO(rb/v2): note we should expose a flag on the endpointRef indicating if the user - // wants the absence of an Endpoints to imply returning a slice of no data, vs failing outright. - // In xdsv1 we call this the "allowEmpty" semantic. Here we are assuming "allowEmpty=true" - var psEndpoints *pbproxystate.Endpoints - if endpointRef.Id != nil { - serviceEndpoints, err := getServiceEndpoints(ctx, rt, endpointRef.Id) - if err != nil { - rt.Logger.Error("error reading service endpoint", "id", endpointRef.Id, "error", err) - // Set the status. - statusCondition = status.ConditionRejectedErrorReadingEndpoints(status.KeyFromID(endpointRef.Id), err.Error()) - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - - return err - } - - // Step 2: Translate it into pbproxystate.Endpoints. - psEndpoints, err = generateProxyStateEndpoints(serviceEndpoints, endpointRef.Port) - if err != nil { - rt.Logger.Error("error translating service endpoints to proxy state endpoints", "endpoint", endpointRef.Id, "error", err) - - // Set the status. - statusCondition = status.ConditionRejectedCreatingProxyStateEndpoints(status.KeyFromID(endpointRef.Id), err.Error()) - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - - return err - } - } else { - psEndpoints = &pbproxystate.Endpoints{} - } - - // Step 3: Add the endpoints to ProxyState. - proxyStateTemplate.Template.ProxyState.Endpoints[xdsClusterName] = psEndpoints - - if endpointRef.Id != nil { - // Track all the endpoints that are used by this ProxyStateTemplate, so we can use this for step 4. - endpointResourceRef := resource.Reference(endpointRef.Id, "") - endpointsInProxyStateTemplate = append(endpointsInProxyStateTemplate, endpointResourceRef) - } - } - - // Step 4: Track relationships between ProxyStateTemplates and ServiceEndpoints. - r.endpointsMapper.TrackItem(req.ID, endpointsInProxyStateTemplate) - if len(endpointsInProxyStateTemplate) == 0 { - r.endpointsMapper.UntrackItem(req.ID) - } - - // Iterate through leaf certificate references. - // For each leaf certificate reference, the controller should: - // 1. Setup a watch for the leaf certificate so that the leaf cert manager will generate and store a leaf - // certificate if it's not already in the leaf cert manager cache. - // 1a. Store a cancel function for that leaf certificate watch. - // 2. Get the leaf certificate from the leaf cert manager. (This should succeed if a watch has been set up). - // 3. Put the leaf certificate contents into the ProxyState leaf certificates map. - // 4. Track relationships between ProxyState and leaf certificates using a bimapper. - leafReferencesMap := proxyStateTemplate.Template.RequiredLeafCertificates - var leafsInProxyStateTemplate []resource.ReferenceOrID - for workloadIdentityName, leafRef := range leafReferencesMap { - - // leafRef must include the namespace and partition - leafResourceReference := leafResourceRef(leafRef.Name, leafRef.Namespace, leafRef.Partition) - leafKey := keyFromReference(leafResourceReference) - leafRequest := &leafcert.ConnectCALeafRequest{ - Token: token, - WorkloadIdentity: leafRef.Name, - EnterpriseMeta: acl.NewEnterpriseMetaWithPartition(leafRef.Partition, leafRef.Namespace), - // Add some jitter to the max query time so that all goroutines don't wake up at approximately the same time. - // Without this, it's likely that these queries will all fire at roughly the same time, because the server - // will have spawned many watches immediately on boot. Typically because the index number will not have changed, - // this controller will not be notified anyway, but it's still better to space out the waking of goroutines. - MaxQueryTime: (10 * time.Minute) + lib.RandomStagger(10*time.Minute), - } - - // Step 1: Setup a watch for this leaf if one doesn't already exist. - if _, ok := r.leafCancels.Get(leafKey); !ok { - certWatchContext, cancel := context.WithCancel(ctx) - err = r.leafCertManager.NotifyCallback(certWatchContext, leafRequest, "", func(ctx context.Context, event cacheshim.UpdateEvent) { - cert, ok := event.Result.(*structs.IssuedCert) - if !ok { - panic("wrong type") - } - if cert == nil { - return - } - controllerEvent := controller.Event{ - Obj: cert, - } - select { - // This callback function is running in its own goroutine, so blocking inside this goroutine to send the - // update event doesn't affect the controller or other leaf certificates. r.leafCertEvents is a buffered - // channel, which should constantly be consumed by the controller custom events queue. If the controller - // custom events consumer isn't clearing up the leafCertEvents channel, then that would be the main - // issue to address, as opposed to this goroutine blocking. - case r.leafCertEvents <- controllerEvent: - // This context is the certWatchContext, so we will reach this case if the watch is canceled, and exit - // the callback goroutine. - case <-ctx.Done(): - } - }) - if err != nil { - rt.Logger.Error("error creating leaf watch", "leafRef", leafResourceReference, "error", err) - // Set the status. - statusCondition = status.ConditionRejectedErrorCreatingLeafWatch(keyFromReference(leafResourceReference), err.Error()) - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - - cancel() - return err - } - r.leafCancels.Set(leafKey, cancel) - } - - // Step 2: Get the leaf certificate. - cert, _, err := r.leafCertManager.Get(ctx, leafRequest) - if err != nil { - rt.Logger.Error("error getting leaf", "leafRef", leafResourceReference, "error", err) - // Set the status. - statusCondition = status.ConditionRejectedErrorGettingLeaf(keyFromReference(leafResourceReference), err.Error()) - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - - return err - } - - // Create the pbproxystate.LeafCertificate out of the structs.IssuedCert returned from the manager. - psLeaf := generateProxyStateLeafCertificates(cert) - if psLeaf == nil { - rt.Logger.Error("error getting leaf certificate contents", "leafRef", leafResourceReference) - - // Set the status. - statusCondition = status.ConditionRejectedErrorCreatingProxyStateLeaf(keyFromReference(leafResourceReference), err.Error()) - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - - return err - } - - // Step 3: Add the leaf certificate to ProxyState. - proxyStateTemplate.Template.ProxyState.LeafCertificates[workloadIdentityName] = psLeaf - - // Track all the leaf certificates that are used by this ProxyStateTemplate, so we can use this for step 4. - leafsInProxyStateTemplate = append(leafsInProxyStateTemplate, leafResourceReference) - - } - // Get the previously tracked leafs for this ProxyStateTemplate so we can use this to cancel watches in step 5. - prevWatchedLeafs := r.leafMapper.LinkRefsForItem(req.ID) - - // Step 4: Track relationships between ProxyStateTemplates and leaf certificates for the current leafs referenced in - // ProxyStateTemplate. - r.leafMapper.TrackItem(req.ID, leafsInProxyStateTemplate) - - // Step 5: Compute whether there are leafs that are no longer referenced by this proxy state template, and cancel - // watches for them if they aren't referenced anywhere. - watches := prevWatchesToCancel(prevWatchedLeafs, leafsInProxyStateTemplate) - r.cancelWatches(watches) - - // Now that the references have been resolved, push the computed proxy state to the updater. - computedProxyState := proxyStateTemplate.Template.ProxyState - - err = r.updater.PushChange(req.ID, &proxytracker.ProxyState{ProxyState: computedProxyState}) - if err != nil { - // Set the status. - statusCondition = status.ConditionRejectedPushChangeFailed(status.KeyFromID(req.ID)) - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - return err - } - - // Set the status. - statusCondition = status.ConditionAccepted() - status.WriteStatusIfChanged(ctx, rt, pstResource, statusCondition) - return nil -} - -// leafResourceRef translates a leaf certificate reference in ProxyState template to an internal resource reference. The -// bimapper package uses resource references, so we use an internal type to create a leaf resource reference since leaf -// certificates are not v2 resources. -func leafResourceRef(workloadIdentity, namespace, partition string) *pbresource.Reference { - // Since leaf certificate references aren't resources in the resource API, we don't have the same guarantees that - // namespace and partition are set. So this is to ensure that we always do set values for tenancy. - if namespace == "" { - namespace = defaultTenancy - } - if partition == "" { - partition = defaultTenancy - } - ref := &pbresource.Reference{ - Name: workloadIdentity, - Type: InternalLeafType, - Tenancy: &pbresource.Tenancy{ - Partition: partition, - Namespace: namespace, - }, - } - return ref -} - -// InternalLeafType sets up an internal resource type to use for leaf certificates, since they are not yet a v2 -// resource. It's exported because it's used by the mesh controller registration which needs to set up the bimapper for -// leaf certificates. -var InternalLeafType = &pbresource.Type{ - Group: "internal", - GroupVersion: "v2beta1", - Kind: "leaf", -} - -// keyFromReference is used to create string keys from resource references. -func keyFromReference(ref resource.ReferenceOrID) string { - return fmt.Sprintf("%s/%s/%s", - resource.ToGVK(ref.GetType()), - tenancyToString(ref.GetTenancy()), - ref.GetName()) -} - -func tenancyToString(tenancy *pbresource.Tenancy) string { - return fmt.Sprintf("%s.%s", tenancy.Partition, tenancy.Namespace) -} - -// generateProxyStateLeafCertificates translates a *structs.IssuedCert into a *pbproxystate.LeafCertificate. -func generateProxyStateLeafCertificates(cert *structs.IssuedCert) *pbproxystate.LeafCertificate { - if cert.CertPEM == "" || cert.PrivateKeyPEM == "" { - return nil - } - return &pbproxystate.LeafCertificate{ - Cert: cert.CertPEM, - Key: cert.PrivateKeyPEM, - } -} - -// cancelWatches cancels watches for leafs that no longer need to be watched, as long as it is referenced by zero ProxyStateTemplates. -func (r *xdsReconciler) cancelWatches(leafResourceRefs []*pbresource.Reference) { - for _, leaf := range leafResourceRefs { - pstItems := r.leafMapper.ItemRefsForLink(leaf) - if len(pstItems) > 0 { - // Don't delete and cancel watches, since this leaf is referenced elsewhere. - continue - } - cancel, ok := r.leafCancels.Get(keyFromReference(leaf)) - if ok { - cancel() - r.leafCancels.Delete(keyFromReference(leaf)) - } - } -} - -// prevWatchesToCancel computes if there are any items in prevWatchedLeafs that are not in currentLeafs, and returns a list of those items. -func prevWatchesToCancel(prevWatchedLeafs []*pbresource.Reference, currentLeafs []resource.ReferenceOrID) []*pbresource.Reference { - prevWatchedLeafsToCancel := make([]*pbresource.Reference, 0, len(prevWatchedLeafs)) - newLeafs := make(map[string]struct{}) - for _, newLeaf := range currentLeafs { - newLeafs[keyFromReference(newLeaf)] = struct{}{} - } - for _, prevLeaf := range prevWatchedLeafs { - if _, ok := newLeafs[keyFromReference(prevLeaf)]; !ok { - prevWatchedLeafsToCancel = append(prevWatchedLeafsToCancel, prevLeaf) - } - } - return prevWatchedLeafsToCancel -} diff --git a/internal/mesh/internal/controllers/xds/controller_test.go b/internal/mesh/internal/controllers/xds/controller_test.go deleted file mode 100644 index 270d0f0fdfa92..0000000000000 --- a/internal/mesh/internal/controllers/xds/controller_test.go +++ /dev/null @@ -1,1169 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "context" - "crypto/x509" - "encoding/pem" - "fmt" - "strings" - "testing" - - "github.com/hashicorp/consul/internal/testing/golden" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "google.golang.org/protobuf/encoding/protojson" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/agent/leafcert" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/controllers/xds/status" - "github.com/hashicorp/consul/internal/mesh/internal/types" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" -) - -type xdsControllerTestSuite struct { - suite.Suite - - ctx context.Context - client *resourcetest.Client - runtime controller.Runtime - - ctl *xdsReconciler - mapper *bimapper.Mapper - updater *mockUpdater - fetcher TrustBundleFetcher - leafMapper *LeafMapper - leafCertManager *leafcert.Manager - leafCancels *LeafCancels - leafCertEvents chan controller.Event - signer *leafcert.TestSigner - - fooProxyStateTemplate *pbresource.Resource - barProxyStateTemplate *pbresource.Resource - barEndpointRefs map[string]*pbproxystate.EndpointRef - fooEndpointRefs map[string]*pbproxystate.EndpointRef - fooLeafRefs map[string]*pbproxystate.LeafCertificateRef - fooEndpoints *pbresource.Resource - fooService *pbresource.Resource - fooBarEndpoints *pbresource.Resource - fooBarService *pbresource.Resource - expectedFooProxyStateEndpoints map[string]*pbproxystate.Endpoints - expectedBarProxyStateEndpoints map[string]*pbproxystate.Endpoints - expectedFooProxyStateSpiffes map[string]string - expectedTrustBundle map[string]*pbproxystate.TrustBundle -} - -func (suite *xdsControllerTestSuite) SetupTest() { - suite.ctx = testutil.TestContext(suite.T()) - resourceClient := svctest.RunResourceService(suite.T(), types.Register, catalog.RegisterTypes) - suite.runtime = controller.Runtime{Client: resourceClient, Logger: testutil.Logger(suite.T())} - suite.client = resourcetest.NewClient(resourceClient) - suite.fetcher = mockFetcher - - suite.mapper = bimapper.New(pbmesh.ProxyStateTemplateType, pbcatalog.ServiceEndpointsType) - suite.updater = newMockUpdater() - - suite.leafMapper = &LeafMapper{ - bimapper.New(pbmesh.ProxyStateTemplateType, InternalLeafType), - } - lcm, signer := leafcert.NewTestManager(suite.T(), nil) - signer.UpdateCA(suite.T(), nil) - suite.signer = signer - suite.leafCertManager = lcm - suite.leafCancels = &LeafCancels{ - Cancels: make(map[string]context.CancelFunc), - } - suite.leafCertEvents = make(chan controller.Event, 1000) - - suite.ctl = &xdsReconciler{ - endpointsMapper: suite.mapper, - updater: suite.updater, - fetchTrustBundle: suite.fetcher, - leafMapper: suite.leafMapper, - leafCertManager: suite.leafCertManager, - leafCancels: suite.leafCancels, - leafCertEvents: suite.leafCertEvents, - datacenter: "dc1", - } -} - -func mockFetcher() (*pbproxystate.TrustBundle, error) { - var bundle pbproxystate.TrustBundle - bundle = pbproxystate.TrustBundle{ - TrustDomain: "some-trust-domain", - Roots: []string{"some-root", "some-other-root"}, - } - return &bundle, nil -} - -// This test ensures when a ProxyState is deleted, it is no longer tracked in the mappers. -func (suite *xdsControllerTestSuite) TestReconcile_NoProxyStateTemplate() { - // Track the id of a non-existent ProxyStateTemplate. - proxyStateTemplateId := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "not-found").ID() - suite.mapper.TrackItem(proxyStateTemplateId, []resource.ReferenceOrID{}) - suite.leafMapper.TrackItem(proxyStateTemplateId, []resource.ReferenceOrID{}) - require.False(suite.T(), suite.mapper.IsEmpty()) - require.False(suite.T(), suite.leafMapper.IsEmpty()) - - // Run the reconcile, and since no ProxyStateTemplate is stored, this simulates a deletion. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: proxyStateTemplateId, - }) - require.NoError(suite.T(), err) - - // Assert that nothing is tracked in the endpoints mapper. - require.True(suite.T(), suite.mapper.IsEmpty()) - require.True(suite.T(), suite.leafMapper.IsEmpty()) -} - -// This test ensures if the controller was previously tracking a ProxyStateTemplate, and now that proxy has -// disconnected from this server, it's ignored and removed from the mapper. -func (suite *xdsControllerTestSuite) TestReconcile_RemoveTrackingProxiesNotConnectedToServer() { - // Store the initial ProxyStateTemplate and track it in the mapper. - proxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{}). - Write(suite.T(), suite.client) - - suite.mapper.TrackItem(proxyStateTemplate.Id, []resource.ReferenceOrID{}) - - // Simulate the proxy disconnecting from this server. The resource still exists, but this proxy might be connected - // to a different server now, so we no longer need to track it. - suite.updater.notConnected = true - - // Run the reconcile. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: proxyStateTemplate.Id, - }) - require.NoError(suite.T(), err) - - // Assert that nothing is tracked in the mapper. - require.True(suite.T(), suite.mapper.IsEmpty()) -} - -// This test sets up the updater to return an error when calling PushChange, and ensures the status is set -// correctly. -func (suite *xdsControllerTestSuite) TestReconcile_PushChangeError() { - // Have the mock simulate an error from the PushChange call. - suite.updater.pushChangeError = true - - // Setup a happy path scenario. - suite.setupFooProxyStateTemplateWithReferences() - - // Run the reconcile. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: suite.fooProxyStateTemplate.Id, - }) - require.Error(suite.T(), err) - - // Assert on the status reflecting endpoint not found. - suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedPushChangeFailed(status.KeyFromID(suite.fooProxyStateTemplate.Id))) -} - -// This test sets up a ProxyStateTemplate that references a ServiceEndpoints that doesn't exist, and ensures the -// status is correct. -func (suite *xdsControllerTestSuite) TestReconcile_MissingEndpoint() { - // Set fooProxyStateTemplate with a reference to fooEndpoints, without storing fooEndpoints so the controller should - // notice it's missing. - fooEndpointsId := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service").WithTenancy(resource.DefaultNamespacedTenancy()).ID() - fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef) - fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{ - Id: fooEndpointsId, - Port: "mesh", - } - - fooProxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "foo-pst"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{ - RequiredEndpoints: fooRequiredEndpoints, - ProxyState: &pbmesh.ProxyState{}, - }). - Write(suite.T(), suite.client) - - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id) - }) - - // Run the reconcile. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: fooProxyStateTemplate.Id, - }) - require.Error(suite.T(), err) - - // Assert on the status reflecting endpoint not found. - suite.client.RequireStatusCondition(suite.T(), fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedErrorReadingEndpoints(status.KeyFromID(fooEndpointsId), "rpc error: code = NotFound desc = resource not found")) -} - -// This test sets up a ProxyStateTemplate that references a ServiceEndpoints that can't be read correctly, and -// checks the status is correct. -func (suite *xdsControllerTestSuite) TestReconcile_ReadEndpointError() { - badID := &pbresource.ID{ - Type: &pbresource.Type{ - Group: "not", - Kind: "found", - GroupVersion: "vfake", - }, - Tenancy: &pbresource.Tenancy{Namespace: "default", Partition: "default", PeerName: "local"}, - } - fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef) - fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{ - Id: badID, - Port: "mesh", - } - - fooProxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "foo-pst"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{ - RequiredEndpoints: fooRequiredEndpoints, - ProxyState: &pbmesh.ProxyState{}, - }). - Write(suite.T(), suite.client) - - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id) - }) - - // Run the reconcile. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: fooProxyStateTemplate.Id, - }) - require.Error(suite.T(), err) - - // Assert on the status reflecting endpoint couldn't be read. - suite.client.RequireStatusCondition(suite.T(), fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedErrorReadingEndpoints( - status.KeyFromID(badID), - "rpc error: code = InvalidArgument desc = id.name invalid: a resource name must consist of lower case alphanumeric characters or '-', must start and end with an alphanumeric character and be less than 64 characters, got: \"\"", - )) -} - -// This test is a happy path creation test to make sure pbproxystate.Endpoints are created in the computed -// pbmesh.ProxyState from the RequiredEndpoints references. More specific translations between endpoint references -// and pbproxystate.Endpoints are unit tested in endpoint_builder.go. -func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateComputesEndpoints() { - // Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints and store them in the state store. - // This setup saves expected values in the suite so it can be asserted against later. - suite.setupFooProxyStateTemplateWithReferences() - - // Run the reconcile. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: suite.fooProxyStateTemplate.Id, - }) - require.NoError(suite.T(), err) - - // Assert on the status. - suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - - // Assert that the endpoints computed in the controller matches the expected endpoints. - actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name) - prototest.AssertDeepEqual(suite.T(), suite.expectedFooProxyStateEndpoints, actualEndpoints) -} - -func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateComputesLeafCerts() { - // Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints and store them in the state store. - // This setup saves expected values in the suite so it can be asserted against later. - suite.setupFooProxyStateTemplateWithReferences() - - // Run the reconcile. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: suite.fooProxyStateTemplate.Id, - }) - require.NoError(suite.T(), err) - - // Assert on the status. - suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - - // Assert that the actual leaf certs computed are match the expected leaf cert spiffes. - actualLeafs := suite.updater.GetLeafs(suite.fooProxyStateTemplate.Id.Name) - - for k, l := range actualLeafs { - pem, _ := pem.Decode([]byte(l.Cert)) - cert, err := x509.ParseCertificate(pem.Bytes) - require.NoError(suite.T(), err) - require.Equal(suite.T(), cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k]) - } -} - -// This test is a happy path creation test to make sure pbproxystate.Template.TrustBundles are created in the computed -// pbmesh.ProxyState from the TrustBundleFetcher. -func (suite *xdsControllerTestSuite) TestReconcile_ProxyStateTemplateSetsTrustBundles() { - suite.setupFooProxyStateTemplateWithReferences() - - // Run the reconcile. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: suite.fooProxyStateTemplate.Id, - }) - require.NoError(suite.T(), err) - - // Assert on the status. - suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - - // Assert that the endpoints computed in the controller matches the expected endpoints. - actualTrustBundle := suite.updater.GetTrustBundle(suite.fooProxyStateTemplate.Id.Name) - prototest.AssertDeepEqual(suite.T(), suite.expectedTrustBundle, actualTrustBundle) -} - -// This test is a happy path creation test that calls reconcile multiple times with a more complex setup. This -// scenario is trickier to test in the controller test because the end computation of the xds controller is not -// stored in the state store. So this test ensures that between multiple reconciles the correct ProxyStates are -// computed for each ProxyStateTemplate. -func (suite *xdsControllerTestSuite) TestReconcile_MultipleProxyStateTemplatesComputesMultipleEndpoints() { - // Set up fooProxyStateTemplate and barProxyStateTemplate and their associated resources and store them. Resources - // and expected results are stored in the suite to assert against. - suite.setupFooBarProxyStateTemplateAndEndpoints() - - // Reconcile the fooProxyStateTemplate. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: suite.fooProxyStateTemplate.Id, - }) - require.NoError(suite.T(), err) - - // Assert on the status. - suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - - // Assert that the endpoints computed in the controller matches the expected endpoints. - actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name) - prototest.AssertDeepEqual(suite.T(), suite.expectedFooProxyStateEndpoints, actualEndpoints) - - // Reconcile the barProxyStateTemplate. - err = suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: suite.barProxyStateTemplate.Id, - }) - require.NoError(suite.T(), err) - - // Assert on the status. - suite.client.RequireStatusCondition(suite.T(), suite.barProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - - // Assert that the endpoints computed in the controller matches the expected endpoints. - actualBarEndpoints := suite.updater.GetEndpoints(suite.barProxyStateTemplate.Id.Name) - prototest.AssertDeepEqual(suite.T(), suite.expectedBarProxyStateEndpoints, actualBarEndpoints) -} - -// Sets up a full controller, and tests that reconciles are getting triggered for the events it should. -func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateEndpointReferences() { - // Run the controller manager. - mgr := controller.NewManager(suite.client, suite.runtime.Logger) - mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1")) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - suite.setupFooProxyStateTemplateWithReferences() - - // Assert that the expected ProxyState matches the actual ProxyState that PushChange was called with. This needs to - // be in a retry block unlike the Reconcile tests because the controller triggers asynchronously. - retry.Run(suite.T(), func(r *retry.R) { - actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name) - // Assert on the status. - suite.client.RequireStatusCondition(r, suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - // Assert that the endpoints computed in the controller matches the expected endpoints. - prototest.AssertDeepEqual(r, suite.expectedFooProxyStateEndpoints, actualEndpoints) - }) - - // Now, update the endpoint to be unhealthy. This will ensure the controller is getting triggered on changes to this - // endpoint that it should be tracking, even when the ProxyStateTemplate does not change. - resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service"). - WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{ - { - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.1.1.1", - Ports: []string{"mesh"}, - }, - { - Host: "10.2.2.2", - Ports: []string{"mesh"}, - }, - }, - HealthStatus: pbcatalog.Health_HEALTH_CRITICAL, - }, - }}). - WithOwner(suite.fooService.Id). - Write(suite.T(), suite.client) - - // Wait for the endpoint to be written. - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireVersionChanged(suite.T(), suite.fooEndpoints.Id, suite.fooEndpoints.Version) - }) - - // Update the expected endpoints to also have unhealthy status. - suite.expectedFooProxyStateEndpoints["test-cluster-1"].Endpoints[0].HealthStatus = pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY - suite.expectedFooProxyStateEndpoints["test-cluster-1"].Endpoints[1].HealthStatus = pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY - - retry.Run(suite.T(), func(r *retry.R) { - actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name) - // Assert on the status. - suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - // Assert that the endpoints computed in the controller matches the expected endpoints. - prototest.AssertDeepEqual(r, suite.expectedFooProxyStateEndpoints, actualEndpoints) - }) - - // Now add a new endpoint reference and endpoint to the fooProxyStateTemplate. This will ensure that the controller - // now tracks the newly added endpoint. - secondService := resourcetest.Resource(pbcatalog.ServiceType, "second-service"). - WithData(suite.T(), &pbcatalog.Service{}). - Write(suite.T(), suite.client) - - secondEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "second-service"). - WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{ - { - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.5.5.5", - Ports: []string{"mesh"}, - }, - { - Host: "10.6.6.6", - Ports: []string{"mesh"}, - }, - }, - }, - }}). - WithOwner(secondService.Id). - Write(suite.T(), suite.client) - - // Update the endpoint references on the fooProxyStateTemplate. - suite.fooEndpointRefs["test-cluster-2"] = &pbproxystate.EndpointRef{ - Id: secondEndpoints.Id, - Port: "mesh", - } - - oldVersion := suite.fooProxyStateTemplate.Version - fooProxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "foo-pst"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{ - RequiredEndpoints: suite.fooEndpointRefs, - ProxyState: &pbmesh.ProxyState{}, - RequiredLeafCertificates: suite.fooLeafRefs, - }). - Write(suite.T(), suite.client) - - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireVersionChanged(r, fooProxyStateTemplate.Id, oldVersion) - }) - - // Update the expected endpoints with this new endpoints. - suite.expectedFooProxyStateEndpoints["test-cluster-2"] = &pbproxystate.Endpoints{ - Endpoints: []*pbproxystate.Endpoint{ - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.5.5.5", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.6.6.6", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - }, - } - - retry.Run(suite.T(), func(r *retry.R) { - actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name) - // Assert on the status. - suite.client.RequireStatusCondition(suite.T(), suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - // Assert that the endpoints computed in the controller matches the expected endpoints. - prototest.AssertDeepEqual(r, suite.expectedFooProxyStateEndpoints, actualEndpoints) - }) - -} - -// Sets up a full controller, and tests that reconciles are getting triggered for the leaf cert events it should. -// This test ensures when a CA is updated, the controller is triggered to update the leaf cert when it changes. -func (suite *xdsControllerTestSuite) TestController_ComputeAddUpdateDeleteLeafReferences() { - // Run the controller manager. - mgr := controller.NewManager(suite.client, suite.runtime.Logger) - mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1")) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - suite.setupFooProxyStateTemplateWithReferences() - leafCertRef := suite.fooLeafRefs["foo-workload-identity"] - fooLeafResRef := leafResourceRef(leafCertRef.Name, leafCertRef.Namespace, leafCertRef.Partition) - - // oldLeaf will store the original leaf from before we trigger a CA update. - var oldLeaf *x509.Certificate - - // Assert that the expected ProxyState matches the actual ProxyState that PushChange was called with. This needs to - // be in a retry block unlike the Reconcile tests because the controller triggers asynchronously. - retry.Run(suite.T(), func(r *retry.R) { - actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name) - actualLeafs := suite.updater.GetLeafs(suite.fooProxyStateTemplate.Id.Name) - // Assert on the status. - suite.client.RequireStatusCondition(r, suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - // Assert that the endpoints computed in the controller matches the expected endpoints. - prototest.AssertDeepEqual(r, suite.expectedFooProxyStateEndpoints, actualEndpoints) - // Assert that the leafs computed in the controller matches the expected leafs. - require.Len(r, actualLeafs, 1) - for k, l := range actualLeafs { - pem, _ := pem.Decode([]byte(l.Cert)) - cert, err := x509.ParseCertificate(pem.Bytes) - oldLeaf = cert - require.NoError(r, err) - require.Equal(r, cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k]) - // Check the state of the cancel functions map. - _, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef)) - require.True(r, ok) - } - }) - - // Update the CA, and ensure the leaf cert is different from the leaf certificate from the step above. - suite.signer.UpdateCA(suite.T(), nil) - retry.Run(suite.T(), func(r *retry.R) { - actualLeafs := suite.updater.GetLeafs(suite.fooProxyStateTemplate.Id.Name) - require.Len(r, actualLeafs, 1) - for k, l := range actualLeafs { - pem, _ := pem.Decode([]byte(l.Cert)) - cert, err := x509.ParseCertificate(pem.Bytes) - // Ensure the leaf was actually updated by checking that the leaf we just got is different from the old leaf. - require.NotEqual(r, oldLeaf.Raw, cert.Raw) - require.NoError(r, err) - require.Equal(r, suite.expectedFooProxyStateSpiffes[k], cert.URIs[0].String()) - // Check the state of the cancel functions map. Even though we've updated the leaf cert, we should still - // have a watch going for it. - _, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef)) - require.True(r, ok) - } - }) - - // Delete the leaf references on the fooProxyStateTemplate - delete(suite.fooLeafRefs, "foo-workload-identity") - oldVersion := suite.fooProxyStateTemplate.Version - fooProxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "foo-pst"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{ - RequiredEndpoints: suite.fooEndpointRefs, - ProxyState: &pbmesh.ProxyState{}, - RequiredLeafCertificates: suite.fooLeafRefs, - }). - Write(suite.T(), suite.client) - - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireVersionChanged(r, fooProxyStateTemplate.Id, oldVersion) - }) - - // Ensure the leaf certificate watches were cancelled since we deleted the leaf reference. - retry.Run(suite.T(), func(r *retry.R) { - _, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef)) - require.False(r, ok) - }) -} - -// Sets up a full controller, and tests that reconciles are getting triggered for the leaf cert events it should. -// This test ensures that when a ProxyStateTemplate is deleted, the leaf watches are cancelled. -func (suite *xdsControllerTestSuite) TestController_ComputeLeafReferencesDeletePST() { - // Run the controller manager. - mgr := controller.NewManager(suite.client, suite.runtime.Logger) - mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1")) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - suite.setupFooProxyStateTemplateWithReferences() - leafCertRef := suite.fooLeafRefs["foo-workload-identity"] - fooLeafResRef := leafResourceRef(leafCertRef.Name, leafCertRef.Namespace, leafCertRef.Partition) - - // Assert that the expected ProxyState matches the actual ProxyState that PushChange was called with. This needs to - // be in a retry block unlike the Reconcile tests because the controller triggers asynchronously. - retry.Run(suite.T(), func(r *retry.R) { - actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name) - actualLeafs := suite.updater.GetLeafs(suite.fooProxyStateTemplate.Id.Name) - // Assert on the status. - suite.client.RequireStatusCondition(r, suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - // Assert that the endpoints computed in the controller matches the expected endpoints. - prototest.AssertDeepEqual(r, suite.expectedFooProxyStateEndpoints, actualEndpoints) - // Assert that the leafs computed in the controller matches the expected leafs. - require.Len(r, actualLeafs, 1) - for k, l := range actualLeafs { - pem, _ := pem.Decode([]byte(l.Cert)) - cert, err := x509.ParseCertificate(pem.Bytes) - require.NoError(r, err) - require.Equal(r, cert.URIs[0].String(), suite.expectedFooProxyStateSpiffes[k]) - // Check the state of the cancel functions map. - _, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef)) - require.True(r, ok) - } - }) - - // Delete the fooProxyStateTemplate - - req := &pbresource.DeleteRequest{ - Id: suite.fooProxyStateTemplate.Id, - } - suite.client.Delete(suite.ctx, req) - - // Ensure the leaf certificate watches were cancelled since we deleted the leaf reference. - retry.Run(suite.T(), func(r *retry.R) { - _, ok := suite.leafCancels.Get(keyFromReference(fooLeafResRef)) - require.False(r, ok) - }) -} - -// Sets up a full controller, and tests that reconciles are getting triggered for the events it should. -func (suite *xdsControllerTestSuite) TestController_ComputeEndpointForProxyConnections() { - // Run the controller manager. - mgr := controller.NewManager(suite.client, suite.runtime.Logger) - - mgr.Register(Controller(suite.mapper, suite.updater, suite.fetcher, suite.leafCertManager, suite.leafMapper, suite.leafCancels, "dc1")) - mgr.SetRaftLeader(true) - go mgr.Run(suite.ctx) - - // Set up fooEndpoints and fooProxyStateTemplate with a reference to fooEndpoints. These need to be stored - // because the controller reconcile looks them up. - suite.setupFooProxyStateTemplateWithReferences() - - // Assert that the expected ProxyState matches the actual ProxyState that PushChange was called with. This needs to - // be in a retry block unlike the Reconcile tests because the controller triggers asynchronously. - retry.Run(suite.T(), func(r *retry.R) { - actualEndpoints := suite.updater.GetEndpoints(suite.fooProxyStateTemplate.Id.Name) - // Assert on the status. - suite.client.RequireStatusCondition(r, suite.fooProxyStateTemplate.Id, ControllerName, status.ConditionAccepted()) - // Assert that the endpoints computed in the controller matches the expected endpoints. - prototest.AssertDeepEqual(r, suite.expectedFooProxyStateEndpoints, actualEndpoints) - }) - - eventChannel := suite.updater.EventChannel() - eventChannel <- controller.Event{Obj: &proxytracker.ProxyConnection{ProxyID: suite.fooProxyStateTemplate.Id}} - - // Wait for the proxy state template to be re-evaluated. - proxyStateTemp := suite.client.WaitForNewVersion(suite.T(), suite.fooProxyStateTemplate.Id, suite.fooProxyStateTemplate.Version) - require.NotNil(suite.T(), proxyStateTemp) -} - -// Setup: fooProxyStateTemplate with: -// - an EndpointsRef to fooEndpoints -// - a LeafCertificateRef to "foo-workload-identity" -// -// Saves all related resources to the suite so they can be looked up by the controller or modified if needed. -func (suite *xdsControllerTestSuite) setupFooProxyStateTemplateWithReferences() { - fooService := resourcetest.Resource(pbcatalog.ServiceType, "foo-service"). - WithData(suite.T(), &pbcatalog.Service{}). - Write(suite.T(), suite.client) - - fooEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service"). - WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{ - { - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.1.1.1", - Ports: []string{"mesh"}, - }, - { - Host: "10.2.2.2", - Ports: []string{"mesh"}, - }, - }, - }, - }}). - WithOwner(fooService.Id). - Write(suite.T(), suite.client) - - fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef) - fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{ - Id: fooEndpoints.Id, - Port: "mesh", - } - - fooRequiredLeafs := make(map[string]*pbproxystate.LeafCertificateRef) - fooRequiredLeafs["foo-workload-identity"] = &pbproxystate.LeafCertificateRef{ - Name: "foo-workload-identity", - } - - fooProxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "foo-pst"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{ - RequiredEndpoints: fooRequiredEndpoints, - RequiredLeafCertificates: fooRequiredLeafs, - ProxyState: &pbmesh.ProxyState{}, - }). - Write(suite.T(), suite.client) - - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id) - }) - - expectedFooLeafSpiffes := map[string]string{ - "foo-workload-identity": "spiffe://11111111-2222-3333-4444-555555555555.consul/ap/default/ns/default/identity/foo-workload-identity", - } - expectedFooProxyStateEndpoints := map[string]*pbproxystate.Endpoints{ - "test-cluster-1": {Endpoints: []*pbproxystate.Endpoint{ - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.1.1.1", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.2.2.2", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - }}, - } - - expectedTrustBundle := map[string]*pbproxystate.TrustBundle{ - "local": { - TrustDomain: "some-trust-domain", - Roots: []string{"some-root", "some-other-root"}, - }, - } - - suite.fooService = fooService - suite.fooEndpoints = fooEndpoints - suite.fooEndpointRefs = fooRequiredEndpoints - suite.fooLeafRefs = fooRequiredLeafs - suite.fooProxyStateTemplate = fooProxyStateTemplate - suite.expectedFooProxyStateEndpoints = expectedFooProxyStateEndpoints - suite.expectedTrustBundle = expectedTrustBundle - suite.expectedFooProxyStateSpiffes = expectedFooLeafSpiffes -} - -// Setup: -// - fooProxyStateTemplate with an EndpointsRef to fooEndpoints and fooBarEndpoints. -// - barProxyStateTemplate with an EndpointsRef to fooBarEndpoints. -// -// Saves all related resources to the suite so they can be modified if needed. -func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints() { - fooService := resourcetest.Resource(pbcatalog.ServiceType, "foo-service"). - WithData(suite.T(), &pbcatalog.Service{}). - Write(suite.T(), suite.client) - - fooEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-service"). - WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{ - { - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.1.1.1", - Ports: []string{"mesh"}, - }, - { - Host: "10.2.2.2", - Ports: []string{"mesh"}, - }, - }, - }, - }}). - WithOwner(fooService.Id). - Write(suite.T(), suite.client) - - fooBarService := resourcetest.Resource(pbcatalog.ServiceType, "foo-bar-service"). - WithData(suite.T(), &pbcatalog.Service{}). - Write(suite.T(), suite.client) - - fooBarEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "foo-bar-service"). - WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{ - { - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.3.3.3", - Ports: []string{"mesh"}, - }, - { - Host: "10.4.4.4", - Ports: []string{"mesh"}, - }, - }, - }, - }}). - WithOwner(fooBarService.Id). - Write(suite.T(), suite.client) - - fooRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef) - fooRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{ - Id: fooEndpoints.Id, - Port: "mesh", - } - fooRequiredEndpoints["test-cluster-2"] = &pbproxystate.EndpointRef{ - Id: fooBarEndpoints.Id, - Port: "mesh", - } - - barRequiredEndpoints := make(map[string]*pbproxystate.EndpointRef) - barRequiredEndpoints["test-cluster-1"] = &pbproxystate.EndpointRef{ - Id: fooBarEndpoints.Id, - // Sidecar proxy controller will usually set mesh port here. - Port: "mesh", - } - - fooProxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "foo-pst"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{ - // Contains the foo and foobar endpoints. - RequiredEndpoints: fooRequiredEndpoints, - ProxyState: &pbmesh.ProxyState{}, - }). - Write(suite.T(), suite.client) - - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireResourceExists(r, fooProxyStateTemplate.Id) - }) - - barProxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "bar-pst"). - WithData(suite.T(), &pbmesh.ProxyStateTemplate{ - // Contains the foobar endpoint. - RequiredEndpoints: barRequiredEndpoints, - ProxyState: &pbmesh.ProxyState{}, - }). - Write(suite.T(), suite.client) - - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireResourceExists(r, barProxyStateTemplate.Id) - }) - - expectedFooProxyStateEndpoints := map[string]*pbproxystate.Endpoints{ - "test-cluster-1": {Endpoints: []*pbproxystate.Endpoint{ - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.1.1.1", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.2.2.2", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - }}, - "test-cluster-2": {Endpoints: []*pbproxystate.Endpoint{ - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.3.3.3", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.4.4.4", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - }}, - } - - expectedBarProxyStateEndpoints := map[string]*pbproxystate.Endpoints{ - "test-cluster-1": {Endpoints: []*pbproxystate.Endpoint{ - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.3.3.3", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.4.4.4", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - }}, - } - - suite.fooProxyStateTemplate = fooProxyStateTemplate - suite.barProxyStateTemplate = barProxyStateTemplate - suite.barEndpointRefs = barRequiredEndpoints - suite.fooEndpointRefs = fooRequiredEndpoints - suite.fooEndpoints = fooEndpoints - suite.fooService = fooService - suite.fooBarEndpoints = fooBarEndpoints - suite.fooBarService = fooBarService - suite.expectedFooProxyStateEndpoints = expectedFooProxyStateEndpoints - suite.expectedBarProxyStateEndpoints = expectedBarProxyStateEndpoints -} - -func (suite *xdsControllerTestSuite) TestReconcile_prevWatchesToCancel() { - makeRef := func(names ...string) []*pbresource.Reference { - out := make([]*pbresource.Reference, len(names)) - for i, name := range names { - out[i] = &pbresource.Reference{ - Name: name, - Type: &pbresource.Type{ - Group: "g", - GroupVersion: "v", - Kind: "k", - }, - Tenancy: &pbresource.Tenancy{}, - } - } - return out - } - convert := func(input []*pbresource.Reference) []resource.ReferenceOrID { - asInterface := make([]resource.ReferenceOrID, len(input)) - for i := range input { - asInterface[i] = input[i] - } - return asInterface - } - - cases := []struct { - old []*pbresource.Reference - new []*pbresource.Reference - expect []*pbresource.Reference - }{ - { - old: makeRef("a", "b", "c"), - new: makeRef("a", "c"), - expect: makeRef("b"), - }, - { - old: makeRef("a", "b", "c"), - new: makeRef("a", "b", "c"), - expect: makeRef(), - }, - { - old: makeRef(), - new: makeRef("a", "b"), - expect: makeRef(), - }, - { - old: makeRef("a", "b"), - new: makeRef(), - expect: makeRef("a", "b"), - }, - { - old: makeRef(), - new: makeRef(), - expect: makeRef(), - }, - } - - for _, tc := range cases { - toCancel := prevWatchesToCancel(tc.old, convert(tc.new)) - require.ElementsMatch(suite.T(), toCancel, tc.expect) - } -} - -func TestXdsController(t *testing.T) { - suite.Run(t, new(xdsControllerTestSuite)) -} - -// TestReconcile_SidecarProxyGoldenFileInputs tests the Reconcile() by using -// the golden test output/expected files from the sidecar proxy tests as inputs -// to the XDS controller reconciliation. -// XDS controller reconciles the full ProxyStateTemplate object. The fields -// that things that it focuses on are leaf certs, endpoints, and trust bundles, -// which is just a subset of the ProxyStateTemplate struct. Prior to XDS controller -// reconciliation, the sidecar proxy controller will have reconciled the other parts -// of the ProxyStateTemplate. -// Since the XDS controller does act on the ProxyStateTemplate, the tests -// utilize that entire object rather than just the parts that XDS controller -// internals reconciles. Namely, by using checking the full ProxyStateTemplate -// rather than just endpoints, leaf certs, and trust bundles, the test also ensures -// side effects or change in scope to XDS controller are not introduce mistakenly. -func (suite *xdsControllerTestSuite) TestReconcile_SidecarProxyGoldenFileInputs() { - path := "../sidecarproxy/builder/testdata" - cases := []string{ - // destinations - please add in alphabetical order - "destination/l4-single-destination-ip-port-bind-address", - "destination/l4-single-destination-unix-socket-bind-address", - "destination/l4-single-implicit-destination-tproxy", - "destination/l4-multi-destination", - "destination/l4-multiple-implicit-destinations-tproxy", - "destination/l4-implicit-and-explicit-destinations-tproxy", - "destination/mixed-multi-destination", - "destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy", - "destination/multiport-l4-and-l7-single-implicit-destination-tproxy", - "destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy", - - //sources - please add in alphabetical order - "source/l4-multiple-workload-addresses-with-specific-ports", - "source/l4-multiple-workload-addresses-without-ports", - "source/l4-single-workload-address-without-ports", - "source/l7-expose-paths", - "source/local-and-inbound-connections", - "source/multiport-l4-multiple-workload-addresses-with-specific-ports", - "source/multiport-l4-multiple-workload-addresses-without-ports", - "source/multiport-l4-workload-with-only-mesh-port", - "source/multiport-l7-multiple-workload-addresses-with-specific-ports", - "source/multiport-l7-multiple-workload-addresses-without-ports", - "source/multiport-l7-multiple-workload-addresses-without-ports", - } - - for _, name := range cases { - suite.Run(name, func() { - // Create ProxyStateTemplate from the golden file. - pst := JSONToProxyTemplate(suite.T(), - golden.GetBytesAtFilePath(suite.T(), fmt.Sprintf("%s/%s.golden", path, name))) - - // Destinations will need endpoint refs set up. - if strings.Split(name, "/")[0] == "destination" && len(pst.ProxyState.Endpoints) == 0 { - suite.addRequiredEndpointsAndRefs(pst) - } - - // Store the initial ProxyStateTemplate. - proxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test"). - WithData(suite.T(), pst). - Write(suite.T(), suite.client) - - // Check with resource service that it exists. - retry.Run(suite.T(), func(r *retry.R) { - suite.client.RequireResourceExists(r, proxyStateTemplate.Id) - }) - - // Track it in the mapper. - suite.mapper.TrackItem(proxyStateTemplate.Id, []resource.ReferenceOrID{}) - - // Run the reconcile, and since no ProxyStateTemplate is stored, this simulates a deletion. - err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: proxyStateTemplate.Id, - }) - require.NoError(suite.T(), err) - require.NotNil(suite.T(), proxyStateTemplate) - - // Get the reconciled proxyStateTemplate to check the reconcile results. - reconciledPS := suite.updater.Get(proxyStateTemplate.Id.Name) - - // Verify leaf cert contents then hard code them for comparison - // and downstream tests since they change from test run to test run. - require.NotEmpty(suite.T(), reconciledPS.LeafCertificates) - reconciledPS.LeafCertificates = map[string]*pbproxystate.LeafCertificate{ - "test-identity": { - Cert: "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - Key: "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n", - }, - } - - // Compare actual vs expected. - actual := prototest.ProtoToJSON(suite.T(), reconciledPS) - expected := golden.Get(suite.T(), actual, name+".golden") - require.JSONEq(suite.T(), expected, actual) - }) - } -} - -func (suite *xdsControllerTestSuite) addRequiredEndpointsAndRefs(pst *pbmesh.ProxyStateTemplate) { - //get service data - serviceData := &pbcatalog.Service{} - var vp uint32 = 7000 - requiredEps := make(map[string]*pbproxystate.EndpointRef) - - // iterate through clusters and set up endpoints for cluster/mesh port. - for clusterName := range pst.ProxyState.Clusters { - if clusterName == "null_route_cluster" || clusterName == "original-destination" { - continue - } - - //increment the random port number. - vp++ - clusterNameSplit := strings.Split(clusterName, ".") - port := clusterNameSplit[0] - svcName := clusterNameSplit[1] - - // set up service data with port info. - serviceData.Ports = append(serviceData.Ports, &pbcatalog.ServicePort{ - TargetPort: port, - VirtualPort: vp, - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }) - - // create service. - svc := resourcetest.Resource(pbcatalog.ServiceType, svcName). - WithData(suite.T(), &pbcatalog.Service{}). - Write(suite.T(), suite.client) - - // create endpoints with svc as owner. - eps := resourcetest.Resource(pbcatalog.ServiceEndpointsType, svcName). - WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{ - { - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.1.1.1", - Ports: []string{"mesh"}, - }, - }, - }, - }}). - WithOwner(svc.Id). - Write(suite.T(), suite.client) - - // add to working list of required endpoints. - requiredEps[clusterName] = &pbproxystate.EndpointRef{ - Id: eps.Id, - Port: "mesh", - } - } - - // set working list of required endpoints as proxy state's RequiredEndpoints. - pst.RequiredEndpoints = requiredEps -} - -func JSONToProxyTemplate(t *testing.T, json []byte) *pbmesh.ProxyStateTemplate { - t.Helper() - proxyTemplate := &pbmesh.ProxyStateTemplate{} - m := protojson.UnmarshalOptions{} - err := m.Unmarshal(json, proxyTemplate) - require.NoError(t, err) - return proxyTemplate -} diff --git a/internal/mesh/internal/controllers/xds/endpoint_builder.go b/internal/mesh/internal/controllers/xds/endpoint_builder.go deleted file mode 100644 index d0e3f84366f9c..0000000000000 --- a/internal/mesh/internal/controllers/xds/endpoint_builder.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "fmt" - "net" - - "golang.org/x/exp/slices" - - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" -) - -func generateProxyStateEndpoints(serviceEndpoints *ServiceEndpointsData, portName string) (*pbproxystate.Endpoints, error) { - var psEndpoints []*pbproxystate.Endpoint - - if serviceEndpoints.Endpoints == nil || serviceEndpoints.Resource == nil { - return nil, fmt.Errorf("service endpoints requires both endpoints and resource") - } - eps := serviceEndpoints.Endpoints.GetEndpoints() - - for _, ep := range eps { - for _, addr := range ep.Addresses { - // Check if the address is using the portName name this proxy state endpoints is for. If it does, create the - // endpoint. - if slices.Contains(addr.Ports, portName) { - // Lookup the portName number from the portName name. - wlPort, ok := ep.Ports[portName] - if !ok { - // This should never happen, as it should be validated by the ServiceEndpoints controller. - return nil, fmt.Errorf("could not find portName %q in endpoint %s", portName, serviceEndpoints.Resource.Id) - } - portNum := wlPort.Port - - psEndpoint, err := createProxyStateEndpoint(addr.Host, portNum, ep.HealthStatus) - if err != nil { - return nil, err - } - psEndpoints = append(psEndpoints, psEndpoint) - } - } - } - - return &pbproxystate.Endpoints{Endpoints: psEndpoints}, nil -} - -func createProxyStateEndpoint(host string, port uint32, health pbcatalog.Health) (*pbproxystate.Endpoint, error) { - addr := net.ParseIP(host) - if addr == nil { - return nil, fmt.Errorf("host is not an ip") - } - - psEndpoint := &pbproxystate.Endpoint{ - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: host, - Port: port, - }, - }, - HealthStatus: endpointHealth(health), - // TODO(xds): Weight will be added later. More information is potentially needed in the reference. - } - return psEndpoint, nil -} - -func endpointHealth(catalogHealth pbcatalog.Health) pbproxystate.HealthStatus { - health := pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY - - if catalogHealth == pbcatalog.Health_HEALTH_CRITICAL { - health = pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY - } - return health -} diff --git a/internal/mesh/internal/controllers/xds/endpoint_builder_test.go b/internal/mesh/internal/controllers/xds/endpoint_builder_test.go deleted file mode 100644 index 756acdb7e9907..0000000000000 --- a/internal/mesh/internal/controllers/xds/endpoint_builder_test.go +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestMakeProxyStateEndpointsFromServiceEndpoints(t *testing.T) { - type test struct { - name string - serviceEndpointsData *ServiceEndpointsData - portName string - expErr string - expectedProxyStateEndpoints *pbproxystate.Endpoints - } - cases := []test{ - { - name: "endpoints with passing health", - serviceEndpointsData: serviceEndpointsData("passing"), - portName: "mesh", - expectedProxyStateEndpoints: &pbproxystate.Endpoints{ - Endpoints: []*pbproxystate.Endpoint{ - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.1.1.1", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.2.2.2", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.3.3.3", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - }, - }, - }, - { - name: "endpoints with critical health", - serviceEndpointsData: serviceEndpointsData("critical"), - portName: "mesh", - expectedProxyStateEndpoints: &pbproxystate.Endpoints{ - Endpoints: []*pbproxystate.Endpoint{ - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.1.1.1", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.2.2.2", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.3.3.3", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_UNHEALTHY, - }, - }, - }, - }, - { - name: "endpoints with any health are considered healthy", - serviceEndpointsData: serviceEndpointsData("any"), - portName: "mesh", - expectedProxyStateEndpoints: &pbproxystate.Endpoints{ - Endpoints: []*pbproxystate.Endpoint{ - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.1.1.1", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.2.2.2", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - { - Address: &pbproxystate.Endpoint_HostPort{ - HostPort: &pbproxystate.HostPortAddress{ - Host: "10.3.3.3", - Port: 20000, - }, - }, - HealthStatus: pbproxystate.HealthStatus_HEALTH_STATUS_HEALTHY, - }, - }, - }, - }, - { - name: "endpoints with missing ports returns an error", - serviceEndpointsData: serviceEndpointsData("missing port lookup"), - portName: "mesh", - expErr: "could not find portName", - }, - { - name: "nil endpoints returns an error", - serviceEndpointsData: serviceEndpointsData("nil endpoints"), - portName: "mesh", - expErr: "service endpoints requires both endpoints and resource", - }, - { - name: "nil resource returns an error", - serviceEndpointsData: serviceEndpointsData("nil resource"), - portName: "mesh", - expErr: "service endpoints requires both endpoints and resource", - }, - { - name: "portName doesn't exist in endpoints results in empty endpoints", - serviceEndpointsData: serviceEndpointsData("passing"), - portName: "does-not-exist", - expectedProxyStateEndpoints: &pbproxystate.Endpoints{ - Endpoints: []*pbproxystate.Endpoint{}, - }, - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - actualEndpoints, err := generateProxyStateEndpoints(tc.serviceEndpointsData, tc.portName) - if tc.expErr != "" { - require.ErrorContains(t, err, tc.expErr) - } else { - prototest.AssertDeepEqual(t, tc.expectedProxyStateEndpoints, actualEndpoints) - } - }) - } -} - -func serviceEndpointsData(variation string) *ServiceEndpointsData { - r := resourcetest.Resource(pbcatalog.ServiceEndpointsType, "test").Build() - eps := &pbcatalog.ServiceEndpoints{ - Endpoints: []*pbcatalog.Endpoint{ - { - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.1.1.1", - Ports: []string{"mesh"}, - }, - { - Host: "10.2.2.2", - Ports: []string{"mesh"}, - }, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - }, - { - Ports: map[string]*pbcatalog.WorkloadPort{ - "mesh": { - Port: 20000, - Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - }, - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "10.3.3.3", - Ports: []string{"mesh"}, - }, - }, - HealthStatus: pbcatalog.Health_HEALTH_PASSING, - }, - }, - } - - switch variation { - case "passing": - case "critical": - eps.Endpoints[0].HealthStatus = pbcatalog.Health_HEALTH_CRITICAL - eps.Endpoints[1].HealthStatus = pbcatalog.Health_HEALTH_CRITICAL - case "any": - eps.Endpoints[0].HealthStatus = pbcatalog.Health_HEALTH_ANY - eps.Endpoints[1].HealthStatus = pbcatalog.Health_HEALTH_ANY - case "missing port lookup": - delete(eps.Endpoints[0].Ports, "mesh") - case "nil endpoints": - eps = nil - case "nil resource": - r = nil - } - - return &ServiceEndpointsData{ - Resource: r, - Endpoints: eps, - } -} diff --git a/internal/mesh/internal/controllers/xds/leaf_cancels.go b/internal/mesh/internal/controllers/xds/leaf_cancels.go deleted file mode 100644 index b1451487d7db5..0000000000000 --- a/internal/mesh/internal/controllers/xds/leaf_cancels.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "context" - "sync" -) - -// LeafCancels holds the cancel functions for leaf certificates being watched by this controller instance. -type LeafCancels struct { - sync.Mutex - // Cancels is a map from a string key constructed from the pbproxystate.LeafReference to a cancel function for the - // leaf watch. - Cancels map[string]context.CancelFunc -} - -func (l *LeafCancels) Get(key string) (context.CancelFunc, bool) { - l.Lock() - defer l.Unlock() - v, ok := l.Cancels[key] - return v, ok -} -func (l *LeafCancels) Set(key string, value context.CancelFunc) { - l.Lock() - defer l.Unlock() - l.Cancels[key] = value -} -func (l *LeafCancels) Delete(key string) { - l.Lock() - defer l.Unlock() - delete(l.Cancels, key) -} diff --git a/internal/mesh/internal/controllers/xds/leaf_mapper.go b/internal/mesh/internal/controllers/xds/leaf_mapper.go deleted file mode 100644 index b268b6b97ccb8..0000000000000 --- a/internal/mesh/internal/controllers/xds/leaf_mapper.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "context" - "fmt" - - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource/mappers/bimapper" -) - -// LeafMapper is a wrapper around endpointsMapper to allow mapping from events to requests for PSTs (as opposed to from a resource to requests for PSTs). -type LeafMapper struct { - *bimapper.Mapper -} - -func (m *LeafMapper) EventMapLink(_ context.Context, _ controller.Runtime, event controller.Event) ([]controller.Request, error) { - // Get cert from event. - cert, ok := event.Obj.(*structs.IssuedCert) - if !ok { - return nil, fmt.Errorf("got invalid event type; expected *structs.IssuedCert") - } - - // The LeafMapper has mappings from leaf certificate resource references to PSTs. So we need to translate the - // contents of the certificate from the event to a leaf resource reference. - leafRef := leafResourceRef(cert.WorkloadIdentity, cert.EnterpriseMeta.NamespaceOrDefault(), cert.EnterpriseMeta.PartitionOrDefault()) - - // Get all the ProxyStateTemplates that reference this leaf. - itemIDs := m.ItemIDsForLink(leafRef) - out := make([]controller.Request, 0, len(itemIDs)) - - for _, item := range itemIDs { - out = append(out, controller.Request{ID: item}) - } - return out, nil -} diff --git a/internal/mesh/internal/controllers/xds/mock_updater.go b/internal/mesh/internal/controllers/xds/mock_updater.go deleted file mode 100644 index 5d62acc4855ea..0000000000000 --- a/internal/mesh/internal/controllers/xds/mock_updater.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "fmt" - "sync" - - "github.com/hashicorp/consul/internal/controller" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// mockUpdater mocks the updater functions, and stores ProxyStates from calls to PushChange, so we can assert it was -// computed correctly in the controller. -type mockUpdater struct { - lock sync.Mutex - // latestPs is a map from a ProxyStateTemplate's id.Name in string form to the last computed ProxyState for that - // ProxyStateTemplate. - latestPs map[string]proxysnapshot.ProxySnapshot - notConnected bool - pushChangeError bool - eventChan chan controller.Event -} - -func newMockUpdater() *mockUpdater { - return &mockUpdater{ - latestPs: make(map[string]proxysnapshot.ProxySnapshot), - } -} - -func (m *mockUpdater) SetPushChangeErrorTrue() { - m.lock.Lock() - defer m.lock.Unlock() - m.pushChangeError = true -} - -func (m *mockUpdater) SetProxyAsNotConnected() { - m.lock.Lock() - defer m.lock.Unlock() - m.notConnected = true -} - -func (m *mockUpdater) PushChange(id *pbresource.ID, snapshot proxysnapshot.ProxySnapshot) error { - m.lock.Lock() - defer m.lock.Unlock() - if m.pushChangeError { - return fmt.Errorf("mock push change error") - } else { - m.setUnsafe(id.Name, snapshot.(*proxytracker.ProxyState)) - } - return nil -} - -func (m *mockUpdater) ProxyConnectedToServer(_ *pbresource.ID) (string, bool) { - m.lock.Lock() - defer m.lock.Unlock() - if m.notConnected { - return "", false - } - return "atoken", true -} - -func (m *mockUpdater) EventChannel() chan controller.Event { - if m.eventChan == nil { - m.eventChan = make(chan controller.Event) - } - return m.eventChan -} - -func (p *mockUpdater) Get(name string) *proxytracker.ProxyState { - p.lock.Lock() - defer p.lock.Unlock() - ps, ok := p.latestPs[name] - if ok { - return ps.(*proxytracker.ProxyState) - } - return nil -} - -func (p *mockUpdater) GetEndpoints(name string) map[string]*pbproxystate.Endpoints { - p.lock.Lock() - defer p.lock.Unlock() - ps, ok := p.latestPs[name] - if ok { - return ps.(*proxytracker.ProxyState).Endpoints - } - return nil -} - -func (p *mockUpdater) GetLeafs(name string) map[string]*pbproxystate.LeafCertificate { - p.lock.Lock() - defer p.lock.Unlock() - ps, ok := p.latestPs[name] - if ok { - return ps.(*proxytracker.ProxyState).LeafCertificates - } - return nil -} - -func (p *mockUpdater) GetTrustBundle(name string) map[string]*pbproxystate.TrustBundle { - p.lock.Lock() - defer p.lock.Unlock() - ps, ok := p.latestPs[name] - if ok { - return ps.(*proxytracker.ProxyState).TrustBundles - } - return nil -} - -func (p *mockUpdater) Set(name string, ps *proxytracker.ProxyState) { - p.lock.Lock() - defer p.lock.Unlock() - p.setUnsafe(name, ps) -} - -func (p *mockUpdater) setUnsafe(name string, ps *proxytracker.ProxyState) { - p.latestPs[name] = ps -} diff --git a/internal/mesh/internal/controllers/xds/proxy_tracker_watch.go b/internal/mesh/internal/controllers/xds/proxy_tracker_watch.go deleted file mode 100644 index cf21dc0f7f409..0000000000000 --- a/internal/mesh/internal/controllers/xds/proxy_tracker_watch.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "context" - "fmt" - - "github.com/hashicorp/consul/internal/controller" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" -) - -func proxySource(updater ProxyUpdater) *controller.Source { - return &controller.Source{Source: updater.EventChannel()} -} - -func proxyMapper(ctx context.Context, rt controller.Runtime, event controller.Event) ([]controller.Request, error) { - connection, ok := event.Obj.(*proxytracker.ProxyConnection) - if !ok { - return nil, fmt.Errorf("expected event to be of type *proxytracker.ProxyConnection but was %+v", event) - } - return []controller.Request{{ID: connection.ProxyID}}, nil -} diff --git a/internal/mesh/internal/controllers/xds/reconciliation_data.go b/internal/mesh/internal/controllers/xds/reconciliation_data.go deleted file mode 100644 index cdbb3a1cd3342..0000000000000 --- a/internal/mesh/internal/controllers/xds/reconciliation_data.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package xds - -import ( - "context" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type ServiceEndpointsData struct { - Resource *pbresource.Resource - Endpoints *pbcatalog.ServiceEndpoints -} - -type ProxyStateTemplateData struct { - Resource *pbresource.Resource - Template *pbmesh.ProxyStateTemplate -} - -// getServiceEndpoints will return a non-nil &ServiceEndpointsData unless there is an error. -func getServiceEndpoints(ctx context.Context, rt controller.Runtime, id *pbresource.ID) (*ServiceEndpointsData, error) { - rsp, err := rt.Client.Read(ctx, &pbresource.ReadRequest{Id: id}) - if err != nil { - return nil, err - } - - var se pbcatalog.ServiceEndpoints - err = rsp.Resource.Data.UnmarshalTo(&se) - if err != nil { - return nil, resource.NewErrDataParse(&se, err) - } - - return &ServiceEndpointsData{Resource: rsp.Resource, Endpoints: &se}, nil -} - -func getProxyStateTemplate(ctx context.Context, rt controller.Runtime, id *pbresource.ID) (*ProxyStateTemplateData, error) { - rsp, err := rt.Client.Read(ctx, &pbresource.ReadRequest{Id: id}) - switch { - case status.Code(err) == codes.NotFound: - return nil, nil - case err != nil: - return nil, err - } - - var pst pbmesh.ProxyStateTemplate - err = rsp.Resource.Data.UnmarshalTo(&pst) - if err != nil { - return nil, resource.NewErrDataParse(&pst, err) - } - - return &ProxyStateTemplateData{Resource: rsp.Resource, Template: &pst}, nil -} diff --git a/internal/mesh/internal/controllers/xds/status/status.go b/internal/mesh/internal/controllers/xds/status/status.go deleted file mode 100644 index 145451f91471d..0000000000000 --- a/internal/mesh/internal/controllers/xds/status/status.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package status - -import ( - "context" - "fmt" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - StatusConditionProxyStateAccepted = "ProxyStateAccepted" - StatusReasonNilProxyState = "ProxyStateNil" - StatusReasonProxyStateReferencesComputed = "ProxyStateReferencesComputed" - StatusReasonEndpointNotRead = "ProxyStateEndpointReferenceReadError" - StatusReasonCreatingProxyStateEndpointsFailed = "ProxyStateEndpointsNotComputed" - StatusReasonPushChangeFailed = "ProxyStatePushChangeFailed" - StatusReasonTrustBundleFetchFailed = "ProxyStateTrustBundleFetchFailed" - StatusReasonLeafWatchSetupFailed = "ProxyStateLeafWatchSetupError" - StatusReasonLeafFetchFailed = "ProxyStateLeafFetchError" - StatusReasonLeafEmpty = "ProxyStateLeafEmptyError" -) - -func KeyFromID(id *pbresource.ID) string { - return fmt.Sprintf("%s/%s/%s", - resource.ToGVK(id.Type), - resource.TenancyToString(id.Tenancy), - id.Name) -} - -func ConditionAccepted() *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_TRUE, - Reason: StatusReasonProxyStateReferencesComputed, - Message: fmt.Sprintf("proxy state was computed and pushed."), - } -} -func ConditionRejectedNilProxyState(pstRef string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonNilProxyState, - Message: fmt.Sprintf("nil proxy state is not valid %q.", pstRef), - } -} -func ConditionRejectedErrorCreatingLeafWatch(leafRef string, err string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonLeafWatchSetupFailed, - Message: fmt.Sprintf("error creating leaf watch %q: %s", leafRef, err), - } -} -func ConditionRejectedErrorGettingLeaf(leafRef string, err string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonLeafFetchFailed, - Message: fmt.Sprintf("error getting leaf from leaf certificate manager %q: %s", leafRef, err), - } -} -func ConditionRejectedErrorCreatingProxyStateLeaf(leafRef string, err string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonLeafEmpty, - Message: fmt.Sprintf("error getting leaf certificate contents %q: %s", leafRef, err), - } -} -func ConditionRejectedErrorReadingEndpoints(endpointRef string, err string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonEndpointNotRead, - Message: fmt.Sprintf("error reading referenced service endpoints %q: %s", endpointRef, err), - } -} -func ConditionRejectedCreatingProxyStateEndpoints(endpointRef string, err string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonCreatingProxyStateEndpointsFailed, - Message: fmt.Sprintf("could not create proxy state endpoints from service endpoints %q: %s", endpointRef, err), - } -} -func ConditionRejectedPushChangeFailed(pstRef string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonPushChangeFailed, - Message: fmt.Sprintf("failed to push change for proxy state template %q", pstRef), - } -} -func ConditionRejectedTrustBundleFetchFailed(pstRef string) *pbresource.Condition { - return &pbresource.Condition{ - Type: StatusConditionProxyStateAccepted, - State: pbresource.Condition_STATE_FALSE, - Reason: StatusReasonTrustBundleFetchFailed, - Message: fmt.Sprintf("failed to fetch trust bundle for proxy state template %q", pstRef), - } -} - -// WriteStatusIfChanged updates the ProxyStateTemplate status if it has changed. -func WriteStatusIfChanged(ctx context.Context, rt controller.Runtime, res *pbresource.Resource, condition *pbresource.Condition) { - newStatus := &pbresource.Status{ - ObservedGeneration: res.Generation, - Conditions: []*pbresource.Condition{ - condition, - }, - } - // If the status is unchanged then we should return and avoid the unnecessary write - const controllerName = "consul.io/xds-controller" - if resource.EqualStatus(res.Status[controllerName], newStatus, false) { - return - } else { - _, err := rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{ - Id: res.Id, - Key: controllerName, - Status: newStatus, - }) - - if err != nil { - rt.Logger.Error("error updating the proxy state template status", "error", err, "proxyStateTeamplate", res.Id) - } - } -} diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden deleted file mode 100644 index dd425312053b5..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden +++ /dev/null @@ -1,185 +0,0 @@ -{ - "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-1.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-1.default.default.dc1" - } - } - ] - }, - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination.golden deleted file mode 100644 index 70448ca450481..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination.golden +++ /dev/null @@ -1,301 +0,0 @@ -{ - "clusters": { - "null_route_cluster": { - "endpointGroup": { - "static": { - "config": { - "connectTimeout": "10s" - } - } - }, - "name": "null_route_cluster", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp2.api-1.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp2.api-2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "routers": [ - { - "l4": { - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - }, - { - "direction": "DIRECTION_OUTBOUND", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - } - } - ], - "unixSocket": { - "mode": "0666", - "path": "/path/to/socket" - } - }, - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 2345 - }, - "name": "default/local/default/api-1:tcp2:1.1.1.1:2345", - "routers": [ - { - "l4": { - "statPrefix": "upstream.tcp2.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp2.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp2.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - }, - { - "direction": "DIRECTION_OUTBOUND", - "name": "default/local/default/api-2:tcp2:/path/to/socket", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp2.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-2.default.default.dc1" - } - } - ], - "unixSocket": { - "mode": "0666", - "path": "/path/to/socket" - } - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index 24c917a4d3381..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,184 +0,0 @@ -{ - "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-1.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-1.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden deleted file mode 100644 index d3657463fde9c..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden +++ /dev/null @@ -1,156 +0,0 @@ -{ - "clusters": { - "null_route_cluster": { - "endpointGroup": { - "static": { - "config": { - "connectTimeout": "10s" - } - } - }, - "name": "null_route_cluster", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "routers": [ - { - "l4": { - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address.golden deleted file mode 100644 index 19ca75501d5b5..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address.golden +++ /dev/null @@ -1,93 +0,0 @@ -{ - "clusters": { - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "tcp.api-2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - } - } - ], - "unixSocket": { - "mode": "0666", - "path": "/path/to/socket" - } - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy.golden deleted file mode 100644 index 780d2a6f49a89..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,124 +0,0 @@ -{ - "clusters": { - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-1.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-1.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden b/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden deleted file mode 100644 index 2638cf3f806e0..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden +++ /dev/null @@ -1,380 +0,0 @@ -{ - "clusters": { - "http.api-1.default.dc1.internal.foo.consul": { - "altStatName": "http.api-1.default.dc1.internal.foo.consul", - "failoverGroup": { - "config": { - "connectTimeout": "55s", - "useAltStatName": true - }, - "endpointGroups": [ - { - "dynamic": { - "config": { - "connectTimeout": "55s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - }, - "name": "failover-target~0~http.api-1.default.dc1.internal.foo.consul" - }, - { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "backup-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/backup1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - }, - "name": "failover-target~1~http.api-1.default.dc1.internal.foo.consul" - } - ] - }, - "name": "http.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "http.api-2.default.dc1.internal.foo.consul": { - "altStatName": "http.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "null_route_cluster": { - "endpointGroup": { - "static": { - "config": { - "connectTimeout": "10s" - } - } - }, - "name": "null_route_cluster", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-1.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "http.api-1.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "http.api-2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-1.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:tcp:1.1.1.1:1234", - "routers": [ - { - "l4": { - "statPrefix": "upstream.tcp.api-1.default.default.dc1", - "weightedClusters": { - "clusters": [ - { - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - } - } - ] - }, - { - "direction": "DIRECTION_OUTBOUND", - "name": "default/local/default/api-2:tcp:/path/to/socket", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-2.default.default.dc1" - } - } - ], - "unixSocket": { - "mode": "0666", - "path": "/path/to/socket" - } - }, - { - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "1.1.1.1", - "port": 1234 - }, - "name": "default/local/default/api-1:http:1.1.1.1:1234", - "routers": [ - { - "l7": { - "route": { - "name": "default/local/default/api-1:http:1.1.1.1:1234" - }, - "statPrefix": "upstream." - } - } - ] - } - ], - "routes": { - "default/local/default/api-1:http:1.1.1.1:1234": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-1:http:1.1.1.1:1234", - "routeRules": [ - { - "destination": { - "destinationConfiguration": { - "timeoutConfig": { - "timeout": "77s" - } - }, - "weightedClusters": { - "clusters": [ - { - "name": "http.api-2.default.dc1.internal.foo.consul", - "weight": 60 - }, - { - "name": "http.api-1.default.dc1.internal.foo.consul", - "weight": 40 - }, - { - "name": "null_route_cluster", - "weight": 10 - } - ] - } - }, - "match": { - "pathMatch": { - "prefix": "/split" - } - } - }, - { - "destination": { - "cluster": { - "name": "http.api-1.default.dc1.internal.foo.consul" - }, - "destinationConfiguration": { - "retryPolicy": { - "numRetries": 4, - "retryOn": "connect-failure" - }, - "timeoutConfig": { - "timeout": "606s" - } - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - }, - { - "destination": { - "cluster": { - "name": "null_route_cluster" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden deleted file mode 100644 index 0d418fc680598..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ /dev/null @@ -1,466 +0,0 @@ -{ - "clusters": { - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "http.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-app2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-app2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app2.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app2.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-app2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "http.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "http.api-app2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-app2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp2.api-app2.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp.api-app2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-app2.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - }, - { - "l7": { - "route": { - "name": "default/local/default/api-app:http" - }, - "statPrefix": "upstream." - }, - "match": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l7": { - "route": { - "name": "default/local/default/api-app2:http" - }, - "statPrefix": "upstream." - }, - "match": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp2.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp2.api-app2.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-app2.default.default.dc1" - }, - "match": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "2.2.2.2", - "prefixLen": 32 - }, - { - "addressPrefix": "3.3.3.3", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "routes": { - "default/local/default/api-app2:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-app2:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "http.api-app2.default.dc1.internal.foo.consul" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "default/local/default/api-app:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-app:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "http.api-app.default.dc1.internal.foo.consul" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden deleted file mode 100644 index c465d0ad84b78..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,262 +0,0 @@ -{ - "clusters": { - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "http.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l7": { - "route": { - "name": "default/local/default/api-app:http" - }, - "statPrefix": "upstream." - }, - "match": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp2.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "routes": { - "default/local/default/api-app:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-app:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "http.api-app.default.dc1.internal.foo.consul" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden deleted file mode 100644 index c465d0ad84b78..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ /dev/null @@ -1,262 +0,0 @@ -{ - "clusters": { - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~http" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", - "protocol": "PROTOCOL_TCP" - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", - "endpointGroup": { - "dynamic": { - "config": { - "connectTimeout": "5s", - "disablePanicThreshold": true - }, - "outboundTls": { - "alpnProtocols": [ - "consul~tcp2" - ], - "outboundMesh": { - "identityKey": "test-identity", - "sni": "api-app.default.dc1.internal.foo.consul", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" - ], - "trustBundlePeerNameKey": "local" - } - } - } - } - }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "http.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "endpoints": [ - { - "healthStatus": "HEALTH_STATUS_HEALTHY", - "hostPort": { - "host": "10.1.1.1", - "port": 20000 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - }, - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "name": "outbound_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "tcp.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 7070, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l7": { - "route": { - "name": "default/local/default/api-app:http" - }, - "statPrefix": "upstream." - }, - "match": { - "destinationPort": 8080, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - }, - { - "l4": { - "cluster": { - "name": "tcp2.api-app.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp2.api-app.default.default.dc1" - }, - "match": { - "destinationPort": 8081, - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ] - } - } - ] - } - ], - "routes": { - "default/local/default/api-app:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "default/local/default/api-app:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "http.api-app.default.dc1.internal.foo.consul" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index c88a05495613c..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,102 +0,0 @@ -{ - "clusters": { - "local_app:port1": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.2", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "statPrefix": "public_listener", - "trafficPermissions": { - "allowPermissions": [ - { - "principals": [ - { - "spiffe": { - "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" - } - } - ] - } - ] - } - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 439c536fdc3bb..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,90 +0,0 @@ -{ - "clusters": { - "local_app:port1": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/l4-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/l4-single-workload-address-without-ports.golden deleted file mode 100644 index 439c536fdc3bb..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/l4-single-workload-address-without-ports.golden +++ /dev/null @@ -1,90 +0,0 @@ -{ - "clusters": { - "local_app:port1": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths.golden b/internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths.golden deleted file mode 100644 index 994b00f41514a..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths.golden +++ /dev/null @@ -1,213 +0,0 @@ -{ - "clusters": { - "exposed_cluster_9090": { - "endpointGroup": { - "static": {} - }, - "name": "exposed_cluster_9090", - "protocol": "PROTOCOL_HTTP" - }, - "exposed_cluster_9091": { - "endpointGroup": { - "static": {} - }, - "name": "exposed_cluster_9091", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:port1": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "exposed_cluster_9090": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - }, - "exposed_cluster_9091": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9091 - } - } - ] - }, - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - } - ] - }, - { - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 1234 - }, - "name": "exposed_path_health1234", - "routers": [ - { - "l7": { - "route": { - "name": "exposed_path_route_health1234" - }, - "statPrefix": "exposed_path_route_health1234", - "staticRoute": true - } - } - ] - }, - { - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 1235 - }, - "name": "exposed_path_GetHealth1235", - "routers": [ - { - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "exposed_path_route_GetHealth1235" - }, - "statPrefix": "exposed_path_route_GetHealth1235", - "staticRoute": true - } - } - ] - } - ], - "routes": { - "exposed_path_route_GetHealth1235": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_route_GetHealth1235", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "exposed_cluster_9091" - } - }, - "match": { - "pathMatch": { - "exact": "GetHealth" - } - } - } - ] - } - ] - }, - "exposed_path_route_health1234": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_route_health1234", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "exposed_cluster_9090" - } - }, - "match": { - "pathMatch": { - "exact": "/health" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections.golden b/internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections.golden deleted file mode 100644 index f75354038bf4d..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections.golden +++ /dev/null @@ -1,305 +0,0 @@ -{ - "clusters": { - "exposed_cluster_9090": { - "endpointGroup": { - "static": {} - }, - "name": "exposed_cluster_9090", - "protocol": "PROTOCOL_HTTP" - }, - "exposed_cluster_9091": { - "endpointGroup": { - "static": {} - }, - "name": "exposed_cluster_9091", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:port1": { - "endpointGroup": { - "static": { - "config": { - "circuitBreakers": { - "upstreamLimits": { - "maxConnections": 123 - } - }, - "connectTimeout": "6s" - } - } - }, - "name": "local_app:port1", - "protocol": "PROTOCOL_TCP" - }, - "local_app:port3": { - "endpointGroup": { - "static": { - "config": { - "circuitBreakers": { - "upstreamLimits": { - "maxConnections": 123 - } - }, - "connectTimeout": "8s" - } - } - }, - "name": "local_app:port3", - "protocol": "PROTOCOL_HTTP" - } - }, - "endpoints": { - "exposed_cluster_9090": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - }, - "exposed_cluster_9091": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9091 - } - } - ] - }, - "local_app:port1": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:port3": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8081 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "balanceConnections": "BALANCE_CONNECTIONS_EXACT", - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:port1" - }, - "maxInboundConnections": "123", - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port1" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "maxInboundConnections": "123", - "route": { - "name": "public_listener:port3" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~port3" - ] - } - } - ] - }, - { - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 1234 - }, - "name": "exposed_path_health1234", - "routers": [ - { - "l7": { - "route": { - "name": "exposed_path_route_health1234" - }, - "statPrefix": "exposed_path_route_health1234", - "staticRoute": true - } - } - ] - }, - { - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 1235 - }, - "name": "exposed_path_GetHealth1235", - "routers": [ - { - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "exposed_path_route_GetHealth1235" - }, - "statPrefix": "exposed_path_route_GetHealth1235", - "staticRoute": true - } - } - ] - } - ], - "routes": { - "exposed_path_route_GetHealth1235": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_route_GetHealth1235", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "exposed_cluster_9091" - } - }, - "match": { - "pathMatch": { - "exact": "GetHealth" - } - } - } - ] - } - ] - }, - "exposed_path_route_health1234": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "exposed_path_route_health1234", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "exposed_cluster_9090" - } - }, - "match": { - "pathMatch": { - "exact": "/health" - } - } - } - ] - } - ] - }, - "public_listener:port3": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:port3", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:port3" - }, - "destinationConfiguration": { - "timeoutConfig": { - "timeout": "9s" - } - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index e2798c8d4e490..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,131 +0,0 @@ -{ - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_TCP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.3", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:admin-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:api-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 21402c187b5e3..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,131 +0,0 @@ -{ - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_TCP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:admin-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:api-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-single-workload-address-without-ports.golden deleted file mode 100644 index 1487da213341e..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-single-workload-address-without-ports.golden +++ /dev/null @@ -1,129 +0,0 @@ -{ - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:admin-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:api-port" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port.golden deleted file mode 100644 index 92f491e9e04d0..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port.golden +++ /dev/null @@ -1,62 +0,0 @@ -{ - "clusters": { - "black-hole-cluster": { - "endpointGroup": { - "static": {} - }, - "name": "black-hole-cluster", - "protocol": "PROTOCOL_TCP" - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "l4": { - "cluster": { - "name": "black-hole-cluster" - }, - "statPrefix": "public_listener" - } - } - ] - } - ], - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index fdab88cd7c184..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,184 +0,0 @@ -{ - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_HTTP2" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.3", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:admin-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:api-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - } - ] - } - ], - "routes": { - "public_listener:admin-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:admin-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:admin-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:api-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:api-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:api-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 3403eed7a864e..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,251 +0,0 @@ -{ - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:grpc-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc-port", - "protocol": "PROTOCOL_GRPC" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - }, - "local_app:grpc-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9091 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:admin-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:api-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc-port" - ] - } - } - ] - } - ], - "routes": { - "public_listener:admin-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:admin-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:admin-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:api-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:api-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:api-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:grpc-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-single-workload-address-without-ports.golden deleted file mode 100644 index 460ede98100a0..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-single-workload-address-without-ports.golden +++ /dev/null @@ -1,248 +0,0 @@ -{ - "clusters": { - "local_app:admin-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:admin-port" - }, - "local_app:api-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:api-port" - }, - "local_app:grpc-port": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc-port" - } - }, - "endpoints": { - "local_app:admin-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - }, - "local_app:api-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9090 - } - } - ] - }, - "local_app:grpc-port": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 9091 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:admin-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~admin-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:api-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~api-port" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc-port" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc-port" - ] - } - } - ] - } - ], - "routes": { - "public_listener:admin-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:admin-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:admin-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:api-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:api-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:api-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:grpc-port": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc-port", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc-port" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/mappers/common/workload_selector_util.go b/internal/mesh/internal/mappers/common/workload_selector_util.go deleted file mode 100644 index 90d96b8f9b47c..0000000000000 --- a/internal/mesh/internal/mappers/common/workload_selector_util.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package common - -import ( - "context" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// MapSelector returns requests of the provided type given a workload -// selector and tenancy. The type has to be name-aligned with the workload. -func MapSelector(ctx context.Context, - client pbresource.ResourceServiceClient, - typ *pbresource.Type, - selector *pbcatalog.WorkloadSelector, - tenancy *pbresource.Tenancy) ([]controller.Request, error) { - if selector == nil { - return nil, nil - } - - var result []controller.Request - - for _, prefix := range selector.GetPrefixes() { - resp, err := client.List(ctx, &pbresource.ListRequest{ - Type: pbcatalog.WorkloadType, - Tenancy: tenancy, - NamePrefix: prefix, - }) - if err != nil { - return nil, err - } - for _, r := range resp.Resources { - id := resource.ReplaceType(typ, r.Id) - result = append(result, controller.Request{ - ID: id, - }) - } - } - - // We don't do lookups for names as this should be done in the controller's reconcile. - for _, name := range selector.GetNames() { - id := &pbresource.ID{ - Name: name, - Tenancy: tenancy, - Type: typ, - } - result = append(result, controller.Request{ - ID: id, - }) - } - - return result, nil -} diff --git a/internal/mesh/internal/mappers/common/workload_selector_util_test.go b/internal/mesh/internal/mappers/common/workload_selector_util_test.go deleted file mode 100644 index 6f9e71e1af54d..0000000000000 --- a/internal/mesh/internal/mappers/common/workload_selector_util_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package common - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestMapSelector(t *testing.T) { - client := svctest.RunResourceService(t, types.Register, catalog.RegisterTypes) - - // Create some workloads. - // For this test, we don't care about the workload data, so we will re-use - // the same data for all workloads. - workloadData := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "127.0.0.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{"p1": {Port: 8080}}, - } - w1 := resourcetest.Resource(pbcatalog.WorkloadType, "w1"). - WithData(t, workloadData). - Write(t, client).Id - w2 := resourcetest.Resource(pbcatalog.WorkloadType, "w2"). - WithData(t, workloadData). - Write(t, client).Id - w3 := resourcetest.Resource(pbcatalog.WorkloadType, "prefix-w3"). - WithData(t, workloadData). - Write(t, client).Id - w4 := resourcetest.Resource(pbcatalog.WorkloadType, "prefix-w4"). - WithData(t, workloadData). - Write(t, client).Id - // This workload should not be used as it's not selected by the workload selector. - resourcetest.Resource(pbcatalog.WorkloadType, "not-selected-workload"). - WithData(t, workloadData). - Write(t, client) - - selector := &pbcatalog.WorkloadSelector{ - Names: []string{"w1", "w2"}, - Prefixes: []string{"prefix"}, - } - expReqs := []controller.Request{ - {ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w1)}, - {ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w2)}, - {ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w3)}, - {ID: resource.ReplaceType(pbmesh.ProxyStateTemplateType, w4)}, - } - - reqs, err := MapSelector(context.Background(), client, - pbmesh.ProxyStateTemplateType, selector, resource.DefaultNamespacedTenancy()) - require.NoError(t, err) - require.Len(t, reqs, len(expReqs)) - prototest.AssertElementsMatch(t, expReqs, reqs) -} diff --git a/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper.go b/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper.go deleted file mode 100644 index 7b064248414b6..0000000000000 --- a/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package workloadselectionmapper - -import ( - "context" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/mappers/common" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/mappers/selectiontracker" - "github.com/hashicorp/consul/lib/stringslice" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type Mapper[T catalog.WorkloadSelecting] struct { - workloadSelectionTracker *selectiontracker.WorkloadSelectionTracker - computedType *pbresource.Type -} - -func New[T catalog.WorkloadSelecting](computedType *pbresource.Type) *Mapper[T] { - if computedType == nil { - panic("computed type is required") - } - return &Mapper[T]{ - workloadSelectionTracker: selectiontracker.New(), - computedType: computedType, - } -} - -// MapToComputedType is responsible for mapping types with workload selectors to the corresponding computed type -// resources which are name-aligned with the workload. This function will also track workload selectors with the ids -// from the workload-selectable types in the mapper. -func (m *Mapper[T]) MapToComputedType(ctx context.Context, rt controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - dec, err := resource.Decode[T](res) - if err != nil { - return nil, err - } - - // First, we return any existing workloads that this proxy configuration selects. - // The number of selected workloads may change in the future, but for this even we - // only need to care about triggering reconcile requests for the current ones. - requests, err := common.MapSelector(ctx, rt.Client, m.computedType, - dec.GetData().GetWorkloads(), res.Id.Tenancy) - if err != nil { - return nil, err - } - - // Then generate requests for any previously selected workloads. - prevSelector := m.workloadSelectionTracker.GetSelector(res.GetId()) - - if !(stringslice.Equal(prevSelector.GetNames(), dec.GetData().GetWorkloads().GetNames()) && - stringslice.Equal(prevSelector.GetPrefixes(), dec.GetData().GetWorkloads().GetPrefixes())) { - // the selector is different, so we need to map those selectors as well. - requestsForPrevSelector, err := common.MapSelector(ctx, rt.Client, m.computedType, - prevSelector, res.Id.Tenancy) - if err != nil { - return nil, err - } - requests = append(requests, requestsForPrevSelector...) - } - - // Second, we track this proxy configuration's selector and ID in the tracker. - m.workloadSelectionTracker.TrackIDForSelector(res.Id, dec.GetData().GetWorkloads()) - - return requests, nil -} - -// IDsForWorkload returns IDs of workload-selecting types that we're tracking for the -// given workload name. -func (m *Mapper[T]) IDsForWorkload(id *pbresource.ID) []*pbresource.ID { - return m.workloadSelectionTracker.GetIDsForWorkload(id) -} - -// UntrackID removes tracking for the workload-selecting resource with the given ID. -func (m *Mapper[T]) UntrackID(id *pbresource.ID) { - m.workloadSelectionTracker.UntrackID(id) -} diff --git a/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper_test.go b/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper_test.go deleted file mode 100644 index 071be1f60d2f1..0000000000000 --- a/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper_test.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package workloadselectionmapper - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/mesh/internal/types" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestMapToComputedType(t *testing.T) { - resourceClient := svctest.RunResourceService(t, types.Register, catalog.RegisterTypes) - mapper := New[*pbmesh.ProxyConfiguration](pbmesh.ComputedProxyConfigurationType) - - workloadData := &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{{Host: "1.1.1.1"}}, - Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - Identity: "test", - } - wID1 := resourcetest.Resource(pbcatalog.WorkloadType, "api-1"). - WithData(t, workloadData). - Write(t, resourceClient).GetId() - wID2 := resourcetest.Resource(pbcatalog.WorkloadType, "api-2"). - WithData(t, workloadData). - Write(t, resourceClient).GetId() - wID3 := resourcetest.Resource(pbcatalog.WorkloadType, "api-abc"). - WithData(t, workloadData). - Write(t, resourceClient).GetId() - wID4 := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). - WithData(t, workloadData). - Write(t, resourceClient).GetId() - - pCfg1 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo", "api-1"}, - Prefixes: []string{"api-a"}, - }, - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - }, - }).Build() - reqs, err := mapper.MapToComputedType(context.Background(), controller.Runtime{Client: resourceClient}, pCfg1) - require.NoError(t, err) - prototest.AssertElementsMatch(t, - controller.MakeRequests(pbmesh.ComputedProxyConfigurationType, []*pbresource.ID{wID1, wID3, wID4}), - reqs) - - pCfg2 := resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - Names: []string{"foo"}, - }, - BootstrapConfig: &pbmesh.BootstrapConfig{ - PrometheusBindAddr: "0.0.0.0:9000", - }, - }).Build() - - reqs, err = mapper.MapToComputedType(context.Background(), controller.Runtime{Client: resourceClient}, pCfg2) - require.NoError(t, err) - prototest.AssertElementsMatch(t, - controller.MakeRequests(pbmesh.ComputedProxyConfigurationType, []*pbresource.ID{wID1, wID2, wID3, wID4}), - reqs) - - // Check mapper state for each workload. - ids := mapper.IDsForWorkload(wID1) - prototest.AssertElementsMatch(t, []*pbresource.ID{pCfg1.Id, pCfg2.Id}, ids) - - ids = mapper.IDsForWorkload(wID2) - prototest.AssertElementsMatch(t, []*pbresource.ID{pCfg2.Id}, ids) - - ids = mapper.IDsForWorkload(wID3) - prototest.AssertElementsMatch(t, []*pbresource.ID{pCfg1.Id, pCfg2.Id}, ids) - - ids = mapper.IDsForWorkload(wID4) - prototest.AssertElementsMatch(t, []*pbresource.ID{pCfg1.Id, pCfg2.Id}, ids) - - // Update pCfg2's selector and check that we generate requests for previous and new selector. - pCfg2 = resourcetest.Resource(pbmesh.ProxyConfigurationType, "cfg2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"foo"}, - }, - BootstrapConfig: &pbmesh.BootstrapConfig{ - PrometheusBindAddr: "0.0.0.0:9000", - }, - }).Build() - - reqs, err = mapper.MapToComputedType(context.Background(), controller.Runtime{Client: resourceClient}, pCfg2) - require.NoError(t, err) - prototest.AssertElementsMatch(t, - controller.MakeRequests(pbmesh.ComputedProxyConfigurationType, []*pbresource.ID{wID4, wID1, wID2, wID3, wID4}), - reqs) - - // Check mapper state for each workload. - ids = mapper.IDsForWorkload(wID1) - prototest.AssertElementsMatch(t, []*pbresource.ID{pCfg1.Id}, ids) - - ids = mapper.IDsForWorkload(wID2) - prototest.AssertElementsMatch(t, []*pbresource.ID{}, ids) - - ids = mapper.IDsForWorkload(wID3) - prototest.AssertElementsMatch(t, []*pbresource.ID{pCfg1.Id}, ids) - - ids = mapper.IDsForWorkload(wID4) - prototest.AssertElementsMatch(t, []*pbresource.ID{pCfg1.Id, pCfg2.Id}, ids) - - // Untrack one of the proxy cfgs and check that mapper is updated. - mapper.UntrackID(pCfg1.Id) - - ids = mapper.IDsForWorkload(wID1) - prototest.AssertElementsMatch(t, []*pbresource.ID{}, ids) - - ids = mapper.IDsForWorkload(wID2) - prototest.AssertElementsMatch(t, []*pbresource.ID{}, ids) - - ids = mapper.IDsForWorkload(wID3) - prototest.AssertElementsMatch(t, []*pbresource.ID{}, ids) - - ids = mapper.IDsForWorkload(wID4) - prototest.AssertElementsMatch(t, []*pbresource.ID{pCfg2.Id}, ids) -} diff --git a/internal/mesh/internal/types/computed_explicit_destinations.go b/internal/mesh/internal/types/computed_explicit_destinations.go deleted file mode 100644 index ac6bbe77798b9..0000000000000 --- a/internal/mesh/internal/types/computed_explicit_destinations.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -func RegisterComputedExplicitDestinations(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.ComputedExplicitDestinationsType, - Proto: &pbmesh.ComputedExplicitDestinations{}, - Scope: resource.ScopeNamespace, - }) -} diff --git a/internal/mesh/internal/types/computed_proxy_configuration.go b/internal/mesh/internal/types/computed_proxy_configuration.go deleted file mode 100644 index 672f4426b6341..0000000000000 --- a/internal/mesh/internal/types/computed_proxy_configuration.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -func RegisterComputedProxyConfiguration(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.ComputedProxyConfigurationType, - Proto: &pbmesh.ComputedProxyConfiguration{}, - Scope: resource.ScopeNamespace, - }) -} diff --git a/internal/mesh/internal/types/computed_routes.go b/internal/mesh/internal/types/computed_routes.go deleted file mode 100644 index b572c01fc3764..0000000000000 --- a/internal/mesh/internal/types/computed_routes.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "fmt" - - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -const ( - // NullRouteBackend is the sentinel string used in ComputedRoutes backend - // targets to indicate that traffic arriving at this destination should - // fail in a protocol-specific way (i.e. HTTP is 5xx) - NullRouteBackend = "NULL-ROUTE" -) - -func RegisterComputedRoutes(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.ComputedRoutesType, - Proto: &pbmesh.ComputedRoutes{}, - Scope: resource.ScopeNamespace, - Validate: ValidateComputedRoutes, - }) -} - -var ValidateComputedRoutes = resource.DecodeAndValidate(validateComputedRoutes) - -func validateComputedRoutes(res *DecodedComputedRoutes) error { - var merr error - - if len(res.Data.PortedConfigs) == 0 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "ported_configs", - Wrapped: resource.ErrEmpty, - }) - } - - // TODO(rb): do more elaborate validation - - for port, pmc := range res.Data.PortedConfigs { - wrapErr := func(err error) error { - return resource.ErrInvalidMapValue{ - Map: "ported_configs", - Key: port, - Wrapped: err, - } - } - if pmc.Config == nil { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "config", - Wrapped: resource.ErrEmpty, - })) - } - - for targetName, target := range pmc.Targets { - wrapTargetErr := func(err error) error { - return wrapErr(resource.ErrInvalidMapValue{ - Map: "targets", - Key: targetName, - Wrapped: err, - }) - } - - switch target.Type { - case pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_UNSPECIFIED: - merr = multierror.Append(merr, wrapTargetErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: resource.ErrMissing, - }), - ) - case pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT: - case pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_INDIRECT: - if target.FailoverConfig != nil { - merr = multierror.Append(merr, wrapTargetErr( - resource.ErrInvalidField{ - Name: "failover_config", - Wrapped: errors.New("failover_config not supported for type = INDIRECT"), - }), - ) - } - default: - merr = multierror.Append(merr, wrapTargetErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: fmt.Errorf("not a supported enum value: %v", target.Type), - }, - )) - } - - if target.DestinationConfig == nil { - merr = multierror.Append(merr, wrapTargetErr(resource.ErrInvalidField{ - Name: "destination_config", - Wrapped: resource.ErrMissing, - })) - } else { - wrapDestConfigErr := func(err error) error { - return wrapTargetErr(resource.ErrInvalidField{ - Name: "destination_config", - Wrapped: err, - }) - } - - destConfig := target.DestinationConfig - if destConfig.ConnectTimeout == nil { - merr = multierror.Append(merr, wrapDestConfigErr(resource.ErrInvalidField{ - Name: "connect_timeout", - Wrapped: resource.ErrMissing, - })) - } else { - connectTimeout := destConfig.ConnectTimeout.AsDuration() - if connectTimeout < 0 { - merr = multierror.Append(merr, wrapDestConfigErr(resource.ErrInvalidField{ - Name: "connect_timeout", - Wrapped: errTimeoutCannotBeNegative(connectTimeout), - })) - } - } - } - - if target.MeshPort == "" { - merr = multierror.Append(merr, wrapTargetErr(resource.ErrInvalidField{ - Name: "mesh_port", - Wrapped: resource.ErrEmpty, - })) - } - if target.ServiceEndpointsId != nil { - merr = multierror.Append(merr, wrapTargetErr(resource.ErrInvalidField{ - Name: "service_endpoints_id", - Wrapped: fmt.Errorf("field should be empty"), - })) - } - if target.ServiceEndpoints != nil { - merr = multierror.Append(merr, wrapTargetErr(resource.ErrInvalidField{ - Name: "service_endpoints", - Wrapped: fmt.Errorf("field should be empty"), - })) - } - if len(target.IdentityRefs) > 0 { - merr = multierror.Append(merr, wrapTargetErr(resource.ErrInvalidField{ - Name: "identity_refs", - Wrapped: fmt.Errorf("field should be empty"), - })) - } - } - - // TODO(rb): do a deep inspection of the config to verify that all - // xRoute backends ultimately point to an item in the targets map. - } - - return merr -} diff --git a/internal/mesh/internal/types/computed_routes_test.go b/internal/mesh/internal/types/computed_routes_test.go deleted file mode 100644 index 8f6aa06f8fcf9..0000000000000 --- a/internal/mesh/internal/types/computed_routes_test.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/durationpb" - - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestValidateComputedRoutes(t *testing.T) { - type testcase struct { - routes *pbmesh.ComputedRoutes - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.ComputedRoutesType, "api"). - WithData(t, tc.routes). - Build() - - err := ValidateComputedRoutes(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.ComputedRoutes](t, res) - prototest.AssertDeepEqual(t, tc.routes, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - "empty": { - routes: &pbmesh.ComputedRoutes{}, - expectErr: `invalid "ported_configs" field: cannot be empty`, - }, - "empty config": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: nil, - }, - }, - }, - expectErr: `invalid value of key "http" within ported_configs: invalid "config" field: cannot be empty`, - }, - "target/missing mesh port": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{}, - }, - Targets: map[string]*pbmesh.BackendTargetDetails{ - "foo": { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "", - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "mesh_port" field: cannot be empty`, - }, - "target/missing type": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{}, - }, - Targets: map[string]*pbmesh.BackendTargetDetails{ - "foo": { - MeshPort: "mesh", - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "type" field: missing required field`, - }, - "target/bad type": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{}, - }, - Targets: map[string]*pbmesh.BackendTargetDetails{ - "foo": { - Type: 99, - MeshPort: "mesh", - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "type" field: not a supported enum value: 99`, - }, - "target/indirect cannot have failover": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{}, - }, - Targets: map[string]*pbmesh.BackendTargetDetails{ - "foo": { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_INDIRECT, - MeshPort: "mesh", - FailoverConfig: &pbmesh.ComputedFailoverConfig{}, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "failover_config" field: failover_config not supported for type = INDIRECT`, - }, - "target/should not have service endpoints id": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{}, - }, - Targets: map[string]*pbmesh.BackendTargetDetails{ - "foo": { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - ServiceEndpointsId: &pbresource.ID{}, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "service_endpoints_id" field: field should be empty`, - }, - "target/should not have service endpoints": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{}, - }, - Targets: map[string]*pbmesh.BackendTargetDetails{ - "foo": { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - ServiceEndpoints: &pbcatalog.ServiceEndpoints{}, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "service_endpoints" field: field should be empty`, - }, - "target/should not have identity refs": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{}, - }, - Targets: map[string]*pbmesh.BackendTargetDetails{ - "foo": { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - IdentityRefs: []*pbresource.Reference{ - {}, - }, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within ported_configs: invalid value of key "foo" within targets: invalid "identity_refs" field: field should be empty`, - }, - "valid": { - routes: &pbmesh.ComputedRoutes{ - PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ - "http": { - Config: &pbmesh.ComputedPortRoutes_Tcp{ - Tcp: &pbmesh.ComputedTCPRoute{}, - }, - Targets: map[string]*pbmesh.BackendTargetDetails{ - "foo": { - Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, - MeshPort: "mesh", - DestinationConfig: &pbmesh.DestinationConfig{ - ConnectTimeout: durationpb.New(5 * time.Second), - }, - }, - }, - }, - }, - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/mesh/internal/types/decoded.go b/internal/mesh/internal/types/decoded.go deleted file mode 100644 index be4836c066ff7..0000000000000 --- a/internal/mesh/internal/types/decoded.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/internal/resource" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -type ( - DecodedHTTPRoute = resource.DecodedResource[*pbmesh.HTTPRoute] - DecodedGRPCRoute = resource.DecodedResource[*pbmesh.GRPCRoute] - DecodedTCPRoute = resource.DecodedResource[*pbmesh.TCPRoute] - DecodedDestinationPolicy = resource.DecodedResource[*pbmesh.DestinationPolicy] - DecodedDestinationsConfiguration = resource.DecodedResource[*pbmesh.DestinationsConfiguration] - DecodedComputedRoutes = resource.DecodedResource[*pbmesh.ComputedRoutes] - DecodedComputedTrafficPermissions = resource.DecodedResource[*pbauth.ComputedTrafficPermissions] - DecodedFailoverPolicy = resource.DecodedResource[*pbcatalog.FailoverPolicy] - DecodedService = resource.DecodedResource[*pbcatalog.Service] - DecodedServiceEndpoints = resource.DecodedResource[*pbcatalog.ServiceEndpoints] - DecodedWorkload = resource.DecodedResource[*pbcatalog.Workload] - DecodedProxyConfiguration = resource.DecodedResource[*pbmesh.ProxyConfiguration] - DecodedComputedProxyConfiguration = resource.DecodedResource[*pbmesh.ComputedProxyConfiguration] - DecodedDestinations = resource.DecodedResource[*pbmesh.Destinations] - DecodedComputedDestinations = resource.DecodedResource[*pbmesh.ComputedExplicitDestinations] - DecodedProxyStateTemplate = resource.DecodedResource[*pbmesh.ProxyStateTemplate] -) diff --git a/internal/mesh/internal/types/destination_policy.go b/internal/mesh/internal/types/destination_policy.go deleted file mode 100644 index 4fe3062367cf5..0000000000000 --- a/internal/mesh/internal/types/destination_policy.go +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "fmt" - - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterDestinationPolicy(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.DestinationPolicyType, - Proto: &pbmesh.DestinationPolicy{}, - Scope: resource.ScopeNamespace, - Validate: ValidateDestinationPolicy, - ACLs: &resource.ACLHooks{ - Read: aclReadHookDestinationPolicy, - Write: aclWriteHookDestinationPolicy, - List: resource.NoOpACLListHook, - }, - }) -} - -var ValidateDestinationPolicy = resource.DecodeAndValidate(validateDestinationPolicy) - -func validateDestinationPolicy(res *DecodedDestinationPolicy) error { - var merr error - - if len(res.Data.PortConfigs) == 0 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "port_configs", - Wrapped: resource.ErrEmpty, - }) - } - - for port, pc := range res.Data.PortConfigs { - wrapErr := func(err error) error { - return resource.ErrInvalidMapValue{ - Map: "port_configs", - Key: port, - Wrapped: err, - } - } - - if dur := pc.ConnectTimeout.AsDuration(); dur < 0 { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "connect_timeout", - Wrapped: fmt.Errorf("'%v', must be >= 0", dur), - })) - } - if dur := pc.RequestTimeout.AsDuration(); dur < 0 { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "request_timeout", - Wrapped: fmt.Errorf("'%v', must be >= 0", dur), - })) - } - - if pc.LoadBalancer != nil { - lb := pc.LoadBalancer - wrapLBErr := func(err error) error { - return wrapErr(resource.ErrInvalidField{ - Name: "load_balancer", - Wrapped: err, - }) - } - - switch lb.Policy { - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_UNSPECIFIED: - // means just do the default - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RANDOM: - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_ROUND_ROBIN: - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_LEAST_REQUEST: - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV: - case pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RING_HASH: - default: - merr = multierror.Append(merr, wrapLBErr(resource.ErrInvalidField{ - Name: "policy", - Wrapped: fmt.Errorf("not a supported enum value: %v", lb.Policy), - })) - } - - if lb.Policy != pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RING_HASH && lb.Config != nil { - if _, ok := lb.Config.(*pbmesh.LoadBalancer_RingHashConfig); ok { - merr = multierror.Append(merr, wrapLBErr(resource.ErrInvalidField{ - Name: "config", - Wrapped: fmt.Errorf("ring_hash_config specified for incompatible load balancing policy %q", lb.Policy), - })) - } - } - - if lb.Policy != pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_LEAST_REQUEST && lb.Config != nil { - if _, ok := lb.Config.(*pbmesh.LoadBalancer_LeastRequestConfig); ok { - merr = multierror.Append(merr, wrapLBErr(resource.ErrInvalidField{ - Name: "config", - Wrapped: fmt.Errorf("least_request_config specified for incompatible load balancing policy %q", lb.Policy), - })) - } - } - - if !lb.Policy.IsHashBased() && len(lb.HashPolicies) > 0 { - merr = multierror.Append(merr, wrapLBErr(resource.ErrInvalidField{ - Name: "hash_policies", - Wrapped: fmt.Errorf("hash_policies specified for non-hash-based policy %q", lb.Policy), - })) - } - - LOOP: - for i, hp := range lb.HashPolicies { - wrapHPErr := func(err error) error { - return wrapLBErr(resource.ErrInvalidListElement{ - Name: "hash_policies", - Index: i, - Wrapped: err, - }) - } - - var hasField bool - switch hp.Field { - case pbmesh.HashPolicyField_HASH_POLICY_FIELD_UNSPECIFIED: - case pbmesh.HashPolicyField_HASH_POLICY_FIELD_HEADER, - pbmesh.HashPolicyField_HASH_POLICY_FIELD_COOKIE, - pbmesh.HashPolicyField_HASH_POLICY_FIELD_QUERY_PARAMETER: - hasField = true - default: - merr = multierror.Append(merr, wrapHPErr(resource.ErrInvalidField{ - Name: "field", - Wrapped: fmt.Errorf("not a supported enum value: %v", hp.Field), - })) - continue LOOP // no need to keep validating - } - - if hp.SourceIp { - if hasField { - merr = multierror.Append(merr, wrapHPErr(resource.ErrInvalidField{ - Name: "field", - Wrapped: fmt.Errorf("a single hash policy cannot hash both a source address and a %q", hp.Field), - })) - } - if hp.FieldValue != "" { - merr = multierror.Append(merr, wrapHPErr(resource.ErrInvalidField{ - Name: "field_value", - Wrapped: errors.New("cannot be specified when hashing source_ip"), - })) - } - } - - if hasField && hp.FieldValue == "" { - merr = multierror.Append(merr, wrapHPErr(resource.ErrInvalidField{ - Name: "field_value", - Wrapped: fmt.Errorf("field %q was specified without a field_value", hp.Field), - })) - } - if hp.FieldValue != "" && !hasField { - merr = multierror.Append(merr, wrapHPErr(resource.ErrInvalidField{ - Name: "field", - Wrapped: resource.ErrMissing, - })) - merr = multierror.Append(merr, wrapHPErr(resource.ErrInvalidField{ - Name: "field_value", - Wrapped: errors.New("requires a field to apply to"), - })) - } - if hp.CookieConfig != nil { - if hp.Field != pbmesh.HashPolicyField_HASH_POLICY_FIELD_COOKIE { - merr = multierror.Append(merr, wrapHPErr(resource.ErrInvalidField{ - Name: "cookie_config", - Wrapped: fmt.Errorf("incompatible with field %q", hp.Field), - })) - } - if hp.CookieConfig.Session && hp.CookieConfig.Ttl.AsDuration() != 0 { - merr = multierror.Append(merr, wrapHPErr(resource.ErrInvalidField{ - Name: "cookie_config", - Wrapped: resource.ErrInvalidField{ - Name: "ttl", - Wrapped: fmt.Errorf("a session cookie cannot have an associated TTL"), - }, - })) - } - } - } - } - - if pc.LocalityPrioritization != nil { - lp := pc.LocalityPrioritization - wrapLPErr := func(err error) error { - return wrapErr(resource.ErrInvalidField{ - Name: "locality_prioritization", - Wrapped: err, - }) - } - - switch lp.Mode { - case pbmesh.LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED: - // means pbmesh.LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_NONE - case pbmesh.LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_NONE: - case pbmesh.LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_FAILOVER: - default: - merr = multierror.Append(merr, wrapLPErr(resource.ErrInvalidField{ - Name: "mode", - Wrapped: fmt.Errorf("not a supported enum value: %v", lp.Mode), - })) - } - } - } - - return merr -} - -func aclReadHookDestinationPolicy(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - // DestinationPolicy is name-aligned with Service - serviceName := id.Name - - // Check service:read permissions. - return authorizer.ToAllowAuthorizer().ServiceReadAllowed(serviceName, authzContext) -} - -func aclWriteHookDestinationPolicy(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - // DestinationPolicy is name-aligned with Service - serviceName := res.Id.Name - - // Check service:write permissions on the service this is controlling. - return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(serviceName, authzContext) -} diff --git a/internal/mesh/internal/types/destination_policy_test.go b/internal/mesh/internal/types/destination_policy_test.go deleted file mode 100644 index 8edb51b2d8314..0000000000000 --- a/internal/mesh/internal/types/destination_policy_test.go +++ /dev/null @@ -1,609 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/durationpb" - - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestValidateDestinationPolicy(t *testing.T) { - type testcase struct { - policy *pbmesh.DestinationPolicy - expectErr string - expectErrs []string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.DestinationPolicyType, "api"). - WithData(t, tc.policy). - Build() - - err := ValidateDestinationPolicy(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.DestinationPolicy](t, res) - prototest.AssertDeepEqual(t, tc.policy, got.Data) - - if tc.expectErr != "" && len(tc.expectErrs) > 0 { - t.Fatalf("cannot test singular and list errors at the same time") - } - - if tc.expectErr == "" && len(tc.expectErrs) == 0 { - require.NoError(t, err) - } else if tc.expectErr != "" { - testutil.RequireErrorContains(t, err, tc.expectErr) - } else { - for _, expectErr := range tc.expectErrs { - testutil.RequireErrorContains(t, err, expectErr) - } - } - } - - cases := map[string]testcase{ - // emptiness - "empty": { - policy: &pbmesh.DestinationPolicy{}, - expectErr: `invalid "port_configs" field: cannot be empty`, - }, - "good connect timeout": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - }, - }, - }, - }, - "bad connect timeout": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(-55 * time.Second), - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "connect_timeout" field: '-55s', must be >= 0`, - }, - "good request timeout": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - RequestTimeout: durationpb.New(55 * time.Second), - }, - }, - }, - }, - "bad request timeout": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - RequestTimeout: durationpb.New(-55 * time.Second), - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "request_timeout" field: '-55s', must be >= 0`, - }, - // load balancer - "lbpolicy: missing enum": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{}, - }, - }, - }, - }, - "lbpolicy: bad enum": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: 99, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid "policy" field: not a supported enum value: 99`, - }, - "lbpolicy: supported": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RANDOM, - }, - }, - }, - }, - }, - "lbpolicy: bad for least request config": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RING_HASH, - Config: &pbmesh.LoadBalancer_LeastRequestConfig{ - LeastRequestConfig: &pbmesh.LeastRequestConfig{ - ChoiceCount: 10, - }, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid "config" field: least_request_config specified for incompatible load balancing policy "LOAD_BALANCER_POLICY_RING_HASH"`, - }, - "lbpolicy: bad for ring hash config": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_LEAST_REQUEST, - Config: &pbmesh.LoadBalancer_RingHashConfig{ - RingHashConfig: &pbmesh.RingHashConfig{ - MinimumRingSize: 1024, - }, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid "config" field: ring_hash_config specified for incompatible load balancing policy "LOAD_BALANCER_POLICY_LEAST_REQUEST"`, - }, - "lbpolicy: good for least request config": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_LEAST_REQUEST, - Config: &pbmesh.LoadBalancer_LeastRequestConfig{ - LeastRequestConfig: &pbmesh.LeastRequestConfig{ - ChoiceCount: 10, - }, - }, - }, - }, - }, - }, - }, - "lbpolicy: good for ring hash config": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RING_HASH, - Config: &pbmesh.LoadBalancer_RingHashConfig{ - RingHashConfig: &pbmesh.RingHashConfig{ - MinimumRingSize: 1024, - }, - }, - }, - }, - }, - }, - }, - "lbpolicy: empty policy with hash policy": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - HashPolicies: []*pbmesh.HashPolicy{ - {SourceIp: true}, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid "hash_policies" field: hash_policies specified for non-hash-based policy "LOAD_BALANCER_POLICY_UNSPECIFIED"`, - }, - "lbconfig: cookie config with header policy": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - Field: pbmesh.HashPolicyField_HASH_POLICY_FIELD_HEADER, - FieldValue: "x-user-id", - CookieConfig: &pbmesh.CookieConfig{ - Ttl: durationpb.New(10 * time.Second), - Path: "/root", - }, - }, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "cookie_config" field: incompatible with field "HASH_POLICY_FIELD_HEADER"`, - }, - "lbconfig: cannot generate session cookie with ttl": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - Field: pbmesh.HashPolicyField_HASH_POLICY_FIELD_COOKIE, - FieldValue: "good-cookie", - CookieConfig: &pbmesh.CookieConfig{ - Session: true, - Ttl: durationpb.New(10 * time.Second), - }, - }, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "cookie_config" field: invalid "ttl" field: a session cookie cannot have an associated TTL`, - }, - "lbconfig: valid cookie policy": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - Field: pbmesh.HashPolicyField_HASH_POLICY_FIELD_COOKIE, - FieldValue: "good-cookie", - CookieConfig: &pbmesh.CookieConfig{ - Ttl: durationpb.New(10 * time.Second), - Path: "/oven", - }, - }, - }, - }, - }, - }, - }, - }, - "lbconfig: bad match field": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - Field: 99, - FieldValue: "X-Consul-Token", - }, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field" field: not a supported enum value: 99`, - }, - "lbconfig: supported match field": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - Field: pbmesh.HashPolicyField_HASH_POLICY_FIELD_HEADER, - FieldValue: "X-Consul-Token", - }, - }, - }, - }, - }, - }, - }, - "lbconfig: missing match field": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - FieldValue: "X-Consul-Token", - }, - }, - }, - }, - }, - }, - expectErrs: []string{ - `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field" field: missing required field`, - `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field_value" field: requires a field to apply to`, - }, - }, - "lbconfig: cannot match on source address and custom field": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - Field: pbmesh.HashPolicyField_HASH_POLICY_FIELD_HEADER, - SourceIp: true, - }, - }, - }, - }, - }, - }, - expectErrs: []string{ - `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field" field: a single hash policy cannot hash both a source address and a "HASH_POLICY_FIELD_HEADER"`, - `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field_value" field: field "HASH_POLICY_FIELD_HEADER" was specified without a field_value`, - }, - }, - "lbconfig: matchvalue not compatible with source address": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - FieldValue: "X-Consul-Token", - SourceIp: true, - }, - }, - }, - }, - }, - }, - expectErrs: []string{ - `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field_value" field: cannot be specified when hashing source_ip`, - `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field_value" field: requires a field to apply to`, - }, - }, - "lbconfig: field without match value": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - Field: pbmesh.HashPolicyField_HASH_POLICY_FIELD_HEADER, - }, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field_value" field: field "HASH_POLICY_FIELD_HEADER" was specified without a field_value`, - }, - "lbconfig: matchvalue without field": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - HashPolicies: []*pbmesh.HashPolicy{ - { - FieldValue: "my-cookie", - }, - }, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "load_balancer" field: invalid element at index 0 of list "hash_policies": invalid "field_value" field: requires a field to apply to`, - }, - "lbconfig: ring hash kitchen sink": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_RING_HASH, - Config: &pbmesh.LoadBalancer_RingHashConfig{ - RingHashConfig: &pbmesh.RingHashConfig{ - MaximumRingSize: 10, - MinimumRingSize: 2, - }, - }, - HashPolicies: []*pbmesh.HashPolicy{ - { - Field: pbmesh.HashPolicyField_HASH_POLICY_FIELD_COOKIE, - FieldValue: "my-cookie", - }, - { - Field: pbmesh.HashPolicyField_HASH_POLICY_FIELD_HEADER, - FieldValue: "alt-header", - Terminal: true, - }, - }, - }, - }, - }, - }, - }, - "lbconfig: least request kitchen sink": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - LoadBalancer: &pbmesh.LoadBalancer{ - Policy: pbmesh.LoadBalancerPolicy_LOAD_BALANCER_POLICY_LEAST_REQUEST, - Config: &pbmesh.LoadBalancer_LeastRequestConfig{ - LeastRequestConfig: &pbmesh.LeastRequestConfig{ - ChoiceCount: 10, - }, - }, - }, - }, - }, - }, - }, - "locality: good mode": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - LocalityPrioritization: &pbmesh.LocalityPrioritization{ - Mode: pbmesh.LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_FAILOVER, - }, - }, - }, - }, - }, - "locality: unset mode": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - LocalityPrioritization: &pbmesh.LocalityPrioritization{ - Mode: pbmesh.LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED, - }, - }, - }, - }, - }, - "locality: bad mode": { - policy: &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - LocalityPrioritization: &pbmesh.LocalityPrioritization{ - Mode: 99, - }, - }, - }, - }, - expectErr: `invalid value of key "http" within port_configs: invalid "locality_prioritization" field: invalid "mode" field: not a supported enum value: 99`, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestDestinationPolicyACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - newPolicy := func(t *testing.T, tenancyStr string) *pbresource.Resource { - res := resourcetest.Resource(pbmesh.DestinationPolicyType, "api"). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - WithData(t, &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - }, - }, - }). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - return res - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - run := func(t *testing.T, name string, tc resourcetest.ACLTestCase) { - t.Run(name, func(t *testing.T) { - resourcetest.RunACLTestCase(t, tc, registry) - }) - } - - isEnterprise := (structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default") - - serviceRead := func(partition, namespace, name string) string { - if isEnterprise { - return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "read" } } }`, partition, namespace, name) - } - return fmt.Sprintf(` service %q { policy = "read" } `, name) - } - serviceWrite := func(partition, namespace, name string) string { - if isEnterprise { - return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "write" } } }`, partition, namespace, name) - } - return fmt.Sprintf(` service %q { policy = "write" } `, name) - } - - assert := func(t *testing.T, name string, rules string, res *pbresource.Resource, readOK, writeOK string) { - tc := resourcetest.ACLTestCase{ - AuthCtx: resource.AuthorizerContext(res.Id.Tenancy), - Rules: rules, - Res: res, - ReadOK: readOK, - WriteOK: writeOK, - ListOK: DEFAULT, - } - run(t, name, tc) - } - - tenancies := []string{"default.default"} - if isEnterprise { - tenancies = append(tenancies, "default.foo", "alpha.default", "alpha.foo") - } - - for _, policyTenancyStr := range tenancies { - t.Run("policy tenancy: "+policyTenancyStr, func(t *testing.T) { - for _, aclTenancyStr := range tenancies { - t.Run("acl tenancy: "+aclTenancyStr, func(t *testing.T) { - aclTenancy := resourcetest.Tenancy(aclTenancyStr) - - maybe := func(match string) string { - if policyTenancyStr != aclTenancyStr { - return DENY - } - return match - } - - t.Run("no rules", func(t *testing.T) { - rules := `` - assert(t, "any", rules, newPolicy(t, policyTenancyStr), DENY, DENY) - }) - t.Run("api:read", func(t *testing.T) { - rules := serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "api") - assert(t, "any", rules, newPolicy(t, policyTenancyStr), maybe(ALLOW), DENY) - }) - t.Run("api:write", func(t *testing.T) { - rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api") - assert(t, "any", rules, newPolicy(t, policyTenancyStr), maybe(ALLOW), maybe(ALLOW)) - }) - }) - } - }) - } -} diff --git a/internal/mesh/internal/types/destinations.go b/internal/mesh/internal/types/destinations.go deleted file mode 100644 index 7de3011e3ef0a..0000000000000 --- a/internal/mesh/internal/types/destinations.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "net" - - "github.com/hashicorp/go-multierror" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterDestinations(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.DestinationsType, - Proto: &pbmesh.Destinations{}, - Scope: resource.ScopeNamespace, - Mutate: MutateDestinations, - Validate: ValidateDestinations, - ACLs: catalog.ACLHooksForWorkloadSelectingType[*pbmesh.Destinations](), - }) -} - -var MutateDestinations = resource.DecodeAndMutate(mutateDestinations) - -func mutateDestinations(res *DecodedDestinations) (bool, error) { - changed := false - - for _, dest := range res.Data.Destinations { - if dest.DestinationRef == nil { - continue // skip; let the validation hook error out instead - } - if dest.DestinationRef.Tenancy != nil && !isLocalPeer(dest.DestinationRef.Tenancy.PeerName) { - // TODO(peering/v2): remove this bypass when we know what to do with - // non-local peer references. - continue - } - orig := proto.Clone(dest.DestinationRef).(*pbresource.Reference) - resource.DefaultReferenceTenancy( - dest.DestinationRef, - res.Id.GetTenancy(), - resource.DefaultNamespacedTenancy(), // Services are all namespace scoped. - ) - - if !proto.Equal(orig, dest.DestinationRef) { - changed = true - } - } - - return changed, nil -} - -func isLocalPeer(p string) bool { - return p == "local" || p == "" -} - -var ValidateDestinations = resource.DecodeAndValidate(validateDestinations) - -func validateDestinations(res *DecodedDestinations) error { - var merr error - - if selErr := catalog.ValidateSelector(res.Data.Workloads, false); selErr != nil { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "workloads", - Wrapped: selErr, - }) - } - - if res.Data.GetPqDestinations() != nil { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "pq_destinations", - Wrapped: resource.ErrUnsupported, - }) - } - - for i, dest := range res.Data.Destinations { - wrapDestErr := func(err error) error { - return resource.ErrInvalidListElement{ - Name: "destinations", - Index: i, - Wrapped: err, - } - } - - wrapRefErr := func(err error) error { - return wrapDestErr(resource.ErrInvalidField{ - Name: "destination_ref", - Wrapped: err, - }) - } - - if refErr := catalog.ValidateLocalServiceRefNoSection(dest.DestinationRef, wrapRefErr); refErr != nil { - merr = multierror.Append(merr, refErr) - } - - if portErr := catalog.ValidatePortName(dest.DestinationPort); portErr != nil { - merr = multierror.Append(merr, wrapDestErr(resource.ErrInvalidField{ - Name: "destination_port", - Wrapped: portErr, - })) - } - - if dest.GetDatacenter() != "" { - merr = multierror.Append(merr, wrapDestErr(resource.ErrInvalidField{ - Name: "datacenter", - Wrapped: resource.ErrUnsupported, - })) - } - - if listenAddrErr := validateListenAddr(dest); listenAddrErr != nil { - merr = multierror.Append(merr, wrapDestErr(listenAddrErr)) - } - } - - return merr -} - -func validateListenAddr(dest *pbmesh.Destination) error { - var merr error - - if dest.GetListenAddr() == nil { - return multierror.Append(merr, resource.ErrInvalidFields{ - Names: []string{"ip_port", "unix"}, - Wrapped: resource.ErrMissingOneOf, - }) - } - - switch listenAddr := dest.GetListenAddr().(type) { - case *pbmesh.Destination_IpPort: - if ipPortErr := validateIPPort(listenAddr.IpPort); ipPortErr != nil { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "ip_port", - Wrapped: ipPortErr, - }) - } - case *pbmesh.Destination_Unix: - if !catalog.IsValidUnixSocketPath(listenAddr.Unix.GetPath()) { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "unix", - Wrapped: resource.ErrInvalidField{ - Name: "path", - Wrapped: errInvalidUnixSocketPath, - }, - }) - } - } - - return merr -} - -func validateIPPort(ipPort *pbmesh.IPPortAddress) error { - var merr error - - if listenPortErr := validatePort(ipPort.GetPort(), "port"); listenPortErr != nil { - merr = multierror.Append(merr, listenPortErr) - } - - if net.ParseIP(ipPort.GetIp()) == nil { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "ip", - Wrapped: errInvalidIP, - }) - } - - return merr -} diff --git a/internal/mesh/internal/types/destinations_configuration.go b/internal/mesh/internal/types/destinations_configuration.go deleted file mode 100644 index 7d46d93ed9993..0000000000000 --- a/internal/mesh/internal/types/destinations_configuration.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/internal/catalog" - - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -func RegisterDestinationsConfiguration(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.DestinationsConfigurationType, - Proto: &pbmesh.DestinationsConfiguration{}, - Scope: resource.ScopeNamespace, - Validate: ValidateDestinationsConfiguration, - ACLs: catalog.ACLHooksForWorkloadSelectingType[*pbmesh.DestinationsConfiguration](), - }) -} - -var ValidateDestinationsConfiguration = resource.DecodeAndValidate(validateDestinationsConfiguration) - -func validateDestinationsConfiguration(res *DecodedDestinationsConfiguration) error { - var merr error - - // Validate the workload selector - if selErr := catalog.ValidateSelector(res.Data.Workloads, false); selErr != nil { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "workloads", - Wrapped: selErr, - }) - } - - return merr -} diff --git a/internal/mesh/internal/types/destinations_configuration_test.go b/internal/mesh/internal/types/destinations_configuration_test.go deleted file mode 100644 index 11af0732d5d9d..0000000000000 --- a/internal/mesh/internal/types/destinations_configuration_test.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - - catalogtesthelpers "github.com/hashicorp/consul/internal/catalog/catalogtest/helpers" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestDestinationsConfigurationACLs(t *testing.T) { - catalogtesthelpers.RunWorkloadSelectingTypeACLsTests[*pbmesh.DestinationsConfiguration](t, pbmesh.DestinationsConfigurationType, - func(selector *pbcatalog.WorkloadSelector) *pbmesh.DestinationsConfiguration { - return &pbmesh.DestinationsConfiguration{Workloads: selector} - }, - RegisterDestinationsConfiguration, - ) -} - -func TestValidateDestinationsConfiguration(t *testing.T) { - type testcase struct { - data *pbmesh.DestinationsConfiguration - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.DestinationsConfigurationType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, tc.data). - Build() - - err := ValidateDestinationsConfiguration(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.DestinationsConfiguration](t, res) - prototest.AssertDeepEqual(t, tc.data, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - // emptiness - "empty": { - data: &pbmesh.DestinationsConfiguration{}, - expectErr: `invalid "workloads" field: cannot be empty`, - }, - "empty selector": { - data: &pbmesh.DestinationsConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{}, - }, - expectErr: `invalid "workloads" field: cannot be empty`, - }, - "bad selector": { - data: &pbmesh.DestinationsConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - Filter: "garbage.foo == bar", - }, - }, - expectErr: `invalid "filter" field: filter "garbage.foo == bar" is invalid: Selector "garbage" is not valid`, - }, - "good selector": { - data: &pbmesh.DestinationsConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - Filter: "metadata.foo == bar", - }, - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/mesh/internal/types/destinations_test.go b/internal/mesh/internal/types/destinations_test.go deleted file mode 100644 index 55624a6316f4b..0000000000000 --- a/internal/mesh/internal/types/destinations_test.go +++ /dev/null @@ -1,427 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - - catalogtesthelpers "github.com/hashicorp/consul/internal/catalog/catalogtest/helpers" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestMutateDestinations(t *testing.T) { - type testcase struct { - tenancy *pbresource.Tenancy - data *pbmesh.Destinations - expect *pbmesh.Destinations - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.DestinationsType, "api"). - WithTenancy(tc.tenancy). - WithData(t, tc.data). - Build() - - err := MutateDestinations(res) - - got := resourcetest.MustDecode[*pbmesh.Destinations](t, res) - - if tc.expectErr == "" { - require.NoError(t, err) - prototest.AssertDeepEqual(t, tc.expect, got.Data) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - "empty-1": { - data: &pbmesh.Destinations{}, - expect: &pbmesh.Destinations{}, - }, - "invalid/nil dest ref": { - data: &pbmesh.Destinations{ - Destinations: []*pbmesh.Destination{ - {DestinationRef: nil}, - }, - }, - expect: &pbmesh.Destinations{ // untouched - Destinations: []*pbmesh.Destination{ - {DestinationRef: nil}, - }, - }, - }, - "dest ref tenancy defaulting": { - tenancy: resourcetest.Tenancy("foo.bar"), - data: &pbmesh.Destinations{ - Destinations: []*pbmesh.Destination{ - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "", "api")}, - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, ".zim", "api")}, - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api")}, - }, - }, - expect: &pbmesh.Destinations{ - Destinations: []*pbmesh.Destination{ - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api")}, - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.zim", "api")}, - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api")}, - }, - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestValidateDestinations(t *testing.T) { - type testcase struct { - data *pbmesh.Destinations - skipMutate bool - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.DestinationsType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, tc.data). - Build() - - if !tc.skipMutate { - require.NoError(t, MutateDestinations(res)) - - // Verify that mutate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.Destinations](t, res) - prototest.AssertDeepEqual(t, tc.data, got.Data) - } - - err := ValidateDestinations(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.Destinations](t, res) - prototest.AssertDeepEqual(t, tc.data, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - // emptiness - "empty": { - data: &pbmesh.Destinations{}, - expectErr: `invalid "workloads" field: cannot be empty`, - }, - "empty selector": { - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{}, - }, - expectErr: `invalid "workloads" field: cannot be empty`, - }, - "bad selector": { - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - Filter: "garbage.foo == bar", - }, - }, - expectErr: `invalid "filter" field: filter "garbage.foo == bar" is invalid: Selector "garbage" is not valid`, - }, - "dest/nil ref": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - }, - Destinations: []*pbmesh.Destination{ - {DestinationRef: nil}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: missing required field`, - }, - "dest/bad type": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - }, - Destinations: []*pbmesh.Destination{ - {DestinationRef: newRefWithTenancy(pbcatalog.WorkloadType, "default.default", "api")}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "type" field: reference must have type catalog.v2beta1.Service`, - }, - "dest/nil tenancy": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - }, - Destinations: []*pbmesh.Destination{ - {DestinationRef: &pbresource.Reference{Type: pbcatalog.ServiceType, Name: "api"}}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "tenancy" field: missing required field`, - }, - "dest/bad dest tenancy/partition": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - }, - Destinations: []*pbmesh.Destination{ - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, ".bar", "api")}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "tenancy" field: invalid "partition" field: cannot be empty`, - }, - "dest/bad dest tenancy/namespace": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - }, - Destinations: []*pbmesh.Destination{ - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo", "api")}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "tenancy" field: invalid "namespace" field: cannot be empty`, - }, - "dest/bad dest tenancy/peer_name": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - }, - Destinations: []*pbmesh.Destination{ - {DestinationRef: resourcetest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(&pbresource.Tenancy{Partition: "foo", Namespace: "bar"}). - Reference("")}, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "tenancy" field: invalid "peer_name" field: must be set to "local"`, - }, - "unsupported pq_destinations": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - PqDestinations: []*pbmesh.PreparedQueryDestination{ - {Name: "foo-query"}, - }, - }, - expectErr: `invalid "pq_destinations" field: field is currently not supported`, - }, - "missing destination port": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1234, - }, - }, - }, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "destination_port" field: cannot be empty`, - }, - "unsupported datacenter": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), - DestinationPort: "p1", - Datacenter: "dc2", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1234, - }, - }, - }, - }, - }, - expectErr: `invalid element at index 0 of list "destinations": invalid "datacenter" field: field is currently not supported`, - }, - "missing listen addr": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), - DestinationPort: "p1", - }, - }, - }, - expectErr: `invalid "ip_port,unix" fields: missing one of the required fields`, - }, - "invalid ip for listen addr": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), - DestinationPort: "p1", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "invalid", - Port: 1234, - }, - }, - }, - }, - }, - expectErr: `invalid "ip" field: IP address is not valid`, - }, - "invalid port for listen addr": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), - DestinationPort: "p1", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 0, - }, - }, - }, - }, - }, - expectErr: `invalid "port" field: port number is outside the range 1 to 65535`, - }, - "invalid unix path for listen addr": { - skipMutate: true, - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), - DestinationPort: "p1", - ListenAddr: &pbmesh.Destination_Unix{ - Unix: &pbmesh.UnixSocketAddress{ - Path: "foo", - }, - }, - }, - }, - }, - expectErr: `invalid "unix" field: invalid "path" field: unix socket path is not valid`, - }, - "normal": { - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), - DestinationPort: "p1", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1234, - }, - }, - }, - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.zim", "api"), - DestinationPort: "p2", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1235, - }, - }, - }, - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api"), - DestinationPort: "p3", - ListenAddr: &pbmesh.Destination_Unix{ - Unix: &pbmesh.UnixSocketAddress{ - Path: "unix://foo/bar", - }, - }, - }, - }, - }, - }, - "normal with selector": { - data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - Filter: "metadata.foo == bar", - }, - Destinations: []*pbmesh.Destination{ - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), - DestinationPort: "p1", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1234, - }, - }, - }, - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.zim", "api"), - DestinationPort: "p2", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "127.0.0.1", - Port: 1235, - }, - }, - }, - { - DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api"), - DestinationPort: "p3", - ListenAddr: &pbmesh.Destination_Unix{ - Unix: &pbmesh.UnixSocketAddress{ - Path: "unix://foo/bar", - }, - }, - }, - }, - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestDestinationsACLs(t *testing.T) { - catalogtesthelpers.RunWorkloadSelectingTypeACLsTests[*pbmesh.Destinations](t, pbmesh.DestinationsType, - func(selector *pbcatalog.WorkloadSelector) *pbmesh.Destinations { - return &pbmesh.Destinations{Workloads: selector} - }, - RegisterDestinations, - ) -} diff --git a/internal/mesh/internal/types/errors.go b/internal/mesh/internal/types/errors.go deleted file mode 100644 index bc9dacbbf0c44..0000000000000 --- a/internal/mesh/internal/types/errors.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" -) - -var ( - errInvalidPort = errors.New("port number is outside the range 1 to 65535") - errInvalidIP = errors.New("IP address is not valid") - errInvalidUnixSocketPath = errors.New("unix socket path is not valid") - errInvalidExposePathProtocol = errors.New("invalid protocol: only HTTP and HTTP2 protocols are allowed") - errMissingProxyConfigData = errors.New("at least one of \"bootstrap_config\" or \"dynamic_config\" fields must be set") -) diff --git a/internal/mesh/internal/types/grpc_route.go b/internal/mesh/internal/types/grpc_route.go deleted file mode 100644 index b861abccdc050..0000000000000 --- a/internal/mesh/internal/types/grpc_route.go +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "fmt" - - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -func RegisterGRPCRoute(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.GRPCRouteType, - Proto: &pbmesh.GRPCRoute{}, - Scope: resource.ScopeNamespace, - Mutate: MutateGRPCRoute, - Validate: ValidateGRPCRoute, - ACLs: xRouteACLHooks[*pbmesh.GRPCRoute](), - }) -} - -var MutateGRPCRoute = resource.DecodeAndMutate(mutateGRPCRoute) - -func mutateGRPCRoute(res *DecodedGRPCRoute) (bool, error) { - changed := false - - if mutateParentRefs(res.Id.Tenancy, res.Data.ParentRefs) { - changed = true - } - - for _, rule := range res.Data.Rules { - for _, backend := range rule.BackendRefs { - if backend.BackendRef == nil || backend.BackendRef.Ref == nil { - continue - } - if mutateXRouteRef(res.Id.Tenancy, backend.BackendRef.Ref) { - changed = true - } - } - } - - return changed, nil -} - -var ValidateGRPCRoute = resource.DecodeAndValidate(validateGRPCRoute) - -func validateGRPCRoute(res *DecodedGRPCRoute) error { - var merr error - if err := validateParentRefs(res.Id, res.Data.ParentRefs); err != nil { - merr = multierror.Append(merr, err) - } - - if len(res.Data.Hostnames) > 0 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "hostnames", - Wrapped: errors.New("should not populate hostnames"), - }) - } - - for i, rule := range res.Data.Rules { - wrapRuleErr := func(err error) error { - return resource.ErrInvalidListElement{ - Name: "rules", - Index: i, - Wrapped: err, - } - } - - for j, match := range rule.Matches { - wrapMatchErr := func(err error) error { - return wrapRuleErr(resource.ErrInvalidListElement{ - Name: "matches", - Index: j, - Wrapped: err, - }) - } - - if match.Method != nil { - switch match.Method.Type { - case pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_UNSPECIFIED: - merr = multierror.Append(merr, wrapMatchErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: resource.ErrMissing, - }, - )) - case pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT: - case pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_REGEX: - default: - merr = multierror.Append(merr, wrapMatchErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: fmt.Errorf("not a supported enum value: %v", match.Method.Type), - }, - )) - } - if match.Method.Service == "" && match.Method.Method == "" { - merr = multierror.Append(merr, wrapMatchErr( - resource.ErrInvalidField{ - Name: "service", - Wrapped: errors.New("at least one of \"service\" or \"method\" must be set"), - }, - )) - } - } - - for k, header := range match.Headers { - wrapMatchHeaderErr := func(err error) error { - return wrapRuleErr(resource.ErrInvalidListElement{ - Name: "headers", - Index: k, - Wrapped: err, - }) - } - - if err := validateHeaderMatchType(header.Type); err != nil { - merr = multierror.Append(merr, wrapMatchHeaderErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: err, - }), - ) - } - - if header.Name == "" { - merr = multierror.Append(merr, wrapMatchHeaderErr( - resource.ErrInvalidField{ - Name: "name", - Wrapped: resource.ErrMissing, - }), - ) - } - } - } - - for j, filter := range rule.Filters { - wrapFilterErr := func(err error) error { - return wrapRuleErr(resource.ErrInvalidListElement{ - Name: "filters", - Index: j, - Wrapped: err, - }) - } - set := 0 - if filter.RequestHeaderModifier != nil { - set++ - } - if filter.ResponseHeaderModifier != nil { - set++ - } - if filter.UrlRewrite != nil { - set++ - if filter.UrlRewrite.PathPrefix == "" { - merr = multierror.Append(merr, wrapFilterErr( - resource.ErrInvalidField{ - Name: "url_rewrite", - Wrapped: resource.ErrInvalidField{ - Name: "path_prefix", - Wrapped: errors.New("field should not be empty if enclosing section is set"), - }, - }, - )) - } - } - if set != 1 { - merr = multierror.Append(merr, wrapFilterErr( - errors.New("exactly one of request_header_modifier, response_header_modifier, or url_rewrite is required"), - )) - } - } - - if len(rule.BackendRefs) == 0 { - merr = multierror.Append(merr, wrapRuleErr( - resource.ErrInvalidField{ - Name: "backend_refs", - Wrapped: resource.ErrEmpty, - }, - )) - } - for j, hbref := range rule.BackendRefs { - wrapBackendRefErr := func(err error) error { - return wrapRuleErr(resource.ErrInvalidListElement{ - Name: "backend_refs", - Index: j, - Wrapped: err, - }) - } - - wrapBackendRefFieldErr := func(err error) error { - return wrapBackendRefErr(resource.ErrInvalidField{ - Name: "backend_ref", - Wrapped: err, - }) - } - if err := validateBackendRef(hbref.BackendRef, wrapBackendRefFieldErr); err != nil { - merr = multierror.Append(merr, err) - } - - if len(hbref.Filters) > 0 { - merr = multierror.Append(merr, wrapBackendRefErr( - resource.ErrInvalidField{ - Name: "filters", - Wrapped: errors.New("filters are not supported at this level yet"), - }, - )) - } - } - - if rule.Timeouts != nil { - for _, err := range validateHTTPTimeouts(rule.Timeouts) { - merr = multierror.Append(merr, wrapRuleErr( - resource.ErrInvalidField{ - Name: "timeouts", - Wrapped: err, - }, - )) - } - } - if rule.Retries != nil { - for _, err := range validateHTTPRetries(rule.Retries) { - merr = multierror.Append(merr, wrapRuleErr( - resource.ErrInvalidField{ - Name: "retries", - Wrapped: err, - }, - )) - } - } - } - - return merr -} diff --git a/internal/mesh/internal/types/grpc_route_test.go b/internal/mesh/internal/types/grpc_route_test.go deleted file mode 100644 index 26340bff77bb4..0000000000000 --- a/internal/mesh/internal/types/grpc_route_test.go +++ /dev/null @@ -1,653 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestMutateGRPCRoute(t *testing.T) { - type testcase struct { - routeTenancy *pbresource.Tenancy - route *pbmesh.GRPCRoute - expect *pbmesh.GRPCRoute - } - - cases := map[string]testcase{} - - // Add common parent refs test cases. - for name, parentTC := range getXRouteParentRefMutateTestCases() { - cases["parent-ref: "+name] = testcase{ - routeTenancy: parentTC.routeTenancy, - route: &pbmesh.GRPCRoute{ - ParentRefs: parentTC.refs, - }, - expect: &pbmesh.GRPCRoute{ - ParentRefs: parentTC.expect, - }, - } - } - // add common backend ref test cases. - for name, backendTC := range getXRouteBackendRefMutateTestCases() { - var ( - refs []*pbmesh.GRPCBackendRef - expect []*pbmesh.GRPCBackendRef - ) - for _, br := range backendTC.refs { - refs = append(refs, &pbmesh.GRPCBackendRef{ - BackendRef: br, - }) - } - for _, br := range backendTC.expect { - expect = append(expect, &pbmesh.GRPCBackendRef{ - BackendRef: br, - }) - } - cases["backend-ref: "+name] = testcase{ - routeTenancy: backendTC.routeTenancy, - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{ - {BackendRefs: refs}, - }, - }, - expect: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{ - {BackendRefs: expect}, - }, - }, - } - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.GRPCRouteType, "api"). - WithTenancy(tc.routeTenancy). - WithData(t, tc.route). - Build() - resource.DefaultIDTenancy(res.Id, nil, resource.DefaultNamespacedTenancy()) - - err := MutateGRPCRoute(res) - require.NoError(t, err) - - got := resourcetest.MustDecode[*pbmesh.GRPCRoute](t, res) - - if tc.expect == nil { - tc.expect = proto.Clone(tc.route).(*pbmesh.GRPCRoute) - } - - prototest.AssertDeepEqual(t, tc.expect, got.Data) - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestValidateGRPCRoute(t *testing.T) { - type testcase struct { - routeTenancy *pbresource.Tenancy - route *pbmesh.GRPCRoute - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.GRPCRouteType, "api"). - WithTenancy(tc.routeTenancy). - WithData(t, tc.route). - Build() - resource.DefaultIDTenancy(res.Id, nil, resource.DefaultNamespacedTenancy()) - - // Ensure things are properly mutated and updated in the inputs. - err := MutateGRPCRoute(res) - require.NoError(t, err) - { - mutated := resourcetest.MustDecode[*pbmesh.GRPCRoute](t, res) - tc.route = mutated.Data - } - - err = ValidateGRPCRoute(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.GRPCRoute](t, res) - prototest.AssertDeepEqual(t, tc.route, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - "hostnames not supported for services": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Hostnames: []string{"foo.local"}, - }, - expectErr: `invalid "hostnames" field: should not populate hostnames`, - }, - "no rules": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - }, - }, - "rules with no matches": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "rules with matches that are empty": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - // none - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "method match with no type is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Service: "foo", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "type" field: missing required field`, - }, - "method match with unknown type is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Type: 99, - Service: "foo", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "type" field: not a supported enum value: 99`, - }, - "method match with no service nor method is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Type: pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT, - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "service" field: at least one of "service" or "method" must be set`, - }, - "method match is good (1)": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Type: pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT, - Service: "foo", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "method match is good (2)": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Type: pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT, - Method: "bar", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "method match is good (3)": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Method: &pbmesh.GRPCMethodMatch{ - Type: pbmesh.GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT, - Service: "foo", - Method: "bar", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "header match with no type is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Headers: []*pbmesh.GRPCHeaderMatch{{ - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "headers": invalid "type" field: missing required field`, - }, - "header match with unknown type is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Headers: []*pbmesh.GRPCHeaderMatch{{ - Type: 99, - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "headers": invalid "type" field: not a supported enum value: 99`, - }, - "header match with no name is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Headers: []*pbmesh.GRPCHeaderMatch{{ - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - }}, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "headers": invalid "name" field: missing required field`, - }, - "header match is good": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Matches: []*pbmesh.GRPCRouteMatch{{ - Headers: []*pbmesh.GRPCHeaderMatch{{ - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "filter empty is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - // none - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "filter req header mod is ok": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "filter resp header mod is ok": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - ResponseHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "filter rewrite header mod missing path prefix": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{}, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": invalid "url_rewrite" field: invalid "path_prefix" field: field should not be empty if enclosing section is set`, - }, - "filter rewrite header mod is ok": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "filter req+resp header mod is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - ResponseHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "filter req+rewrite header mod is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "filter resp+rewrite header mod is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - ResponseHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "filter req+resp+rewrite header mod is bad": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Filters: []*pbmesh.GRPCRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - ResponseHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }}, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "backend ref with filters is unsupported": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - Filters: []*pbmesh.GRPCRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }}, - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "backend_refs": invalid "filters" field: filters are not supported at this level yet`, - }, - "nil backend ref": { - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - BackendRefs: []*pbmesh.GRPCBackendRef{nil}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "backend_refs": invalid "backend_ref" field: missing required field`, - }, - } - - // Add common timeouts test cases. - for name, timeoutsTC := range getXRouteTimeoutsTestCases() { - cases["timeouts: "+name] = testcase{ - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Timeouts: timeoutsTC.timeouts, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: timeoutsTC.expectErr, - } - } - - // Add common retries test cases. - for name, retriesTC := range getXRouteRetriesTestCases() { - cases["retries: "+name] = testcase{ - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{{ - Retries: retriesTC.retries, - BackendRefs: []*pbmesh.GRPCBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: retriesTC.expectErr, - } - } - - // Add common parent refs test cases. - for name, parentTC := range getXRouteParentRefTestCases() { - cases["parent-ref: "+name] = testcase{ - routeTenancy: parentTC.routeTenancy, - route: &pbmesh.GRPCRoute{ - ParentRefs: parentTC.refs, - }, - expectErr: parentTC.expectErr, - } - } - // add common backend ref test cases. - for name, backendTC := range getXRouteBackendRefTestCases() { - var refs []*pbmesh.GRPCBackendRef - for _, br := range backendTC.refs { - refs = append(refs, &pbmesh.GRPCBackendRef{ - BackendRef: br, - }) - } - cases["backend-ref: "+name] = testcase{ - routeTenancy: backendTC.routeTenancy, - route: &pbmesh.GRPCRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.GRPCRouteRule{ - {BackendRefs: refs}, - }, - }, - expectErr: backendTC.expectErr, - } - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestGRPCRouteACLs(t *testing.T) { - testXRouteACLs[*pbmesh.GRPCRoute](t, func(t *testing.T, parentRefs, backendRefs []*pbresource.Reference) *pbresource.Resource { - data := &pbmesh.GRPCRoute{ - ParentRefs: nil, - } - for _, ref := range parentRefs { - data.ParentRefs = append(data.ParentRefs, &pbmesh.ParentReference{ - Ref: ref, - }) - } - - var ruleRefs []*pbmesh.GRPCBackendRef - for _, ref := range backendRefs { - ruleRefs = append(ruleRefs, &pbmesh.GRPCBackendRef{ - BackendRef: &pbmesh.BackendReference{ - Ref: ref, - }, - }) - } - data.Rules = []*pbmesh.GRPCRouteRule{ - {BackendRefs: ruleRefs}, - } - - return resourcetest.Resource(pbmesh.GRPCRouteType, "api-grpc-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Build() - }) -} diff --git a/internal/mesh/internal/types/http_route.go b/internal/mesh/internal/types/http_route.go deleted file mode 100644 index d32f55dc6cc82..0000000000000 --- a/internal/mesh/internal/types/http_route.go +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "fmt" - "net/http" - "strings" - - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -func RegisterHTTPRoute(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.HTTPRouteType, - Proto: &pbmesh.HTTPRoute{}, - Scope: resource.ScopeNamespace, - Mutate: MutateHTTPRoute, - Validate: ValidateHTTPRoute, - ACLs: xRouteACLHooks[*pbmesh.HTTPRoute](), - }) -} - -var MutateHTTPRoute = resource.DecodeAndMutate(mutateHTTPRoute) - -func mutateHTTPRoute(res *DecodedHTTPRoute) (bool, error) { - changed := false - - if mutateParentRefs(res.Id.Tenancy, res.Data.ParentRefs) { - changed = true - } - - for _, rule := range res.Data.Rules { - for _, match := range rule.Matches { - if match.Method != "" { - norm := strings.ToUpper(match.Method) - if match.Method != norm { - match.Method = norm - changed = true - } - } - } - for _, backend := range rule.BackendRefs { - if backend.BackendRef == nil || backend.BackendRef.Ref == nil { - continue - } - if mutateXRouteRef(res.Id.Tenancy, backend.BackendRef.Ref) { - changed = true - } - } - } - - return changed, nil -} - -var ValidateHTTPRoute = resource.DecodeAndValidate(validateHTTPRoute) - -func validateHTTPRoute(res *DecodedHTTPRoute) error { - var merr error - if err := validateParentRefs(res.Id, res.Data.ParentRefs); err != nil { - merr = multierror.Append(merr, err) - } - - if len(res.Data.Hostnames) > 0 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "hostnames", - Wrapped: errors.New("should not populate hostnames"), - }) - } - - for i, rule := range res.Data.Rules { - wrapRuleErr := func(err error) error { - return resource.ErrInvalidListElement{ - Name: "rules", - Index: i, - Wrapped: err, - } - } - - for j, match := range rule.Matches { - wrapMatchErr := func(err error) error { - return wrapRuleErr(resource.ErrInvalidListElement{ - Name: "matches", - Index: j, - Wrapped: err, - }) - } - - if match.Path != nil { - wrapMatchPathErr := func(err error) error { - return wrapMatchErr(resource.ErrInvalidField{ - Name: "path", - Wrapped: err, - }) - } - // enumcover:pbmesh.PathMatchType - switch match.Path.Type { - case pbmesh.PathMatchType_PATH_MATCH_TYPE_UNSPECIFIED: - merr = multierror.Append(merr, wrapMatchPathErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: resource.ErrMissing, - }, - )) - case pbmesh.PathMatchType_PATH_MATCH_TYPE_EXACT: - if !strings.HasPrefix(match.Path.Value, "/") { - merr = multierror.Append(merr, wrapMatchPathErr( - resource.ErrInvalidField{ - Name: "value", - Wrapped: fmt.Errorf("exact patch value does not start with '/': %q", match.Path.Value), - }, - )) - } - case pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX: - if !strings.HasPrefix(match.Path.Value, "/") { - merr = multierror.Append(merr, wrapMatchPathErr( - resource.ErrInvalidField{ - Name: "value", - Wrapped: fmt.Errorf("prefix patch value does not start with '/': %q", match.Path.Value), - }, - )) - } - case pbmesh.PathMatchType_PATH_MATCH_TYPE_REGEX: - if match.Path.Value == "" { - merr = multierror.Append(merr, wrapMatchPathErr( - resource.ErrInvalidField{ - Name: "value", - Wrapped: resource.ErrEmpty, - }, - )) - } - default: - merr = multierror.Append(merr, wrapMatchPathErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: fmt.Errorf("not a supported enum value: %v", match.Path.Type), - }, - )) - } - } - - for k, hdr := range match.Headers { - wrapMatchHeaderErr := func(err error) error { - return wrapMatchErr(resource.ErrInvalidListElement{ - Name: "headers", - Index: k, - Wrapped: err, - }) - } - - if err := validateHeaderMatchType(hdr.Type); err != nil { - merr = multierror.Append(merr, wrapMatchHeaderErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: err, - }), - ) - } - - if hdr.Name == "" { - merr = multierror.Append(merr, wrapMatchHeaderErr( - resource.ErrInvalidField{ - Name: "name", - Wrapped: resource.ErrMissing, - }), - ) - } - } - - for k, qm := range match.QueryParams { - wrapMatchParamErr := func(err error) error { - return wrapMatchErr(resource.ErrInvalidListElement{ - Name: "query_params", - Index: k, - Wrapped: err, - }) - } - - // enumcover:pbmesh.QueryParamMatchType - switch qm.Type { - case pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_UNSPECIFIED: - merr = multierror.Append(merr, wrapMatchParamErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: resource.ErrMissing, - }), - ) - case pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT: - case pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_REGEX: - case pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_PRESENT: - default: - merr = multierror.Append(merr, wrapMatchParamErr( - resource.ErrInvalidField{ - Name: "type", - Wrapped: fmt.Errorf("not a supported enum value: %v", qm.Type), - }, - )) - } - - if qm.Name == "" { - merr = multierror.Append(merr, wrapMatchParamErr( - resource.ErrInvalidField{ - Name: "name", - Wrapped: resource.ErrMissing, - }), - ) - } - } - - if match.Method != "" && !isValidHTTPMethod(match.Method) { - merr = multierror.Append(merr, wrapMatchErr( - resource.ErrInvalidField{ - Name: "method", - Wrapped: fmt.Errorf("not a valid http method: %q", match.Method), - }, - )) - } - } - - var ( - hasReqMod bool - hasUrlRewrite bool - ) - for j, filter := range rule.Filters { - wrapFilterErr := func(err error) error { - return wrapRuleErr(resource.ErrInvalidListElement{ - Name: "filters", - Index: j, - Wrapped: err, - }) - } - set := 0 - if filter.RequestHeaderModifier != nil { - set++ - hasReqMod = true - } - if filter.ResponseHeaderModifier != nil { - set++ - } - if filter.UrlRewrite != nil { - set++ - hasUrlRewrite = true - if filter.UrlRewrite.PathPrefix == "" { - merr = multierror.Append(merr, wrapFilterErr( - resource.ErrInvalidField{ - Name: "url_rewrite", - Wrapped: resource.ErrInvalidField{ - Name: "path_prefix", - Wrapped: errors.New("field should not be empty if enclosing section is set"), - }, - }, - )) - } - } - if set != 1 { - merr = multierror.Append(merr, wrapFilterErr( - errors.New("exactly one of request_header_modifier, response_header_modifier, or url_rewrite is required"), - )) - } - } - - if hasReqMod && hasUrlRewrite { - merr = multierror.Append(merr, wrapRuleErr( - errors.New("exactly one of request_header_modifier or url_rewrite can be set at a time"), - )) - } - - if len(rule.BackendRefs) == 0 { - merr = multierror.Append(merr, wrapRuleErr( - resource.ErrInvalidField{ - Name: "backend_refs", - Wrapped: resource.ErrEmpty, - }, - )) - } - for j, hbref := range rule.BackendRefs { - wrapBackendRefErr := func(err error) error { - return wrapRuleErr(resource.ErrInvalidListElement{ - Name: "backend_refs", - Index: j, - Wrapped: err, - }) - } - - wrapBackendRefFieldErr := func(err error) error { - return wrapBackendRefErr(resource.ErrInvalidField{ - Name: "backend_ref", - Wrapped: err, - }) - } - if err := validateBackendRef(hbref.BackendRef, wrapBackendRefFieldErr); err != nil { - merr = multierror.Append(merr, err) - } - - if len(hbref.Filters) > 0 { - merr = multierror.Append(merr, wrapBackendRefErr( - resource.ErrInvalidField{ - Name: "filters", - Wrapped: errors.New("filters are not supported at this level yet"), - }, - )) - } - } - - if rule.Timeouts != nil { - for _, err := range validateHTTPTimeouts(rule.Timeouts) { - merr = multierror.Append(merr, wrapRuleErr( - resource.ErrInvalidField{ - Name: "timeouts", - Wrapped: err, - }, - )) - } - } - if rule.Retries != nil { - for _, err := range validateHTTPRetries(rule.Retries) { - merr = multierror.Append(merr, wrapRuleErr( - resource.ErrInvalidField{ - Name: "retries", - Wrapped: err, - }, - )) - } - } - } - - return merr -} - -func isValidHTTPMethod(method string) bool { - switch method { - case http.MethodGet, - http.MethodHead, - http.MethodPost, - http.MethodPut, - http.MethodPatch, - http.MethodDelete, - http.MethodConnect, - http.MethodOptions, - http.MethodTrace: - return true - default: - return false - } -} diff --git a/internal/mesh/internal/types/http_route_test.go b/internal/mesh/internal/types/http_route_test.go deleted file mode 100644 index 81c8b5ab00419..0000000000000 --- a/internal/mesh/internal/types/http_route_test.go +++ /dev/null @@ -1,911 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestMutateHTTPRoute(t *testing.T) { - type testcase struct { - routeTenancy *pbresource.Tenancy - route *pbmesh.HTTPRoute - expect *pbmesh.HTTPRoute - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.HTTPRouteType, "api"). - WithTenancy(tc.routeTenancy). - WithData(t, tc.route). - Build() - resource.DefaultIDTenancy(res.Id, nil, resource.DefaultNamespacedTenancy()) - - err := MutateHTTPRoute(res) - - got := resourcetest.MustDecode[*pbmesh.HTTPRoute](t, res) - - if tc.expectErr == "" { - require.NoError(t, err) - - if tc.expect == nil { - tc.expect = proto.Clone(tc.route).(*pbmesh.HTTPRoute) - } - - prototest.AssertDeepEqual(t, tc.expect, got.Data) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - "no-rules": { - route: &pbmesh.HTTPRoute{}, - }, - "rules-with-no-matches": { - route: &pbmesh.HTTPRoute{ - Rules: []*pbmesh.HTTPRouteRule{{ - // none - }}, - }, - }, - "rules-with-matches-no-methods": { - route: &pbmesh.HTTPRoute{ - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/foo", - }, - }}, - }}, - }, - }, - "rules-with-matches-methods-uppercase": { - route: &pbmesh.HTTPRoute{ - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{ - { - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/foo", - }, - Method: "GET", - }, - { - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/bar", - }, - Method: "POST", - }, - }, - }}, - }, - }, - "rules-with-matches-methods-lowercase": { - route: &pbmesh.HTTPRoute{ - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{ - { - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/foo", - }, - Method: "get", - }, - { - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/bar", - }, - Method: "post", - }, - }, - }}, - }, - expect: &pbmesh.HTTPRoute{ - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{ - { - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/foo", - }, - Method: "GET", - }, - { - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/bar", - }, - Method: "POST", - }, - }, - }}, - }, - }, - } - - // Add common parent refs test cases. - for name, parentTC := range getXRouteParentRefMutateTestCases() { - cases["parent-ref: "+name] = testcase{ - routeTenancy: parentTC.routeTenancy, - route: &pbmesh.HTTPRoute{ - ParentRefs: parentTC.refs, - }, - expect: &pbmesh.HTTPRoute{ - ParentRefs: parentTC.expect, - }, - } - } - // add common backend ref test cases. - for name, backendTC := range getXRouteBackendRefMutateTestCases() { - var ( - refs []*pbmesh.HTTPBackendRef - expect []*pbmesh.HTTPBackendRef - ) - for _, br := range backendTC.refs { - refs = append(refs, &pbmesh.HTTPBackendRef{ - BackendRef: br, - }) - } - for _, br := range backendTC.expect { - expect = append(expect, &pbmesh.HTTPBackendRef{ - BackendRef: br, - }) - } - cases["backend-ref: "+name] = testcase{ - routeTenancy: backendTC.routeTenancy, - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{ - {BackendRefs: refs}, - }, - }, - expect: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{ - {BackendRefs: expect}, - }, - }, - } - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestValidateHTTPRoute(t *testing.T) { - type testcase struct { - routeTenancy *pbresource.Tenancy - route *pbmesh.HTTPRoute - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.HTTPRouteType, "api"). - WithTenancy(tc.routeTenancy). - WithData(t, tc.route). - Build() - resource.DefaultIDTenancy(res.Id, nil, resource.DefaultNamespacedTenancy()) - - // Ensure things are properly mutated and updated in the inputs. - err := MutateHTTPRoute(res) - require.NoError(t, err) - { - mutated := resourcetest.MustDecode[*pbmesh.HTTPRoute](t, res) - tc.route = mutated.Data - } - - err = ValidateHTTPRoute(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.HTTPRoute](t, res) - prototest.AssertDeepEqual(t, tc.route, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - "hostnames not supported for services": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Hostnames: []string{"foo.local"}, - }, - expectErr: `invalid "hostnames" field: should not populate hostnames`, - }, - "no rules": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - }, - }, - "rules with no matches": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "rules with matches that are empty": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - // none - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "path match with no type is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Value: "/foo", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "path" field: invalid "type" field: missing required field`, - }, - "path match with unknown type is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: 99, - Value: "/foo", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "path" field: invalid "type" field: not a supported enum value: 99`, - }, - "exact path match with no leading slash is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_EXACT, - Value: "foo", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "path" field: invalid "value" field: exact patch value does not start with '/': "foo"`, - }, - "prefix path match with no leading slash is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "foo", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "path" field: invalid "value" field: prefix patch value does not start with '/': "foo"`, - }, - "exact path match with leading slash is good": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_EXACT, - Value: "/foo", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "prefix path match with leading slash is good": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_PREFIX, - Value: "/foo", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "regex empty path match is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_REGEX, - Value: "", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "path" field: invalid "value" field: cannot be empty`, - }, - "regex path match is good": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Path: &pbmesh.HTTPPathMatch{ - Type: pbmesh.PathMatchType_PATH_MATCH_TYPE_REGEX, - Value: "/[^/]+/healthz", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "header match with no type is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Headers: []*pbmesh.HTTPHeaderMatch{{ - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid element at index 0 of list "headers": invalid "type" field: missing required field`, - }, - "header match with unknown type is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Headers: []*pbmesh.HTTPHeaderMatch{{ - Type: 99, - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid element at index 0 of list "headers": invalid "type" field: not a supported enum value: 99`, - }, - "header match with no name is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Headers: []*pbmesh.HTTPHeaderMatch{{ - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - }}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid element at index 0 of list "headers": invalid "name" field: missing required field`, - }, - "header match is good": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Headers: []*pbmesh.HTTPHeaderMatch{{ - Type: pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT, - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "queryparam match with no type is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - QueryParams: []*pbmesh.HTTPQueryParamMatch{{ - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid element at index 0 of list "query_params": invalid "type" field: missing required field`, - }, - "queryparam match with unknown type is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - QueryParams: []*pbmesh.HTTPQueryParamMatch{{ - Type: 99, - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid element at index 0 of list "query_params": invalid "type" field: not a supported enum value: 99`, - }, - "queryparam match with no name is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - QueryParams: []*pbmesh.HTTPQueryParamMatch{{ - Type: pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT, - }}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid element at index 0 of list "query_params": invalid "name" field: missing required field`, - }, - "queryparam match is good": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - QueryParams: []*pbmesh.HTTPQueryParamMatch{{ - Type: pbmesh.QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT, - Name: "x-foo", - }}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "method match is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Method: "BOB", - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "matches": invalid "method" field: not a valid http method: "BOB"`, - }, - "method match is good": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Matches: []*pbmesh.HTTPRouteMatch{{ - Method: "DELETE", - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "filter empty is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - // none - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "filter req header mod is ok": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "filter resp header mod is ok": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - ResponseHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "filter rewrite header mod missing path prefix": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": invalid "url_rewrite" field: invalid "path_prefix" field: field should not be empty if enclosing section is set`, - }, - "filter rewrite header mod is ok": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - }, - "filter req+resp header mod is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - ResponseHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "filter req+rewrite header mod is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "filter resp+rewrite header mod is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - ResponseHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "filter req+rewrite on two rules is not allowed": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{ - { - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }, - { - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }, - }, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": exactly one of request_header_modifier or url_rewrite can be set at a time`, - }, - "filter req+resp+rewrite header mod is bad": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Filters: []*pbmesh.HTTPRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - ResponseHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - UrlRewrite: &pbmesh.HTTPURLRewriteFilter{ - PathPrefix: "/blah", - }, - }}, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "filters": exactly one of request_header_modifier, response_header_modifier, or url_rewrite`, - }, - "backend ref with filters is unsupported": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - Filters: []*pbmesh.HTTPRouteFilter{{ - RequestHeaderModifier: &pbmesh.HTTPHeaderFilter{}, - }}, - }}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "backend_refs": invalid "filters" field: filters are not supported at this level yet`, - }, - "nil backend ref": { - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - BackendRefs: []*pbmesh.HTTPBackendRef{nil}, - }}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 0 of list "backend_refs": invalid "backend_ref" field: missing required field`, - }, - } - - // Add common timeouts test cases. - for name, timeoutsTC := range getXRouteTimeoutsTestCases() { - cases["timeouts: "+name] = testcase{ - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Timeouts: timeoutsTC.timeouts, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: timeoutsTC.expectErr, - } - } - - // Add common retries test cases. - for name, retriesTC := range getXRouteRetriesTestCases() { - cases["retries: "+name] = testcase{ - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{{ - Retries: retriesTC.retries, - BackendRefs: []*pbmesh.HTTPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }}, - }, - expectErr: retriesTC.expectErr, - } - } - - // Add common parent refs test cases. - for name, parentTC := range getXRouteParentRefTestCases() { - cases["parent-ref: "+name] = testcase{ - routeTenancy: parentTC.routeTenancy, - route: &pbmesh.HTTPRoute{ - ParentRefs: parentTC.refs, - }, - expectErr: parentTC.expectErr, - } - } - // add common backend ref test cases. - for name, backendTC := range getXRouteBackendRefTestCases() { - var refs []*pbmesh.HTTPBackendRef - for _, br := range backendTC.refs { - refs = append(refs, &pbmesh.HTTPBackendRef{ - BackendRef: br, - }) - } - cases["backend-ref: "+name] = testcase{ - routeTenancy: backendTC.routeTenancy, - route: &pbmesh.HTTPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.HTTPRouteRule{ - {BackendRefs: refs}, - }, - }, - expectErr: backendTC.expectErr, - } - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestHTTPRouteACLs(t *testing.T) { - testXRouteACLs[*pbmesh.HTTPRoute](t, func(t *testing.T, parentRefs, backendRefs []*pbresource.Reference) *pbresource.Resource { - data := &pbmesh.HTTPRoute{ - ParentRefs: nil, - } - for _, ref := range parentRefs { - data.ParentRefs = append(data.ParentRefs, &pbmesh.ParentReference{ - Ref: ref, - }) - } - - var ruleRefs []*pbmesh.HTTPBackendRef - for _, ref := range backendRefs { - ruleRefs = append(ruleRefs, &pbmesh.HTTPBackendRef{ - BackendRef: &pbmesh.BackendReference{ - Ref: ref, - }, - }) - } - data.Rules = []*pbmesh.HTTPRouteRule{ - {BackendRefs: ruleRefs}, - } - - return resourcetest.Resource(pbmesh.HTTPRouteType, "api-http-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Build() - }) -} diff --git a/internal/mesh/internal/types/intermediate/types.go b/internal/mesh/internal/types/intermediate/types.go deleted file mode 100644 index d6b4b39e42e4e..0000000000000 --- a/internal/mesh/internal/types/intermediate/types.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package intermediate - -import ( - "github.com/hashicorp/consul/internal/mesh/internal/types" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type Destination struct { - Explicit *pbmesh.Destination - Service *types.DecodedService // for the name of this destination - VirtualIPs []string // for the name of this destination - ComputedPortRoutes *pbmesh.ComputedPortRoutes // for the name of this destination -} - -type Status struct { - ID *pbresource.ID - Generation string - Conditions []*pbresource.Condition - OldStatus map[string]*pbresource.Status -} diff --git a/internal/mesh/internal/types/proxy_configuration.go b/internal/mesh/internal/types/proxy_configuration.go index 9a4388a40f01d..9205dc81b132a 100644 --- a/internal/mesh/internal/types/proxy_configuration.go +++ b/internal/mesh/internal/types/proxy_configuration.go @@ -1,217 +1,32 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( - "math" + "github.com/hashicorp/consul/internal/resource" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" +) - "github.com/hashicorp/consul/internal/catalog" +const ( + ProxyConfigurationKind = "ProxyConfiguration" +) - "github.com/hashicorp/go-multierror" +var ( + ProxyConfigurationV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: CurrentVersion, + Kind: ProxyConfigurationKind, + } - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/sdk/iptables" + ProxyConfigurationType = ProxyConfigurationV1Alpha1Type ) func RegisterProxyConfiguration(r resource.Registry) { r.Register(resource.Registration{ - Type: pbmesh.ProxyConfigurationType, + Type: ProxyConfigurationV1Alpha1Type, Proto: &pbmesh.ProxyConfiguration{}, - Scope: resource.ScopeNamespace, - Mutate: MutateProxyConfiguration, - Validate: ValidateProxyConfiguration, - ACLs: catalog.ACLHooksForWorkloadSelectingType[*pbmesh.ProxyConfiguration](), + Validate: nil, }) } - -var MutateProxyConfiguration = resource.DecodeAndMutate(mutateProxyConfiguration) - -func mutateProxyConfiguration(res *DecodedProxyConfiguration) (bool, error) { - changed := false - - // Default the tproxy outbound port. - if res.Data.IsTransparentProxy() { - if res.Data.GetDynamicConfig().GetTransparentProxy() == nil { - res.Data.DynamicConfig.TransparentProxy = &pbmesh.TransparentProxy{ - OutboundListenerPort: iptables.DefaultTProxyOutboundPort, - } - changed = true - } else if res.Data.GetDynamicConfig().GetTransparentProxy().OutboundListenerPort == 0 { - res.Data.DynamicConfig.TransparentProxy.OutboundListenerPort = iptables.DefaultTProxyOutboundPort - changed = true - } - } - - return changed, nil -} - -var ValidateProxyConfiguration = resource.DecodeAndValidate(validateProxyConfiguration) - -func validateProxyConfiguration(res *DecodedProxyConfiguration) error { - var err error - - if selErr := catalog.ValidateSelector(res.Data.Workloads, false); selErr != nil { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "workloads", - Wrapped: selErr, - }) - } - - if res.Data.GetDynamicConfig() == nil && res.Data.GetBootstrapConfig() == nil { - err = multierror.Append(err, resource.ErrInvalidFields{ - Names: []string{"dynamic_config", "bootstrap_config"}, - Wrapped: errMissingProxyConfigData, - }) - } - - // nolint:staticcheck - if res.Data.GetOpaqueConfig() != nil { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "opaque_config", - Wrapped: resource.ErrUnsupported, - }) - } - - if dynamicCfgErr := validateDynamicProxyConfiguration(res.Data.GetDynamicConfig()); dynamicCfgErr != nil { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "dynamic_config", - Wrapped: dynamicCfgErr, - }) - } - - return err -} - -func validateDynamicProxyConfiguration(cfg *pbmesh.DynamicConfig) error { - if cfg == nil { - return nil - } - - var err error - - // Error if any of the currently unsupported fields is set. - if cfg.GetMutualTlsMode() != pbmesh.MutualTLSMode_MUTUAL_TLS_MODE_DEFAULT { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "mutual_tls_mode", - Wrapped: resource.ErrUnsupported, - }) - } - - if cfg.GetMeshGatewayMode() != pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "mesh_gateway_mode", - Wrapped: resource.ErrUnsupported, - }) - } - - if cfg.GetAccessLogs() != nil { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "access_logs", - Wrapped: resource.ErrUnsupported, - }) - } - - if cfg.GetPublicListenerJson() != "" { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "public_listener_json", - Wrapped: resource.ErrUnsupported, - }) - } - - if cfg.GetListenerTracingJson() != "" { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "listener_tracing_json", - Wrapped: resource.ErrUnsupported, - }) - } - - if cfg.GetLocalClusterJson() != "" { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "local_cluster_json", - Wrapped: resource.ErrUnsupported, - }) - } - - // nolint:staticcheck - if cfg.GetLocalWorkloadAddress() != "" { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "local_workload_address", - Wrapped: resource.ErrUnsupported, - }) - } - - // nolint:staticcheck - if cfg.GetLocalWorkloadPort() != 0 { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "local_workload_port", - Wrapped: resource.ErrUnsupported, - }) - } - - // nolint:staticcheck - if cfg.GetLocalWorkloadSocketPath() != "" { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "local_workload_socket_path", - Wrapped: resource.ErrUnsupported, - }) - } - - if tproxyCfg := cfg.GetTransparentProxy(); tproxyCfg != nil { - if tproxyCfg.DialedDirectly { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "transparent_proxy", - Wrapped: resource.ErrInvalidField{ - Name: "dialed_directly", - Wrapped: resource.ErrUnsupported, - }, - }) - } - - if outboundListenerPortErr := validatePort(tproxyCfg.OutboundListenerPort, "outbound_listener_port"); outboundListenerPortErr != nil { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "transparent_proxy", - Wrapped: outboundListenerPortErr, - }) - } - } - - if exposeCfg := cfg.GetExposeConfig(); exposeCfg != nil { - for i, path := range exposeCfg.GetExposePaths() { - if listenerPortErr := validatePort(path.ListenerPort, "listener_port"); listenerPortErr != nil { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "expose_config", - Wrapped: resource.ErrInvalidListElement{ - Name: "expose_paths", - Index: i, - Wrapped: listenerPortErr, - }, - }) - } - - if localPathPortErr := validatePort(path.LocalPathPort, "local_path_port"); localPathPortErr != nil { - err = multierror.Append(err, resource.ErrInvalidField{ - Name: "expose_config", - Wrapped: resource.ErrInvalidListElement{ - Name: "expose_paths", - Index: i, - Wrapped: localPathPortErr, - }, - }) - } - } - } - - return err -} - -func validatePort(port uint32, fieldName string) error { - if port < 1 || port > math.MaxUint16 { - return resource.ErrInvalidField{ - Name: fieldName, - Wrapped: errInvalidPort, - } - } - return nil -} diff --git a/internal/mesh/internal/types/proxy_configuration_test.go b/internal/mesh/internal/types/proxy_configuration_test.go deleted file mode 100644 index f5c52d474c355..0000000000000 --- a/internal/mesh/internal/types/proxy_configuration_test.go +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "math" - "testing" - - "github.com/hashicorp/go-multierror" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/structpb" - - catalogtesthelpers "github.com/hashicorp/consul/internal/catalog/catalogtest/helpers" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/iptables" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestProxyConfigurationACLs(t *testing.T) { - catalogtesthelpers.RunWorkloadSelectingTypeACLsTests[*pbmesh.ProxyConfiguration](t, pbmesh.ProxyConfigurationType, - func(selector *pbcatalog.WorkloadSelector) *pbmesh.ProxyConfiguration { - return &pbmesh.ProxyConfiguration{ - Workloads: selector, - DynamicConfig: &pbmesh.DynamicConfig{}, - } - }, - RegisterProxyConfiguration, - ) -} - -func TestMutateProxyConfiguration(t *testing.T) { - cases := map[string]struct { - data *pbmesh.ProxyConfiguration - expData *pbmesh.ProxyConfiguration - }{ - "tproxy disabled": { - data: &pbmesh.ProxyConfiguration{}, - expData: &pbmesh.ProxyConfiguration{}, - }, - "tproxy disabled explicitly": { - data: &pbmesh.ProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_DIRECT, - }, - }, - expData: &pbmesh.ProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_DIRECT, - }, - }, - }, - "tproxy enabled and tproxy config is nil": { - data: &pbmesh.ProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - }, - }, - expData: &pbmesh.ProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - TransparentProxy: &pbmesh.TransparentProxy{ - OutboundListenerPort: iptables.DefaultTProxyOutboundPort, - }, - }, - }, - }, - "tproxy enabled and tproxy config is empty": { - data: &pbmesh.ProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - TransparentProxy: &pbmesh.TransparentProxy{}, - }, - }, - expData: &pbmesh.ProxyConfiguration{ - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - TransparentProxy: &pbmesh.TransparentProxy{ - OutboundListenerPort: iptables.DefaultTProxyOutboundPort, - }, - }, - }, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - res := resourcetest.Resource(pbmesh.ProxyConfigurationType, "test"). - WithData(t, c.data). - Build() - - err := MutateProxyConfiguration(res) - require.NoError(t, err) - - got := resourcetest.MustDecode[*pbmesh.ProxyConfiguration](t, res) - prototest.AssertDeepEqual(t, c.expData, got.GetData()) - }) - } -} - -func TestValidateProxyConfiguration_MissingBothDynamicAndBootstrapConfig(t *testing.T) { - proxyCfg := &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - } - - res := resourcetest.Resource(pbmesh.ProxyConfigurationType, "test"). - WithData(t, proxyCfg). - Build() - - err := ValidateProxyConfiguration(res) - - var expError error - expError = multierror.Append(expError, - resource.ErrInvalidFields{ - Names: []string{"dynamic_config", "bootstrap_config"}, - Wrapped: errMissingProxyConfigData, - }, - ) - require.Equal(t, err, expError) -} - -func TestValidateProxyConfiguration_AllFieldsInvalid(t *testing.T) { - proxyCfg := &pbmesh.ProxyConfiguration{ - // Omit workload selector. - - DynamicConfig: &pbmesh.DynamicConfig{ - // Set unsupported fields. - MutualTlsMode: pbmesh.MutualTLSMode_MUTUAL_TLS_MODE_PERMISSIVE, - MeshGatewayMode: pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_LOCAL, - AccessLogs: &pbmesh.AccessLogsConfig{}, - PublicListenerJson: "listener-json", - ListenerTracingJson: "tracing-json", - LocalClusterJson: "cluster-json", - LocalWorkloadAddress: "1.1.1.1", - LocalWorkloadPort: 1234, - LocalWorkloadSocketPath: "/foo/bar", - - TransparentProxy: &pbmesh.TransparentProxy{ - DialedDirectly: true, // unsupported - OutboundListenerPort: math.MaxUint16 + 1, // invalid - }, - - // Create invalid expose paths config. - ExposeConfig: &pbmesh.ExposeConfig{ - ExposePaths: []*pbmesh.ExposePath{ - { - ListenerPort: 0, - LocalPathPort: math.MaxUint16 + 1, - }, - }, - }, - }, - - OpaqueConfig: &structpb.Struct{}, - } - - res := resourcetest.Resource(pbmesh.ProxyConfigurationType, "test"). - WithData(t, proxyCfg). - Build() - - err := ValidateProxyConfiguration(res) - - var dynamicCfgErr error - unsupportedFields := []string{ - "mutual_tls_mode", - "mesh_gateway_mode", - "access_logs", - "public_listener_json", - "listener_tracing_json", - "local_cluster_json", - "local_workload_address", - "local_workload_port", - "local_workload_socket_path", - } - for _, f := range unsupportedFields { - dynamicCfgErr = multierror.Append(dynamicCfgErr, - resource.ErrInvalidField{ - Name: f, - Wrapped: resource.ErrUnsupported, - }, - ) - } - dynamicCfgErr = multierror.Append(dynamicCfgErr, - resource.ErrInvalidField{ - Name: "transparent_proxy", - Wrapped: resource.ErrInvalidField{ - Name: "dialed_directly", - Wrapped: resource.ErrUnsupported, - }, - }, - resource.ErrInvalidField{ - Name: "transparent_proxy", - Wrapped: resource.ErrInvalidField{ - Name: "outbound_listener_port", - Wrapped: errInvalidPort, - }, - }, - resource.ErrInvalidField{ - Name: "expose_config", - Wrapped: resource.ErrInvalidListElement{ - Name: "expose_paths", - Wrapped: resource.ErrInvalidField{ - Name: "listener_port", - Wrapped: errInvalidPort, - }, - }, - }, - resource.ErrInvalidField{ - Name: "expose_config", - Wrapped: resource.ErrInvalidListElement{ - Name: "expose_paths", - Wrapped: resource.ErrInvalidField{ - Name: "local_path_port", - Wrapped: errInvalidPort, - }, - }, - }, - ) - - var expError error - expError = multierror.Append(expError, - resource.ErrInvalidField{ - Name: "workloads", - Wrapped: resource.ErrEmpty, - }, - resource.ErrInvalidField{ - Name: "opaque_config", - Wrapped: resource.ErrUnsupported, - }, - resource.ErrInvalidField{ - Name: "dynamic_config", - Wrapped: dynamicCfgErr, - }, - ) - - require.Equal(t, err, expError) -} - -func TestValidateProxyConfiguration_AllFieldsValid(t *testing.T) { - proxyCfg := &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, - - DynamicConfig: &pbmesh.DynamicConfig{ - MutualTlsMode: pbmesh.MutualTLSMode_MUTUAL_TLS_MODE_DEFAULT, - MeshGatewayMode: pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED, - - TransparentProxy: &pbmesh.TransparentProxy{ - DialedDirectly: false, - OutboundListenerPort: 15500, - }, - - ExposeConfig: &pbmesh.ExposeConfig{ - ExposePaths: []*pbmesh.ExposePath{ - { - ListenerPort: 1234, - LocalPathPort: 1235, - }, - }, - }, - }, - - BootstrapConfig: &pbmesh.BootstrapConfig{ - StatsdUrl: "stats-url", - DogstatsdUrl: "dogstats-url", - StatsTags: []string{"tags"}, - PrometheusBindAddr: "prom-bind-addr", - StatsBindAddr: "stats-bind-addr", - ReadyBindAddr: "ready-bind-addr", - OverrideJsonTpl: "override-json-tpl", - StaticClustersJson: "static-clusters-json", - StaticListenersJson: "static-listeners-json", - StatsSinksJson: "stats-sinks-json", - StatsConfigJson: "stats-config-json", - StatsFlushInterval: "stats-flush-interval", - TracingConfigJson: "tracing-config-json", - TelemetryCollectorBindSocketDir: "telemetry-collector-bind-socket-dir", - }, - } - - res := resourcetest.Resource(pbmesh.ProxyConfigurationType, "test"). - WithData(t, proxyCfg). - Build() - - err := ValidateProxyConfiguration(res) - require.NoError(t, err) -} - -func TestValidateProxyConfiguration_WorkloadSelector(t *testing.T) { - type testcase struct { - data *pbmesh.ProxyConfiguration - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.ProxyConfigurationType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, tc.data). - Build() - - // Ensure things are properly mutated and updated in the inputs. - err := MutateProxyConfiguration(res) - require.NoError(t, err) - { - mutated := resourcetest.MustDecode[*pbmesh.ProxyConfiguration](t, res) - tc.data = mutated.Data - } - - err = ValidateProxyConfiguration(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.ProxyConfiguration](t, res) - prototest.AssertDeepEqual(t, tc.data, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - // emptiness - "empty": { - data: &pbmesh.ProxyConfiguration{}, - expectErr: `invalid "workloads" field: cannot be empty`, - }, - "empty selector": { - data: &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{}, - }, - expectErr: `invalid "workloads" field: cannot be empty`, - }, - "bad selector": { - data: &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - Filter: "garbage.foo == bar", - }, - }, - expectErr: `invalid "filter" field: filter "garbage.foo == bar" is invalid: Selector "garbage" is not valid`, - }, - "good selector": { - data: &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, - Filter: "metadata.foo == bar", - }, - DynamicConfig: &pbmesh.DynamicConfig{}, - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/mesh/internal/types/proxy_state_template.go b/internal/mesh/internal/types/proxy_state_template.go deleted file mode 100644 index 43d2148217e03..0000000000000 --- a/internal/mesh/internal/types/proxy_state_template.go +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - "github.com/hashicorp/consul/internal/catalog" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterProxyStateTemplate(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.ProxyStateTemplateType, - Proto: &pbmesh.ProxyStateTemplate{}, - Scope: resource.ScopeNamespace, - Validate: ValidateProxyStateTemplate, - ACLs: &resource.ACLHooks{ - Read: func(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - // Check service:read and operator:read permissions. - // If service:read is not allowed, check operator:read. We want to allow both as this - // resource is mostly useful for debuggability and we want to cover - // the most cases that serve that purpose. - serviceReadErr := authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.Name, authzContext) - operatorReadErr := authorizer.ToAllowAuthorizer().OperatorReadAllowed(authzContext) - - switch { - case serviceReadErr != nil: - return serviceReadErr - case operatorReadErr != nil: - return operatorReadErr - } - - return nil - }, - Write: func(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, p *pbresource.Resource) error { - // Require operator:write only for "break-glass" scenarios as this resource should be mostly - // managed by a controller. - return authorizer.ToAllowAuthorizer().OperatorWriteAllowed(authzContext) - }, - List: resource.NoOpACLListHook, - }, - }) -} - -var ValidateProxyStateTemplate = resource.DecodeAndValidate(validateProxyStateTemplate) - -func validateProxyStateTemplate(res *DecodedProxyStateTemplate) error { - // TODO(v2): validate a lot more of this - - var merr error - - if res.Data.ProxyState != nil { - wrapProxyStateErr := func(err error) error { - return resource.ErrInvalidField{ - Name: "proxy_state", - Wrapped: err, - } - } - for name, cluster := range res.Data.ProxyState.Clusters { - if name == "" { - merr = multierror.Append(merr, wrapProxyStateErr(resource.ErrInvalidMapKey{ - Map: "clusters", - Key: name, - Wrapped: resource.ErrEmpty, - })) - continue - } - - wrapClusterErr := func(err error) error { - return wrapProxyStateErr(resource.ErrInvalidMapValue{ - Map: "clusters", - Key: name, - Wrapped: err, - }) - } - - if name != cluster.Name { - merr = multierror.Append(merr, wrapClusterErr(resource.ErrInvalidField{ - Name: "name", - Wrapped: fmt.Errorf("cluster name %q does not match map key %q", cluster.Name, name), - })) - } - - if portErr := catalog.ValidateProtocol(pbcatalog.Protocol(cluster.Protocol)); portErr != nil { - merr = multierror.Append(merr, wrapClusterErr(resource.ErrInvalidField{ - Name: "protocol", - Wrapped: portErr, - })) - } - - if pbcatalog.Protocol(cluster.Protocol) == pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { - merr = multierror.Append(merr, wrapClusterErr(resource.ErrInvalidField{ - Name: "protocol", - Wrapped: resource.ErrMissing, - })) - } - - if pbcatalog.Protocol(cluster.Protocol) == pbcatalog.Protocol_PROTOCOL_MESH { - merr = multierror.Append(merr, wrapClusterErr(resource.ErrInvalidField{ - Name: "protocol", - Wrapped: fmt.Errorf("protocol %q is not a valid cluster traffic protocol", - cluster.Protocol.String()), - })) - } - - wrapGroupErr := func(err error) error { - return wrapClusterErr(resource.ErrInvalidField{ - Name: "group", - Wrapped: err, - }) - } - - if cluster.Group == nil { - merr = multierror.Append(merr, wrapGroupErr(resource.ErrMissing)) - } else { - switch x := cluster.Group.(type) { - case *pbproxystate.Cluster_EndpointGroup: - wrapInnerGroupErr := func(err error) error { - return wrapGroupErr(resource.ErrInvalidField{ - Name: "endpoint_group", - Wrapped: err, - }) - } - - if x.EndpointGroup == nil { - merr = multierror.Append(merr, wrapInnerGroupErr(resource.ErrMissing)) - continue - } - - // The inner name field is optional, but if specified it has to - // match the enclosing cluster. - - if x.EndpointGroup.Name != "" && x.EndpointGroup.Name != cluster.Name { - merr = multierror.Append(merr, wrapInnerGroupErr(resource.ErrInvalidField{ - Name: "name", - Wrapped: fmt.Errorf("optional but %q does not match enclosing cluster name %q", - x.EndpointGroup.Name, cluster.Name), - })) - } - - case *pbproxystate.Cluster_FailoverGroup: - wrapInnerGroupErr := func(err error) error { - return wrapGroupErr(resource.ErrInvalidField{ - Name: "failover_group", - Wrapped: err, - }) - } - - if x.FailoverGroup == nil { - merr = multierror.Append(merr, wrapInnerGroupErr(resource.ErrMissing)) - continue - } - - if len(x.FailoverGroup.EndpointGroups) == 0 { - merr = multierror.Append(merr, wrapInnerGroupErr(resource.ErrInvalidField{ - Name: "endpoint_groups", - Wrapped: resource.ErrEmpty, - })) - } - - for i, eg := range x.FailoverGroup.EndpointGroups { - wrapFailoverEndpointGroupErr := func(err error) error { - return wrapInnerGroupErr(resource.ErrInvalidListElement{ - Name: "endpoint_groups", - Index: i, - Wrapped: err, - }) - } - // The inner name field is required and cannot match the enclosing cluster. - switch { - case eg.Name == "": - merr = multierror.Append(merr, wrapFailoverEndpointGroupErr(resource.ErrInvalidField{ - Name: "name", - Wrapped: resource.ErrEmpty, - })) - case eg.Name == cluster.Name: - merr = multierror.Append(merr, wrapFailoverEndpointGroupErr(resource.ErrInvalidField{ - Name: "name", - Wrapped: fmt.Errorf( - "name cannot be the same as the enclosing cluster %q", - eg.Name, - ), - })) - } - } - default: - merr = multierror.Append(merr, wrapGroupErr(fmt.Errorf("unknown type: %T", cluster.Group))) - } - } - } - } - - return merr -} diff --git a/internal/mesh/internal/types/proxy_state_template_test.go b/internal/mesh/internal/types/proxy_state_template_test.go deleted file mode 100644 index d562a9c43a29e..0000000000000 --- a/internal/mesh/internal/types/proxy_state_template_test.go +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestValidateProxyStateTemplate(t *testing.T) { - type testcase struct { - pst *pbmesh.ProxyStateTemplate - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "api"). - WithData(t, tc.pst). - Build() - - err := ValidateProxyStateTemplate(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.ProxyStateTemplate](t, res) - prototest.AssertDeepEqual(t, tc.pst, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - pstForCluster := func(name string, cluster *pbproxystate.Cluster) *pbmesh.ProxyStateTemplate { - return &pbmesh.ProxyStateTemplate{ - ProxyState: &pbmesh.ProxyState{ - Clusters: map[string]*pbproxystate.Cluster{ - name: cluster, - }, - }, - } - } - - clusterForGroups := func(name string, groups ...*pbproxystate.EndpointGroup) *pbproxystate.Cluster { - cluster := &pbproxystate.Cluster{ - Name: name, - Protocol: pbproxystate.Protocol_PROTOCOL_TCP, - } - - require.NotEmpty(t, groups) - - if len(groups) == 1 { - cluster.Group = &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: groups[0], - } - } else { - cluster.Group = &pbproxystate.Cluster_FailoverGroup{ - FailoverGroup: &pbproxystate.FailoverGroup{ - EndpointGroups: groups, - }, - } - } - return cluster - } - - endpointGroup := func(name string) *pbproxystate.EndpointGroup { - return &pbproxystate.EndpointGroup{ - Name: name, - Group: &pbproxystate.EndpointGroup_Dynamic{ - Dynamic: &pbproxystate.DynamicEndpointGroup{}, - }, - } - } - - // also cover clusters with names that don't match the map key - // also empty map keys - cases := map[string]testcase{ - // ============== COMMON ============== - "cluster with invalid protocol": { - pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ - Name: "api-cluster", - Protocol: 100, - }), - expectErr: `invalid value of key "api-cluster" within clusters: invalid "protocol" field: not a supported enum value: 100`, - }, - "cluster with mesh protocol": { - pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ - Name: "api-cluster", - Protocol: pbproxystate.Protocol_PROTOCOL_MESH, - }), - expectErr: `invalid value of key "api-cluster" within clusters: invalid "protocol" field: protocol "PROTOCOL_MESH" is not a valid cluster traffic protocol`, - }, - "cluster with missing protocol": { - pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ - Name: "api-cluster", - Protocol: pbproxystate.Protocol_PROTOCOL_UNSPECIFIED, - }), - expectErr: `invalid value of key "api-cluster" within clusters: invalid "protocol" field: missing required field`, - }, - "cluster with missing cluster group": { - pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ - Name: "api-cluster", - }), - expectErr: `invalid "proxy_state" field: invalid value of key "api-cluster" within clusters: invalid "group" field: missing required field`, - }, - // ============== STANDARD ============== - "standard cluster with empty map key": { - pst: pstForCluster("", clusterForGroups("api-cluster", - endpointGroup(""), - )), - expectErr: `invalid "proxy_state" field: map clusters contains an invalid key - "": cannot be empty`, - }, - "standard cluster with missing cluster name": { - pst: pstForCluster("api-cluster", clusterForGroups("", - endpointGroup(""), - )), - expectErr: `invalid "proxy_state" field: invalid value of key "api-cluster" within clusters: invalid "name" field: cluster name "" does not match map key "api-cluster"`, - }, - "standard cluster with empty endpoint group name": { - pst: pstForCluster("api-cluster", clusterForGroups("api-cluster", - endpointGroup(""), - )), - }, - "standard cluster with same endpoint group name": { - pst: pstForCluster("api-cluster", clusterForGroups("api-cluster", - endpointGroup("api-cluster"), - )), - }, - "standard cluster with different endpoint group name": { - pst: pstForCluster("api-cluster", clusterForGroups("api-cluster", - endpointGroup("garbage"), - )), - expectErr: `invalid "proxy_state" field: invalid value of key "api-cluster" within clusters: invalid "group" field: invalid "endpoint_group" field: invalid "name" field: optional but "garbage" does not match enclosing cluster name "api-cluster"`, - }, - // ============== FAILOVER ============== - "failover cluster with empty map key": { - pst: pstForCluster("", clusterForGroups("api-cluster", - endpointGroup("api-cluster~0"), - endpointGroup("api-cluster~1"), - )), - expectErr: `invalid "proxy_state" field: map clusters contains an invalid key - "": cannot be empty`, - }, - "failover cluster with missing cluster name": { - pst: pstForCluster("api-cluster", clusterForGroups("", - endpointGroup("api-cluster~0"), - endpointGroup("api-cluster~1"), - )), - expectErr: `invalid "proxy_state" field: invalid value of key "api-cluster" within clusters: invalid "name" field: cluster name "" does not match map key "api-cluster"`, - }, - "failover cluster with empty endpoint group name": { - pst: pstForCluster("api-cluster", clusterForGroups("api-cluster", - endpointGroup("api-cluster~0"), - endpointGroup(""), - )), - expectErr: `invalid "proxy_state" field: invalid value of key "api-cluster" within clusters: invalid "group" field: invalid "failover_group" field: invalid element at index 1 of list "endpoint_groups": invalid "name" field: cannot be empty`, - }, - "failover cluster with same endpoint group name": { - pst: pstForCluster("api-cluster", clusterForGroups("api-cluster", - endpointGroup("api-cluster~0"), - endpointGroup("api-cluster"), - )), - expectErr: `invalid "proxy_state" field: invalid value of key "api-cluster" within clusters: invalid "group" field: invalid "failover_group" field: invalid element at index 1 of list "endpoint_groups": invalid "name" field: name cannot be the same as the enclosing cluster "api-cluster"`, - }, - "failover cluster with no groups": { - pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ - Name: "api-cluster", - Group: &pbproxystate.Cluster_FailoverGroup{ - FailoverGroup: &pbproxystate.FailoverGroup{ - EndpointGroups: nil, - }, - }, - }), - expectErr: `invalid "proxy_state" field: invalid value of key "api-cluster" within clusters: invalid "group" field: invalid "failover_group" field: invalid "endpoint_groups" field: cannot be empty`, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - t.Logf("%+v", tc.pst) - run(t, tc) - }) - } -} diff --git a/internal/mesh/internal/types/tcp_route.go b/internal/mesh/internal/types/tcp_route.go deleted file mode 100644 index 02dd5aaa10fdd..0000000000000 --- a/internal/mesh/internal/types/tcp_route.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -func RegisterTCPRoute(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmesh.TCPRouteType, - Proto: &pbmesh.TCPRoute{}, - Scope: resource.ScopeNamespace, - Mutate: MutateTCPRoute, - Validate: ValidateTCPRoute, - ACLs: xRouteACLHooks[*pbmesh.TCPRoute](), - }) -} - -var MutateTCPRoute = resource.DecodeAndMutate(mutateTCPRoute) - -func mutateTCPRoute(res *DecodedTCPRoute) (bool, error) { - changed := false - - if mutateParentRefs(res.Id.Tenancy, res.Data.ParentRefs) { - changed = true - } - - for _, rule := range res.Data.Rules { - for _, backend := range rule.BackendRefs { - if backend.BackendRef == nil || backend.BackendRef.Ref == nil { - continue - } - if mutateXRouteRef(res.Id.Tenancy, backend.BackendRef.Ref) { - changed = true - } - } - } - - return changed, nil -} - -var ValidateTCPRoute = resource.DecodeAndValidate(validateTCPRoute) - -func validateTCPRoute(res *DecodedTCPRoute) error { - var merr error - - if err := validateParentRefs(res.Id, res.Data.ParentRefs); err != nil { - merr = multierror.Append(merr, err) - } - - if len(res.Data.Rules) > 1 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "rules", - Wrapped: fmt.Errorf("must only specify a single rule for now"), - }) - } - - for i, rule := range res.Data.Rules { - wrapRuleErr := func(err error) error { - return resource.ErrInvalidListElement{ - Name: "rules", - Index: i, - Wrapped: err, - } - } - - if len(rule.BackendRefs) == 0 { - merr = multierror.Append(merr, wrapRuleErr( - resource.ErrInvalidField{ - Name: "backend_refs", - Wrapped: resource.ErrEmpty, - }, - )) - } - for j, hbref := range rule.BackendRefs { - wrapBackendRefErr := func(err error) error { - return wrapRuleErr(resource.ErrInvalidListElement{ - Name: "backend_refs", - Index: j, - Wrapped: err, - }) - } - - wrapBackendRefFieldErr := func(err error) error { - return wrapBackendRefErr(resource.ErrInvalidField{ - Name: "backend_ref", - Wrapped: err, - }) - } - if err := validateBackendRef(hbref.BackendRef, wrapBackendRefFieldErr); err != nil { - merr = multierror.Append(merr, err) - } - } - } - - return merr -} diff --git a/internal/mesh/internal/types/tcp_route_test.go b/internal/mesh/internal/types/tcp_route_test.go deleted file mode 100644 index 7dd9a6a80d284..0000000000000 --- a/internal/mesh/internal/types/tcp_route_test.go +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestMutateTCPRoute(t *testing.T) { - type testcase struct { - routeTenancy *pbresource.Tenancy - route *pbmesh.TCPRoute - expect *pbmesh.TCPRoute - } - - cases := map[string]testcase{} - - // Add common parent refs test cases. - for name, parentTC := range getXRouteParentRefMutateTestCases() { - cases["parent-ref: "+name] = testcase{ - routeTenancy: parentTC.routeTenancy, - route: &pbmesh.TCPRoute{ - ParentRefs: parentTC.refs, - }, - expect: &pbmesh.TCPRoute{ - ParentRefs: parentTC.expect, - }, - } - } - // add common backend ref test cases. - for name, backendTC := range getXRouteBackendRefMutateTestCases() { - var ( - refs []*pbmesh.TCPBackendRef - expect []*pbmesh.TCPBackendRef - ) - for _, br := range backendTC.refs { - refs = append(refs, &pbmesh.TCPBackendRef{ - BackendRef: br, - }) - } - for _, br := range backendTC.expect { - expect = append(expect, &pbmesh.TCPBackendRef{ - BackendRef: br, - }) - } - cases["backend-ref: "+name] = testcase{ - routeTenancy: backendTC.routeTenancy, - route: &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.TCPRouteRule{ - {BackendRefs: refs}, - }, - }, - expect: &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.TCPRouteRule{ - {BackendRefs: expect}, - }, - }, - } - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.TCPRouteType, "api"). - WithTenancy(tc.routeTenancy). - WithData(t, tc.route). - Build() - resource.DefaultIDTenancy(res.Id, nil, resource.DefaultNamespacedTenancy()) - - err := MutateTCPRoute(res) - require.NoError(t, err) - - got := resourcetest.MustDecode[*pbmesh.TCPRoute](t, res) - - if tc.expect == nil { - tc.expect = proto.Clone(tc.route).(*pbmesh.TCPRoute) - } - - prototest.AssertDeepEqual(t, tc.expect, got.Data) - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestValidateTCPRoute(t *testing.T) { - type testcase struct { - routeTenancy *pbresource.Tenancy - route *pbmesh.TCPRoute - expectErr string - } - - run := func(t *testing.T, tc testcase) { - res := resourcetest.Resource(pbmesh.TCPRouteType, "api"). - WithTenancy(tc.routeTenancy). - WithData(t, tc.route). - Build() - resource.DefaultIDTenancy(res.Id, nil, resource.DefaultNamespacedTenancy()) - - // Ensure things are properly mutated and updated in the inputs. - err := MutateTCPRoute(res) - require.NoError(t, err) - { - mutated := resourcetest.MustDecode[*pbmesh.TCPRoute](t, res) - tc.route = mutated.Data - } - - err = ValidateTCPRoute(res) - - // Verify that validate didn't actually change the object. - got := resourcetest.MustDecode[*pbmesh.TCPRoute](t, res) - prototest.AssertDeepEqual(t, tc.route, got.Data) - - if tc.expectErr == "" { - require.NoError(t, err) - } else { - testutil.RequireErrorContains(t, err, tc.expectErr) - } - } - - cases := map[string]testcase{ - "no rules": { - route: &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - }, - }, - "more than one rule": { - route: &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.TCPRouteRule{ - { - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "api", ""), - }}, - }, - { - BackendRefs: []*pbmesh.TCPBackendRef{{ - BackendRef: newBackendRef(pbcatalog.ServiceType, "db", ""), - }}, - }, - }, - }, - expectErr: `invalid "rules" field: must only specify a single rule for now`, - }, - } - - // Add common parent refs test cases. - for name, parentTC := range getXRouteParentRefTestCases() { - cases["parent-ref: "+name] = testcase{ - routeTenancy: parentTC.routeTenancy, - route: &pbmesh.TCPRoute{ - ParentRefs: parentTC.refs, - }, - expectErr: parentTC.expectErr, - } - } - // add common backend ref test cases. - for name, backendTC := range getXRouteBackendRefTestCases() { - var refs []*pbmesh.TCPBackendRef - for _, br := range backendTC.refs { - refs = append(refs, &pbmesh.TCPBackendRef{ - BackendRef: br, - }) - } - cases["backend-ref: "+name] = testcase{ - routeTenancy: backendTC.routeTenancy, - route: &pbmesh.TCPRoute{ - ParentRefs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "web", ""), - }, - Rules: []*pbmesh.TCPRouteRule{ - {BackendRefs: refs}, - }, - }, - expectErr: backendTC.expectErr, - } - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestTCPRouteACLs(t *testing.T) { - testXRouteACLs[*pbmesh.TCPRoute](t, func(t *testing.T, parentRefs, backendRefs []*pbresource.Reference) *pbresource.Resource { - data := &pbmesh.TCPRoute{ - ParentRefs: nil, - } - for _, ref := range parentRefs { - data.ParentRefs = append(data.ParentRefs, &pbmesh.ParentReference{ - Ref: ref, - }) - } - - var ruleRefs []*pbmesh.TCPBackendRef - for _, ref := range backendRefs { - ruleRefs = append(ruleRefs, &pbmesh.TCPBackendRef{ - BackendRef: &pbmesh.BackendReference{ - Ref: ref, - }, - }) - } - data.Rules = []*pbmesh.TCPRouteRule{ - {BackendRefs: ruleRefs}, - } - - return resourcetest.Resource(pbmesh.TCPRouteType, "api-tcp-route"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Build() - }) -} diff --git a/internal/mesh/internal/types/types.go b/internal/mesh/internal/types/types.go index cf1443aabf18d..3eeb69bd101c2 100644 --- a/internal/mesh/internal/types/types.go +++ b/internal/mesh/internal/types/types.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types @@ -7,17 +7,13 @@ import ( "github.com/hashicorp/consul/internal/resource" ) +const ( + GroupName = "mesh" + VersionV1Alpha1 = "v1alpha1" + CurrentVersion = VersionV1Alpha1 +) + func Register(r resource.Registry) { RegisterProxyConfiguration(r) - RegisterComputedProxyConfiguration(r) - RegisterDestinations(r) - RegisterComputedExplicitDestinations(r) - RegisterProxyStateTemplate(r) - RegisterHTTPRoute(r) - RegisterTCPRoute(r) - RegisterGRPCRoute(r) - RegisterDestinationPolicy(r) - RegisterComputedRoutes(r) - // todo (v2): uncomment once we implement it. - //RegisterDestinationsConfiguration(r) + RegisterUpstreams(r) } diff --git a/internal/mesh/internal/types/types_test.go b/internal/mesh/internal/types/types_test.go index 801d3de018467..4324e87078301 100644 --- a/internal/mesh/internal/types/types_test.go +++ b/internal/mesh/internal/types/types_test.go @@ -1,16 +1,14 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types import ( "testing" - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/stretchr/testify/require" ) func TestTypeRegistration(t *testing.T) { @@ -19,16 +17,8 @@ func TestTypeRegistration(t *testing.T) { // are correct as that would amount more or less to hardcoding structs // from types.go a second time here. requiredKinds := []string{ - pbmesh.ProxyConfigurationKind, - pbmesh.DestinationsKind, - pbmesh.ProxyStateTemplateKind, - pbmesh.HTTPRouteKind, - pbmesh.TCPRouteKind, - pbmesh.GRPCRouteKind, - pbmesh.DestinationPolicyKind, - pbmesh.ComputedRoutesKind, - // todo (v2): re-enable once we implement it. - //pbmesh.DestinationsConfigurationKind, + ProxyConfigurationKind, + UpstreamsKind, } r := resource.NewRegistry() @@ -37,8 +27,8 @@ func TestTypeRegistration(t *testing.T) { for _, kind := range requiredKinds { t.Run(kind, func(t *testing.T) { registration, ok := r.Resolve(&pbresource.Type{ - Group: pbmesh.GroupName, - GroupVersion: pbmesh.Version, + Group: GroupName, + GroupVersion: CurrentVersion, Kind: kind, }) diff --git a/internal/mesh/internal/types/upstreams.go b/internal/mesh/internal/types/upstreams.go new file mode 100644 index 0000000000000..54fd14b098d55 --- /dev/null +++ b/internal/mesh/internal/types/upstreams.go @@ -0,0 +1,32 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package types + +import ( + "github.com/hashicorp/consul/internal/resource" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v1alpha1" + "github.com/hashicorp/consul/proto-public/pbresource" +) + +const ( + UpstreamsKind = "Upstreams" +) + +var ( + UpstreamsV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: CurrentVersion, + Kind: UpstreamsKind, + } + + UpstreamsType = UpstreamsV1Alpha1Type +) + +func RegisterUpstreams(r resource.Registry) { + r.Register(resource.Registration{ + Type: UpstreamsV1Alpha1Type, + Proto: &pbmesh.Upstreams{}, + Validate: nil, + }) +} diff --git a/internal/mesh/internal/types/util.go b/internal/mesh/internal/types/util.go deleted file mode 100644 index a484f0943f8d6..0000000000000 --- a/internal/mesh/internal/types/util.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func IsRouteType(typ *pbresource.Type) bool { - return IsHTTPRouteType(typ) || - IsGRPCRouteType(typ) || - IsTCPRouteType(typ) -} - -func IsHTTPRouteType(typ *pbresource.Type) bool { - switch { - case resource.EqualType(typ, pbmesh.HTTPRouteType): - return true - } - return false -} - -func IsGRPCRouteType(typ *pbresource.Type) bool { - switch { - case resource.EqualType(typ, pbmesh.GRPCRouteType): - return true - } - return false -} - -func IsTCPRouteType(typ *pbresource.Type) bool { - switch { - case resource.EqualType(typ, pbmesh.TCPRouteType): - return true - } - return false -} - -func IsFailoverPolicyType(typ *pbresource.Type) bool { - switch { - case resource.EqualType(typ, pbcatalog.FailoverPolicyType): - return true - } - return false -} - -func IsDestinationPolicyType(typ *pbresource.Type) bool { - switch { - case resource.EqualType(typ, pbmesh.DestinationPolicyType): - return true - } - return false -} - -func IsServiceType(typ *pbresource.Type) bool { - switch { - case resource.EqualType(typ, pbcatalog.ServiceType): - return true - } - return false -} - -func IsComputedRoutesType(typ *pbresource.Type) bool { - switch { - case resource.EqualType(typ, pbmesh.ComputedRoutesType): - return true - } - return false -} - -// BackendRefToComputedRoutesTarget turns the provided BackendReference into an -// opaque string format suitable for use as a map key and reference in a -// standalone object or reference. -// -// It is opaque in that the caller should not attempt to parse it, and there is -// no implied storage or wire compatibility concern, since the data is treated -// opaquely at use time. -func BackendRefToComputedRoutesTarget(backendRef *pbmesh.BackendReference) string { - ref := backendRef.Ref - - s := fmt.Sprintf( - "%s/%s/%s?port=%s", - resource.TypeToString(ref.Type), - resource.TenancyToString(ref.Tenancy), - ref.Name, - backendRef.Port, - ) - - if backendRef.Datacenter != "" { - s += "&dc=" + backendRef.Datacenter - } - - return s -} diff --git a/internal/mesh/internal/types/xroute.go b/internal/mesh/internal/types/xroute.go deleted file mode 100644 index 92e2136cd1356..0000000000000 --- a/internal/mesh/internal/types/xroute.go +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "fmt" - "time" - - "github.com/hashicorp/go-multierror" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/catalog" - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type XRouteData interface { - proto.Message - XRouteWithRefs -} - -type XRouteWithRefs interface { - GetParentRefs() []*pbmesh.ParentReference - GetUnderlyingBackendRefs() []*pbmesh.BackendReference -} - -type portedRefKey struct { - Key resource.ReferenceKey - Port string -} - -func mutateParentRefs(xrouteTenancy *pbresource.Tenancy, parentRefs []*pbmesh.ParentReference) (changed bool) { - for _, parent := range parentRefs { - if parent.Ref == nil { - continue - } - changedThis := mutateXRouteRef(xrouteTenancy, parent.Ref) - if changedThis { - changed = true - } - } - return changed -} - -func mutateXRouteRef(xrouteTenancy *pbresource.Tenancy, ref *pbresource.Reference) (changed bool) { - if ref == nil { - return false - } - orig := proto.Clone(ref).(*pbresource.Reference) - resource.DefaultReferenceTenancy( - ref, - xrouteTenancy, - resource.DefaultNamespacedTenancy(), // All xRoutes are namespace scoped. - ) - - return !proto.Equal(orig, ref) -} - -func validateParentRefs(id *pbresource.ID, parentRefs []*pbmesh.ParentReference) error { - var merr error - if len(parentRefs) == 0 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "parent_refs", - Wrapped: resource.ErrEmpty, - }) - } - - var ( - seen = make(map[portedRefKey]struct{}) - seenAny = make(map[resource.ReferenceKey][]string) - ) - for i, parent := range parentRefs { - wrapErr := func(err error) error { - return resource.ErrInvalidListElement{ - Name: "parent_refs", - Index: i, - Wrapped: err, - } - } - - wrapRefErr := func(err error) error { - return wrapErr(resource.ErrInvalidField{ - Name: "ref", - Wrapped: err, - }) - } - - if err := catalog.ValidateLocalServiceRefNoSection(parent.Ref, wrapRefErr); err != nil { - merr = multierror.Append(merr, err) - } else { - if !resource.EqualTenancy(id.Tenancy, parent.Ref.Tenancy) { - merr = multierror.Append(merr, wrapRefErr(resource.ErrInvalidField{ - Name: "tenancy", - Wrapped: resource.ErrReferenceTenancyNotEqual, - })) - } - prk := portedRefKey{ - Key: resource.NewReferenceKey(parent.Ref), - Port: parent.Port, - } - - _, portExist := seen[prk] - - if parent.Port == "" { - coveredPorts, exactExists := seenAny[prk.Key] - - if portExist { // check for duplicate wild - merr = multierror.Append(merr, wrapErr( - resource.ErrInvalidField{ - Name: "port", - Wrapped: fmt.Errorf( - "parent ref %q for wildcard port exists twice", - resource.ReferenceToString(parent.Ref), - ), - }, - )) - } else if exactExists { // check for existing exact - merr = multierror.Append(merr, wrapErr( - resource.ErrInvalidField{ - Name: "port", - Wrapped: fmt.Errorf( - "parent ref %q for ports %v covered by wildcard port already", - resource.ReferenceToString(parent.Ref), - coveredPorts, - ), - }, - )) - } else { - seen[prk] = struct{}{} - } - - } else { - prkWild := prk - prkWild.Port = "" - _, wildExist := seen[prkWild] - - if portExist { // check for duplicate exact - merr = multierror.Append(merr, wrapErr( - resource.ErrInvalidField{ - Name: "port", - Wrapped: fmt.Errorf( - "parent ref %q for port %q exists twice", - resource.ReferenceToString(parent.Ref), - parent.Port, - ), - }, - )) - } else if wildExist { // check for existing wild - merr = multierror.Append(merr, wrapErr( - resource.ErrInvalidField{ - Name: "port", - Wrapped: fmt.Errorf( - "parent ref %q for port %q covered by wildcard port already", - resource.ReferenceToString(parent.Ref), - parent.Port, - ), - }, - )) - } else { - seen[prk] = struct{}{} - seenAny[prk.Key] = append(seenAny[prk.Key], parent.Port) - } - } - } - } - - return merr -} - -func validateBackendRef(backendRef *pbmesh.BackendReference, wrapErr func(error) error) error { - if backendRef == nil { - return wrapErr(resource.ErrMissing) - } - - var merr error - - wrapRefErr := func(err error) error { - return wrapErr(resource.ErrInvalidField{ - Name: "ref", - Wrapped: err, - }) - } - if err := catalog.ValidateLocalServiceRefNoSection(backendRef.Ref, wrapRefErr); err != nil { - merr = multierror.Append(merr, err) - } - if backendRef.Datacenter != "" { - merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ - Name: "datacenter", - Wrapped: errors.New("datacenter is not yet supported on backend refs"), - })) - } - - return merr -} - -func validateHeaderMatchType(typ pbmesh.HeaderMatchType) error { - // enumcover:pbmesh.HeaderMatchType - switch typ { - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_UNSPECIFIED: - return resource.ErrMissing - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_EXACT: - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_REGEX: - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_PRESENT: - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_PREFIX: - case pbmesh.HeaderMatchType_HEADER_MATCH_TYPE_SUFFIX: - default: - return fmt.Errorf("not a supported enum value: %v", typ) - } - return nil -} - -func errTimeoutCannotBeNegative(d time.Duration) error { - return fmt.Errorf("timeout cannot be negative: %v", d) -} - -func validateHTTPTimeouts(timeouts *pbmesh.HTTPRouteTimeouts) []error { - if timeouts == nil { - return nil - } - - var errs []error - - if timeouts.Request != nil { - val := timeouts.Request.AsDuration() - if val < 0 { - errs = append(errs, resource.ErrInvalidField{ - Name: "request", - Wrapped: errTimeoutCannotBeNegative(val), - }) - } - } - if timeouts.Idle != nil { - val := timeouts.Idle.AsDuration() - if val < 0 { - errs = append(errs, resource.ErrInvalidField{ - Name: "idle", - Wrapped: errTimeoutCannotBeNegative(val), - }) - } - } - - return errs -} - -func validateHTTPRetries(retries *pbmesh.HTTPRouteRetries) []error { - if retries == nil { - return nil - } - - var errs []error - - for i, condition := range retries.OnConditions { - if !isValidRetryCondition(condition) { - errs = append(errs, resource.ErrInvalidListElement{ - Name: "on_conditions", - Index: i, - Wrapped: fmt.Errorf("not a valid retry condition: %q", condition), - }) - } - } - - return errs -} - -func isValidRetryCondition(retryOn string) bool { - switch retryOn { - case "5xx", - "gateway-error", - "reset", - "connect-failure", - "envoy-ratelimited", - "retriable-4xx", - "refused-stream", - "cancelled", - "deadline-exceeded", - "internal", - "resource-exhausted", - "unavailable": - return true - default: - return false - } -} - -func xRouteACLHooks[R XRouteData]() *resource.ACLHooks { - hooks := &resource.ACLHooks{ - Read: resource.DecodeAndAuthorizeRead(aclReadHookXRoute[R]), - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookXRoute[R]), - List: resource.NoOpACLListHook, - } - - return hooks -} - -func aclReadHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.AuthorizerContext, res *resource.DecodedResource[R]) error { - // Need service:read on ALL of the services this is controlling traffic for. - for _, parentRef := range res.Data.GetParentRefs() { - parentAuthzContext := resource.AuthorizerContext(parentRef.Ref.GetTenancy()) - parentServiceName := parentRef.Ref.GetName() - - if err := authorizer.ToAllowAuthorizer().ServiceReadAllowed(parentServiceName, parentAuthzContext); err != nil { - return err - } - } - - return nil -} - -func aclWriteHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.AuthorizerContext, res *resource.DecodedResource[R]) error { - // Need service:write on ALL of the services this is controlling traffic for. - for _, parentRef := range res.Data.GetParentRefs() { - parentAuthzContext := resource.AuthorizerContext(parentRef.Ref.GetTenancy()) - parentServiceName := parentRef.Ref.GetName() - - if err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(parentServiceName, parentAuthzContext); err != nil { - return err - } - } - - // Need service:read on ALL of the services this directs traffic at. - for _, backendRef := range res.Data.GetUnderlyingBackendRefs() { - backendAuthzContext := resource.AuthorizerContext(backendRef.Ref.GetTenancy()) - backendServiceName := backendRef.Ref.GetName() - - if err := authorizer.ToAllowAuthorizer().ServiceReadAllowed(backendServiceName, backendAuthzContext); err != nil { - return err - } - } - - return nil -} diff --git a/internal/mesh/internal/types/xroute_test.go b/internal/mesh/internal/types/xroute_test.go deleted file mode 100644 index 5ba39e24cc073..0000000000000 --- a/internal/mesh/internal/types/xroute_test.go +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type xRouteParentRefMutateTestcase struct { - routeTenancy *pbresource.Tenancy - refs []*pbmesh.ParentReference - expect []*pbmesh.ParentReference -} - -func getXRouteParentRefMutateTestCases() map[string]xRouteParentRefMutateTestcase { - newRef := func(typ *pbresource.Type, tenancyStr, name string) *pbresource.Reference { - return resourcetest.Resource(typ, name). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - Reference("") - } - - newParentRef := func(typ *pbresource.Type, tenancyStr, name, port string) *pbmesh.ParentReference { - return &pbmesh.ParentReference{ - Ref: newRef(typ, tenancyStr, name), - Port: port, - } - } - - return map[string]xRouteParentRefMutateTestcase{ - "parent ref tenancies defaulted": { - routeTenancy: resourcetest.Tenancy("foo.bar"), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", ""), - newParentRef(pbcatalog.ServiceType, ".zim", "api", ""), - newParentRef(pbcatalog.ServiceType, "gir.zim", "api", ""), - }, - expect: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "foo.bar", "api", ""), - newParentRef(pbcatalog.ServiceType, "foo.zim", "api", ""), - newParentRef(pbcatalog.ServiceType, "gir.zim", "api", ""), - }, - }, - } -} - -type xRouteBackendRefMutateTestcase struct { - routeTenancy *pbresource.Tenancy - refs []*pbmesh.BackendReference - expect []*pbmesh.BackendReference -} - -func getXRouteBackendRefMutateTestCases() map[string]xRouteBackendRefMutateTestcase { - newRef := func(typ *pbresource.Type, tenancyStr, name string) *pbresource.Reference { - return resourcetest.Resource(typ, name). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - Reference("") - } - - newBackendRef := func(typ *pbresource.Type, tenancyStr, name, port string) *pbmesh.BackendReference { - return &pbmesh.BackendReference{ - Ref: newRef(typ, tenancyStr, name), - Port: port, - } - } - - return map[string]xRouteBackendRefMutateTestcase{ - "backend ref tenancies defaulted": { - routeTenancy: resourcetest.Tenancy("foo.bar"), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "", "api", ""), - newBackendRef(pbcatalog.ServiceType, ".zim", "api", ""), - newBackendRef(pbcatalog.ServiceType, "gir.zim", "api", ""), - }, - expect: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "foo.bar", "api", ""), - newBackendRef(pbcatalog.ServiceType, "foo.zim", "api", ""), - newBackendRef(pbcatalog.ServiceType, "gir.zim", "api", ""), - }, - }, - } -} - -type xRouteParentRefTestcase struct { - routeTenancy *pbresource.Tenancy - refs []*pbmesh.ParentReference - expectErr string -} - -func getXRouteParentRefTestCases() map[string]xRouteParentRefTestcase { - newRef := func(typ *pbresource.Type, tenancyStr, name string) *pbresource.Reference { - return resourcetest.Resource(typ, name). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - Reference("") - } - - newParentRef := func(typ *pbresource.Type, tenancyStr, name, port string) *pbmesh.ParentReference { - return &pbmesh.ParentReference{ - Ref: newRef(typ, tenancyStr, name), - Port: port, - } - } - - return map[string]xRouteParentRefTestcase{ - "no parent refs": { - routeTenancy: resource.DefaultNamespacedTenancy(), - expectErr: `invalid "parent_refs" field: cannot be empty`, - }, - "parent ref with nil ref": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", ""), - { - Ref: nil, - Port: "http", - }, - }, - expectErr: `invalid element at index 1 of list "parent_refs": invalid "ref" field: missing required field`, - }, - "parent ref with bad type ref": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", ""), - newParentRef(pbcatalog.WorkloadType, "", "api", ""), - }, - expectErr: `invalid element at index 1 of list "parent_refs": invalid "ref" field: invalid "type" field: reference must have type catalog.v2beta1.Service`, - }, - "parent ref with section": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", ""), - { - Ref: resourcetest.Resource(pbcatalog.ServiceType, "web").Reference("section2"), - Port: "http", - }, - }, - expectErr: `invalid element at index 1 of list "parent_refs": invalid "ref" field: invalid "section" field: section cannot be set here`, - }, - "cross namespace parent": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "default.foo", "api", ""), - }, - expectErr: `invalid element at index 0 of list "parent_refs": invalid "ref" field: invalid "tenancy" field: resource tenancy and reference tenancy differ`, - }, - "cross partition parent": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "alpha.default", "api", ""), - }, - expectErr: `invalid element at index 0 of list "parent_refs": invalid "ref" field: invalid "tenancy" field: resource tenancy and reference tenancy differ`, - }, - "cross tenancy parent": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "alpha.foo", "api", ""), - }, - expectErr: `invalid element at index 0 of list "parent_refs": invalid "ref" field: invalid "tenancy" field: resource tenancy and reference tenancy differ`, - }, - "duplicate exact parents": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", "http"), - newParentRef(pbcatalog.ServiceType, "", "api", "http"), - }, - expectErr: `invalid element at index 1 of list "parent_refs": invalid "port" field: parent ref "catalog.v2beta1.Service/default.local.default/api" for port "http" exists twice`, - }, - "duplicate wild parents": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", ""), - newParentRef(pbcatalog.ServiceType, "", "api", ""), - }, - expectErr: `invalid element at index 1 of list "parent_refs": invalid "port" field: parent ref "catalog.v2beta1.Service/default.local.default/api" for wildcard port exists twice`, - }, - "duplicate parents via exact+wild overlap": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", "http"), - newParentRef(pbcatalog.ServiceType, "", "api", ""), - }, - expectErr: `invalid element at index 1 of list "parent_refs": invalid "port" field: parent ref "catalog.v2beta1.Service/default.local.default/api" for ports [http] covered by wildcard port already`, - }, - "duplicate parents via exact+wild overlap (reversed)": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", ""), - newParentRef(pbcatalog.ServiceType, "", "api", "http"), - }, - expectErr: `invalid element at index 1 of list "parent_refs": invalid "port" field: parent ref "catalog.v2beta1.Service/default.local.default/api" for port "http" covered by wildcard port already`, - }, - "good single parent ref": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", "http"), - }, - }, - "good muliple parent refs": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.ParentReference{ - newParentRef(pbcatalog.ServiceType, "", "api", "http"), - newParentRef(pbcatalog.ServiceType, "", "web", ""), - }, - }, - } -} - -type xRouteBackendRefTestcase struct { - routeTenancy *pbresource.Tenancy - refs []*pbmesh.BackendReference - expectErr string -} - -func getXRouteBackendRefTestCases() map[string]xRouteBackendRefTestcase { - newRef := func(typ *pbresource.Type, tenancyStr, name string) *pbresource.Reference { - return resourcetest.Resource(typ, name). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - Reference("") - } - - newBackendRef := func(typ *pbresource.Type, tenancyStr, name, port string) *pbmesh.BackendReference { - return &pbmesh.BackendReference{ - Ref: newRef(typ, tenancyStr, name), - Port: port, - } - } - return map[string]xRouteBackendRefTestcase{ - "no backend refs": { - routeTenancy: resource.DefaultNamespacedTenancy(), - expectErr: `invalid "backend_refs" field: cannot be empty`, - }, - "backend ref with nil ref": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "", "api", ""), - { - Ref: nil, - Port: "http", - }, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 1 of list "backend_refs": invalid "backend_ref" field: invalid "ref" field: missing required field`, - }, - "backend ref with bad type ref": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "", "api", ""), - newBackendRef(pbcatalog.WorkloadType, "", "api", ""), - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 1 of list "backend_refs": invalid "backend_ref" field: invalid "ref" field: invalid "type" field: reference must have type catalog.v2beta1.Service`, - }, - "backend ref with section": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "", "api", ""), - { - Ref: resourcetest.Resource(pbcatalog.ServiceType, "web").Reference("section2"), - Port: "http", - }, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 1 of list "backend_refs": invalid "backend_ref" field: invalid "ref" field: invalid "section" field: section cannot be set here`, - }, - "backend ref with datacenter": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "", "api", ""), - { - Ref: newRef(pbcatalog.ServiceType, "", "db"), - Port: "http", - Datacenter: "dc2", - }, - }, - expectErr: `invalid element at index 0 of list "rules": invalid element at index 1 of list "backend_refs": invalid "backend_ref" field: invalid "datacenter" field: datacenter is not yet supported on backend refs`, - }, - "cross namespace backend": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "default.foo", "api", ""), - }, - }, - "cross partition backend": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "alpha.default", "api", ""), - }, - }, - "cross tenancy backend": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "alpha.foo", "api", ""), - }, - }, - "good backend ref": { - routeTenancy: resource.DefaultNamespacedTenancy(), - refs: []*pbmesh.BackendReference{ - newBackendRef(pbcatalog.ServiceType, "", "api", ""), - { - Ref: newRef(pbcatalog.ServiceType, "", "db"), - Port: "http", - }, - }, - }, - } -} - -type xRouteTimeoutsTestcase struct { - timeouts *pbmesh.HTTPRouteTimeouts - expectErr string -} - -func getXRouteTimeoutsTestCases() map[string]xRouteTimeoutsTestcase { - return map[string]xRouteTimeoutsTestcase{ - "bad request": { - timeouts: &pbmesh.HTTPRouteTimeouts{ - Request: durationpb.New(-1 * time.Second), - }, - expectErr: `invalid element at index 0 of list "rules": invalid "timeouts" field: invalid "request" field: timeout cannot be negative: -1s`, - }, - "bad idle": { - timeouts: &pbmesh.HTTPRouteTimeouts{ - Idle: durationpb.New(-1 * time.Second), - }, - expectErr: `invalid element at index 0 of list "rules": invalid "timeouts" field: invalid "idle" field: timeout cannot be negative: -1s`, - }, - "good all": { - timeouts: &pbmesh.HTTPRouteTimeouts{ - Request: durationpb.New(1 * time.Second), - Idle: durationpb.New(3 * time.Second), - }, - }, - } -} - -type xRouteRetriesTestcase struct { - retries *pbmesh.HTTPRouteRetries - expectErr string -} - -func getXRouteRetriesTestCases() map[string]xRouteRetriesTestcase { - return map[string]xRouteRetriesTestcase{ - "bad conditions": { - retries: &pbmesh.HTTPRouteRetries{ - OnConditions: []string{"garbage"}, - }, - expectErr: `invalid element at index 0 of list "rules": invalid "retries" field: invalid element at index 0 of list "on_conditions": not a valid retry condition: "garbage"`, - }, - "good all": { - retries: &pbmesh.HTTPRouteRetries{ - Number: wrapperspb.UInt32(5), - OnConditions: []string{"internal"}, - }, - }, - } -} - -func testXRouteACLs[R XRouteData](t *testing.T, newRoute func(t *testing.T, parentRefs, backendRefs []*pbresource.Reference) *pbresource.Resource) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - userNewRoute := newRoute - newRoute = func(t *testing.T, parentRefs, backendRefs []*pbresource.Reference) *pbresource.Resource { - require.NotEmpty(t, parentRefs) - require.NotEmpty(t, backendRefs) - res := userNewRoute(t, parentRefs, backendRefs) - res.Id.Tenancy = parentRefs[0].Tenancy - resourcetest.ValidateAndNormalize(t, registry, res) - return res - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - serviceRef := func(tenancy, name string) *pbresource.Reference { - return newRefWithTenancy(pbcatalog.ServiceType, tenancy, name) - } - - resOneParentOneBackend := func(parentTenancy, backendTenancy string) *pbresource.Resource { - return newRoute(t, - []*pbresource.Reference{ - serviceRef(parentTenancy, "api1"), - }, - []*pbresource.Reference{ - serviceRef(backendTenancy, "backend1"), - }, - ) - } - resTwoParentsOneBackend := func(parentTenancy, backendTenancy string) *pbresource.Resource { - return newRoute(t, - []*pbresource.Reference{ - serviceRef(parentTenancy, "api1"), - serviceRef(parentTenancy, "api2"), - }, - []*pbresource.Reference{ - serviceRef(backendTenancy, "backend1"), - }, - ) - } - resOneParentTwoBackends := func(parentTenancy, backendTenancy string) *pbresource.Resource { - return newRoute(t, - []*pbresource.Reference{ - serviceRef(parentTenancy, "api1"), - }, - []*pbresource.Reference{ - serviceRef(backendTenancy, "backend1"), - serviceRef(backendTenancy, "backend2"), - }, - ) - } - resTwoParentsTwoBackends := func(parentTenancy, backendTenancy string) *pbresource.Resource { - return newRoute(t, - []*pbresource.Reference{ - serviceRef(parentTenancy, "api1"), - serviceRef(parentTenancy, "api2"), - }, - []*pbresource.Reference{ - serviceRef(backendTenancy, "backend1"), - serviceRef(backendTenancy, "backend2"), - }, - ) - } - - run := func(t *testing.T, name string, tc resourcetest.ACLTestCase) { - t.Run(name, func(t *testing.T) { - resourcetest.RunACLTestCase(t, tc, registry) - }) - } - - isEnterprise := (structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default") - - serviceRead := func(partition, namespace, name string) string { - if isEnterprise { - return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "read" } } }`, partition, namespace, name) - } - return fmt.Sprintf(` service %q { policy = "read" } `, name) - } - serviceWrite := func(partition, namespace, name string) string { - if isEnterprise { - return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "write" } } }`, partition, namespace, name) - } - return fmt.Sprintf(` service %q { policy = "write" } `, name) - } - - assert := func(t *testing.T, name string, rules string, res *pbresource.Resource, readOK, writeOK string) { - tc := resourcetest.ACLTestCase{ - Rules: rules, - Res: res, - ReadOK: readOK, - WriteOK: writeOK, - ListOK: DEFAULT, - ReadHookRequiresResource: true, - } - run(t, name, tc) - } - - tenancies := []string{"default.default"} - if isEnterprise { - tenancies = append(tenancies, "default.foo", "alpha.default", "alpha.foo") - } - - for _, parentTenancyStr := range tenancies { - t.Run("route tenancy: "+parentTenancyStr, func(t *testing.T) { - for _, backendTenancyStr := range tenancies { - t.Run("backend tenancy: "+backendTenancyStr, func(t *testing.T) { - for _, aclTenancyStr := range tenancies { - t.Run("acl tenancy: "+aclTenancyStr, func(t *testing.T) { - aclTenancy := resourcetest.Tenancy(aclTenancyStr) - - maybe := func(match string, parentOnly bool) string { - if parentTenancyStr != aclTenancyStr { - return DENY - } - if !parentOnly && backendTenancyStr != aclTenancyStr { - return DENY - } - return match - } - - t.Run("no rules", func(t *testing.T) { - rules := `` - assert(t, "1parent 1backend", rules, resOneParentOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) - assert(t, "1parent 2backends", rules, resOneParentTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) - assert(t, "2parents 1backend", rules, resTwoParentsOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) - assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) - }) - t.Run("api1:read", func(t *testing.T) { - rules := serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "api1") - assert(t, "1parent 1backend", rules, resOneParentOneBackend(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) - assert(t, "1parent 2backends", rules, resOneParentTwoBackends(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) - assert(t, "2parents 1backend", rules, resTwoParentsOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) - assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) - }) - t.Run("api1:write", func(t *testing.T) { - rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api1") - assert(t, "1parent 1backend", rules, resOneParentOneBackend(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) - assert(t, "1parent 2backends", rules, resOneParentTwoBackends(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) - assert(t, "2parents 1backend", rules, resTwoParentsOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) - assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) - }) - t.Run("api1:write backend1:read", func(t *testing.T) { - rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api1") + - serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "backend1") - assert(t, "1parent 1backend", rules, resOneParentOneBackend(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), maybe(ALLOW, false)) - assert(t, "1parent 2backends", rules, resOneParentTwoBackends(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) - assert(t, "2parents 1backend", rules, resTwoParentsOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) - assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) - }) - }) - } - }) - } - }) - } -} - -func newRef(typ *pbresource.Type, name string) *pbresource.Reference { - return resourcetest.Resource(typ, name). - WithTenancy(resource.DefaultNamespacedTenancy()). - Reference("") -} - -func newRefWithTenancy(typ *pbresource.Type, tenancyStr, name string) *pbresource.Reference { - return resourcetest.Resource(typ, name). - WithTenancy(resourcetest.Tenancy(tenancyStr)). - Reference("") -} - -func newBackendRef(typ *pbresource.Type, name, port string) *pbmesh.BackendReference { - return &pbmesh.BackendReference{ - Ref: newRef(typ, name), - Port: port, - } -} - -func newParentRef(typ *pbresource.Type, name, port string) *pbmesh.ParentReference { - return newParentRefWithTenancy(typ, "default.default", name, port) -} - -func newParentRefWithTenancy(typ *pbresource.Type, tenancyStr string, name, port string) *pbmesh.ParentReference { - return &pbmesh.ParentReference{ - Ref: newRefWithTenancy(typ, tenancyStr, name), - Port: port, - } -} diff --git a/internal/mesh/proxy-snapshot/proxy_snapshot.go b/internal/mesh/proxy-snapshot/proxy_snapshot.go deleted file mode 100644 index e1c972c08a4e6..0000000000000 --- a/internal/mesh/proxy-snapshot/proxy_snapshot.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxysnapshot - -import "github.com/hashicorp/consul/acl" - -// ProxySnapshot is an abstraction that allows interchangeability between -// Catalog V1 ConfigSnapshot and Catalog V2 ProxyState. -type ProxySnapshot interface { - AllowEmptyListeners() bool - AllowEmptyRoutes() bool - AllowEmptyClusters() bool - Authorize(authz acl.Authorizer) error - LoggerName() string -} - -// CancelFunc is a type for a returned function that can be called to cancel a -// watch. -type CancelFunc func() diff --git a/internal/mesh/proxy-tracker/mock_SessionLimiter.go b/internal/mesh/proxy-tracker/mock_SessionLimiter.go deleted file mode 100644 index 32375dbdc3862..0000000000000 --- a/internal/mesh/proxy-tracker/mock_SessionLimiter.go +++ /dev/null @@ -1,53 +0,0 @@ -// Code generated by mockery v2.33.1. DO NOT EDIT. - -package proxytracker - -import ( - limiter "github.com/hashicorp/consul/agent/grpc-external/limiter" - mock "github.com/stretchr/testify/mock" -) - -// MockSessionLimiter is an autogenerated mock type for the SessionLimiter type -type MockSessionLimiter struct { - mock.Mock -} - -// BeginSession provides a mock function with given fields: -func (_m *MockSessionLimiter) BeginSession() (limiter.Session, error) { - ret := _m.Called() - - var r0 limiter.Session - var r1 error - if rf, ok := ret.Get(0).(func() (limiter.Session, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() limiter.Session); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(limiter.Session) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewMockSessionLimiter creates a new instance of MockSessionLimiter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockSessionLimiter(t interface { - mock.TestingT - Cleanup(func()) -}) *MockSessionLimiter { - mock := &MockSessionLimiter{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/internal/mesh/proxy-tracker/proxy_state_exports.go b/internal/mesh/proxy-tracker/proxy_state_exports.go deleted file mode 100644 index cdc6d6d845807..0000000000000 --- a/internal/mesh/proxy-tracker/proxy_state_exports.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxytracker - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" -) - -// ProxyState is an implementation of the ProxySnapshot interface for pbmesh.ProxyState. -// It is a simple wrapper around pbmesh.ProxyState so that it can be used -// by the ProxyWatcher interface in XDS processing. This struct is necessary -// because pbmesh.ProxyState is a proto definition and there were complications -// adding these functions directly to that proto definition. -type ProxyState struct { - *pbmesh.ProxyState -} - -// TODO(proxystate): need to modify ProxyState to carry a type/kind (connect proxy, mesh gateway, etc.) -// for sidecar proxies, all Allow* functions -// should return false, but for different gateways we'd need to add it to IR. - -func (p *ProxyState) AllowEmptyListeners() bool { - return false -} - -func (p *ProxyState) AllowEmptyRoutes() bool { - return false -} - -func (p *ProxyState) AllowEmptyClusters() bool { - return false -} - -func (p *ProxyState) Authorize(authz acl.Authorizer) error { - // authorize for mesh proxies. - // TODO(proxystate): implement differently for gateways - allow := authz.ToAllowAuthorizer() - if err := allow.IdentityWriteAllowed(p.Identity.Name, resource.AuthorizerContext(p.Identity.Tenancy)); err != nil { - return err - } - - return nil -} - -func (p *ProxyState) LoggerName() string { - return "" -} diff --git a/internal/mesh/proxy-tracker/proxy_state_exports_test.go b/internal/mesh/proxy-tracker/proxy_state_exports_test.go deleted file mode 100644 index 18d15fb53dad5..0000000000000 --- a/internal/mesh/proxy-tracker/proxy_state_exports_test.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxytracker - -import ( - "github.com/hashicorp/consul/acl" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - "strings" - "testing" -) - -func TestProxyState_Authorize(t *testing.T) { - testIdentity := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "mesh", - GroupVersion: "v1alpha1", - Kind: "Identity", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "default", - Namespace: "default", - PeerName: "local", - }, - Name: "test-identity", - } - - type testCase struct { - description string - proxyState *ProxyState - configureAuthorizer func(authorizer *acl.MockAuthorizer) - expectedErrorMessage string - } - testsCases := []testCase{ - { - description: "ProxyState - if identity write is allowed for the workload then allow.", - proxyState: &ProxyState{ - ProxyState: &pbmesh.ProxyState{ - Identity: testIdentity, - }, - }, - expectedErrorMessage: "", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("IdentityWrite", testIdentity.Name, mock.Anything).Return(acl.Allow) - }, - }, - { - description: "ProxyState - if identity write is not allowed for the workload then deny.", - proxyState: &ProxyState{ - ProxyState: &pbmesh.ProxyState{ - Identity: testIdentity, - }, - }, - expectedErrorMessage: "Permission denied: token with AccessorID '' lacks permission 'identity:write' on \"test-identity\"", - configureAuthorizer: func(authz *acl.MockAuthorizer) { - authz.On("IdentityWrite", testIdentity.Name, mock.Anything).Return(acl.Deny) - }, - }, - } - for _, tc := range testsCases { - t.Run(tc.description, func(t *testing.T) { - authz := &acl.MockAuthorizer{} - authz.On("ToAllow").Return(acl.AllowAuthorizer{Authorizer: authz}) - tc.configureAuthorizer(authz) - err := tc.proxyState.Authorize(authz) - errMsg := "" - if err != nil { - errMsg = err.Error() - } - // using contains because Enterprise tests append the parition and namespace - // information to the message. - require.True(t, strings.Contains(errMsg, tc.expectedErrorMessage)) - }) - } -} diff --git a/internal/mesh/proxy-tracker/proxy_tracker.go b/internal/mesh/proxy-tracker/proxy_tracker.go deleted file mode 100644 index d9dae03a13cde..0000000000000 --- a/internal/mesh/proxy-tracker/proxy_tracker.go +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxytracker - -import ( - "errors" - "fmt" - "sync" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/agent/grpc-external/limiter" - "github.com/hashicorp/consul/internal/controller" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" - "github.com/hashicorp/consul/internal/resource" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// ProxyConnection implements the queue.ItemType interface so that it can be used in a controller.Event. -// It is sent on the newProxyConnectionCh channel. -// TODO(ProxyState): needs to support tenancy in the future. -type ProxyConnection struct { - ProxyID *pbresource.ID -} - -// Key is current resourceID.Name. -func (e *ProxyConnection) Key() string { - return e.ProxyID.GetName() -} - -// proxyWatchData is a handle on all of the relevant bits that is created by calling Watch(). -// It is meant to be stored in the proxies cache by proxyID so that watches can be notified -// when the ProxyState for that proxyID has changed. -type proxyWatchData struct { - // notifyCh is the channel that the watcher receives updates from ProxyTracker. - notifyCh chan proxysnapshot.ProxySnapshot - // state is the current/last updated ProxyState for a given proxy. - state proxysnapshot.ProxySnapshot - // token is the ACL token provided by the watcher. - token string - // nodeName is the node where the given proxy resides. - nodeName string -} - -type ProxyTrackerConfig struct { - // logger will be used to write log messages. - Logger hclog.Logger - - // sessionLimiter is used to enforce xDS concurrency limits. - SessionLimiter SessionLimiter -} - -// ProxyTracker implements the Watcher and Updater interfaces. The Watcher is used by the xds server to add a new proxy -// to this server, and get back a channel for updates. The Updater is used by the ProxyState controller running on the -// server to push ProxyState updates to the notify channel. -type ProxyTracker struct { - config ProxyTrackerConfig - // proxies is a cache of the proxies connected to this server and configuration information for each one. - proxies map[resource.ReferenceKey]*proxyWatchData - // newProxyConnectionCh is the channel that the "updater" retains to receive messages from ProxyTracker that a new - // proxy has connected to ProxyTracker and a signal the "updater" should call PushChanges with a new state. - newProxyConnectionCh chan controller.Event - // shutdownCh is a channel that closes when ProxyTracker is shutdown. ShutdownChannel is never written to, only closed to - // indicate a shutdown has been initiated. - shutdownCh chan struct{} - // mu is a mutex that is used internally for locking when reading and modifying ProxyTracker state, namely the proxies map. - mu sync.Mutex -} - -// NewProxyTracker returns a ProxyTracker instance given a configuration. -func NewProxyTracker(cfg ProxyTrackerConfig) *ProxyTracker { - return &ProxyTracker{ - config: cfg, - proxies: make(map[resource.ReferenceKey]*proxyWatchData), - // buffering this channel since ProxyTracker will be registering watches for all proxies. - // using the buffer will limit errors related to controller and the proxy are both running - // but the controllers listening function is not blocking on the particular receive line. - // This channel is meant to error when the controller is "not ready" which means up and alive. - // This buffer will try to reduce false negatives and limit unnecessary erroring. - newProxyConnectionCh: make(chan controller.Event, 1000), - shutdownCh: make(chan struct{}), - } -} - -// Watch connects a proxy with ProxyTracker and returns the consumer a channel to receive updates, -// a channel to notify of xDS terminated session, and a cancel function to cancel the watch. -func (pt *ProxyTracker) Watch(proxyID *pbresource.ID, - nodeName string, token string) (<-chan proxysnapshot.ProxySnapshot, - limiter.SessionTerminatedChan, proxysnapshot.CancelFunc, error) { - pt.config.Logger.Trace("watch initiated", "proxyID", proxyID, "nodeName", nodeName) - if err := pt.validateWatchArgs(proxyID, nodeName); err != nil { - pt.config.Logger.Error("args failed validation", err) - return nil, nil, nil, err - } - // Begin a session with the xDS session concurrency limiter. - // - // See: https://github.com/hashicorp/consul/issues/15753 - session, err := pt.config.SessionLimiter.BeginSession() - if err != nil { - pt.config.Logger.Error("failed to begin session with xDS session concurrency limiter", err) - return nil, nil, nil, err - } - - // This buffering is crucial otherwise we'd block immediately trying to - // deliver the current snapshot below if we already have one. - - proxyStateChan := make(chan proxysnapshot.ProxySnapshot, 1) - watchData := &proxyWatchData{ - notifyCh: proxyStateChan, - state: nil, - token: token, - nodeName: nodeName, - } - - proxyReferenceKey := resource.NewReferenceKey(proxyID) - cancel := func() { - pt.mu.Lock() - defer pt.mu.Unlock() - pt.cancelWatchLocked(proxyReferenceKey, proxyStateChan, session) - } - - pt.mu.Lock() - defer pt.mu.Unlock() - - pt.proxies[proxyReferenceKey] = watchData - - //Send an event to the controller - err = pt.notifyNewProxyChannel(proxyID) - if err != nil { - pt.config.Logger.Error("failed to notify controller of new proxy connection", err) - pt.cancelWatchLocked(proxyReferenceKey, watchData.notifyCh, session) - return nil, nil, nil, err - } - pt.config.Logger.Trace("controller notified of watch created", "proxyID", proxyID, "nodeName", nodeName) - - return proxyStateChan, session.Terminated(), cancel, nil -} - -// notifyNewProxyChannel attempts to send a message to newProxyConnectionCh and will return an error if there's no receiver. -// This will handle conditions where a proxy is connected but there's no controller for some reason to receive the event. -// This will error back to the proxy's Watch call and will cause the proxy call Watch again to retry connection until the controller -// is available. -func (pt *ProxyTracker) notifyNewProxyChannel(proxyID *pbresource.ID) error { - controllerEvent := controller.Event{ - Obj: &ProxyConnection{ - ProxyID: proxyID, - }, - } - select { - case pt.newProxyConnectionCh <- controllerEvent: - return nil - // using default here to return errors is only safe when we have a large buffer. - // the receiver is on a loop to read from the channel. If the sequence of - // sender blocks on the channel and then the receiver blocks on the channel is not - // aligned, then extraneous errors could be returned to the proxy that are just - // false negatives and the controller could be up and healthy. - default: - return fmt.Errorf("failed to notify the controller of the proxy connecting") - } -} - -// cancelWatchLocked does the following: -// - deletes the key from the proxies array. -// - ends the session with xDS session limiter. -// - closes the proxy state channel assigned to the proxy. -// This function assumes the state lock is already held. -func (pt *ProxyTracker) cancelWatchLocked(proxyReferenceKey resource.ReferenceKey, proxyStateChan chan proxysnapshot.ProxySnapshot, session limiter.Session) { - delete(pt.proxies, proxyReferenceKey) - session.End() - close(proxyStateChan) - pt.config.Logger.Trace("watch cancelled", "proxyReferenceKey", proxyReferenceKey) -} - -// validateWatchArgs checks the proxyIDand nodeName passed to Watch -// and returns an error if the args are not properly constructed. -func (pt *ProxyTracker) validateWatchArgs(proxyID *pbresource.ID, - nodeName string) error { - if proxyID == nil { - return errors.New("proxyID is required") - } else if proxyID.GetType().GetKind() != pbmesh.ProxyStateTemplateType.Kind { - return fmt.Errorf("proxyID must be a %s", pbmesh.ProxyStateTemplateType.GetKind()) - } else if nodeName == "" { - return errors.New("nodeName is required") - } - - return nil -} - -// PushChange allows pushing a computed ProxyState to xds for xds resource generation to send to a proxy. -func (pt *ProxyTracker) PushChange(proxyID *pbresource.ID, proxyState proxysnapshot.ProxySnapshot) error { - pt.config.Logger.Trace("push change called for proxy", "proxyID", proxyID) - proxyReferenceKey := resource.NewReferenceKey(proxyID) - pt.mu.Lock() - defer pt.mu.Unlock() - if data, ok := pt.proxies[proxyReferenceKey]; ok { - data.state = proxyState - - pt.deliverLatest(proxyID, proxyState, data.notifyCh) - } else { - return errors.New("proxyState change could not be sent because proxy is not connected") - } - - return nil -} - -func (pt *ProxyTracker) deliverLatest(proxyID *pbresource.ID, proxyState proxysnapshot.ProxySnapshot, ch chan proxysnapshot.ProxySnapshot) { - pt.config.Logger.Trace("delivering latest proxy snapshot to proxy", "proxyID", proxyID) - // Send if chan is empty - select { - case ch <- proxyState: - return - default: - } - - // Not empty, drain the chan of older snapshots and redeliver. For now we only - // use 1-buffered chans but this will still work if we change that later. -OUTER: - for { - select { - case <-ch: - continue - default: - break OUTER - } - } - - // Now send again - select { - case ch <- proxyState: - return - default: - // This should not be possible since we should be the only sender, enforced - // by m.mu but error and drop the update rather than panic. - pt.config.Logger.Error("failed to deliver proxyState to proxy", - "proxy", proxyID.String(), - ) - } -} - -// EventChannel returns an event channel that sends controller events when a proxy connects to a server. -func (pt *ProxyTracker) EventChannel() chan controller.Event { - return pt.newProxyConnectionCh -} - -// ShutdownChannel returns a channel that closes when ProxyTracker is shutdown. ShutdownChannel is never written to, only closed to -// indicate a shutdown has been initiated. -func (pt *ProxyTracker) ShutdownChannel() chan struct{} { - return pt.shutdownCh -} - -// ProxyConnectedToServer returns whether this id is connected to this server. -func (pt *ProxyTracker) ProxyConnectedToServer(proxyID *pbresource.ID) (string, bool) { - pt.mu.Lock() - defer pt.mu.Unlock() - proxyReferenceKey := resource.NewReferenceKey(proxyID) - proxyData, ok := pt.proxies[proxyReferenceKey] - if ok { - return proxyData.token, ok - } - return "", ok -} - -// Shutdown removes all state and close all channels. -func (pt *ProxyTracker) Shutdown() { - pt.config.Logger.Info("proxy tracker shutdown initiated") - pt.mu.Lock() - defer pt.mu.Unlock() - - // Close all current watchers first - for proxyID, watchData := range pt.proxies { - close(watchData.notifyCh) - delete(pt.proxies, proxyID) - } - - close(pt.newProxyConnectionCh) - close(pt.shutdownCh) -} - -//go:generate mockery --name SessionLimiter --inpackage -type SessionLimiter interface { - BeginSession() (limiter.Session, error) -} diff --git a/internal/mesh/proxy-tracker/proxy_tracker_test.go b/internal/mesh/proxy-tracker/proxy_tracker_test.go deleted file mode 100644 index d6c1fc1ce5e06..0000000000000 --- a/internal/mesh/proxy-tracker/proxy_tracker_test.go +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package proxytracker - -import ( - "errors" - "fmt" - "testing" - - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/agent/grpc-external/limiter" - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestProxyTracker_Watch(t *testing.T) { - resourceID := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").ID() - proxyReferenceKey := resource.NewReferenceKey(resourceID) - lim := NewMockSessionLimiter(t) - session1 := newMockSession(t) - session1TermCh := make(limiter.SessionTerminatedChan) - session1.On("Terminated").Return(session1TermCh) - session1.On("End").Return() - lim.On("BeginSession").Return(session1, nil) - logger := testutil.Logger(t) - - pt := NewProxyTracker(ProxyTrackerConfig{ - Logger: logger, - SessionLimiter: lim, - }) - - // Watch() - proxyStateChan, _, cancelFunc, err := pt.Watch(resourceID, "node 1", "token") - require.NoError(t, err) - - // ensure New Proxy Connection message is sent - newProxyMsg := <-pt.EventChannel() - require.Equal(t, resourceID.Name, newProxyMsg.Obj.Key()) - - // watchData is stored in the proxies array with a nil state - watchData, ok := pt.proxies[proxyReferenceKey] - require.True(t, ok) - require.NotNil(t, watchData) - require.Nil(t, watchData.state) - - // calling cancelFunc does the following: - // - closes the proxy state channel - // - and removes the map entry for the proxy - // - session is ended - cancelFunc() - - // read channel to see if there is data and it is open. - receivedState, channelOpen := <-proxyStateChan - require.Nil(t, receivedState) - require.False(t, channelOpen) - - // key is removed from proxies array - _, ok = pt.proxies[proxyReferenceKey] - require.False(t, ok) - - // session ended - session1.AssertCalled(t, "Terminated") - session1.AssertCalled(t, "End") -} - -func TestProxyTracker_Watch_ErrorConsumerNotReady(t *testing.T) { - resourceID := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").ID() - proxyReferenceKey := resource.NewReferenceKey(resourceID) - lim := NewMockSessionLimiter(t) - session1 := newMockSession(t) - session1.On("End").Return() - lim.On("BeginSession").Return(session1, nil) - logger := testutil.Logger(t) - - pt := NewProxyTracker(ProxyTrackerConfig{ - Logger: logger, - SessionLimiter: lim, - }) - - //fill up buffered channel while the consumer is not ready to simulate the error - for i := 0; i < 1000; i++ { - event := controller.Event{Obj: &ProxyConnection{ProxyID: resourcetest.Resource(pbmesh.ProxyStateTemplateType, fmt.Sprintf("test%d", i)).ID()}} - pt.newProxyConnectionCh <- event - } - - // Watch() - proxyStateChan, sessionTerminatedCh, cancelFunc, err := pt.Watch(resourceID, "node 1", "token") - require.Nil(t, cancelFunc) - require.Nil(t, proxyStateChan) - require.Nil(t, sessionTerminatedCh) - require.Error(t, err) - require.Equal(t, "failed to notify the controller of the proxy connecting", err.Error()) - - // it is not stored in the proxies array - watchData, ok := pt.proxies[proxyReferenceKey] - require.False(t, ok) - require.Nil(t, watchData) -} - -func TestProxyTracker_Watch_ArgValidationErrors(t *testing.T) { - type testcase struct { - description string - proxyID *pbresource.ID - nodeName string - token string - expectedError error - } - testcases := []*testcase{ - { - description: "Empty proxyID", - proxyID: nil, - nodeName: "something", - token: "something", - expectedError: errors.New("proxyID is required"), - }, - { - description: "Empty nodeName", - proxyID: resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").ID(), - nodeName: "", - token: "something", - expectedError: errors.New("nodeName is required"), - }, - { - description: "resource is not ProxyStateTemplate", - proxyID: resourcetest.Resource(pbmesh.ProxyConfigurationType, "test").ID(), - nodeName: "something", - token: "something else", - expectedError: errors.New("proxyID must be a ProxyStateTemplate"), - }, - } - for _, tc := range testcases { - lim := NewMockSessionLimiter(t) - lim.On("BeginSession").Return(nil, nil).Maybe() - logger := testutil.Logger(t) - - pt := NewProxyTracker(ProxyTrackerConfig{ - Logger: logger, - SessionLimiter: lim, - }) - - // Watch() - proxyStateChan, sessionTerminateCh, cancelFunc, err := pt.Watch(tc.proxyID, tc.nodeName, tc.token) - require.Error(t, err) - require.Equal(t, tc.expectedError, err) - require.Nil(t, proxyStateChan) - require.Nil(t, sessionTerminateCh) - require.Nil(t, cancelFunc) - } -} - -func TestProxyTracker_Watch_SessionLimiterError(t *testing.T) { - resourceID := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").ID() - lim := NewMockSessionLimiter(t) - lim.On("BeginSession").Return(nil, errors.New("kaboom")) - logger := testutil.Logger(t) - pt := NewProxyTracker(ProxyTrackerConfig{ - Logger: logger, - SessionLimiter: lim, - }) - - // Watch() - proxyStateChan, sessionTerminateCh, cancelFunc, err := pt.Watch(resourceID, "node 1", "token") - require.Error(t, err) - require.Equal(t, "kaboom", err.Error()) - require.Nil(t, proxyStateChan) - require.Nil(t, sessionTerminateCh) - require.Nil(t, cancelFunc) -} - -func TestProxyTracker_PushChange(t *testing.T) { - resourceID := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").ID() - proxyReferenceKey := resource.NewReferenceKey(resourceID) - lim := NewMockSessionLimiter(t) - session1 := newMockSession(t) - session1TermCh := make(limiter.SessionTerminatedChan) - session1.On("Terminated").Return(session1TermCh) - lim.On("BeginSession").Return(session1, nil) - logger := testutil.Logger(t) - - pt := NewProxyTracker(ProxyTrackerConfig{ - Logger: logger, - SessionLimiter: lim, - }) - - // Watch() - proxyStateChan, _, _, err := pt.Watch(resourceID, "node 1", "token") - require.NoError(t, err) - - // PushChange - proxyState := &ProxyState{ProxyState: &pbmesh.ProxyState{}} - - // using a goroutine so that the channel and main test thread do not cause - // blocking issues with each other - go func() { - err = pt.PushChange(resourceID, proxyState) - require.NoError(t, err) - }() - - // channel receives a copy - receivedState, channelOpen := <-proxyStateChan - require.True(t, channelOpen) - require.Equal(t, proxyState, receivedState) - - // it is stored in the proxies array - watchData, ok := pt.proxies[proxyReferenceKey] - require.True(t, ok) - require.Equal(t, proxyState, watchData.state) -} - -func TestProxyTracker_PushChanges_ErrorProxyNotConnected(t *testing.T) { - resourceID := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").ID() - lim := NewMockSessionLimiter(t) - logger := testutil.Logger(t) - - pt := NewProxyTracker(ProxyTrackerConfig{ - Logger: logger, - SessionLimiter: lim, - }) - - // PushChange - proxyState := &ProxyState{ProxyState: &pbmesh.ProxyState{}} - - err := pt.PushChange(resourceID, proxyState) - require.Error(t, err) - require.Equal(t, "proxyState change could not be sent because proxy is not connected", err.Error()) -} - -func TestProxyTracker_ProxyConnectedToServer(t *testing.T) { - type testcase struct { - name string - shouldExist bool - preProcessingFunc func(pt *ProxyTracker, resourceID *pbresource.ID, limiter *MockSessionLimiter, session *mockSession, channel limiter.SessionTerminatedChan) - } - testsCases := []*testcase{ - { - name: "Resource that has not been sent through Watch() should return false", - shouldExist: false, - preProcessingFunc: func(pt *ProxyTracker, resourceID *pbresource.ID, limiter *MockSessionLimiter, session *mockSession, channel limiter.SessionTerminatedChan) { - session.On("Terminated").Return(channel).Maybe() - session.On("End").Return().Maybe() - limiter.On("BeginSession").Return(session, nil).Maybe() - }, - }, - { - name: "Resource used that is already passed in through Watch() should return true", - shouldExist: true, - preProcessingFunc: func(pt *ProxyTracker, resourceID *pbresource.ID, limiter *MockSessionLimiter, session *mockSession, channel limiter.SessionTerminatedChan) { - session.On("Terminated").Return(channel).Maybe() - session.On("End").Return().Maybe() - limiter.On("BeginSession").Return(session, nil) - _, _, _, _ = pt.Watch(resourceID, "node 1", "token") - }, - }, - } - - for _, tc := range testsCases { - lim := NewMockSessionLimiter(t) - session1 := newMockSession(t) - session1TermCh := make(limiter.SessionTerminatedChan) - logger := testutil.Logger(t) - - pt := NewProxyTracker(ProxyTrackerConfig{ - Logger: logger, - SessionLimiter: lim, - }) - resourceID := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").ID() - tc.preProcessingFunc(pt, resourceID, lim, session1, session1TermCh) - _, ok := pt.ProxyConnectedToServer(resourceID) - require.Equal(t, tc.shouldExist, ok) - } -} - -func TestProxyTracker_Shutdown(t *testing.T) { - resourceID := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test").ID() - proxyReferenceKey := resource.NewReferenceKey(resourceID) - lim := NewMockSessionLimiter(t) - session1 := newMockSession(t) - session1TermCh := make(limiter.SessionTerminatedChan) - session1.On("Terminated").Return(session1TermCh) - session1.On("End").Return().Maybe() - lim.On("BeginSession").Return(session1, nil) - logger := testutil.Logger(t) - - pt := NewProxyTracker(ProxyTrackerConfig{ - Logger: logger, - SessionLimiter: lim, - }) - - // Watch() - proxyStateChan, _, _, err := pt.Watch(resourceID, "node 1", "token") - require.NoError(t, err) - - pt.Shutdown() - - // proxy channels are all disconnected and proxy is removed from proxies map - receivedState, channelOpen := <-proxyStateChan - require.Nil(t, receivedState) - require.False(t, channelOpen) - _, ok := pt.proxies[proxyReferenceKey] - require.False(t, ok) - - // shutdownCh is closed - select { - case <-pt.ShutdownChannel(): - default: - t.Fatalf("shutdown channel should be closed") - } - // newProxyConnectionCh is closed - select { - case <-pt.EventChannel(): - default: - t.Fatalf("shutdown channel should be closed") - } -} - -type mockSession struct { - mock.Mock -} - -func newMockSession(t *testing.T) *mockSession { - m := &mockSession{} - m.Mock.Test(t) - - t.Cleanup(func() { m.AssertExpectations(t) }) - - return m -} - -func (m *mockSession) End() { m.Called() } - -func (m *mockSession) Terminated() limiter.SessionTerminatedChan { - return m.Called().Get(0).(limiter.SessionTerminatedChan) -} diff --git a/internal/multicluster/exports.go b/internal/multicluster/exports.go deleted file mode 100644 index fcf5873d81ceb..0000000000000 --- a/internal/multicluster/exports.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package multicluster - -import ( - "github.com/hashicorp/consul/internal/multicluster/internal/types" - "github.com/hashicorp/consul/internal/resource" -) - -var ( - // API Group Information - APIGroup = types.GroupName - VersionV2Beta1 = types.VersionV2Beta1 - CurrentVersion = types.CurrentVersion -) - -// RegisterTypes adds all resource types within the "multicluster" API group -// to the given type registry -func RegisterTypes(r resource.Registry) { - types.Register(r) -} diff --git a/internal/multicluster/internal/types/computed_exported_services.go b/internal/multicluster/internal/types/computed_exported_services.go deleted file mode 100644 index 70c900c9b86cd..0000000000000 --- a/internal/multicluster/internal/types/computed_exported_services.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - ComputedExportedServicesName = "global" -) - -func RegisterComputedExportedServices(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmulticluster.ComputedExportedServicesType, - Proto: &pbmulticluster.ComputedExportedServices{}, - Scope: resource.ScopePartition, - Validate: ValidateComputedExportedServices, - ACLs: &resource.ACLHooks{ - Read: aclReadHookComputedExportedServices, - Write: aclWriteHookComputedExportedServices, - List: resource.NoOpACLListHook, - }, - }) -} - -func aclReadHookComputedExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshReadAllowed(authzContext) -} - -func aclWriteHookComputedExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshWriteAllowed(authzContext) -} diff --git a/internal/multicluster/internal/types/computed_exported_services_test.go b/internal/multicluster/internal/types/computed_exported_services_test.go deleted file mode 100644 index 79462c7088c32..0000000000000 --- a/internal/multicluster/internal/types/computed_exported_services_test.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/require" - "testing" -) - -func computedExportedServicesWithPartition(partitionName string) *pbmulticluster.ComputedExportedServices { - consumers := []*pbmulticluster.ComputedExportedService{ - { - Consumers: []*pbmulticluster.ComputedExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ComputedExportedServicesConsumer_Partition{ - Partition: partitionName, - }, - }, - }, - }, - } - return &pbmulticluster.ComputedExportedServices{ - Consumers: consumers, - } -} - -func computedExportedServicesWithPeer(peerName string) *pbmulticluster.ComputedExportedServices { - consumers := []*pbmulticluster.ComputedExportedService{ - { - Consumers: []*pbmulticluster.ComputedExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ComputedExportedServicesConsumer_Peer{ - Peer: peerName, - }, - }, - }, - }, - } - return &pbmulticluster.ComputedExportedServices{ - Consumers: consumers, - } -} - -func TestComputedExportedServicesValidations_InvalidName(t *testing.T) { - res := resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, "computed-exported-services"). - WithData(t, computedExportedServicesWithPeer("peer")). - Build() - - err := ValidateComputedExportedServices(res) - require.Error(t, err) - expectedError := errors.New("invalid \"name\" field: name can only be \"global\"") - require.ErrorAs(t, err, &expectedError) -} - -func TestComputedExportedServicesACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - readOK string - writeOK string - listOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - exportedServiceData := &pbmulticluster.ComputedExportedServices{} - res := resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, "global"). - WithData(t, exportedServiceData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh read policy": { - rules: `mesh = "read"`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh write policy": { - rules: `mesh = "write"`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - for _, tc := range cases { - aclTestCase := resourcetest.ACLTestCase{ - Rules: tc.rules, - Res: res, - ReadOK: tc.readOK, - WriteOK: tc.writeOK, - ListOK: tc.listOK, - } - resourcetest.RunACLTestCase(t, aclTestCase, registry) - } -} - -func TestComputedExportedServicesValidations(t *testing.T) { - type testcase struct { - Resource *pbresource.Resource - expectErrorCE []string - expectErrorENT []string - } - - isEnterprise := structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default" - - run := func(t *testing.T, tc testcase) { - expectError := tc.expectErrorCE - if isEnterprise { - expectError = tc.expectErrorENT - } - err := ValidateComputedExportedServices(tc.Resource) - if len(expectError) == 0 { - require.NoError(t, err) - } else { - require.Error(t, err) - for _, er := range expectError { - require.ErrorContains(t, err, er) - } - } - } - - cases := map[string]testcase{ - "computed exported services with peer": { - Resource: resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, ComputedExportedServicesName). - WithData(t, computedExportedServicesWithPeer("peer")). - Build(), - }, - "computed exported services with partition": { - Resource: resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, ComputedExportedServicesName). - WithData(t, computedExportedServicesWithPartition("partition")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can only be set in Enterprise`}, - }, - "computed exported services with peer empty": { - Resource: resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, ComputedExportedServicesName). - WithData(t, computedExportedServicesWithPeer("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "peer": can not be empty`}, - expectErrorENT: []string{`invalid element at index 0 of list "peer": can not be empty`}, - }, - "computed exported services with partition empty": { - Resource: resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, ComputedExportedServicesName). - WithData(t, computedExportedServicesWithPartition("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can not be empty`, - `invalid element at index 0 of list "partition": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "partition": can not be empty`}, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/multicluster/internal/types/exported_services.go b/internal/multicluster/internal/types/exported_services.go deleted file mode 100644 index 87cebb244ab4e..0000000000000 --- a/internal/multicluster/internal/types/exported_services.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterExportedServices(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmulticluster.ExportedServicesType, - Proto: &pbmulticluster.ExportedServices{}, - Scope: resource.ScopeNamespace, - Validate: ValidateExportedServices, - ACLs: &resource.ACLHooks{ - Read: aclReadHookExportedServices, - Write: aclWriteHookExportedServices, - List: resource.NoOpACLListHook, - }, - }) -} - -func aclReadHookExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { - if res == nil { - return resource.ErrNeedResource - } - - var exportedService pbmulticluster.ExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - for _, serviceName := range exportedService.Services { - if err := authorizer.ToAllowAuthorizer().ServiceReadAllowed(serviceName, authzContext); err != nil { - return err - } - } - return nil -} - -func aclWriteHookExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - var exportedService pbmulticluster.ExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - for _, serviceName := range exportedService.Services { - if err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(serviceName, authzContext); err != nil { - return err - } - } - return nil -} diff --git a/internal/multicluster/internal/types/exported_services_test.go b/internal/multicluster/internal/types/exported_services_test.go deleted file mode 100644 index ea80b16e43df4..0000000000000 --- a/internal/multicluster/internal/types/exported_services_test.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/require" - "testing" -) - -func inValidExportedServices() *pbmulticluster.ExportedServices { - return &pbmulticluster.ExportedServices{} -} - -func exportedServicesWithPeer(peerName string) *pbmulticluster.ExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Peer{ - Peer: peerName, - }, - }, - } - return &pbmulticluster.ExportedServices{ - Services: []string{"api", "frontend", "backend"}, - Consumers: consumers, - } -} - -func exportedServicesWithPartition(partitionName string) *pbmulticluster.ExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Partition{ - Partition: partitionName, - }, - }, - } - return &pbmulticluster.ExportedServices{ - Services: []string{"api", "frontend", "backend"}, - Consumers: consumers, - } -} - -func exportedServicesWithSamenessGroup(samenessGroupName string) *pbmulticluster.ExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_SamenessGroup{ - SamenessGroup: samenessGroupName, - }, - }, - } - return &pbmulticluster.ExportedServices{ - Services: []string{"api", "frontend", "backend"}, - Consumers: consumers, - } -} - -func TestExportedServicesValidation_NoServices(t *testing.T) { - res := resourcetest.Resource(pbmulticluster.ExportedServicesType, "exportedservices1"). - WithData(t, inValidExportedServices()). - Build() - - err := ValidateExportedServices(res) - require.Error(t, err) - expectedError := errors.New("invalid \"services\" field: at least one service must be set") - require.ErrorAs(t, err, &expectedError) -} - -func TestExportedServicesACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - readOK string - writeOK string - listOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - exportedServiceData := &pbmulticluster.ExportedServices{ - Services: []string{"api", "backend"}, - } - res := resourcetest.Resource(pbmulticluster.ExportedServicesType, "exps"). - WithData(t, exportedServiceData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "all services has read policy": { - rules: `service "api" { policy = "read" } service "backend" {policy = "read"}`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "all services has write policy": { - rules: `service "api" { policy = "write" } service "backend" {policy = "write"}`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - "only one services has read policy": { - rules: `service "api" { policy = "read" }`, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "only one services has write policy": { - rules: `service "api" { policy = "write" }`, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - } - - for _, tc := range cases { - aclTestCase := resourcetest.ACLTestCase{ - Rules: tc.rules, - Res: res, - ReadOK: tc.readOK, - WriteOK: tc.writeOK, - ListOK: tc.listOK, - } - resourcetest.RunACLTestCase(t, aclTestCase, registry) - } -} - -func TestExportedServicesValidation(t *testing.T) { - type testcase struct { - Resource *pbresource.Resource - expectErrorCE []string - expectErrorENT []string - } - - isEnterprise := structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default" - - run := func(t *testing.T, tc testcase) { - expectError := tc.expectErrorCE - if isEnterprise { - expectError = tc.expectErrorENT - } - err := ValidateExportedServices(tc.Resource) - if len(expectError) == 0 { - require.NoError(t, err) - } else { - require.Error(t, err) - for _, er := range expectError { - require.ErrorContains(t, err, er) - } - } - } - - cases := map[string]testcase{ - "exported services with peer": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithPeer("peer")). - Build(), - }, - "exported services with partition": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithPartition("partition")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can only be set in Enterprise`}, - }, - "exported services with sameness_group": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithSamenessGroup("sameness_group")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - }, - "exported services with peer empty": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithPeer("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - expectErrorENT: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - }, - "exported services with partition empty": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithPartition("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can not be empty`, - `invalid element at index 0 of list "partition": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "partition": can not be empty`}, - }, - "exported services with sameness_group empty": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithSamenessGroup("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can not be empty`, - `invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "sameness_group": can not be empty`}, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/multicluster/internal/types/helpers.go b/internal/multicluster/internal/types/helpers.go deleted file mode 100644 index 5dac17f1e7a97..0000000000000 --- a/internal/multicluster/internal/types/helpers.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/go-multierror" -) - -func validateExportedServiceConsumerCommon(consumer *pbmulticluster.ExportedServicesConsumer, indx int) error { - switch consumer.GetConsumerTenancy().(type) { - case *pbmulticluster.ExportedServicesConsumer_Peer: - { - if consumer.GetPeer() == "" || consumer.GetPeer() == "local" { - return resource.ErrInvalidListElement{ - Name: "peer", - Index: indx, - Wrapped: fmt.Errorf("can not be empty or local"), - } - } - } - case *pbmulticluster.ExportedServicesConsumer_Partition: - { - if consumer.GetPartition() == "" { - return resource.ErrInvalidListElement{ - Name: "partition", - Index: indx, - Wrapped: fmt.Errorf("can not be empty"), - } - } - } - case *pbmulticluster.ExportedServicesConsumer_SamenessGroup: - { - if consumer.GetSamenessGroup() == "" { - return resource.ErrInvalidListElement{ - Name: "sameness_group", - Index: indx, - Wrapped: fmt.Errorf("can not be empty"), - } - } - } - } - return nil -} - -func validateExportedServicesConsumersEnterprise(consumers []*pbmulticluster.ExportedServicesConsumer) error { - var merr error - - for indx, consumer := range consumers { - vmerr := validateExportedServiceConsumerCommon(consumer, indx) - if vmerr != nil { - merr = multierror.Append(merr, vmerr) - } - vmerr = validateExportedServicesConsumer(consumer, indx) - if vmerr != nil { - merr = multierror.Append(merr, vmerr) - } - } - - return merr -} - -func ValidateExportedServices(res *pbresource.Resource) error { - var exportedService pbmulticluster.ExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - var merr error - - if len(exportedService.Services) == 0 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "services", - Wrapped: fmt.Errorf("at least one service must be set"), - }) - } - - vmerr := validateExportedServicesConsumersEnterprise(exportedService.Consumers) - - if vmerr != nil { - merr = multierror.Append(merr, vmerr) - } - - return merr -} - -func ValidateNamespaceExportedServices(res *pbresource.Resource) error { - var exportedService pbmulticluster.NamespaceExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - return validateExportedServicesConsumersEnterprise(exportedService.Consumers) -} - -func ValidatePartitionExportedServices(res *pbresource.Resource) error { - var exportedService pbmulticluster.PartitionExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - return validateExportedServicesConsumersEnterprise(exportedService.Consumers) -} - -func ValidateComputedExportedServices(res *pbresource.Resource) error { - var computedExportedServices pbmulticluster.ComputedExportedServices - - if err := res.Data.UnmarshalTo(&computedExportedServices); err != nil { - return resource.NewErrDataParse(&computedExportedServices, err) - } - - var merr error - - if res.Id.Name != ComputedExportedServicesName { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "name", - Wrapped: fmt.Errorf("name can only be \"global\""), - }) - } - - vmerr := ValidateComputedExportedServicesEnterprise(&computedExportedServices) - - if vmerr != nil { - merr = multierror.Append(merr, vmerr) - } - - return merr -} diff --git a/internal/multicluster/internal/types/helpers_ce.go b/internal/multicluster/internal/types/helpers_ce.go deleted file mode 100644 index b997b8671ad05..0000000000000 --- a/internal/multicluster/internal/types/helpers_ce.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package types - -import ( - "fmt" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/go-multierror" -) - -func validateExportedServicesConsumer(consumer *pbmulticluster.ExportedServicesConsumer, indx int) error { - switch consumer.GetConsumerTenancy().(type) { - case *pbmulticluster.ExportedServicesConsumer_Partition: - return resource.ErrInvalidListElement{ - Name: "partition", - Index: indx, - Wrapped: fmt.Errorf("can only be set in Enterprise"), - } - case *pbmulticluster.ExportedServicesConsumer_SamenessGroup: - return resource.ErrInvalidListElement{ - Name: "sameness_group", - Index: indx, - Wrapped: fmt.Errorf("can only be set in Enterprise"), - } - } - return nil -} - -func ValidateComputedExportedServicesEnterprise(computedExportedServices *pbmulticluster.ComputedExportedServices) error { - - var merr error - - for indx, consumer := range computedExportedServices.GetConsumers() { - for _, computedExportedServiceConsumer := range consumer.GetConsumers() { - switch computedExportedServiceConsumer.GetConsumerTenancy().(type) { - case *pbmulticluster.ComputedExportedServicesConsumer_Partition: - merr = multierror.Append(merr, resource.ErrInvalidListElement{ - Name: "partition", - Index: indx, - Wrapped: fmt.Errorf("can only be set in Enterprise"), - }) - if computedExportedServiceConsumer.GetPartition() == "" { - merr = multierror.Append(merr, resource.ErrInvalidListElement{ - Name: "partition", - Index: indx, - Wrapped: fmt.Errorf("can not be empty"), - }) - } - case *pbmulticluster.ComputedExportedServicesConsumer_Peer: - if computedExportedServiceConsumer.GetPeer() == "" { - merr = multierror.Append(merr, resource.ErrInvalidListElement{ - Name: "peer", - Index: indx, - Wrapped: fmt.Errorf("can not be empty"), - }) - } - } - } - } - - return merr -} diff --git a/internal/multicluster/internal/types/namespace_exported_services.go b/internal/multicluster/internal/types/namespace_exported_services.go deleted file mode 100644 index 857ea868b8e96..0000000000000 --- a/internal/multicluster/internal/types/namespace_exported_services.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterNamespaceExportedServices(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmulticluster.NamespaceExportedServicesType, - Proto: &pbmulticluster.NamespaceExportedServices{}, - Scope: resource.ScopeNamespace, - Validate: ValidateNamespaceExportedServices, - ACLs: &resource.ACLHooks{ - Read: aclReadHookNamespaceExportedServices, - Write: aclWriteHookNamespaceExportedServices, - List: resource.NoOpACLListHook, - }, - }) -} - -func aclReadHookNamespaceExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshReadAllowed(authzContext) -} - -func aclWriteHookNamespaceExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshWriteAllowed(authzContext) -} diff --git a/internal/multicluster/internal/types/namespace_exported_services_test.go b/internal/multicluster/internal/types/namespace_exported_services_test.go deleted file mode 100644 index ab88a03767fce..0000000000000 --- a/internal/multicluster/internal/types/namespace_exported_services_test.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/require" - "testing" -) - -func validNamespaceExportedServicesWithPeer(peerName string) *pbmulticluster.NamespaceExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Peer{ - Peer: peerName, - }, - }, - } - return &pbmulticluster.NamespaceExportedServices{ - Consumers: consumers, - } -} - -func validNamespaceExportedServicesWithPartition(partitionName string) *pbmulticluster.NamespaceExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Partition{ - Partition: partitionName, - }, - }, - } - return &pbmulticluster.NamespaceExportedServices{ - Consumers: consumers, - } -} - -func validNamespaceExportedServicesWithSamenessGroup(samenessGroupName string) *pbmulticluster.NamespaceExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_SamenessGroup{ - SamenessGroup: samenessGroupName, - }, - }, - } - return &pbmulticluster.NamespaceExportedServices{ - Consumers: consumers, - } -} -func TestNamespaceExportedServicesACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - readOK string - writeOK string - listOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh read policy": { - rules: `mesh = "read"`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh write policy": { - rules: `mesh = "write"`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - exportedServiceData := &pbmulticluster.NamespaceExportedServices{} - res := resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, exportedServiceData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - for _, tc := range cases { - aclTestCase := resourcetest.ACLTestCase{ - Rules: tc.rules, - Res: res, - ReadOK: tc.readOK, - WriteOK: tc.writeOK, - ListOK: tc.listOK, - } - resourcetest.RunACLTestCase(t, aclTestCase, registry) - } -} - -func TestNamespaceExportedServicesValidations(t *testing.T) { - type testcase struct { - Resource *pbresource.Resource - expectErrorCE []string - expectErrorENT []string - } - - isEnterprise := structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default" - - run := func(t *testing.T, tc testcase) { - expectError := tc.expectErrorCE - if isEnterprise { - expectError = tc.expectErrorENT - } - err := ValidateNamespaceExportedServices(tc.Resource) - if len(expectError) == 0 { - require.NoError(t, err) - } else { - require.Error(t, err) - for _, er := range expectError { - require.ErrorContains(t, err, er) - } - } - } - - cases := map[string]testcase{ - "namespace exported services with peer": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithPeer("peer")). - Build(), - }, - "namespace exported services with partition": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithPartition("partition")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can only be set in Enterprise`}, - }, - "namespace exported services with sameness_group": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithSamenessGroup("sameness_group")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - }, - "namespace exported services with peer empty": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithPeer("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - expectErrorENT: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - }, - "namespace exported services with partition empty": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithPartition("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can not be empty`, - `invalid element at index 0 of list "partition": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "partition": can not be empty`}, - }, - "namespace exported services with sameness_group empty": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithSamenessGroup("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can not be empty`, - `invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "sameness_group": can not be empty`}, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/multicluster/internal/types/partition_exported_services.go b/internal/multicluster/internal/types/partition_exported_services.go deleted file mode 100644 index 110eb5d6efa13..0000000000000 --- a/internal/multicluster/internal/types/partition_exported_services.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterPartitionExportedServices(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmulticluster.PartitionExportedServicesType, - Proto: &pbmulticluster.PartitionExportedServices{}, - Scope: resource.ScopePartition, - Validate: ValidatePartitionExportedServices, - ACLs: &resource.ACLHooks{ - Read: aclReadHookPartitionExportedServices, - Write: aclWriteHookPartitionExportedServices, - List: resource.NoOpACLListHook, - }, - }) -} - -func aclReadHookPartitionExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshReadAllowed(authzContext) -} - -func aclWriteHookPartitionExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshWriteAllowed(authzContext) -} diff --git a/internal/multicluster/internal/types/partition_exported_services_test.go b/internal/multicluster/internal/types/partition_exported_services_test.go deleted file mode 100644 index fdd90ef11d12f..0000000000000 --- a/internal/multicluster/internal/types/partition_exported_services_test.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/require" - "testing" -) - -func validPartitionExportedServicesWithPeer(peerName string) *pbmulticluster.PartitionExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Peer{ - Peer: peerName, - }, - }, - } - return &pbmulticluster.PartitionExportedServices{ - Consumers: consumers, - } -} - -func validPartitionExportedServicesWithPartition(partitionName string) *pbmulticluster.PartitionExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Partition{ - Partition: partitionName, - }, - }, - } - return &pbmulticluster.PartitionExportedServices{ - Consumers: consumers, - } -} - -func validPartitionExportedServicesWithSamenessGroup(samenessGroupName string) *pbmulticluster.PartitionExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_SamenessGroup{ - SamenessGroup: samenessGroupName, - }, - }, - } - return &pbmulticluster.PartitionExportedServices{ - Consumers: consumers, - } -} - -func TestPartitionExportedServicesACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - readOK string - writeOK string - listOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh read policy": { - rules: `mesh = "read"`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh write policy": { - rules: `mesh = "write"`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - exportedServiceData := &pbmulticluster.PartitionExportedServices{} - res := resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, exportedServiceData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - for _, tc := range cases { - aclTestCase := resourcetest.ACLTestCase{ - Rules: tc.rules, - Res: res, - ReadOK: tc.readOK, - WriteOK: tc.writeOK, - ListOK: tc.listOK, - } - resourcetest.RunACLTestCase(t, aclTestCase, registry) - } -} - -func TestPartitionExportedServicesValidations(t *testing.T) { - type testcase struct { - Resource *pbresource.Resource - expectErrorCE []string - expectErrorENT []string - } - - isEnterprise := structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default" - - run := func(t *testing.T, tc testcase) { - expectError := tc.expectErrorCE - if isEnterprise { - expectError = tc.expectErrorENT - } - err := ValidatePartitionExportedServices(tc.Resource) - if len(expectError) == 0 { - require.NoError(t, err) - } else { - require.Error(t, err) - for _, er := range expectError { - require.ErrorContains(t, err, er) - } - } - } - - cases := map[string]testcase{ - "partition exported services with peer": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithPeer("peer")). - Build(), - }, - "partition exported services with partition": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithPartition("partition")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can only be set in Enterprise`}, - }, - "partition exported services with sameness_group": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithSamenessGroup("sameness_group")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - }, - "partition exported services with peer empty": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithPeer("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - expectErrorENT: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - }, - "partition exported services with partition empty": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithPartition("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can not be empty`, - `invalid element at index 0 of list "partition": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "partition": can not be empty`}, - }, - "partition exported services with sameness_group empty": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithSamenessGroup("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can not be empty`, - `invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "sameness_group": can not be empty`}, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/multicluster/internal/types/types.go b/internal/multicluster/internal/types/types.go deleted file mode 100644 index 9ee6691e19ec8..0000000000000 --- a/internal/multicluster/internal/types/types.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/internal/resource" -) - -const ( - GroupName = "multicluster" - VersionV2Beta1 = "v2beta1" - CurrentVersion = VersionV2Beta1 -) - -func Register(r resource.Registry) { - RegisterExportedServices(r) - RegisterNamespaceExportedServices(r) - RegisterPartitionExportedServices(r) - RegisterComputedExportedServices(r) -} diff --git a/internal/protohcl/any.go b/internal/protohcl/any.go deleted file mode 100644 index 87b4549bfd079..0000000000000 --- a/internal/protohcl/any.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "fmt" - "strings" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/types/known/anypb" -) - -const wellKnownTypeAny = "google.protobuf.Any" - -type AnyTypeProvider interface { - AnyType(*UnmarshalContext, MessageDecoder) (protoreflect.FullName, MessageDecoder, error) -} - -type AnyTypeURLProvider struct { - TypeURLFieldName string -} - -func (p *AnyTypeURLProvider) AnyType(ctx *UnmarshalContext, decoder MessageDecoder) (protoreflect.FullName, MessageDecoder, error) { - typeURLFieldName := "type_url" - if p != nil { - typeURLFieldName = p.TypeURLFieldName - } - - var typeURL *IterField - err := decoder.EachField(FieldIterator{ - Desc: (&anypb.Any{}).ProtoReflect().Descriptor(), - Func: func(field *IterField) error { - if field.Name == typeURLFieldName { - typeURL = field - } - return nil - }, - IgnoreUnknown: true, - }) - if err != nil { - return "", nil, err - } - - if typeURL == nil || typeURL.Val == nil { - return "", nil, fmt.Errorf("%s field is required to decode Any", typeURLFieldName) - } - - url, err := stringFromCty(*typeURL.Val) - if err != nil { - return "", nil, err - } - - slashIdx := strings.LastIndex(url, "/") - typeName := url - // strip all "hostname" parts of the URL path - if slashIdx > 1 && slashIdx+1 < len(url) { - typeName = url[slashIdx+1:] - } - - return protoreflect.FullName(typeName), decoder.SkipFields(typeURLFieldName), nil -} - -func (u UnmarshalOptions) decodeAny(ctx *UnmarshalContext, decoder MessageDecoder, msg protoreflect.Message) error { - var typeProvider AnyTypeProvider = &AnyTypeURLProvider{TypeURLFieldName: "type_url"} - if u.AnyTypeProvider != nil { - typeProvider = u.AnyTypeProvider - } - - var ( - typeName protoreflect.FullName - err error - ) - typeName, decoder, err = typeProvider.AnyType(ctx, decoder) - if err != nil { - return fmt.Errorf("error getting type for Any field: %w", err) - } - - // the type.googleapis.come/ should be optional - mt, err := protoregistry.GlobalTypes.FindMessageByName(typeName) - if err != nil { - return fmt.Errorf("error looking up type information for %s: %w", typeName, err) - } - - newMsg := mt.New() - - err = u.decodeMessage(&UnmarshalContext{ - Parent: ctx.Parent, - Name: ctx.Name, - Message: newMsg, - }, decoder, newMsg) - if err != nil { - return err - } - - enc, err := proto.Marshal(newMsg.Interface()) - if err != nil { - return fmt.Errorf("error marshalling Any data as protobuf value: %w", err) - } - - anyValue := msg.Interface().(*anypb.Any) - - // This will look like . and not quite like a full URL with a path - anyValue.TypeUrl = string(newMsg.Descriptor().FullName()) - anyValue.Value = enc - - return nil -} - -func isAnyField(desc protoreflect.FieldDescriptor) bool { - if desc.Kind() != protoreflect.MessageKind { - return false - } - return desc.Message().FullName() == wellKnownTypeAny -} diff --git a/internal/protohcl/attributes.go b/internal/protohcl/attributes.go deleted file mode 100644 index 90501722b1fe3..0000000000000 --- a/internal/protohcl/attributes.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "fmt" - - "github.com/pkg/errors" - "github.com/zclconf/go-cty/cty" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" -) - -func (u UnmarshalOptions) decodeAttribute(ctx *UnmarshalContext, newMessage newMessageFn, f protoreflect.FieldDescriptor, val cty.Value, listAllowed bool) (protoreflect.Value, error) { - if f.IsMap() { - return u.decodeAttributeToMap(ctx, newMessage, f, val) - } - - if f.IsList() && listAllowed { - return u.decodeAttributeToList(ctx, newMessage, f, val) - } - - ok, value, err := decodeAttributeToWellKnownType(f, val) - if ok { - return value, errors.Wrapf(err, "%s: Failed to unmarshal argument %s", ctx.ErrorRange(), ctx.Name) - } - - ok, value, err = u.decodeAttributeToMessage(ctx, newMessage, f, val) - if ok { - return value, err - } - - value, err = decodeAttributeToPrimitive(f, val) - if err != nil { - return value, errors.Wrapf(err, "%s: Failed to unmarshal argument %s", ctx.ErrorRange(), ctx.Name) - } - return value, nil -} - -func (u UnmarshalOptions) decodeAttributeToMessage(ctx *UnmarshalContext, newMessage newMessageFn, desc protoreflect.FieldDescriptor, val cty.Value) (bool, protoreflect.Value, error) { - if desc.Kind() != protoreflect.MessageKind { - return false, protoreflect.Value{}, nil - } - - msg := newMessage().Message() - - ctx = &UnmarshalContext{ - Parent: ctx.Parent, - Name: ctx.Name, - Message: msg, - Range: ctx.Range, - } - - // We have limited support for HCL functions, essentially just those that - // return a protobuf message (like the resource `gvk` function) in which - // case, the message will be wrapped in a cty capsule. - if val.Type().IsCapsuleType() { - msg, ok := val.EncapsulatedValue().(proto.Message) - if ok { - return true, protoreflect.ValueOf(msg.ProtoReflect()), nil - } else { - return true, protoreflect.Value{}, fmt.Errorf("expected encapsulated value to be a message, actual type: %T", val.EncapsulatedValue()) - } - } - - if !val.Type().IsObjectType() { - return false, protoreflect.Value{}, nil - } - - decoder := newObjectDecoder(val, u.FieldNamer, ctx.ErrorRange()) - - if err := u.decodeMessage(ctx, decoder, msg); err != nil { - return true, protoreflect.Value{}, err - } - return true, protoreflect.ValueOf(msg), nil -} - -func (u UnmarshalOptions) decodeAttributeToList(ctx *UnmarshalContext, newMessage newMessageFn, desc protoreflect.FieldDescriptor, value cty.Value) (protoreflect.Value, error) { - if value.IsNull() { - return protoreflect.Value{}, nil - } - - valueType := value.Type() - if !valueType.IsListType() && !valueType.IsTupleType() { - return protoreflect.Value{}, fmt.Errorf("expected list/tuple type after HCL decode but the actual type was %s", valueType.FriendlyName()) - } - - if value.LengthInt() < 1 { - return protoreflect.Value{}, nil - } - - protoList := newMessage().List() - - var err error - var idx int - value.ForEachElement(func(_ cty.Value, val cty.Value) bool { - var protoVal protoreflect.Value - protoVal, err = u.decodeAttribute(&UnmarshalContext{ - Parent: ctx, - Name: fmt.Sprintf("%s[%d]", u.FieldNamer.NameField(desc), idx), - }, protoList.NewElement, desc, val, false) - if err != nil { - return true - } - - idx++ - protoList.Append(protoVal) - return false - }) - if err != nil { - return protoreflect.Value{}, err - } - - return protoreflect.ValueOfList(protoList), nil -} - -func (u UnmarshalOptions) decodeAttributeToMap(ctx *UnmarshalContext, newMessage newMessageFn, desc protoreflect.FieldDescriptor, value cty.Value) (protoreflect.Value, error) { - if value.IsNull() { - return protoreflect.Value{}, nil - } - - valueType := value.Type() - if !valueType.IsMapType() && !valueType.IsObjectType() { - return protoreflect.Value{}, fmt.Errorf("expected map/object type after HCL decode but the actual type was %s", valueType.FriendlyName()) - } - - if value.LengthInt() < 1 { - return protoreflect.Value{}, nil - } - - protoMap := newMessage().Map() - protoValueDesc := desc.MapValue() - var err error - - value.ForEachElement(func(key cty.Value, val cty.Value) (stop bool) { - var protoVal protoreflect.Value - protoVal, err = u.decodeAttribute(&UnmarshalContext{ - Parent: ctx, - Name: fmt.Sprintf("%s[%q]", u.FieldNamer.NameField(desc), key.AsString()), - Message: nil, // TODO: what should this really be? - }, protoMap.NewValue, protoValueDesc, val, false) - if err != nil { - return true - } - if protoVal.IsValid() { - // HCL doesn't support non-string keyed maps so we blindly use string keys - protoMap.Set(protoreflect.ValueOfString(key.AsString()).MapKey(), protoVal) - } - return false - }) - if err != nil { - return protoreflect.Value{}, err - } - - return protoreflect.ValueOfMap(protoMap), nil -} diff --git a/internal/protohcl/blocks.go b/internal/protohcl/blocks.go deleted file mode 100644 index cafffa99367da..0000000000000 --- a/internal/protohcl/blocks.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "fmt" - - "github.com/hashicorp/hcl/v2" - "google.golang.org/protobuf/reflect/protoreflect" -) - -func (u UnmarshalOptions) decodeBlocks(ctx *UnmarshalContext, blocks hcl.Blocks, msg protoreflect.Message, f protoreflect.FieldDescriptor) (protoreflect.Value, error) { - if f.Kind() != protoreflect.MessageKind { - return protoreflect.Value{}, fmt.Errorf("only protobuf message kinds can use HCL block syntax") - } - - if f.IsMap() { - return u.decodeBlocksToMap(ctx, blocks, msg, f) - } - - if f.IsList() { - return u.decodeBlocksToList(ctx, blocks, msg, f) - } - - return u.decodeBlocksToMessage(ctx, blocks, msg, f) -} - -func (u UnmarshalOptions) decodeBlocksToMap(ctx *UnmarshalContext, blocks hcl.Blocks, msg protoreflect.Message, f protoreflect.FieldDescriptor) (protoreflect.Value, error) { - val := msg.NewField(f) - mapVal := val.Map() - - for _, block := range blocks { - if len(block.Labels) != 1 { - return protoreflect.Value{}, fmt.Errorf("protobuf map fields must have 1 HCL block label") - } - - key := protoreflect.ValueOfString(block.Labels[0]) - value := mapVal.NewValue() - msgVal := value.Message() - - err := u.decodeMessage( - &UnmarshalContext{ - Parent: ctx, - Name: fmt.Sprintf("%s[%q]", u.FieldNamer.NameField(f), block.Labels[0]), - Message: msgVal, - Range: block.DefRange, - }, - u.bodyDecoder(block.Body), - msgVal, - ) - if err != nil { - return protoreflect.Value{}, err - } - - mapVal.Set(key.MapKey(), value) - } - return val, nil -} - -func (u UnmarshalOptions) decodeBlocksToList(ctx *UnmarshalContext, blocks hcl.Blocks, msg protoreflect.Message, f protoreflect.FieldDescriptor) (protoreflect.Value, error) { - val := msg.NewField(f) - listVal := val.List() - - var err error - for idx, block := range blocks { - if len(block.Labels) > 0 { - return protoreflect.Value{}, fmt.Errorf("repeated protobuf fields must not have HCL block labels") - } - elem := listVal.NewElement() - elemMsg := elem.Message() - - err = u.decodeMessage( - &UnmarshalContext{ - Parent: ctx, - Name: fmt.Sprintf("%s[%d]", u.FieldNamer.NameField(f), idx), - Message: elemMsg, - Range: block.DefRange, - }, - u.bodyDecoder(block.Body), - elemMsg, - ) - if err != nil { - return protoreflect.Value{}, err - } - listVal.Append(elem) - } - - return val, nil -} - -func (u UnmarshalOptions) decodeBlocksToMessage(ctx *UnmarshalContext, blocks hcl.Blocks, msg protoreflect.Message, f protoreflect.FieldDescriptor) (protoreflect.Value, error) { - if len(blocks) > 1 { - return protoreflect.Value{}, fmt.Errorf("only one HCL block may be specified for a non-repeated protobuf Message") - } - - val := msg.NewField(f) - valMsg := val.Message() - - err := u.decodeMessage( - &UnmarshalContext{ - Parent: ctx, - Name: blocks[0].Type, - Message: valMsg, - Range: blocks[0].DefRange, - }, - u.bodyDecoder(blocks[0].Body), - valMsg, - ) - if err != nil { - return protoreflect.Value{}, err - } - - return val, nil -} diff --git a/internal/protohcl/cty.go b/internal/protohcl/cty.go deleted file mode 100644 index e7ed37ed16996..0000000000000 --- a/internal/protohcl/cty.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "encoding/base64" - "fmt" - - "github.com/zclconf/go-cty/cty" - "github.com/zclconf/go-cty/cty/gocty" -) - -func boolFromCty(val cty.Value) (bool, error) { - if val.Type() != cty.Bool { - return false, fmt.Errorf("expected value of type %s but actual type is %s", cty.Bool.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return false, nil - } - - return val.True(), nil -} - -func int32FromCty(val cty.Value) (int32, error) { - if val.Type() != cty.Number { - return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return 0, nil - } - - var goVal int32 - if err := gocty.FromCtyValue(val, &goVal); err != nil { - return 0, fmt.Errorf("error converting cty value of type %s to int32: %w", val.Type().FriendlyName(), err) - } - return goVal, nil -} - -func uint32FromCty(val cty.Value) (uint32, error) { - if val.Type() != cty.Number { - return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return 0, nil - } - - var goVal uint32 - if err := gocty.FromCtyValue(val, &goVal); err != nil { - return 0, fmt.Errorf("error converting cty value of type %s to uint32: %w", val.Type().FriendlyName(), err) - } - return goVal, nil -} - -func int64FromCty(val cty.Value) (int64, error) { - if val.Type() != cty.Number { - return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return 0, nil - } - - var goVal int64 - if err := gocty.FromCtyValue(val, &goVal); err != nil { - return 0, fmt.Errorf("error converting cty value of type %s to int64: %w", val.Type().FriendlyName(), err) - } - return goVal, nil -} - -func uint64FromCty(val cty.Value) (uint64, error) { - if val.Type() != cty.Number { - return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return 0, nil - } - - var goVal uint64 - if err := gocty.FromCtyValue(val, &goVal); err != nil { - return 0, fmt.Errorf("error converting cty value of type %s to uint64: %w", val.Type().FriendlyName(), err) - } - return goVal, nil -} - -func floatFromCty(val cty.Value) (float32, error) { - if val.Type() != cty.Number { - return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return 0, nil - } - - var goVal float32 - if err := gocty.FromCtyValue(val, &goVal); err != nil { - return 0, fmt.Errorf("error converting cty value of type %s to float32: %w", val.Type().FriendlyName(), err) - } - return goVal, nil -} - -func doubleFromCty(val cty.Value) (float64, error) { - if val.Type() != cty.Number { - return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return 0, nil - } - - var goVal float64 - if err := gocty.FromCtyValue(val, &goVal); err != nil { - return 0, fmt.Errorf("error converting cty value of type %s to float64: %w", val.Type().FriendlyName(), err) - } - return goVal, nil -} - -func stringFromCty(val cty.Value) (string, error) { - if val.Type() != cty.String { - return "", fmt.Errorf("expected value of type %s but actual type is %s", cty.String.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return "", nil - } - return val.AsString(), nil -} - -func bytesFromCty(val cty.Value) ([]byte, error) { - if val.Type() != cty.String { - return nil, fmt.Errorf("expected value of type %s but actual type is %s", cty.String.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - return nil, nil - } - - encoded := val.AsString() - decoded, err := base64.StdEncoding.DecodeString(encoded) - if err != nil { - return nil, fmt.Errorf("error base64 decoding byte string: %w", err) - } - - return decoded, nil -} diff --git a/internal/protohcl/decoder.go b/internal/protohcl/decoder.go deleted file mode 100644 index 95b3bb86ffd92..0000000000000 --- a/internal/protohcl/decoder.go +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "fmt" - "sort" - - "github.com/hashicorp/hcl/v2" - "github.com/zclconf/go-cty/cty" - "github.com/zclconf/go-cty/cty/function" - "google.golang.org/protobuf/reflect/protoreflect" -) - -// MessageDecoder provides an abstract way to decode protobuf messages from HCL -// blocks or objects. -type MessageDecoder interface { - // EachField calls the given iterator for each field provided in the HCL source. - EachField(iter FieldIterator) error - - // SkipFields returns a MessageDecoder that skips over the given fields. It is - // primarily used for doing two-pass decoding of protobuf `Any` fields. - SkipFields(fields ...string) MessageDecoder -} - -// IterField represents a field discovered by the MessageDecoder. -type IterField struct { - // Name is the HCL name of the field. - Name string - - // Desc is the protobuf field descriptor. - Desc protoreflect.FieldDescriptor - - // Val is the field value, only if it was given using HCL attribute syntax. - Val *cty.Value - - // Blocks contains the HCL blocks that were given for this field. - Blocks []*hcl.Block - - // Range determines where in the HCL source the field was given, it is useful - // for error messages. - Range hcl.Range -} - -// FieldIterator is given to MessageDecoder.EachField to iterate over all of the -// fields in a given HCL block or object. -type FieldIterator struct { - // IgnoreUnknown instructs the MessageDecoder to skip over any fields not - // included in Desc. - IgnoreUnknown bool - - // Desc is the protobuf descriptor for the message the caller is decoding into. - // It is used to determine which fields are valid. - Desc protoreflect.MessageDescriptor - - // Func is called for each field in the given HCL block or object. - Func func(field *IterField) error -} - -func newBodyDecoder( - body hcl.Body, - namer FieldNamer, - functions map[string]function.Function, -) MessageDecoder { - return bodyDecoder{ - body: body, - namer: namer, - functions: functions, - skipFields: make(map[string]struct{}), - } -} - -type bodyDecoder struct { - body hcl.Body - namer FieldNamer - functions map[string]function.Function - skipFields map[string]struct{} -} - -func (bd bodyDecoder) EachField(iter FieldIterator) error { - schema, err := bd.schema(iter.Desc) - if err != nil { - return err - } - - var ( - content *hcl.BodyContent - diags hcl.Diagnostics - ) - if iter.IgnoreUnknown { - content, _, diags = bd.body.PartialContent(schema) - } else { - content, diags = bd.body.Content(schema) - } - if diags.HasErrors() { - return diags - } - - fields := make([]*IterField, 0) - - for _, attr := range content.Attributes { - if _, ok := bd.skipFields[attr.Name]; ok { - continue - } - - desc := bd.namer.GetField(iter.Desc.Fields(), attr.Name) - - val, err := attr.Expr.Value(&hcl.EvalContext{Functions: bd.functions}) - if err != nil { - return err - } - - fields = append(fields, &IterField{ - Name: attr.Name, - Desc: desc, - Val: &val, - Range: attr.Expr.Range(), - }) - } - - for blockType, blocks := range content.Blocks.ByType() { - if _, ok := bd.skipFields[blockType]; ok { - continue - } - - desc := bd.namer.GetField(iter.Desc.Fields(), blockType) - - fields = append(fields, &IterField{ - Name: blockType, - Desc: desc, - Blocks: blocks, - }) - } - - // Always handle Any fields last, as decoding them may require type information - // gathered from other fields (e.g. as in the case of Resource GVKs). - sort.Slice(fields, func(a, b int) bool { - if isAnyField(fields[b].Desc) && !isAnyField(fields[a].Desc) { - return true - } - return a < b - }) - - for _, field := range fields { - if err := iter.Func(field); err != nil { - return err - } - } - - return nil -} - -func (bd bodyDecoder) SkipFields(fields ...string) MessageDecoder { - skip := make(map[string]struct{}, len(fields)+len(bd.skipFields)) - for k, v := range bd.skipFields { - skip[k] = v - } - for _, field := range fields { - skip[field] = struct{}{} - } - - // Note: we rely on the fact bd isn't a pointer to copy the struct here. - bd.skipFields = skip - return bd -} - -func (bd bodyDecoder) schema(desc protoreflect.MessageDescriptor) (*hcl.BodySchema, error) { - var schema hcl.BodySchema - - fields := desc.Fields() - for i := 0; i < fields.Len(); i++ { - f := fields.Get(i) - - kind := f.Kind() - // maps are special and whether they can use block syntax depends on the value type - if f.IsMap() { - valueDesc := f.MapValue() - valueKind := valueDesc.Kind() - - wktHint := wellKnownTypeSchemaHint(valueDesc) - - // Maps with values that are Messages can generally be decoded using the block syntax. - // The exception are some of the Well-Known-Types that appear as scalar values with - // either string or numeric encoding but get parsed into message types. It is still - // fine to also decode these from the attribute syntax. - if valueKind == protoreflect.MessageKind && wktHint != wellKnownAttribute { - schema.Blocks = append(schema.Blocks, hcl.BlockHeaderSchema{ - Type: bd.namer.NameField(f), - LabelNames: []string{"key"}, - }) - } - - // non-message types or Well Known Message types that need attribute encoding - // get decoded as attributes - schema.Attributes = append(schema.Attributes, hcl.AttributeSchema{ - Name: bd.namer.NameField(f), - }) - continue - } - - wktHint := wellKnownTypeSchemaHint(f) - - // message types generally will use block syntax unless its a well known - // message type that requires attribute syntax specifically. - if kind == protoreflect.MessageKind && wktHint != wellKnownAttribute { - schema.Blocks = append(schema.Blocks, hcl.BlockHeaderSchema{ - Type: bd.namer.NameField(f), - }) - } - - // by default use attribute encoding - // - primitives - // - repeated primitives - // - Well Known Types requiring attribute syntax - // - repeated Well Known Types requiring attribute syntax - schema.Attributes = append(schema.Attributes, hcl.AttributeSchema{ - Name: bd.namer.NameField(f), - }) - continue - } - - // Add skipped fields to the schema so HCL doesn't throw an error when it finds them. - for field := range bd.skipFields { - schema.Attributes = append(schema.Attributes, hcl.AttributeSchema{Name: field}) - schema.Blocks = append(schema.Blocks, hcl.BlockHeaderSchema{Type: field}) - } - - return &schema, nil -} - -func newObjectDecoder(object cty.Value, namer FieldNamer, rng hcl.Range) MessageDecoder { - return objectDecoder{ - object: object, - namer: namer, - rng: rng, - skipFields: make(map[string]struct{}), - } -} - -type objectDecoder struct { - object cty.Value - namer FieldNamer - rng hcl.Range - skipFields map[string]struct{} -} - -func (od objectDecoder) EachField(iter FieldIterator) error { - for attr := range od.object.Type().AttributeTypes() { - if _, ok := od.skipFields[attr]; ok { - continue - } - - desc := od.namer.GetField(iter.Desc.Fields(), attr) - if desc == nil { - if iter.IgnoreUnknown { - continue - } else { - return fmt.Errorf("%s: Unsupported argument; An argument named %q is not expected here.", od.rng, attr) - } - } - - val := od.object.GetAttr(attr) - if err := iter.Func(&IterField{ - Name: attr, - Desc: desc, - Val: &val, - }); err != nil { - return err - } - } - return nil -} - -func (od objectDecoder) SkipFields(fields ...string) MessageDecoder { - skip := make(map[string]struct{}, len(fields)+len(od.skipFields)) - for k, v := range od.skipFields { - skip[k] = v - } - for _, field := range fields { - skip[field] = struct{}{} - } - - // Note: we rely on the fact od isn't a pointer to copy the struct here. - od.skipFields = skip - return od -} diff --git a/internal/protohcl/doc.go b/internal/protohcl/doc.go deleted file mode 100644 index e3270f7cdcf19..0000000000000 --- a/internal/protohcl/doc.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// The protohcl package aims to define a canonical way to translate between -// protobuf and HCL encodings of data. -// -// Similar to google.golang.org/protobuf/encoding/protojson it intends to be -// opinionated about what the canonical HCL representation of a protobuf type -// should be. -// -// As HCL is a user centric data format as opposed to JSON/Protobuf which -// are intended to be used more by machines, efficiency is not a primary goal -// of this package as it is expected that users are either doing the encoding to and -// decoding from HCL at the edge (such as within the Consul CLI) or that even -// when done on servers, the rate that servers perform these translations should -// be low enough to have any inefficiency produce a tangible performance impact. -// -// HCL has two different syntaxes that could be used to represent data: attribute and block -// -// This implementation chooses to represent primitive values, enums and the well known wrapper types and -// collections of these values (maps and repeated fields) with attribute syntax. Other messages and collections -// with message value types will be represented with block syntax for example -// -// message Foo { -// map map_of_ints = 1; -// map map_of_messages = 2; -// } -// -// would have HCL like: -// -// map_of_ints = { -// "foo": 1, -// "bar": 2, -// } -// map_of_messages "foo" { -// ...other fields -// } -// map_of_messages "bar" { -// ...other fields -// } -// -// Similar goes for list of primitives vs list of messages (except the block syntax uses no labels). The differences -// between primitive fields outside of a collection and a message field really just amounts to not having to specify -// the "=" between the field name and the "{" character. -// -// Field Mapping -// | proto3 | HCL Type | example | notes | -// |------------------------+---------------+---------+---------------------------------------------------------------------------------+ -// | message | Object | | Represented as a block | -// | enum | String | | | -// | map | Map | | All keys are converted to/from strings. | -// | repeated V | List | | | -// | bool | Bool | | | -// | string | String | | | -// | bytes | base64 String | | | -// | int32, fixed32, uint32 | Number | | | -// | int64, fixed64, uint64 | Number | | | -// | float, double | Number | | | -// -// ----- Well Known Types ----- -// -// | Any | Object | | | -// | Timestamp | String | | RFC 3339 compliant | -// | Duration | String | | String form is what would be accepted by time.ParseDuration | -// | Struct | Map | | | -// | Empty | Object | | An object with no fields | -// | BoolValue | Bool | | Mostly the same as a regular bool except null values in the HCL are preserved | -// | BytesValue | Bytes | | Mostly the same as a regular bytes except null values in the HCL are preserved | -// | StringValue | String | | Mostly the same as a regular string except null values in the HCL are preserved | -// | FloatValue | Number | | Mostly the same as a regular float except null values in the HCL are preserved | -// | DoubleValue | Number | | Mostly the same as a regular double except null values in the HCL are preserved | -// | Int32Value | Number | | Mostly the same as a regular int32 except null values in the HCL are preserved | -// | UInt32Value | Number | | Mostly the same as a regular uint32 except null values in the HCL are preserved | -// | Int64Value | Number | | Mostly the same as a regular int64 except null values in the HCL are preserved | -// | UInt64Value | Number | | Mostly the same as a regular uint64 except null values in the HCL are preserved | -// | FieldMask | String | | Each string of the FieldMask will be joined with a '.' | -// - -package protohcl diff --git a/internal/protohcl/naming.go b/internal/protohcl/naming.go deleted file mode 100644 index d8eef2275fd7d..0000000000000 --- a/internal/protohcl/naming.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import "google.golang.org/protobuf/reflect/protoreflect" - -type FieldNamer interface { - NameField(protoreflect.FieldDescriptor) string - GetField(protoreflect.FieldDescriptors, string) protoreflect.FieldDescriptor -} - -type textFieldNamer struct{} - -func (textFieldNamer) NameField(fd protoreflect.FieldDescriptor) string { - return fd.TextName() -} - -func (textFieldNamer) GetField(fds protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor { - return fds.ByTextName(name) -} diff --git a/internal/protohcl/oneof.go b/internal/protohcl/oneof.go deleted file mode 100644 index 0c95326614bda..0000000000000 --- a/internal/protohcl/oneof.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "fmt" - "strings" - - "google.golang.org/protobuf/reflect/protoreflect" -) - -type oneOfTracker struct { - namer FieldNamer - set map[protoreflect.FullName]string -} - -func newOneOfTracker(namer FieldNamer) *oneOfTracker { - return &oneOfTracker{ - namer: namer, - set: make(map[protoreflect.FullName]string), - } -} - -func (o *oneOfTracker) markFieldAsSet(desc protoreflect.FieldDescriptor) error { - oneof := desc.ContainingOneof() - if oneof == nil { - return nil - } - - oneOfName := oneof.FullName() - - if otherFieldName, ok := o.set[oneOfName]; ok { - oneOfFields := oneof.Fields() - var builder strings.Builder - - for i := 0; i < oneOfFields.Len(); i++ { - name := o.namer.NameField(oneOfFields.Get(i)) - - if i == oneOfFields.Len()-1 { - builder.WriteString(fmt.Sprintf("%q", name)) - } else if i == oneOfFields.Len()-2 { - builder.WriteString(fmt.Sprintf("%q and ", name)) - } else { - builder.WriteString(fmt.Sprintf("%q, ", name)) - } - } - - return fmt.Errorf("Cannot set %q because %q was previously set. Only one of %s may be set.", o.namer.NameField(desc), otherFieldName, builder.String()) - } - - o.set[oneOfName] = o.namer.NameField(desc) - return nil -} diff --git a/internal/protohcl/primitives.go b/internal/protohcl/primitives.go deleted file mode 100644 index c93218c997484..0000000000000 --- a/internal/protohcl/primitives.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "fmt" - - "github.com/zclconf/go-cty/cty" - "google.golang.org/protobuf/reflect/protoreflect" -) - -func decodeAttributeToPrimitive(desc protoreflect.FieldDescriptor, val cty.Value) (protoreflect.Value, error) { - switch kind := desc.Kind(); kind { - case protoreflect.BoolKind: - return protoBoolFromCty(val) - case protoreflect.EnumKind: - return protoEnumFromCty(desc, val) - case protoreflect.Int32Kind: - return protoInt32FromCty(val) - case protoreflect.Sint32Kind: - return protoInt32FromCty(val) - case protoreflect.Uint32Kind: - return protoUint32FromCty(val) - case protoreflect.Int64Kind: - return protoInt64FromCty(val) - case protoreflect.Sint64Kind: - return protoInt64FromCty(val) - case protoreflect.Uint64Kind: - return protoUint64FromCty(val) - case protoreflect.Sfixed32Kind: - return protoInt32FromCty(val) - case protoreflect.Fixed32Kind: - return protoUint32FromCty(val) - case protoreflect.FloatKind: - return protoFloatFromCty(val) - case protoreflect.Sfixed64Kind: - return protoInt64FromCty(val) - case protoreflect.Fixed64Kind: - return protoUint64FromCty(val) - case protoreflect.DoubleKind: - return protoDoubleFromCty(val) - case protoreflect.StringKind: - return protoStringFromCty(val) - case protoreflect.BytesKind: - return protoBytesFromCty(val) - default: - return protoreflect.Value{}, fmt.Errorf("unknown primitive protobuf kind: %q", kind.String()) - } -} - -func protoBoolFromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := boolFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfBool(goVal), nil -} - -func protoEnumFromCty(desc protoreflect.FieldDescriptor, val cty.Value) (protoreflect.Value, error) { - if val.Type() != cty.String { - return protoreflect.Value{}, fmt.Errorf("expected value of type %s but actual type is %s", cty.String.FriendlyName(), val.Type().FriendlyName()) - } - - if val.IsNull() { - if desc.HasDefault() { - defaultValDesc := desc.DefaultEnumValue() - return protoreflect.ValueOfEnum(defaultValDesc.Number()), nil - } - return protoreflect.Value{}, fmt.Errorf("no default value for type and value is null") - } - - valDesc := desc.Enum().Values().ByName(protoreflect.Name(val.AsString())) - if valDesc == nil { - if desc.HasDefault() { - defaultValDesc := desc.DefaultEnumValue() - return protoreflect.ValueOfEnum(defaultValDesc.Number()), nil - } - return protoreflect.Value{}, fmt.Errorf("no default value for type and value is invalid") - } - - return protoreflect.ValueOfEnum(valDesc.Number()), nil -} - -func protoInt32FromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := int32FromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfInt32(goVal), nil -} - -func protoUint32FromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := uint32FromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfUint32(goVal), nil -} - -func protoInt64FromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := int64FromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfInt64(goVal), nil -} - -func protoUint64FromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := uint64FromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfUint64(goVal), nil -} - -func protoFloatFromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := floatFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfFloat32(goVal), nil -} - -func protoDoubleFromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := doubleFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfFloat64(goVal), nil -} - -func protoStringFromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := stringFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfString(goVal), nil -} - -func protoBytesFromCty(val cty.Value) (protoreflect.Value, error) { - goVal, err := bytesFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoreflect.ValueOfBytes(goVal), nil -} diff --git a/internal/protohcl/testproto/buf.gen.yaml b/internal/protohcl/testproto/buf.gen.yaml deleted file mode 100644 index fecee5cf24962..0000000000000 --- a/internal/protohcl/testproto/buf.gen.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -version: v1 -managed: - enabled: true - go_package_prefix: - default: github.com/hashicorp/consul/internal/protohcl/testproto -plugins: - - name: go - out: . - opt: paths=source_relative diff --git a/internal/protohcl/testproto/example.pb.go b/internal/protohcl/testproto/example.pb.go deleted file mode 100644 index 304eac53d6d90..0000000000000 --- a/internal/protohcl/testproto/example.pb.go +++ /dev/null @@ -1,997 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: example.proto - -package testproto - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - durationpb "google.golang.org/protobuf/types/known/durationpb" - emptypb "google.golang.org/protobuf/types/known/emptypb" - structpb "google.golang.org/protobuf/types/known/structpb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Protocol int32 - -const ( - Protocol_PROTOCOL_UNSPECIFIED Protocol = 0 - Protocol_PROTOCOL_TCP Protocol = 1 - Protocol_PROTOCOL_UDP Protocol = 2 -) - -// Enum value maps for Protocol. -var ( - Protocol_name = map[int32]string{ - 0: "PROTOCOL_UNSPECIFIED", - 1: "PROTOCOL_TCP", - 2: "PROTOCOL_UDP", - } - Protocol_value = map[string]int32{ - "PROTOCOL_UNSPECIFIED": 0, - "PROTOCOL_TCP": 1, - "PROTOCOL_UDP": 2, - } -) - -func (x Protocol) Enum() *Protocol { - p := new(Protocol) - *p = x - return p -} - -func (x Protocol) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Protocol) Descriptor() protoreflect.EnumDescriptor { - return file_example_proto_enumTypes[0].Descriptor() -} - -func (Protocol) Type() protoreflect.EnumType { - return &file_example_proto_enumTypes[0] -} - -func (x Protocol) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Protocol.Descriptor instead. -func (Protocol) EnumDescriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{0} -} - -type Primitives struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DoubleVal float64 `protobuf:"fixed64,1,opt,name=double_val,json=doubleVal,proto3" json:"double_val,omitempty"` - FloatVal float32 `protobuf:"fixed32,2,opt,name=float_val,json=floatVal,proto3" json:"float_val,omitempty"` - Int32Val int32 `protobuf:"varint,3,opt,name=int32_val,json=int32Val,proto3" json:"int32_val,omitempty"` - Int64Val int64 `protobuf:"varint,4,opt,name=int64_val,json=int64Val,proto3" json:"int64_val,omitempty"` - Uint32Val uint32 `protobuf:"varint,5,opt,name=uint32_val,json=uint32Val,proto3" json:"uint32_val,omitempty"` - Uint64Val uint64 `protobuf:"varint,6,opt,name=uint64_val,json=uint64Val,proto3" json:"uint64_val,omitempty"` - Sint32Val int32 `protobuf:"zigzag32,7,opt,name=sint32_val,json=sint32Val,proto3" json:"sint32_val,omitempty"` - Sint64Val int64 `protobuf:"zigzag64,8,opt,name=sint64_val,json=sint64Val,proto3" json:"sint64_val,omitempty"` - Fixed32Val uint32 `protobuf:"fixed32,9,opt,name=fixed32_val,json=fixed32Val,proto3" json:"fixed32_val,omitempty"` - Fixed64Val uint64 `protobuf:"fixed64,10,opt,name=fixed64_val,json=fixed64Val,proto3" json:"fixed64_val,omitempty"` - Sfixed32Val int32 `protobuf:"fixed32,11,opt,name=sfixed32_val,json=sfixed32Val,proto3" json:"sfixed32_val,omitempty"` - Sfixed64Val int64 `protobuf:"fixed64,12,opt,name=sfixed64_val,json=sfixed64Val,proto3" json:"sfixed64_val,omitempty"` - BoolVal bool `protobuf:"varint,13,opt,name=bool_val,json=boolVal,proto3" json:"bool_val,omitempty"` - StringVal string `protobuf:"bytes,14,opt,name=string_val,json=stringVal,proto3" json:"string_val,omitempty"` - ByteVal []byte `protobuf:"bytes,15,opt,name=byte_val,json=byteVal,proto3" json:"byte_val,omitempty"` -} - -func (x *Primitives) Reset() { - *x = Primitives{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Primitives) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Primitives) ProtoMessage() {} - -func (x *Primitives) ProtoReflect() protoreflect.Message { - mi := &file_example_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Primitives.ProtoReflect.Descriptor instead. -func (*Primitives) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{0} -} - -func (x *Primitives) GetDoubleVal() float64 { - if x != nil { - return x.DoubleVal - } - return 0 -} - -func (x *Primitives) GetFloatVal() float32 { - if x != nil { - return x.FloatVal - } - return 0 -} - -func (x *Primitives) GetInt32Val() int32 { - if x != nil { - return x.Int32Val - } - return 0 -} - -func (x *Primitives) GetInt64Val() int64 { - if x != nil { - return x.Int64Val - } - return 0 -} - -func (x *Primitives) GetUint32Val() uint32 { - if x != nil { - return x.Uint32Val - } - return 0 -} - -func (x *Primitives) GetUint64Val() uint64 { - if x != nil { - return x.Uint64Val - } - return 0 -} - -func (x *Primitives) GetSint32Val() int32 { - if x != nil { - return x.Sint32Val - } - return 0 -} - -func (x *Primitives) GetSint64Val() int64 { - if x != nil { - return x.Sint64Val - } - return 0 -} - -func (x *Primitives) GetFixed32Val() uint32 { - if x != nil { - return x.Fixed32Val - } - return 0 -} - -func (x *Primitives) GetFixed64Val() uint64 { - if x != nil { - return x.Fixed64Val - } - return 0 -} - -func (x *Primitives) GetSfixed32Val() int32 { - if x != nil { - return x.Sfixed32Val - } - return 0 -} - -func (x *Primitives) GetSfixed64Val() int64 { - if x != nil { - return x.Sfixed64Val - } - return 0 -} - -func (x *Primitives) GetBoolVal() bool { - if x != nil { - return x.BoolVal - } - return false -} - -func (x *Primitives) GetStringVal() string { - if x != nil { - return x.StringVal - } - return "" -} - -func (x *Primitives) GetByteVal() []byte { - if x != nil { - return x.ByteVal - } - return nil -} - -type NestedAndCollections struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Primitives *Primitives `protobuf:"bytes,1,opt,name=primitives,proto3" json:"primitives,omitempty"` - PrimitivesList []*Primitives `protobuf:"bytes,2,rep,name=primitives_list,json=primitivesList,proto3" json:"primitives_list,omitempty"` - PrimitivesMap map[string]*Primitives `protobuf:"bytes,3,rep,name=primitives_map,json=primitivesMap,proto3" json:"primitives_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - ProtocolMap map[string]Protocol `protobuf:"bytes,4,rep,name=protocol_map,json=protocolMap,proto3" json:"protocol_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3,enum=hashicorp.consul.internal.protohcl.testproto.Protocol"` - IntList []int32 `protobuf:"varint,5,rep,packed,name=int_list,json=intList,proto3" json:"int_list,omitempty"` -} - -func (x *NestedAndCollections) Reset() { - *x = NestedAndCollections{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NestedAndCollections) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NestedAndCollections) ProtoMessage() {} - -func (x *NestedAndCollections) ProtoReflect() protoreflect.Message { - mi := &file_example_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NestedAndCollections.ProtoReflect.Descriptor instead. -func (*NestedAndCollections) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{1} -} - -func (x *NestedAndCollections) GetPrimitives() *Primitives { - if x != nil { - return x.Primitives - } - return nil -} - -func (x *NestedAndCollections) GetPrimitivesList() []*Primitives { - if x != nil { - return x.PrimitivesList - } - return nil -} - -func (x *NestedAndCollections) GetPrimitivesMap() map[string]*Primitives { - if x != nil { - return x.PrimitivesMap - } - return nil -} - -func (x *NestedAndCollections) GetProtocolMap() map[string]Protocol { - if x != nil { - return x.ProtocolMap - } - return nil -} - -func (x *NestedAndCollections) GetIntList() []int32 { - if x != nil { - return x.IntList - } - return nil -} - -type Wrappers struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DoubleVal *wrapperspb.DoubleValue `protobuf:"bytes,1,opt,name=double_val,json=doubleVal,proto3" json:"double_val,omitempty"` - FloatVal *wrapperspb.FloatValue `protobuf:"bytes,2,opt,name=float_val,json=floatVal,proto3" json:"float_val,omitempty"` - Int32Val *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=int32_val,json=int32Val,proto3" json:"int32_val,omitempty"` - Int64Val *wrapperspb.Int64Value `protobuf:"bytes,4,opt,name=int64_val,json=int64Val,proto3" json:"int64_val,omitempty"` - Uint32Val *wrapperspb.UInt32Value `protobuf:"bytes,5,opt,name=uint32_val,json=uint32Val,proto3" json:"uint32_val,omitempty"` - Uint64Val *wrapperspb.UInt64Value `protobuf:"bytes,6,opt,name=uint64_val,json=uint64Val,proto3" json:"uint64_val,omitempty"` - BoolVal *wrapperspb.BoolValue `protobuf:"bytes,13,opt,name=bool_val,json=boolVal,proto3" json:"bool_val,omitempty"` - StringVal *wrapperspb.StringValue `protobuf:"bytes,14,opt,name=string_val,json=stringVal,proto3" json:"string_val,omitempty"` - BytesVal *wrapperspb.BytesValue `protobuf:"bytes,15,opt,name=bytes_val,json=bytesVal,proto3" json:"bytes_val,omitempty"` -} - -func (x *Wrappers) Reset() { - *x = Wrappers{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Wrappers) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Wrappers) ProtoMessage() {} - -func (x *Wrappers) ProtoReflect() protoreflect.Message { - mi := &file_example_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Wrappers.ProtoReflect.Descriptor instead. -func (*Wrappers) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{2} -} - -func (x *Wrappers) GetDoubleVal() *wrapperspb.DoubleValue { - if x != nil { - return x.DoubleVal - } - return nil -} - -func (x *Wrappers) GetFloatVal() *wrapperspb.FloatValue { - if x != nil { - return x.FloatVal - } - return nil -} - -func (x *Wrappers) GetInt32Val() *wrapperspb.Int32Value { - if x != nil { - return x.Int32Val - } - return nil -} - -func (x *Wrappers) GetInt64Val() *wrapperspb.Int64Value { - if x != nil { - return x.Int64Val - } - return nil -} - -func (x *Wrappers) GetUint32Val() *wrapperspb.UInt32Value { - if x != nil { - return x.Uint32Val - } - return nil -} - -func (x *Wrappers) GetUint64Val() *wrapperspb.UInt64Value { - if x != nil { - return x.Uint64Val - } - return nil -} - -func (x *Wrappers) GetBoolVal() *wrapperspb.BoolValue { - if x != nil { - return x.BoolVal - } - return nil -} - -func (x *Wrappers) GetStringVal() *wrapperspb.StringValue { - if x != nil { - return x.StringVal - } - return nil -} - -func (x *Wrappers) GetBytesVal() *wrapperspb.BytesValue { - if x != nil { - return x.BytesVal - } - return nil -} - -type OneOf struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Data: - // - // *OneOf_Int32Val - // *OneOf_Primitives - Data isOneOf_Data `protobuf_oneof:"data"` -} - -func (x *OneOf) Reset() { - *x = OneOf{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OneOf) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OneOf) ProtoMessage() {} - -func (x *OneOf) ProtoReflect() protoreflect.Message { - mi := &file_example_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OneOf.ProtoReflect.Descriptor instead. -func (*OneOf) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{3} -} - -func (m *OneOf) GetData() isOneOf_Data { - if m != nil { - return m.Data - } - return nil -} - -func (x *OneOf) GetInt32Val() int32 { - if x, ok := x.GetData().(*OneOf_Int32Val); ok { - return x.Int32Val - } - return 0 -} - -func (x *OneOf) GetPrimitives() *Primitives { - if x, ok := x.GetData().(*OneOf_Primitives); ok { - return x.Primitives - } - return nil -} - -type isOneOf_Data interface { - isOneOf_Data() -} - -type OneOf_Int32Val struct { - Int32Val int32 `protobuf:"varint,1,opt,name=int32_val,json=int32Val,proto3,oneof"` -} - -type OneOf_Primitives struct { - Primitives *Primitives `protobuf:"bytes,2,opt,name=primitives,proto3,oneof"` // note repeated fields (including maps) are not allowed in oneofs -} - -func (*OneOf_Int32Val) isOneOf_Data() {} - -func (*OneOf_Primitives) isOneOf_Data() {} - -type NonDynamicWellKnown struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - EmptyVal *emptypb.Empty `protobuf:"bytes,1,opt,name=empty_val,json=emptyVal,proto3" json:"empty_val,omitempty"` - TimestampVal *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=timestamp_val,json=timestampVal,proto3" json:"timestamp_val,omitempty"` - DurationVal *durationpb.Duration `protobuf:"bytes,3,opt,name=duration_val,json=durationVal,proto3" json:"duration_val,omitempty"` -} - -func (x *NonDynamicWellKnown) Reset() { - *x = NonDynamicWellKnown{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NonDynamicWellKnown) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NonDynamicWellKnown) ProtoMessage() {} - -func (x *NonDynamicWellKnown) ProtoReflect() protoreflect.Message { - mi := &file_example_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NonDynamicWellKnown.ProtoReflect.Descriptor instead. -func (*NonDynamicWellKnown) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{4} -} - -func (x *NonDynamicWellKnown) GetEmptyVal() *emptypb.Empty { - if x != nil { - return x.EmptyVal - } - return nil -} - -func (x *NonDynamicWellKnown) GetTimestampVal() *timestamppb.Timestamp { - if x != nil { - return x.TimestampVal - } - return nil -} - -func (x *NonDynamicWellKnown) GetDurationVal() *durationpb.Duration { - if x != nil { - return x.DurationVal - } - return nil -} - -type DynamicWellKnown struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AnyVal *anypb.Any `protobuf:"bytes,1,opt,name=any_val,json=anyVal,proto3" json:"any_val,omitempty"` - StructVal *structpb.Struct `protobuf:"bytes,2,opt,name=struct_val,json=structVal,proto3" json:"struct_val,omitempty"` - AnyList []*anypb.Any `protobuf:"bytes,3,rep,name=any_list,json=anyList,proto3" json:"any_list,omitempty"` -} - -func (x *DynamicWellKnown) Reset() { - *x = DynamicWellKnown{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DynamicWellKnown) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DynamicWellKnown) ProtoMessage() {} - -func (x *DynamicWellKnown) ProtoReflect() protoreflect.Message { - mi := &file_example_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DynamicWellKnown.ProtoReflect.Descriptor instead. -func (*DynamicWellKnown) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{5} -} - -func (x *DynamicWellKnown) GetAnyVal() *anypb.Any { - if x != nil { - return x.AnyVal - } - return nil -} - -func (x *DynamicWellKnown) GetStructVal() *structpb.Struct { - if x != nil { - return x.StructVal - } - return nil -} - -func (x *DynamicWellKnown) GetAnyList() []*anypb.Any { - if x != nil { - return x.AnyList - } - return nil -} - -var File_example_proto protoreflect.FileDescriptor - -var file_example_proto_rawDesc = []byte{ - 0x0a, 0x0d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x2c, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, - 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdb, 0x03, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, - 0x76, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, - 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, - 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x12, - 0x1b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09, - 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x08, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x69, 0x6e, - 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x75, - 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x69, 0x6e, 0x74, - 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75, 0x69, - 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69, 0x6e, 0x74, 0x33, - 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x73, 0x69, 0x6e, - 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69, 0x6e, 0x74, 0x36, 0x34, - 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x12, 0x52, 0x09, 0x73, 0x69, 0x6e, 0x74, - 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, - 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x07, 0x52, 0x0a, 0x66, 0x69, 0x78, 0x65, - 0x64, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, - 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0a, 0x66, 0x69, 0x78, - 0x65, 0x64, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x66, 0x69, 0x78, 0x65, - 0x64, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x0b, 0x73, - 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x66, - 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x10, - 0x52, 0x0b, 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x19, 0x0a, - 0x08, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x79, 0x74, 0x65, 0x5f, - 0x76, 0x61, 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x79, 0x74, 0x65, 0x56, - 0x61, 0x6c, 0x22, 0xd8, 0x05, 0x0a, 0x14, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x6e, 0x64, - 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x0a, 0x70, - 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, - 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x69, - 0x74, 0x69, 0x76, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, - 0x76, 0x65, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, - 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x52, 0x0e, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, - 0x69, 0x76, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x7c, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6d, - 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x55, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x4d, - 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, - 0x76, 0x65, 0x73, 0x4d, 0x61, 0x70, 0x12, 0x76, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x53, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, - 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x73, 0x74, - 0x65, 0x64, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x61, 0x70, 0x12, 0x19, - 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x05, - 0x52, 0x07, 0x69, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x1a, 0x7a, 0x0a, 0x12, 0x50, 0x72, 0x69, - 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x4e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x76, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4c, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9d, 0x04, - 0x0a, 0x08, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x0a, 0x64, 0x6f, - 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x64, 0x6f, - 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, - 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f, - 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, - 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x69, - 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x74, - 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, - 0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, - 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, - 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, - 0x35, 0x0a, 0x08, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x62, - 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c, - 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x22, 0x8a, 0x01, - 0x0a, 0x05, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x33, 0x32, - 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, - 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x5a, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, - 0x69, 0x76, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, - 0x69, 0x76, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, - 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xc9, 0x01, 0x0a, 0x13, 0x4e, - 0x6f, 0x6e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, - 0x77, 0x6e, 0x12, 0x33, 0x0a, 0x09, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x08, 0x65, - 0x6d, 0x70, 0x74, 0x79, 0x56, 0x61, 0x6c, 0x12, 0x3f, 0x0a, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x12, 0x3c, 0x0a, 0x0c, 0x64, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x6c, 0x22, 0xaa, 0x01, 0x0a, 0x10, 0x44, 0x79, 0x6e, 0x61, 0x6d, - 0x69, 0x63, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x12, 0x2d, 0x0a, 0x07, 0x61, - 0x6e, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, - 0x6e, 0x79, 0x52, 0x06, 0x61, 0x6e, 0x79, 0x56, 0x61, 0x6c, 0x12, 0x36, 0x0a, 0x0a, 0x73, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x09, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x56, - 0x61, 0x6c, 0x12, 0x2f, 0x0a, 0x08, 0x61, 0x6e, 0x79, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x61, 0x6e, 0x79, 0x4c, - 0x69, 0x73, 0x74, 0x2a, 0x48, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, - 0x18, 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, - 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x43, 0x50, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, - 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x55, 0x44, 0x50, 0x10, 0x02, 0x42, 0xcf, 0x02, - 0x0a, 0x30, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x42, 0x0c, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, - 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0xa2, 0x02, 0x05, 0x48, 0x43, - 0x49, 0x50, 0x54, 0xaa, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0xca, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x5c, 0x54, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0xe2, 0x02, 0x38, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x5c, 0x54, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x30, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x68, 0x63, 0x6c, 0x3a, 0x3a, 0x54, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_example_proto_rawDescOnce sync.Once - file_example_proto_rawDescData = file_example_proto_rawDesc -) - -func file_example_proto_rawDescGZIP() []byte { - file_example_proto_rawDescOnce.Do(func() { - file_example_proto_rawDescData = protoimpl.X.CompressGZIP(file_example_proto_rawDescData) - }) - return file_example_proto_rawDescData -} - -var file_example_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_example_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_example_proto_goTypes = []interface{}{ - (Protocol)(0), // 0: hashicorp.consul.internal.protohcl.testproto.Protocol - (*Primitives)(nil), // 1: hashicorp.consul.internal.protohcl.testproto.Primitives - (*NestedAndCollections)(nil), // 2: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections - (*Wrappers)(nil), // 3: hashicorp.consul.internal.protohcl.testproto.Wrappers - (*OneOf)(nil), // 4: hashicorp.consul.internal.protohcl.testproto.OneOf - (*NonDynamicWellKnown)(nil), // 5: hashicorp.consul.internal.protohcl.testproto.NonDynamicWellKnown - (*DynamicWellKnown)(nil), // 6: hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown - nil, // 7: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.PrimitivesMapEntry - nil, // 8: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.ProtocolMapEntry - (*wrapperspb.DoubleValue)(nil), // 9: google.protobuf.DoubleValue - (*wrapperspb.FloatValue)(nil), // 10: google.protobuf.FloatValue - (*wrapperspb.Int32Value)(nil), // 11: google.protobuf.Int32Value - (*wrapperspb.Int64Value)(nil), // 12: google.protobuf.Int64Value - (*wrapperspb.UInt32Value)(nil), // 13: google.protobuf.UInt32Value - (*wrapperspb.UInt64Value)(nil), // 14: google.protobuf.UInt64Value - (*wrapperspb.BoolValue)(nil), // 15: google.protobuf.BoolValue - (*wrapperspb.StringValue)(nil), // 16: google.protobuf.StringValue - (*wrapperspb.BytesValue)(nil), // 17: google.protobuf.BytesValue - (*emptypb.Empty)(nil), // 18: google.protobuf.Empty - (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp - (*durationpb.Duration)(nil), // 20: google.protobuf.Duration - (*anypb.Any)(nil), // 21: google.protobuf.Any - (*structpb.Struct)(nil), // 22: google.protobuf.Struct -} -var file_example_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.primitives:type_name -> hashicorp.consul.internal.protohcl.testproto.Primitives - 1, // 1: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.primitives_list:type_name -> hashicorp.consul.internal.protohcl.testproto.Primitives - 7, // 2: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.primitives_map:type_name -> hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.PrimitivesMapEntry - 8, // 3: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.protocol_map:type_name -> hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.ProtocolMapEntry - 9, // 4: hashicorp.consul.internal.protohcl.testproto.Wrappers.double_val:type_name -> google.protobuf.DoubleValue - 10, // 5: hashicorp.consul.internal.protohcl.testproto.Wrappers.float_val:type_name -> google.protobuf.FloatValue - 11, // 6: hashicorp.consul.internal.protohcl.testproto.Wrappers.int32_val:type_name -> google.protobuf.Int32Value - 12, // 7: hashicorp.consul.internal.protohcl.testproto.Wrappers.int64_val:type_name -> google.protobuf.Int64Value - 13, // 8: hashicorp.consul.internal.protohcl.testproto.Wrappers.uint32_val:type_name -> google.protobuf.UInt32Value - 14, // 9: hashicorp.consul.internal.protohcl.testproto.Wrappers.uint64_val:type_name -> google.protobuf.UInt64Value - 15, // 10: hashicorp.consul.internal.protohcl.testproto.Wrappers.bool_val:type_name -> google.protobuf.BoolValue - 16, // 11: hashicorp.consul.internal.protohcl.testproto.Wrappers.string_val:type_name -> google.protobuf.StringValue - 17, // 12: hashicorp.consul.internal.protohcl.testproto.Wrappers.bytes_val:type_name -> google.protobuf.BytesValue - 1, // 13: hashicorp.consul.internal.protohcl.testproto.OneOf.primitives:type_name -> hashicorp.consul.internal.protohcl.testproto.Primitives - 18, // 14: hashicorp.consul.internal.protohcl.testproto.NonDynamicWellKnown.empty_val:type_name -> google.protobuf.Empty - 19, // 15: hashicorp.consul.internal.protohcl.testproto.NonDynamicWellKnown.timestamp_val:type_name -> google.protobuf.Timestamp - 20, // 16: hashicorp.consul.internal.protohcl.testproto.NonDynamicWellKnown.duration_val:type_name -> google.protobuf.Duration - 21, // 17: hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown.any_val:type_name -> google.protobuf.Any - 22, // 18: hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown.struct_val:type_name -> google.protobuf.Struct - 21, // 19: hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown.any_list:type_name -> google.protobuf.Any - 1, // 20: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.PrimitivesMapEntry.value:type_name -> hashicorp.consul.internal.protohcl.testproto.Primitives - 0, // 21: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.ProtocolMapEntry.value:type_name -> hashicorp.consul.internal.protohcl.testproto.Protocol - 22, // [22:22] is the sub-list for method output_type - 22, // [22:22] is the sub-list for method input_type - 22, // [22:22] is the sub-list for extension type_name - 22, // [22:22] is the sub-list for extension extendee - 0, // [0:22] is the sub-list for field type_name -} - -func init() { file_example_proto_init() } -func file_example_proto_init() { - if File_example_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_example_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Primitives); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NestedAndCollections); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Wrappers); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OneOf); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NonDynamicWellKnown); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DynamicWellKnown); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_example_proto_msgTypes[3].OneofWrappers = []interface{}{ - (*OneOf_Int32Val)(nil), - (*OneOf_Primitives)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_example_proto_rawDesc, - NumEnums: 1, - NumMessages: 8, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_example_proto_goTypes, - DependencyIndexes: file_example_proto_depIdxs, - EnumInfos: file_example_proto_enumTypes, - MessageInfos: file_example_proto_msgTypes, - }.Build() - File_example_proto = out.File - file_example_proto_rawDesc = nil - file_example_proto_goTypes = nil - file_example_proto_depIdxs = nil -} diff --git a/internal/protohcl/testproto/example.proto b/internal/protohcl/testproto/example.proto deleted file mode 100644 index 17bf737fa3aca..0000000000000 --- a/internal/protohcl/testproto/example.proto +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.internal.protohcl.testproto; - -import "google/protobuf/duration.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/timestamp.proto"; -import "google/protobuf/wrappers.proto"; -import "google/protobuf/any.proto"; -import "google/protobuf/struct.proto"; - -message Primitives { - double double_val = 1; - float float_val = 2; - int32 int32_val = 3; - int64 int64_val = 4; - uint32 uint32_val = 5; - uint64 uint64_val = 6; - sint32 sint32_val = 7; - sint64 sint64_val = 8; - fixed32 fixed32_val = 9; - fixed64 fixed64_val = 10; - sfixed32 sfixed32_val = 11; - sfixed64 sfixed64_val = 12; - bool bool_val = 13; - string string_val = 14; - bytes byte_val = 15; -} - -enum Protocol { - PROTOCOL_UNSPECIFIED = 0; - PROTOCOL_TCP = 1; - PROTOCOL_UDP = 2; -} - -message NestedAndCollections { - Primitives primitives = 1; - repeated Primitives primitives_list = 2; - map primitives_map = 3; - map protocol_map = 4; - repeated int32 int_list = 5; -} - -message Wrappers { - google.protobuf.DoubleValue double_val = 1; - google.protobuf.FloatValue float_val = 2; - google.protobuf.Int32Value int32_val = 3; - google.protobuf.Int64Value int64_val = 4; - google.protobuf.UInt32Value uint32_val = 5; - google.protobuf.UInt64Value uint64_val = 6; - google.protobuf.BoolValue bool_val = 13; - google.protobuf.StringValue string_val = 14; - google.protobuf.BytesValue bytes_val = 15; -} - -message OneOf { - oneof data { - int32 int32_val = 1; - Primitives primitives = 2; - // note repeated fields (including maps) are not allowed in oneofs - } -} - -message NonDynamicWellKnown { - google.protobuf.Empty empty_val = 1; - google.protobuf.Timestamp timestamp_val = 2; - google.protobuf.Duration duration_val = 3; -} - -message DynamicWellKnown { - google.protobuf.Any any_val = 1; - google.protobuf.Struct struct_val = 2; - repeated google.protobuf.Any any_list = 3; -} diff --git a/internal/protohcl/unmarshal.go b/internal/protohcl/unmarshal.go deleted file mode 100644 index 0f3c80a4c26e3..0000000000000 --- a/internal/protohcl/unmarshal.go +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/hcl/v2/hclparse" - "github.com/zclconf/go-cty/cty/function" - "google.golang.org/protobuf/reflect/protoreflect" -) - -// UnmarshalContext provides information about the context in which we are -// unmarshalling HCL. It is primarily used for decoding Any fields based on -// surrounding information (e.g. the resource Type block). -type UnmarshalContext struct { - // Parent context. - Parent *UnmarshalContext - - // Name of the field that we are unmarshalling. - Name string - - // Message is the protobuf message that we are unmarshalling into (may be nil). - Message protoreflect.Message - - // Range of where this field was in the HCL source. - Range hcl.Range -} - -// ErrorRange returns a range that can be used in error messages. -func (ctx *UnmarshalContext) ErrorRange() hcl.Range { - for { - if !ctx.Range.Empty() || ctx.Parent == nil { - return ctx.Range - } - ctx = ctx.Parent - } -} - -func Unmarshal(src []byte, dest protoreflect.ProtoMessage) error { - return UnmarshalOptions{}.Unmarshal(src, dest) -} - -type UnmarshalOptions struct { - AnyTypeProvider AnyTypeProvider - SourceFileName string - FieldNamer FieldNamer - Functions map[string]function.Function -} - -func (u UnmarshalOptions) Unmarshal(src []byte, dest protoreflect.ProtoMessage) error { - rmsg := dest.ProtoReflect() - - file, diags := hclparse.NewParser().ParseHCL(src, u.SourceFileName) - - // error performing basic HCL parsing - if diags.HasErrors() { - return diags - } - - u.clearAll(rmsg) - - if u.FieldNamer == nil { - u.FieldNamer = textFieldNamer{} - } - - return u.decodeMessage( - &UnmarshalContext{Message: rmsg}, - u.bodyDecoder(file.Body), - rmsg, - ) -} - -func (u UnmarshalOptions) bodyDecoder(body hcl.Body) MessageDecoder { - return newBodyDecoder(body, u.FieldNamer, u.Functions) -} - -func (u UnmarshalOptions) decodeMessage(ctx *UnmarshalContext, decoder MessageDecoder, msg protoreflect.Message) error { - desc := msg.Descriptor() - - if desc.FullName() == wellKnownTypeAny { - return u.decodeAny(ctx, decoder, msg) - } - - tracker := newOneOfTracker(u.FieldNamer) - - return decoder.EachField(FieldIterator{ - Desc: desc, - Func: func(field *IterField) error { - if err := tracker.markFieldAsSet(field.Desc); err != nil { - return err - } - - var ( - protoVal protoreflect.Value - err error - ) - switch { - case field.Val != nil: - protoVal, err = u.decodeAttribute( - &UnmarshalContext{ - Parent: ctx, - Name: field.Name, - Range: field.Range, - }, - func() protoreflect.Value { return msg.NewField(field.Desc) }, - field.Desc, - *field.Val, - true, - ) - case len(field.Blocks) != 0: - protoVal, err = u.decodeBlocks(ctx, field.Blocks, msg, field.Desc) - default: - panic("decoder yielded no blocks or attributes") - } - if err != nil { - return err - } - - if protoVal.IsValid() { - msg.Set(field.Desc, protoVal) - } - - return nil - }, - }) -} - -type newMessageFn func() protoreflect.Value - -func (u UnmarshalOptions) clearAll(msg protoreflect.Message) { - fields := msg.Descriptor().Fields() - - for i := 0; i < fields.Len(); i++ { - msg.Clear(fields.Get(i)) - } -} diff --git a/internal/protohcl/unmarshal_test.go b/internal/protohcl/unmarshal_test.go deleted file mode 100644 index b1fc854279af2..0000000000000 --- a/internal/protohcl/unmarshal_test.go +++ /dev/null @@ -1,610 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "encoding/json" - "fmt" - "reflect" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/zclconf/go-cty/cty" - "github.com/zclconf/go-cty/cty/function" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/protohcl/testproto" - "github.com/hashicorp/hcl/v2/hclparse" -) - -func TestPrimitives(t *testing.T) { - hcl := ` - double_val = 1.234 - float_val = 2.345 - int32_val = 536870912 - int64_val = 25769803776 - uint32_val = 2148532224 - uint64_val = 9223372041149743104 - sint32_val = 536870912 - sint64_val = 25769803776 - fixed32_val = 2148532224 - fixed64_val = 9223372041149743104 - sfixed32_val = 536870912 - sfixed64_val = 25769803776 - bool_val = true - string_val = "foo" - // This is base64 encoded "bar" - byte_val = "YmFy" - ` - - var out testproto.Primitives - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - - require.Equal(t, out.DoubleVal, float64(1.234)) - require.Equal(t, out.FloatVal, float32(2.345)) - require.Equal(t, out.Int32Val, int32(536870912)) - require.Equal(t, out.Int64Val, int64(25769803776)) - require.Equal(t, out.Uint32Val, uint32(2148532224)) - require.Equal(t, out.Uint64Val, uint64(9223372041149743104)) - require.Equal(t, out.Sint32Val, int32(536870912)) - require.Equal(t, out.Sint64Val, int64(25769803776)) - require.Equal(t, out.Fixed32Val, uint32(2148532224)) - require.Equal(t, out.Fixed64Val, uint64(9223372041149743104)) - require.Equal(t, out.Sfixed32Val, int32(536870912)) - require.Equal(t, out.Sfixed64Val, int64(25769803776)) - require.Equal(t, out.BoolVal, true) - require.Equal(t, out.StringVal, "foo") - require.Equal(t, out.ByteVal, []byte("bar")) -} - -func TestNestedAndCollections(t *testing.T) { - hcl := ` - primitives { - uint32_val = 42 - } - - primitives_map "foo" { - uint32_val = 42 - } - - protocol_map = { - "foo" = "PROTOCOL_TCP" - } - - primitives_list { - uint32_val = 42 - } - - primitives_list { - uint32_val = 56 - } - - int_list = [ - 1, - 2 - ] - - ` - - var out testproto.NestedAndCollections - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - - require.NotNil(t, out.Primitives) - require.Equal(t, out.Primitives.Uint32Val, uint32(42)) - require.NotNil(t, out.PrimitivesMap) - require.Equal(t, out.PrimitivesMap["foo"].Uint32Val, uint32(42)) - require.NotNil(t, out.ProtocolMap) - require.Equal(t, out.ProtocolMap["foo"], testproto.Protocol_PROTOCOL_TCP) - require.Len(t, out.PrimitivesList, 2) - require.Equal(t, out.PrimitivesList[0].Uint32Val, uint32(42)) - require.Equal(t, out.PrimitivesList[1].Uint32Val, uint32(56)) - require.Len(t, out.IntList, 2) - require.Equal(t, out.IntList[1], int32(2)) -} - -func TestNestedAndCollections_AttributeSyntax(t *testing.T) { - hcl := ` - primitives { - uint32_val = 42 - } - - primitives_map = { - "foo" = { - uint32_val = 42 - } - } - - protocol_map = { - "foo" = "PROTOCOL_TCP" - } - - primitives_list = [ - { - uint32_val = 42 - }, - { - uint32_val = 56 - } - ] - - int_list = [ - 1, - 2 - ] - - ` - - var out testproto.NestedAndCollections - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - - require.NotNil(t, out.Primitives) - require.Equal(t, out.Primitives.Uint32Val, uint32(42)) - require.NotNil(t, out.PrimitivesMap) - require.Equal(t, out.PrimitivesMap["foo"].Uint32Val, uint32(42)) - require.NotNil(t, out.ProtocolMap) - require.Equal(t, out.ProtocolMap["foo"], testproto.Protocol_PROTOCOL_TCP) - require.Len(t, out.PrimitivesList, 2) - require.Equal(t, out.PrimitivesList[0].Uint32Val, uint32(42)) - require.Equal(t, out.PrimitivesList[1].Uint32Val, uint32(56)) - require.Len(t, out.IntList, 2) - require.Equal(t, out.IntList[1], int32(2)) -} - -func TestPrimitiveWrappers(t *testing.T) { - hcl := ` - double_val = 1.234 - float_val = 2.345 - int32_val = 536870912 - int64_val = 25769803776 - uint32_val = 2148532224 - uint64_val = 9223372041149743104 - bool_val = true - string_val = "foo" - // This is base64 encoded "bar" - bytes_val = "YmFy" - ` - var out testproto.Wrappers - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - require.Equal(t, out.DoubleVal.Value, float64(1.234)) - require.Equal(t, out.FloatVal.Value, float32(2.345)) - require.Equal(t, out.Int32Val.Value, int32(536870912)) - require.Equal(t, out.Int64Val.Value, int64(25769803776)) - require.Equal(t, out.Uint32Val.Value, uint32(2148532224)) - require.Equal(t, out.Uint64Val.Value, uint64(9223372041149743104)) - require.Equal(t, out.BoolVal.Value, true) - require.Equal(t, out.StringVal.Value, "foo") - require.Equal(t, out.BytesVal.Value, []byte("bar")) -} - -func TestNonDynamicWellKnown(t *testing.T) { - hcl := ` - empty_val = {} - timestamp_val = "2023-02-27T12:34:56.789Z" - duration_val = "12s" - ` - var out testproto.NonDynamicWellKnown - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - require.NotNil(t, out.EmptyVal) - require.NotNil(t, out.TimestampVal) - require.Equal(t, out.TimestampVal.AsTime(), time.Date(2023, 2, 27, 12, 34, 56, 789000000, time.UTC)) - require.NotNil(t, out.DurationVal) - require.Equal(t, out.DurationVal.AsDuration(), time.Second*12) -} - -func TestInvalidTimestamp(t *testing.T) { - if testing.Short() { - t.Skip("too slow for testing.Short") - } - - t.Parallel() - - cases := map[string]struct { - hcl string - expectXDS bool - }{ - "invalid": { - hcl: ` - timestamp_val = "Sat Jun 12 2023 14:59:57 GMT+0200" - `, - }, - "range error": { - hcl: ` - timestamp_val = "2023-02-27T25:34:56.789Z" - `, - }, - } - - for name, tc := range cases { - tc := tc - var out testproto.NonDynamicWellKnown - t.Run(name, func(t *testing.T) { - - err := Unmarshal([]byte(tc.hcl), &out) - require.Error(t, err) - require.Nil(t, out.TimestampVal) - require.ErrorContains(t, err, "error parsing timestamp") - }) - } -} - -func TestInvalidDuration(t *testing.T) { - hcl := ` - duration_val = "abc" - ` - var out testproto.NonDynamicWellKnown - - err := Unmarshal([]byte(hcl), &out) - require.ErrorContains(t, err, "error parsing string duration:") - require.Nil(t, out.DurationVal) -} - -func TestOneOf(t *testing.T) { - hcl1 := ` - int32_val = 3 - ` - - hcl2 := ` - primitives { - int32_val = 3 - } - ` - - hcl3 := ` - int32_val = 3 - primitives { - int32_val = 4 - } - ` - - var out testproto.OneOf - - err := Unmarshal([]byte(hcl1), &out) - require.NoError(t, err) - require.Equal(t, out.GetInt32Val(), int32(3)) - - err = Unmarshal([]byte(hcl2), &out) - require.NoError(t, err) - primitives := out.GetPrimitives() - require.NotNil(t, primitives) - require.Equal(t, primitives.Int32Val, int32(3)) - - err = Unmarshal([]byte(hcl3), &out) - require.Error(t, err) -} - -func TestAny(t *testing.T) { - hcl := ` - any_val { - type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives" - uint32_val = 42 - } - - any_list = [ - { - type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives" - uint32_val = 123 - }, - { - type_url = "hashicorp.consul.internal.protohcl.testproto.Wrappers" - uint32_val = 321 - } - ] - ` - var out testproto.DynamicWellKnown - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - require.NotNil(t, out.AnyVal) - require.Equal(t, out.AnyVal.TypeUrl, "hashicorp.consul.internal.protohcl.testproto.Primitives") - - raw, err := anypb.UnmarshalNew(out.AnyVal, proto.UnmarshalOptions{}) - require.NoError(t, err) - require.NotNil(t, raw) - - primitives, ok := raw.(*testproto.Primitives) - require.True(t, ok) - require.Equal(t, primitives.Uint32Val, uint32(42)) -} - -func TestAnyTypeDynamicWellKnown(t *testing.T) { - hcl := ` - any_val { - type_url = "hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown" - any_val { - type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives" - uint32_val = 42 - } - } - ` - var out testproto.DynamicWellKnown - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - require.NotNil(t, out.AnyVal) - require.Equal(t, out.AnyVal.TypeUrl, "hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown") - - raw, err := anypb.UnmarshalNew(out.AnyVal, proto.UnmarshalOptions{}) - require.NoError(t, err) - require.NotNil(t, raw) - - anyVal, ok := raw.(*testproto.DynamicWellKnown) - require.True(t, ok) - - res, err := anypb.UnmarshalNew(anyVal.AnyVal, proto.UnmarshalOptions{}) - require.NoError(t, err) - require.NotNil(t, res) - - primitives, ok := res.(*testproto.Primitives) - require.True(t, ok) - require.Equal(t, primitives.Uint32Val, uint32(42)) -} - -func TestAnyTypeNestedAndCollections(t *testing.T) { - hcl := ` - any_val { - type_url = "hashicorp.consul.internal.protohcl.testproto.NestedAndCollections" - primitives { - uint32_val = 42 - } - } - ` - var out testproto.DynamicWellKnown - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - require.NotNil(t, out.AnyVal) - require.Equal(t, out.AnyVal.TypeUrl, "hashicorp.consul.internal.protohcl.testproto.NestedAndCollections") - - raw, err := anypb.UnmarshalNew(out.AnyVal, proto.UnmarshalOptions{}) - require.NoError(t, err) - require.NotNil(t, raw) - - nestedCollections, ok := raw.(*testproto.NestedAndCollections) - require.True(t, ok) - require.NotNil(t, nestedCollections.Primitives) - require.Equal(t, nestedCollections.Primitives.Uint32Val, uint32(42)) -} - -func TestAnyTypeErrors(t *testing.T) { - type testCase struct { - description string - hcl string - error string - } - testCases := []testCase{ - { - description: "type_url is expected", - hcl: ` - any_val { - uint32_val = 42 - } - `, - error: "type_url field is required to decode Any", - }, - { - description: "type_url is unknown", - hcl: ` - any_val { - type_url = "hashicorp.consul.internal.protohcl.testproto.Integer" - uint32_val = 42 - } - `, - error: "error looking up type information for hashicorp.consul.internal.protohcl.testproto.Integer", - }, - { - description: "unknown field", - hcl: ` - any_val { - type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives" - int_val = 42 - } - `, - error: "Unsupported argument; An argument named \"int_val\" is not expected here", - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.description, func(t *testing.T) { - t.Parallel() - var out testproto.DynamicWellKnown - - err := Unmarshal([]byte(tc.hcl), &out) - require.Error(t, err) - require.Contains(t, err.Error(), tc.error) - }) - } -} - -func TestStruct(t *testing.T) { - hcl := ` - struct_val = { - "null"= null - "bool"= true - "foo" = "bar" - "baz" = 1.234 - "nested" = { - "foo" = 12, - "bar" = "something" - } - } - ` - - var out testproto.DynamicWellKnown - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - require.NotNil(t, out.StructVal) - - valMap := out.StructVal.AsMap() - jsonVal, err := json.Marshal(valMap) - require.NoError(t, err) - - expected := `{ - "null": null, - "bool": true, - "foo": "bar", - "baz": 1.234, - "nested": { - "foo": 12, - "bar": "something" - } - } - ` - require.JSONEq(t, expected, string(jsonVal)) -} - -func TestStructList(t *testing.T) { - hcl := ` - struct_val = { - "list_int" = [ - 1, - 2, - 3, - ] - "list_string": [ - "abc", - "def" - ] - "list_bool": [ - true, - false - ] - "list_maps" = [ - { - "arrr" = "matey" - }, - { - "hoist" = "the colors" - } - ] - "list_list" = [ - [ - "hello", - "world", - null - ] - ] - } - ` - - var out testproto.DynamicWellKnown - - err := Unmarshal([]byte(hcl), &out) - require.NoError(t, err) - require.NotNil(t, out.StructVal) - - valMap := out.StructVal.AsMap() - jsonVal, err := json.Marshal(valMap) - require.NoError(t, err) - - expected := `{ - "list_int": [ - 1, - 2, - 3 - ], - "list_string": [ - "abc", - "def" - ], - "list_bool": [ - true, - false - ], - "list_maps": [ - { - "arrr": "matey" - }, - { - "hoist": "the colors" - } - ], - "list_list": [ - [ - "hello", - "world", - null - ] - ] - } - ` - require.JSONEq(t, expected, string(jsonVal)) -} - -func TestFunctionExecution(t *testing.T) { - hcl := ` - primitives = primitive_defaults() - ` - - var out testproto.NestedAndCollections - - var ( - testType = cty.Capsule("type", reflect.TypeOf(testproto.Primitives{})) - - test = function.New(&function.Spec{ - Params: []function.Parameter{}, - Type: function.StaticReturnType(testType), - Impl: func(args []cty.Value, _ cty.Type) (cty.Value, error) { - t := &testproto.Primitives{ - StringVal: "test", - Int32Val: 10, - BoolVal: false, - } - return cty.CapsuleVal(testType, t), nil - }, - }) - ) - - err := UnmarshalOptions{ - Functions: map[string]function.Function{"primitive_defaults": test}, - }.Unmarshal([]byte(hcl), &out) - - require.NoError(t, err) - - require.NotNil(t, out.Primitives) - require.Equal(t, out.Primitives.StringVal, "test") - require.Equal(t, out.Primitives.Int32Val, int32(10)) - require.Equal(t, out.Primitives.BoolVal, false) -} - -func TestSkipFields(t *testing.T) { - - u := UnmarshalOptions{} - - hcl := ` - any_val { - type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives" - uint32_val = 10 - }` - - file, diags := hclparse.NewParser().ParseHCL([]byte(hcl), "") - - require.False(t, diags.HasErrors()) - - decoder := u.bodyDecoder(file.Body) - - decoder = decoder.SkipFields("type_url") - - decoder = decoder.SkipFields("type_url", "uint32_val") - - expected := map[string]struct{}{ - "type_url": {}, - "uint32_val": {}, - } - - require.Contains(t, fmt.Sprintf("%v", decoder), fmt.Sprintf("%v", expected)) -} diff --git a/internal/protohcl/well_known_types.go b/internal/protohcl/well_known_types.go deleted file mode 100644 index 756f908fc413d..0000000000000 --- a/internal/protohcl/well_known_types.go +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protohcl - -import ( - "fmt" - "time" - - "github.com/zclconf/go-cty/cty" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/emptypb" - "google.golang.org/protobuf/types/known/structpb" - "google.golang.org/protobuf/types/known/timestamppb" - "google.golang.org/protobuf/types/known/wrapperspb" -) - -const ( - // maximum time in seconds that a time.Time which comes from - // an RFC 3339 timestamp can represent - maxTimestampSeconds = 253402300799 - // minimum time in seconds that a time.Time which comes from - // an RFC 3339 timestamp can represent. This is negative - // because RFC 3339 base time is year 0001 whereas time.Time - // starts in 1970 - minTimestampSeconds = -62135596800 -) - -var ( - // minTime is the earliest time representable as both an - // RFC 3339 timestamp and a time.Time value - minTime = time.Unix(minTimestampSeconds, 0) - // maxTime is the latest time respresentable as both an - // RFC 3339 timestamp and a time.Time value - maxTime = time.Unix(maxTimestampSeconds, 999999999) -) - -type wktSchemaHint int - -const ( - notWellKnownType wktSchemaHint = iota - wellKnownBlock - wellKnownAttribute -) - -// wellKnownTypeSchemaHint returns what sort of syntax should be used to represent -// the well known type field. -// -// NotWellKnownType - use attribute block syntax based on other information -// WellKnownAttribute - use attribute syntax -// WellKnownBlock - use block syntax -func wellKnownTypeSchemaHint(desc protoreflect.FieldDescriptor) wktSchemaHint { - if desc.Kind() != protoreflect.MessageKind { - return notWellKnownType - } - - switch desc.Message().FullName() { - case "google.protobuf.DoubleValue": - return wellKnownAttribute - case "google.protobuf.FloatValue": - return wellKnownAttribute - case "google.protobuf.Int32Value": - return wellKnownAttribute - case "google.protobuf.Int64Value": - return wellKnownAttribute - case "google.protobuf.UInt32Value": - return wellKnownAttribute - case "google.protobuf.UInt64Value": - return wellKnownAttribute - case "google.protobuf.BoolValue": - return wellKnownAttribute - case "google.protobuf.StringValue": - return wellKnownAttribute - case "google.protobuf.BytesValue": - return wellKnownAttribute - case "google.protobuf.Empty": - // block syntax is used for Empty to allow transitioning to using - // a different proto message with fields in the future. - return wellKnownBlock - case "google.protobuf.Timestamp": - return wellKnownAttribute - case "google.protobuf.Duration": - return wellKnownAttribute - case "google.protobuf.Struct": - // as the Struct has completely free form fields that we cannot - // know about in advance we cannot use block syntax - return wellKnownAttribute - case "google.protobuf.Any": - return wellKnownBlock - default: - return notWellKnownType - } -} - -func decodeAttributeToWellKnownType(desc protoreflect.FieldDescriptor, val cty.Value) (bool, protoreflect.Value, error) { - if desc.Kind() != protoreflect.MessageKind { - return false, protoreflect.Value{}, nil - } - - switch desc.Message().FullName() { - case "google.protobuf.DoubleValue": - protoVal, err := protoDoubleWrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.FloatValue": - protoVal, err := protoFloatWrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.Int32Value": - protoVal, err := protoInt32WrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.Int64Value": - protoVal, err := protoInt64WrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.UInt32Value": - protoVal, err := protoUint32WrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.UInt64Value": - protoVal, err := protoUint64WrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.BoolValue": - protoVal, err := protoBoolWrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.StringValue": - protoVal, err := protoStringWrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.BytesValue": - protoVal, err := protoBytesWrapperFromCty(val) - return true, protoVal, err - case "google.protobuf.Empty": - protoVal, err := protoEmptyFromCty(val) - return true, protoVal, err - case "google.protobuf.Timestamp": - protoVal, err := protoTimestampFromCty(val) - return true, protoVal, err - case "google.protobuf.Duration": - protoVal, err := protoDurationFromCty(val) - return true, protoVal, err - case "google.protobuf.Struct": - protoVal, err := protoStructFromCty(val) - return true, protoVal, err - default: - return false, protoreflect.Value{}, nil - } -} - -func protoWrapperFromBool(v bool) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.Bool(v).ProtoReflect()) -} -func protoWrapperFromInt32(v int32) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.Int32(v).ProtoReflect()) -} -func protoWrapperFromInt64(v int64) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.Int64(v).ProtoReflect()) -} -func protoWrapperFromUint32(v uint32) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.UInt32(v).ProtoReflect()) -} -func protoWrapperFromUint64(v uint64) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.UInt64(v).ProtoReflect()) -} -func protoWrapperFromFloat(v float32) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.Float(v).ProtoReflect()) -} -func protoWrapperFromDouble(v float64) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.Double(v).ProtoReflect()) -} -func protoWrapperFromString(v string) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.String(v).ProtoReflect()) -} -func protoWrapperFromBytes(v []byte) protoreflect.Value { - return protoreflect.ValueOfMessage(wrapperspb.Bytes(v).ProtoReflect()) -} - -func protoBoolWrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := boolFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromBool(v), nil -} -func protoInt32WrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := int32FromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromInt32(v), nil -} -func protoInt64WrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := int64FromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromInt64(v), nil -} -func protoUint32WrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := uint32FromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromUint32(v), nil -} -func protoUint64WrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := uint64FromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromUint64(v), nil -} -func protoFloatWrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := floatFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromFloat(v), nil -} -func protoDoubleWrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := doubleFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromDouble(v), nil -} -func protoStringWrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := stringFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromString(v), nil -} -func protoBytesWrapperFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := bytesFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - return protoWrapperFromBytes(v), nil -} - -func protoEmptyFromCty(val cty.Value) (protoreflect.Value, error) { - var e emptypb.Empty - if val.IsNull() { - return protoreflect.Value{}, nil - } - - valType := val.Type() - if (valType.IsObjectType() || valType.IsMapType()) && val.LengthInt() == 0 { - return protoreflect.ValueOfMessage(e.ProtoReflect()), nil - } - - return protoreflect.Value{}, fmt.Errorf("well known empty type can only be represented as an hcl map/object - actual type %q", valType.FriendlyName()) -} - -func protoTimestampFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := stringFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - - t, err := time.Parse(time.RFC3339Nano, v) - if err != nil { - return protoreflect.Value{}, fmt.Errorf("error parsing timestamp: %w", err) - } - - if t.Before(minTime) || t.After(maxTime) { - return protoreflect.Value{}, fmt.Errorf("time is out of range %s to %s - %s", minTime.String(), maxTime.String(), v) - } - - return protoreflect.ValueOfMessage(timestamppb.New(t).ProtoReflect()), nil -} - -func protoDurationFromCty(val cty.Value) (protoreflect.Value, error) { - v, err := stringFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - - d, err := time.ParseDuration(v) - if err != nil { - return protoreflect.Value{}, fmt.Errorf("error parsing string duration: %w", err) - } - - return protoreflect.ValueOfMessage(durationpb.New(d).ProtoReflect()), nil -} - -func protoStructFromCty(val cty.Value) (protoreflect.Value, error) { - s, err := protoStructObjectFromCty(val) - if err != nil { - return protoreflect.Value{}, err - } - - return protoreflect.ValueOfMessage(s.ProtoReflect()), nil -} - -func protoStructObjectFromCty(val cty.Value) (*structpb.Struct, error) { - valType := val.Type() - if !valType.IsObjectType() && !valType.IsMapType() { - return nil, fmt.Errorf("Struct type must be either an object or map type") - } - - structValues := make(map[string]*structpb.Value) - - for k, v := range val.AsValueMap() { - vType := v.Type() - - if v.IsNull() { - structValues[k] = structpb.NewNullValue() - } else if vType.IsListType() || vType.IsSetType() || vType.IsTupleType() { - listVal, err := protoStructListValueFromCty(v) - if err != nil { - return nil, err - } - structValues[k] = structpb.NewListValue(listVal) - } else if vType.IsMapType() || vType.IsObjectType() { - objVal, err := protoStructObjectFromCty(v) - if err != nil { - return nil, err - } - structValues[k] = structpb.NewStructValue(objVal) - } else if vType.IsPrimitiveType() { - switch vType { - case cty.String: - stringVal, err := stringFromCty(v) - if err != nil { - return nil, err - } - - structValues[k] = structpb.NewStringValue(stringVal) - case cty.Bool: - boolVal, err := boolFromCty(v) - if err != nil { - return nil, err - } - - structValues[k] = structpb.NewBoolValue(boolVal) - case cty.Number: - doubleVal, err := doubleFromCty(v) - if err != nil { - return nil, err - } - - structValues[k] = structpb.NewNumberValue(doubleVal) - default: - return nil, fmt.Errorf("unknown cty primitive type: %s", vType.FriendlyName()) - } - } else { - return nil, fmt.Errorf("unsupported cty type: %s", vType.FriendlyName()) - } - } - - return &structpb.Struct{ - Fields: structValues, - }, nil -} - -func protoStructListValueFromCty(val cty.Value) (*structpb.ListValue, error) { - var values []*structpb.Value - - var err error - val.ForEachElement(func(_ cty.Value, value cty.Value) bool { - vType := value.Type() - - if value.IsNull() { - values = append(values, structpb.NewNullValue()) - } else if vType.IsListType() || vType.IsSetType() || vType.IsTupleType() { - var listVal *structpb.ListValue - listVal, err = protoStructListValueFromCty(value) - if err != nil { - return true - } - values = append(values, structpb.NewListValue(listVal)) - } else if vType.IsMapType() || vType.IsObjectType() { - var objVal *structpb.Struct - objVal, err = protoStructObjectFromCty(value) - if err != nil { - return true - } - values = append(values, structpb.NewStructValue(objVal)) - } else if vType.IsPrimitiveType() { - switch vType { - case cty.String: - var stringVal string - stringVal, err = stringFromCty(value) - if err != nil { - return true - } - - values = append(values, structpb.NewStringValue(stringVal)) - case cty.Bool: - var boolVal bool - boolVal, err = boolFromCty(value) - if err != nil { - return true - } - - values = append(values, structpb.NewBoolValue(boolVal)) - case cty.Number: - var doubleVal float64 - doubleVal, err = doubleFromCty(value) - if err != nil { - return true - } - - values = append(values, structpb.NewNumberValue(doubleVal)) - default: - err = fmt.Errorf("unknown cty primitive type: %s", vType.FriendlyName()) - return true - } - } else { - err = fmt.Errorf("unsupported cty type: %s", vType.FriendlyName()) - return true - } - return false - }) - - if err != nil { - return nil, err - } - - return &structpb.ListValue{ - Values: values, - }, nil -} diff --git a/internal/protoutil/protoutil.go b/internal/protoutil/protoutil.go deleted file mode 100644 index 21a16dd1f3fe8..0000000000000 --- a/internal/protoutil/protoutil.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package protoutil - -import ( - "google.golang.org/protobuf/proto" -) - -func Clone[T proto.Message](v T) T { - return proto.Clone(v).(T) -} - -func CloneSlice[T proto.Message](in []T) []T { - if in == nil { - return nil - } - out := make([]T, 0, len(in)) - for _, v := range in { - out = append(out, Clone[T](v)) - } - return out -} diff --git a/internal/radix/doc.go b/internal/radix/doc.go index f69f68a2d6b07..47e8961d0d0a5 100644 --- a/internal/radix/doc.go +++ b/internal/radix/doc.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - // This packages contents were originally copied from github.com/armon/go-radix. // After the intial copy all the data structures were made to use Go 1.18 generics // instead of relying on the use of interface{} or the any type. diff --git a/internal/radix/radix.go b/internal/radix/radix.go index c2b7ee838935f..0f1d8d772ac7c 100644 --- a/internal/radix/radix.go +++ b/internal/radix/radix.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package radix import ( diff --git a/internal/radix/radix_test.go b/internal/radix/radix_test.go index ea7015dc29c24..9f616b73f438e 100644 --- a/internal/radix/radix_test.go +++ b/internal/radix/radix_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package radix import ( diff --git a/internal/resource/acls.go b/internal/resource/acls.go deleted file mode 100644 index 55a5872fc0de8..0000000000000 --- a/internal/resource/acls.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import "github.com/hashicorp/consul/acl" - -// NoOpACLListHook is a common function that can be used if no special list permission is required for a resource. -func NoOpACLListHook(_ acl.Authorizer, _ *acl.AuthorizerContext) error { - // No-op List permission as we want to default to filtering resources - // from the list using the Read enforcement. - return nil -} diff --git a/internal/resource/authz.go b/internal/resource/authz.go deleted file mode 100644 index 77a5d7850f9a8..0000000000000 --- a/internal/resource/authz.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -func peerNameV2ToV1(peer string) string { - // The name of the local/default peer is different between v1 and v2. - if peer == "local" { - return "" - } - return peer -} - -func peerNameV1ToV2(peer string) string { - // The name of the local/default peer is different between v1 and v2. - if peer == "" { - return "local" - } - return peer -} diff --git a/internal/resource/authz_ce.go b/internal/resource/authz_ce.go deleted file mode 100644 index 69a1749e20177..0000000000000 --- a/internal/resource/authz_ce.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package resource - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// AuthorizerContext builds an ACL AuthorizerContext for the given tenancy. -func AuthorizerContext(t *pbresource.Tenancy) *acl.AuthorizerContext { - return &acl.AuthorizerContext{ - Peer: peerNameV2ToV1(t.PeerName), - } -} diff --git a/internal/resource/authz_ce_test.go b/internal/resource/authz_ce_test.go deleted file mode 100644 index a2b76f86bfe1a..0000000000000 --- a/internal/resource/authz_ce_test.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package resource - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func TestAuthorizerContext_CE(t *testing.T) { - t.Run("no peer", func(t *testing.T) { - require.Equal(t, - &acl.AuthorizerContext{}, - AuthorizerContext(&pbresource.Tenancy{ - Partition: "foo", - Namespace: "bar", - }), - ) - }) - - t.Run("with local peer", func(t *testing.T) { - require.Equal(t, - &acl.AuthorizerContext{}, - AuthorizerContext(&pbresource.Tenancy{ - Partition: "foo", - Namespace: "bar", - PeerName: "local", - }), - ) - }) - - t.Run("with non-local peer", func(t *testing.T) { - require.Equal(t, - &acl.AuthorizerContext{ - Peer: "remote", - }, - AuthorizerContext(&pbresource.Tenancy{ - Partition: "foo", - Namespace: "bar", - PeerName: "remote", - }), - ) - }) -} diff --git a/internal/resource/decode.go b/internal/resource/decode.go deleted file mode 100644 index d96cb79a9a7ca..0000000000000 --- a/internal/resource/decode.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "context" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// DecodedResource is a generic holder to contain an original Resource and its -// decoded contents. -type DecodedResource[T proto.Message] struct { - // Embedding here allows us to shadow the Resource.Data Any field to fake out - // using a single struct with inlined data. - *pbresource.Resource - Data T -} - -func (d *DecodedResource[T]) GetResource() *pbresource.Resource { - if d == nil { - return nil - } - - return d.Resource -} - -func (d *DecodedResource[T]) GetData() T { - if d == nil { - var zero T - return zero - } - - return d.Data -} - -// Decode will generically decode the provided resource into a 2-field -// structure that holds onto the original Resource and the decoded contents. -// -// Returns an ErrDataParse on unmarshalling errors. -func Decode[T proto.Message](res *pbresource.Resource) (*DecodedResource[T], error) { - var zero T - data := zero.ProtoReflect().New().Interface().(T) - // check that there is data to unmarshall - if res.Data != nil { - if err := res.Data.UnmarshalTo(data); err != nil { - return nil, NewErrDataParse(data, err) - } - } - return &DecodedResource[T]{ - Resource: res, - Data: data, - }, nil -} - -// GetDecodedResource will generically read the requested resource using the -// client and either return nil on a NotFound or decode the response value. -func GetDecodedResource[T proto.Message](ctx context.Context, client pbresource.ResourceServiceClient, id *pbresource.ID) (*DecodedResource[T], error) { - rsp, err := client.Read(ctx, &pbresource.ReadRequest{Id: id}) - switch { - case status.Code(err) == codes.NotFound: - return nil, nil - case err != nil: - return nil, err - } - return Decode[T](rsp.Resource) -} diff --git a/internal/resource/decode_test.go b/internal/resource/decode_test.go deleted file mode 100644 index 02e86fddfbf7d..0000000000000 --- a/internal/resource/decode_test.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/types/known/anypb" - - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/demo" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/proto-public/pbresource" - pbdemo "github.com/hashicorp/consul/proto/private/pbdemo/v2" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestGetDecodedResource(t *testing.T) { - var ( - baseClient = svctest.RunResourceService(t, demo.RegisterTypes) - client = rtest.NewClient(baseClient) - ctx = testutil.TestContext(t) - ) - - babypantsID := &pbresource.ID{ - Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "babypants", - } - - testutil.RunStep(t, "not found", func(t *testing.T) { - got, err := resource.GetDecodedResource[*pbdemo.Artist](ctx, client, babypantsID) - require.NoError(t, err) - require.Nil(t, got) - }) - - testutil.RunStep(t, "found", func(t *testing.T) { - data := &pbdemo.Artist{ - Name: "caspar babypants", - } - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, data). - Write(t, client) - - got, err := resource.GetDecodedResource[*pbdemo.Artist](ctx, client, babypantsID) - require.NoError(t, err) - require.NotNil(t, got) - - // Clone generated fields over. - res.Id.Uid = got.Resource.Id.Uid - res.Version = got.Resource.Version - res.Generation = got.Resource.Generation - - // Clone defaulted fields over - data.Genre = pbdemo.Genre_GENRE_DISCO - - prototest.AssertDeepEqual(t, res, got.Resource) - prototest.AssertDeepEqual(t, data, got.Data) - }) -} - -func TestDecode(t *testing.T) { - t.Run("good", func(t *testing.T) { - fooData := &pbdemo.Artist{ - Name: "caspar babypants", - } - any, err := anypb.New(fooData) - require.NoError(t, err) - - foo := &pbresource.Resource{ - Id: &pbresource.ID{ - Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "babypants", - }, - Data: any, - Metadata: map[string]string{ - "generated_at": time.Now().Format(time.RFC3339), - }, - } - - dec, err := resource.Decode[*pbdemo.Artist](foo) - require.NoError(t, err) - - prototest.AssertDeepEqual(t, foo, dec.Resource) - prototest.AssertDeepEqual(t, fooData, dec.Data) - }) - - t.Run("bad", func(t *testing.T) { - foo := &pbresource.Resource{ - Id: &pbresource.ID{ - Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "babypants", - }, - Data: &anypb.Any{ - TypeUrl: "garbage", - Value: []byte("more garbage"), - }, - Metadata: map[string]string{ - "generated_at": time.Now().Format(time.RFC3339), - }, - } - - _, err := resource.Decode[*pbdemo.Artist](foo) - require.Error(t, err) - }) -} diff --git a/internal/resource/demo/controller.go b/internal/resource/demo/controller.go index a8757fcae2624..11afc3bac5e6e 100644 --- a/internal/resource/demo/controller.go +++ b/internal/resource/demo/controller.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package demo @@ -71,7 +71,7 @@ func (r *artistReconciler) Reconcile(ctx context.Context, rt controller.Runtime, actualAlbums, err := rt.Client.List(ctx, &pbresource.ListRequest{ Type: TypeV2Album, Tenancy: res.Id.Tenancy, - NamePrefix: fmt.Sprintf("%s-", res.Id.Name), + NamePrefix: fmt.Sprintf("%s/", res.Id.Name), }) if err != nil { return err diff --git a/internal/resource/demo/controller_test.go b/internal/resource/demo/controller_test.go index a8c2640d615a8..8d4ee79c73e00 100644 --- a/internal/resource/demo/controller_test.go +++ b/internal/resource/demo/controller_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package demo diff --git a/internal/resource/demo/demo.go b/internal/resource/demo/demo.go index 12fced6718e61..20ad89c962c42 100644 --- a/internal/resource/demo/demo.go +++ b/internal/resource/demo/demo.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package demo includes fake resource types for working on Consul's generic // state storage without having to refer to specific features. @@ -22,20 +22,11 @@ import ( ) var ( - // TypeV1Executive represents a a C-suite executive of the company. - // Used as a resource to test cluster scope. - TypeV1Executive = &pbresource.Type{ - Group: "demo", - GroupVersion: "v1", - Kind: "Executive", - } - - // TypeV1RecordLabel represents a record label which artists are signed to. - // Used as a resource to test partiion scope. - TypeV1RecordLabel = &pbresource.Type{ - Group: "demo", - GroupVersion: "v1", - Kind: "RecordLabel", + // TenancyDefault contains the default values for all tenancy units. + TenancyDefault = &pbresource.Tenancy{ + Partition: "default", + PeerName: "local", + Namespace: "default", } // TypeV1Artist represents a musician or group of musicians. @@ -52,13 +43,6 @@ var ( Kind: "Album", } - // TypeV1Concept represents an abstract concept that can be associated with any other resource. - TypeV1Concept = &pbresource.Type{ - Group: "demo", - GroupVersion: "v1", - Kind: "Concept", - } - // TypeV2Artist represents a musician or group of musicians. TypeV2Artist = &pbresource.Type{ Group: "demo", @@ -80,12 +64,6 @@ const ( ArtistV2ReadPolicy = `key_prefix "resource/demo.v2.Artist/" { policy = "read" }` ArtistV2WritePolicy = `key_prefix "resource/demo.v2.Artist/" { policy = "write" }` ArtistV2ListPolicy = `key_prefix "resource/" { policy = "list" }` - - ExecutiveV1ReadPolicy = `key_prefix "resource/demo.v1.Executive/" { policy = "read" }` - ExecutiveV1WritePolicy = `key_prefix "resource/demo.v1.Executive/" { policy = "write" }` - - LabelV1ReadPolicy = `key_prefix "resource/demo.v1.Label/" { policy = "read" }` - LabelV1WritePolicy = `key_prefix "resource/demo.v1.Label/" { policy = "write" }` ) // RegisterTypes registers the demo types. Should only be called in tests and @@ -94,25 +72,20 @@ const ( // TODO(spatel): We're standing-in key ACLs for demo resources until our ACL // system can be more modularly extended (or support generic resource permissions). func RegisterTypes(r resource.Registry) { - readACL := func(authz acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, res *pbresource.Resource) error { - if resource.EqualType(TypeV1RecordLabel, id.Type) { - if res == nil { - return resource.ErrNeedResource - } - } + readACL := func(authz acl.Authorizer, id *pbresource.ID) error { key := fmt.Sprintf("resource/%s/%s", resource.ToGVK(id.Type), id.Name) - return authz.ToAllowAuthorizer().KeyReadAllowed(key, authzContext) + return authz.ToAllowAuthorizer().KeyReadAllowed(key, &acl.AuthorizerContext{}) } - writeACL := func(authz acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - key := fmt.Sprintf("resource/%s/%s", resource.ToGVK(res.Id.Type), res.Id.Name) - return authz.ToAllowAuthorizer().KeyWriteAllowed(key, authzContext) + writeACL := func(authz acl.Authorizer, id *pbresource.ID) error { + key := fmt.Sprintf("resource/%s/%s", resource.ToGVK(id.Type), id.Name) + return authz.ToAllowAuthorizer().KeyWriteAllowed(key, &acl.AuthorizerContext{}) } - makeListACL := func(typ *pbresource.Type) func(acl.Authorizer, *acl.AuthorizerContext) error { - return func(authz acl.Authorizer, authzContext *acl.AuthorizerContext) error { + makeListACL := func(typ *pbresource.Type) func(acl.Authorizer, *pbresource.Tenancy) error { + return func(authz acl.Authorizer, tenancy *pbresource.Tenancy) error { key := fmt.Sprintf("resource/%s", resource.ToGVK(typ)) - return authz.ToAllowAuthorizer().KeyListAllowed(key, authzContext) + return authz.ToAllowAuthorizer().KeyListAllowed(key, &acl.AuthorizerContext{}) } } @@ -151,32 +124,9 @@ func RegisterTypes(r resource.Registry) { return nil } - r.Register(resource.Registration{ - Type: TypeV1Executive, - Proto: &pbdemov1.Executive{}, - Scope: resource.ScopeCluster, - ACLs: &resource.ACLHooks{ - Read: readACL, - Write: writeACL, - List: makeListACL(TypeV1Executive), - }, - }) - - r.Register(resource.Registration{ - Type: TypeV1RecordLabel, - Proto: &pbdemov1.RecordLabel{}, - Scope: resource.ScopePartition, - ACLs: &resource.ACLHooks{ - Read: readACL, - Write: writeACL, - List: makeListACL(TypeV1RecordLabel), - }, - }) - r.Register(resource.Registration{ Type: TypeV1Artist, Proto: &pbdemov1.Artist{}, - Scope: resource.ScopeNamespace, ACLs: &resource.ACLHooks{ Read: readACL, Write: writeACL, @@ -188,7 +138,6 @@ func RegisterTypes(r resource.Registry) { r.Register(resource.Registration{ Type: TypeV1Album, Proto: &pbdemov1.Album{}, - Scope: resource.ScopeNamespace, ACLs: &resource.ACLHooks{ Read: readACL, Write: writeACL, @@ -196,21 +145,9 @@ func RegisterTypes(r resource.Registry) { }, }) - r.Register(resource.Registration{ - Type: TypeV1Concept, - Proto: &pbdemov1.Concept{}, - Scope: resource.ScopeNamespace, - ACLs: &resource.ACLHooks{ - Read: readACL, - Write: writeACL, - List: makeListACL(TypeV1Concept), - }, - }) - r.Register(resource.Registration{ Type: TypeV2Artist, Proto: &pbdemov2.Artist{}, - Scope: resource.ScopeNamespace, ACLs: &resource.ACLHooks{ Read: readACL, Write: writeACL, @@ -223,7 +160,6 @@ func RegisterTypes(r resource.Registry) { r.Register(resource.Registration{ Type: TypeV2Album, Proto: &pbdemov2.Album{}, - Scope: resource.ScopeNamespace, ACLs: &resource.ACLHooks{ Read: readACL, Write: writeACL, @@ -232,61 +168,6 @@ func RegisterTypes(r resource.Registry) { }) } -// GenerateV1Executive generates a named Executive resource. -func GenerateV1Executive(name, position string) (*pbresource.Resource, error) { - data, err := anypb.New(&pbdemov1.Executive{Position: position}) - if err != nil { - return nil, err - } - - return &pbresource.Resource{ - Id: &pbresource.ID{ - Type: TypeV1Executive, - Tenancy: resource.DefaultClusteredTenancy(), - Name: name, - }, - Data: data, - Metadata: map[string]string{ - "generated_at": time.Now().Format(time.RFC3339), - }, - }, nil -} - -// GenerateV1RecordLabel generates a named RecordLabel resource. -func GenerateV1RecordLabel(name string) (*pbresource.Resource, error) { - data, err := anypb.New(&pbdemov1.RecordLabel{Name: name}) - if err != nil { - return nil, err - } - - return &pbresource.Resource{ - Id: &pbresource.ID{ - Type: TypeV1RecordLabel, - Tenancy: resource.DefaultPartitionedTenancy(), - Name: name, - }, - Data: data, - Metadata: map[string]string{ - "generated_at": time.Now().Format(time.RFC3339), - }, - }, nil -} - -// GenerateV1Concept generates a named concept resource. -func GenerateV1Concept(name string) (*pbresource.Resource, error) { - return &pbresource.Resource{ - Id: &pbresource.ID{ - Type: TypeV1Concept, - Tenancy: resource.DefaultPartitionedTenancy(), - Name: name, - }, - Data: nil, - Metadata: map[string]string{ - "generated_at": time.Now().Format(time.RFC3339), - }, - }, nil -} - // GenerateV2Artist generates a random Artist resource. func GenerateV2Artist() (*pbresource.Resource, error) { adjective := adjectives[rand.Intn(len(adjectives))] @@ -310,7 +191,7 @@ func GenerateV2Artist() (*pbresource.Resource, error) { return &pbresource.Resource{ Id: &pbresource.ID{ Type: TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), + Tenancy: TenancyDefault, Name: fmt.Sprintf("%s-%s", strings.ToLower(adjective), strings.ToLower(noun)), }, Data: data, @@ -353,8 +234,8 @@ func generateV2Album(artistID *pbresource.ID, rand *rand.Rand) (*pbresource.Reso return &pbresource.Resource{ Id: &pbresource.ID{ Type: TypeV2Album, - Tenancy: clone(artistID.Tenancy), - Name: fmt.Sprintf("%s-%s-%s", artistID.Name, strings.ToLower(adjective), strings.ToLower(noun)), + Tenancy: artistID.Tenancy, + Name: fmt.Sprintf("%s/%s-%s", artistID.Name, strings.ToLower(adjective), strings.ToLower(noun)), }, Owner: artistID, Data: data, diff --git a/internal/resource/equality.go b/internal/resource/equality.go index 25e098b1a3610..c7c880cddc9eb 100644 --- a/internal/resource/equality.go +++ b/internal/resource/equality.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -20,7 +20,7 @@ func EqualType(a, b *pbresource.Type) bool { a.Kind == b.Kind } -// EqualTenancy compares two resource tenancies for equality without reflection. +// EqualType compares two resource tenancies for equality without reflection. func EqualTenancy(a, b *pbresource.Tenancy) bool { if a == b { return true @@ -35,7 +35,7 @@ func EqualTenancy(a, b *pbresource.Tenancy) bool { a.Namespace == b.Namespace } -// EqualID compares two resource IDs for equality without reflection. +// EqualType compares two resource IDs for equality without reflection. func EqualID(a, b *pbresource.ID) bool { if a == b { return true @@ -120,22 +120,6 @@ func EqualReference(a, b *pbresource.Reference) bool { a.Section == b.Section } -// ReferenceOrIDMatch compares two references or IDs to see if they both refer -// to the same thing. -// -// Note that this only compares fields that are common between them as -// represented by the ReferenceOrID interface and notably ignores the section -// field on references and the uid field on ids. -func ReferenceOrIDMatch(ref1, ref2 ReferenceOrID) bool { - if ref1 == nil || ref2 == nil { - return false - } - - return EqualType(ref1.GetType(), ref2.GetType()) && - EqualTenancy(ref1.GetTenancy(), ref2.GetTenancy()) && - ref1.GetName() == ref2.GetName() -} - // EqualStatusMap compares two status maps for equality without reflection. func EqualStatusMap(a, b map[string]*pbresource.Status) bool { if len(a) != len(b) { diff --git a/internal/resource/equality_test.go b/internal/resource/equality_test.go index 8413905606383..4fb7cb666b3aa 100644 --- a/internal/resource/equality_test.go +++ b/internal/resource/equality_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource_test @@ -283,310 +283,6 @@ func TestEqualID(t *testing.T) { }) } -func TestEqualReference(t *testing.T) { - t.Run("same pointer", func(t *testing.T) { - id := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - require.True(t, resource.EqualReference(id, id)) - }) - - t.Run("equal", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := clone(a) - require.True(t, resource.EqualReference(a, b)) - }) - - t.Run("nil", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - require.False(t, resource.EqualReference(a, nil)) - require.False(t, resource.EqualReference(nil, a)) - }) - - t.Run("different type", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := clone(a) - b.Type.Kind = "album" - require.False(t, resource.EqualReference(a, b)) - }) - - t.Run("different tenancy", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := clone(a) - b.Tenancy.Namespace = "qux" - require.False(t, resource.EqualReference(a, b)) - }) - - t.Run("different name", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := clone(a) - b.Name = "boom" - require.False(t, resource.EqualReference(a, b)) - }) - - t.Run("different section", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := clone(a) - b.Section = "not-blah" - require.False(t, resource.EqualReference(a, b)) - }) -} - -func TestReferenceOrIDMatch(t *testing.T) { - t.Run("equal", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := &pbresource.ID{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Uid: ulid.Make().String(), - } - require.True(t, resource.ReferenceOrIDMatch(a, b)) - }) - - t.Run("nil", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := &pbresource.ID{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Uid: ulid.Make().String(), - } - require.False(t, resource.ReferenceOrIDMatch(a, nil)) - require.False(t, resource.ReferenceOrIDMatch(nil, b)) - }) - - t.Run("different type", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := &pbresource.ID{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Uid: ulid.Make().String(), - } - b.Type.Kind = "album" - require.False(t, resource.ReferenceOrIDMatch(a, b)) - }) - - t.Run("different tenancy", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := &pbresource.ID{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Uid: ulid.Make().String(), - } - b.Tenancy.Namespace = "qux" - require.False(t, resource.ReferenceOrIDMatch(a, b)) - }) - - t.Run("different name", func(t *testing.T) { - a := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Section: "blah", - } - b := &pbresource.ID{ - Type: &pbresource.Type{ - Group: "demo", - GroupVersion: "v2", - Kind: "artist", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "foo", - PeerName: "bar", - Namespace: "baz", - }, - Name: "qux", - Uid: ulid.Make().String(), - } - b.Name = "boom" - require.False(t, resource.ReferenceOrIDMatch(a, b)) - }) -} - func TestEqualStatus(t *testing.T) { orig := &pbresource.Status{ ObservedGeneration: ulid.Make().String(), diff --git a/internal/resource/errors.go b/internal/resource/errors.go index 24dd96e90ec4a..c258f9ad35b13 100644 --- a/internal/resource/errors.go +++ b/internal/resource/errors.go @@ -1,47 +1,22 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource import ( + "errors" "fmt" - "strings" - - "google.golang.org/protobuf/reflect/protoreflect" "github.com/hashicorp/consul/proto-public/pbresource" + "google.golang.org/protobuf/reflect/protoreflect" ) var ( - ErrMissing = NewConstError("missing required field") - ErrMissingOneOf = NewConstError("missing one of the required fields") - ErrEmpty = NewConstError("cannot be empty") - ErrReferenceTenancyNotEqual = NewConstError("resource tenancy and reference tenancy differ") - ErrUnsupported = NewConstError("field is currently not supported") + ErrMissing = errors.New("missing required field") + ErrEmpty = errors.New("cannot be empty") + ErrReferenceTenancyNotEqual = errors.New("resource tenancy and reference tenancy differ") ) -// ConstError is more or less equivalent to the stdlib errors.errorstring. However, having -// our own exported type allows us to more accurately compare error values in tests. -// -// - go-cmp will not compared unexported fields by default. -// - cmp.AllowUnexported() requires a concrete struct type and due to the stdlib not -// exporting the errorstring type there doesn't seem to be a way to get at the type. -// - cmpopts.EquateErrors has issues with protobuf types within other error structs. -// -// Due to these factors the easiest thing to do is to create a custom comparer for -// the ConstError type and use it where necessary. -type ConstError struct { - message string -} - -func NewConstError(msg string) ConstError { - return ConstError{message: msg} -} - -func (e ConstError) Error() string { - return e.message -} - type ErrDataParse struct { TypeName string Wrapped error @@ -137,20 +112,6 @@ type ErrOwnerTenantInvalid struct { } func (err ErrOwnerTenantInvalid) Error() string { - if err.ResourceTenancy == nil && err.OwnerTenancy != nil { - return fmt.Sprintf( - "empty resource tenancy cannot be owned by a resource in partition %s, namespace %s and peer %s", - err.OwnerTenancy.Partition, err.OwnerTenancy.Namespace, err.OwnerTenancy.PeerName, - ) - } - - if err.ResourceTenancy != nil && err.OwnerTenancy == nil { - return fmt.Sprintf( - "resource in partition %s, namespace %s and peer %s cannot be owned by a resource with empty tenancy", - err.ResourceTenancy.Partition, err.ResourceTenancy.Namespace, err.ResourceTenancy.PeerName, - ) - } - return fmt.Sprintf( "resource in partition %s, namespace %s and peer %s cannot be owned by a resource in partition %s, namespace %s and peer %s", err.ResourceTenancy.Partition, err.ResourceTenancy.Namespace, err.ResourceTenancy.PeerName, @@ -165,17 +126,3 @@ type ErrInvalidReferenceType struct { func (err ErrInvalidReferenceType) Error() string { return fmt.Sprintf("reference must have type %s", ToGVK(err.AllowedType)) } - -type ErrInvalidFields struct { - Names []string - Wrapped error -} - -func (err ErrInvalidFields) Error() string { - allFields := strings.Join(err.Names, ",") - return fmt.Sprintf("invalid %q fields: %v", allFields, err.Wrapped) -} - -func (err ErrInvalidFields) Unwrap() error { - return err.Wrapped -} diff --git a/internal/resource/errors_test.go b/internal/resource/errors_test.go index 2c1ca911976fc..990a91607723b 100644 --- a/internal/resource/errors_test.go +++ b/internal/resource/errors_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -11,9 +11,8 @@ import ( "path/filepath" "testing" - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/stretchr/testify/require" ) // update allows golden files to be updated based on the current output. @@ -93,7 +92,7 @@ func TestErrorUnwrap(t *testing.T) { cases := map[string]error{ "ErrDataParse": ErrDataParse{ - TypeName: "hashicorp.consul.catalog.v2beta1.Service", + TypeName: "hashicorp.consul.catalog.v1alpha1.Service", Wrapped: fakeWrappedErr, }, "ErrInvalidField": ErrInvalidField{ diff --git a/internal/resource/filter.go b/internal/resource/filter.go deleted file mode 100644 index 44a368929357f..0000000000000 --- a/internal/resource/filter.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "fmt" - - "github.com/hashicorp/go-bexpr" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// FilterResourcesByMetadata will use the provided go-bexpr based filter to -// retain matching items from the provided slice. -// -// The only variables usable in the expressions are the metadata keys prefixed -// by "metadata." -// -// If no filter is provided, then this does nothing and returns the input. -func FilterResourcesByMetadata(resources []*pbresource.Resource, filter string) ([]*pbresource.Resource, error) { - if filter == "" || len(resources) == 0 { - return resources, nil - } - - eval, err := createMetadataFilterEvaluator(filter) - if err != nil { - return nil, err - } - - filtered := make([]*pbresource.Resource, 0, len(resources)) - for _, res := range resources { - vars := &metadataFilterFieldDetails{ - Meta: res.Metadata, - } - match, err := eval.Evaluate(vars) - if err != nil { - return nil, err - } - if match { - filtered = append(filtered, res) - } - } - if len(filtered) == 0 { - return nil, nil - } - return filtered, nil -} - -// FilterMatchesResourceMetadata will use the provided go-bexpr based filter to -// determine if the provided resource matches. -// -// The only variables usable in the expressions are the metadata keys prefixed -// by "metadata." -// -// If no filter is provided, then this returns true. -func FilterMatchesResourceMetadata(res *pbresource.Resource, filter string) (bool, error) { - if res == nil { - return false, nil - } else if filter == "" { - return true, nil - } - - eval, err := createMetadataFilterEvaluator(filter) - if err != nil { - return false, err - } - - vars := &metadataFilterFieldDetails{ - Meta: res.Metadata, - } - match, err := eval.Evaluate(vars) - if err != nil { - return false, err - } - return match, nil -} - -// ValidateMetadataFilter will validate that the provided filter is going to be -// a valid input to the FilterResourcesByMetadata function. -// -// This is best called from a Validate hook. -func ValidateMetadataFilter(filter string) error { - if filter == "" { - return nil - } - - _, err := createMetadataFilterEvaluator(filter) - return err -} - -func createMetadataFilterEvaluator(filter string) (*bexpr.Evaluator, error) { - sampleVars := &metadataFilterFieldDetails{ - Meta: make(map[string]string), - } - eval, err := bexpr.CreateEvaluatorForType(filter, nil, sampleVars) - if err != nil { - return nil, fmt.Errorf("filter %q is invalid: %w", filter, err) - } - return eval, nil -} - -type metadataFilterFieldDetails struct { - Meta map[string]string `bexpr:"metadata"` -} diff --git a/internal/resource/filter_test.go b/internal/resource/filter_test.go deleted file mode 100644 index e15ec08030c05..0000000000000 --- a/internal/resource/filter_test.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" - "github.com/hashicorp/consul/sdk/testutil" -) - -func TestFilterResourcesByMetadata(t *testing.T) { - type testcase struct { - in []*pbresource.Resource - filter string - expect []*pbresource.Resource - expectErr string - } - - create := func(name string, kvs ...string) *pbresource.Resource { - require.True(t, len(kvs)%2 == 0) - - meta := make(map[string]string) - for i := 0; i < len(kvs); i += 2 { - meta[kvs[i]] = kvs[i+1] - } - - return &pbresource.Resource{ - Id: &pbresource.ID{ - Name: name, - }, - Metadata: meta, - } - } - - run := func(t *testing.T, tc testcase) { - got, err := FilterResourcesByMetadata(tc.in, tc.filter) - if tc.expectErr != "" { - require.Error(t, err) - testutil.RequireErrorContains(t, err, tc.expectErr) - } else { - require.NoError(t, err) - prototest.AssertDeepEqual(t, tc.expect, got) - } - } - - cases := map[string]testcase{ - "nil input": {}, - "no filter": { - in: []*pbresource.Resource{ - create("one"), - create("two"), - create("three"), - create("four"), - }, - filter: "", - expect: []*pbresource.Resource{ - create("one"), - create("two"), - create("three"), - create("four"), - }, - }, - "bad filter": { - in: []*pbresource.Resource{ - create("one"), - create("two"), - create("three"), - create("four"), - }, - filter: "garbage.value == zzz", - expectErr: `Selector "garbage" is not valid`, - }, - "filter everything out": { - in: []*pbresource.Resource{ - create("one"), - create("two"), - create("three"), - create("four"), - }, - filter: "metadata.foo == bar", - }, - "filter simply": { - in: []*pbresource.Resource{ - create("one", "foo", "bar"), - create("two", "foo", "baz"), - create("three", "zim", "gir"), - create("four", "zim", "gaz", "foo", "bar"), - }, - filter: "metadata.foo == bar", - expect: []*pbresource.Resource{ - create("one", "foo", "bar"), - create("four", "zim", "gaz", "foo", "bar"), - }, - }, - "filter prefix": { - in: []*pbresource.Resource{ - create("one", "foo", "bar"), - create("two", "foo", "baz"), - create("three", "zim", "gir"), - create("four", "zim", "gaz", "foo", "bar"), - create("four", "zim", "zzz"), - }, - filter: "(zim in metadata) and (metadata.zim matches `^g.`)", - expect: []*pbresource.Resource{ - create("three", "zim", "gir"), - create("four", "zim", "gaz", "foo", "bar"), - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func TestFilterMatchesResourceMetadata(t *testing.T) { - type testcase struct { - res *pbresource.Resource - filter string - expect bool - expectErr string - } - - create := func(name string, kvs ...string) *pbresource.Resource { - require.True(t, len(kvs)%2 == 0) - - meta := make(map[string]string) - for i := 0; i < len(kvs); i += 2 { - meta[kvs[i]] = kvs[i+1] - } - - return &pbresource.Resource{ - Id: &pbresource.ID{ - Name: name, - }, - Metadata: meta, - } - } - - run := func(t *testing.T, tc testcase) { - got, err := FilterMatchesResourceMetadata(tc.res, tc.filter) - if tc.expectErr != "" { - require.Error(t, err) - testutil.RequireErrorContains(t, err, tc.expectErr) - } else { - require.NoError(t, err) - require.Equal(t, tc.expect, got) - } - } - - cases := map[string]testcase{ - "nil input": {}, - "no filter": { - res: create("one"), - filter: "", - expect: true, - }, - "bad filter": { - res: create("one"), - filter: "garbage.value == zzz", - expectErr: `Selector "garbage" is not valid`, - }, - "no match": { - res: create("one"), - filter: "metadata.foo == bar", - }, - "match simply": { - res: create("one", "foo", "bar"), - filter: "metadata.foo == bar", - expect: true, - }, - "match via prefix": { - res: create("four", "zim", "gaz", "foo", "bar"), - filter: "(zim in metadata) and (metadata.zim matches `^g.`)", - expect: true, - }, - "no match via prefix": { - res: create("four", "zim", "zzz", "foo", "bar"), - filter: "(zim in metadata) and (metadata.zim matches `^g.`)", - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/resource/hooks.go b/internal/resource/hooks.go deleted file mode 100644 index 2b9d72b88925f..0000000000000 --- a/internal/resource/hooks.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/proto-public/pbresource" - "google.golang.org/protobuf/proto" -) - -// DecodedValidationHook is the function signature needed for usage with the DecodeAndValidate function -type DecodedValidationHook[T proto.Message] func(*DecodedResource[T]) error - -// DecodeAndValidate will generate a validation hook function that decodes the specified type and -// passes it off to another validation hook. This is mainly a convenience to avoid many other -// validation hooks needing to attempt decoding the data and erroring in a consistent manner. -func DecodeAndValidate[T proto.Message](fn DecodedValidationHook[T]) ValidationHook { - return func(res *pbresource.Resource) error { - decoded, err := Decode[T](res) - if err != nil { - return err - } - - return fn(decoded) - } -} - -// DecodedMutationHook is the function signature needed for usage with the DecodeAndMutate function -// The boolean return value indicates whether the Data field within the DecodedResource was modified. -// When true, the DecodeAndMutate hook function will automatically re-encode the Any data and store -// it on the internal Resource's Data field. -type DecodedMutationHook[T proto.Message] func(*DecodedResource[T]) (bool, error) - -// DecodeAndMutate will generate a MutationHook that decodes the specified type and passes it -// off to another mutation hook. This is mainly a convenience to avoid other mutation hooks -// needing to decode and potentially reencode the Any data. When the inner mutation hook returns -// no error and that the Data was modified (true for the boolean return value), the generated -// hook will reencode the Any data back into the Resource wrapper -func DecodeAndMutate[T proto.Message](fn DecodedMutationHook[T]) MutationHook { - return func(res *pbresource.Resource) error { - decoded, err := Decode[T](res) - if err != nil { - return err - } - - modified, err := fn(decoded) - if err != nil { - return err - } - - if modified { - return decoded.Resource.Data.MarshalFrom(decoded.Data) - } - return nil - } -} - -// DecodedAuthorizationHook is the function signature needed for usage with the DecodeAndAuthorizeWrite -// and DecodeAndAuthorizeRead functions. -type DecodedAuthorizationHook[T proto.Message] func(acl.Authorizer, *acl.AuthorizerContext, *DecodedResource[T]) error - -// DecodeAndAuthorizeWrite will generate an ACLAuthorizeWriteHook that decodes the specified type and passes -// it off to another authorization hook. This is mainly a convenience to avoid many other write authorization -// hooks needing to attempt decoding the data and erroring in a consistent manner. -func DecodeAndAuthorizeWrite[T proto.Message](fn DecodedAuthorizationHook[T]) ACLAuthorizeWriteHook { - return func(authz acl.Authorizer, ctx *acl.AuthorizerContext, res *pbresource.Resource) error { - decoded, err := Decode[T](res) - if err != nil { - return err - } - - return fn(authz, ctx, decoded) - } -} - -// DecodeAndAuthorizeRead will generate an ACLAuthorizeReadHook that decodes the specified type and passes -// it off to another authorization hook. This is mainly a convenience to avoid many other read authorization -// hooks needing to attempt decoding the data and erroring in a consistent manner. -func DecodeAndAuthorizeRead[T proto.Message](fn DecodedAuthorizationHook[T]) ACLAuthorizeReadHook { - return func(authz acl.Authorizer, ctx *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { - if res == nil { - return ErrNeedResource - } - - decoded, err := Decode[T](res) - if err != nil { - return err - } - - return fn(authz, ctx, decoded) - } -} - -type ReadAuthorizationWithResourceHook func(acl.Authorizer, *acl.AuthorizerContext, *pbresource.Resource) error - -// AuthorizeReadWithResource is a small wrapper to ensure that the authorization function is -// invoked with the full resource being read instead of just an id. -func AuthorizeReadWithResource(fn ReadAuthorizationWithResourceHook) ACLAuthorizeReadHook { - return func(authz acl.Authorizer, ctx *acl.AuthorizerContext, id *pbresource.ID, res *pbresource.Resource) error { - if res == nil { - return ErrNeedResource - } - - return fn(authz, ctx, res) - } -} diff --git a/internal/resource/hooks_test.go b/internal/resource/hooks_test.go deleted file mode 100644 index d9fa4d4272b74..0000000000000 --- a/internal/resource/hooks_test.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/demo" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/proto-public/pbresource" - pbdemo "github.com/hashicorp/consul/proto/private/pbdemo/v2" - "github.com/stretchr/testify/require" -) - -func TestDecodeAndValidate(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("ok", func(t *testing.T) { - err := resource.DecodeAndValidate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) error { - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - return nil - })(res) - - require.NoError(t, err) - }) - - t.Run("inner-validation-error", func(t *testing.T) { - fakeErr := fmt.Errorf("fake") - - err := resource.DecodeAndValidate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) error { - return fakeErr - })(res) - - require.Error(t, err) - require.Equal(t, fakeErr, err) - }) - - t.Run("decode-error", func(t *testing.T) { - err := resource.DecodeAndValidate[*pbdemo.Album](func(dec *resource.DecodedResource[*pbdemo.Album]) error { - require.Fail(t, "callback should not be called when decoding fails") - return nil - })(res) - - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) - }) -} - -func TestDecodeAndMutate(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("no-writeback", func(t *testing.T) { - original := res.Data.Value - - err := resource.DecodeAndMutate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) (bool, error) { - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - // we are going to change the data but not tell the outer hook about it - dec.Data.Name = "changed" - - return false, nil - })(res) - - require.NoError(t, err) - // Ensure that the outer hook didn't overwrite the resources data because we told it not to - require.Equal(t, original, res.Data.Value) - }) - - t.Run("writeback", func(t *testing.T) { - original := res.Data.Value - - err := resource.DecodeAndMutate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) (bool, error) { - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - dec.Data.Name = "changed" - - return true, nil - })(res) - - require.NoError(t, err) - // Ensure that the outer hook reencoded the Any data because we told it to. - require.NotEqual(t, original, res.Data.Value) - }) - - t.Run("inner-mutation-error", func(t *testing.T) { - fakeErr := fmt.Errorf("fake") - - err := resource.DecodeAndMutate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) (bool, error) { - return false, fakeErr - })(res) - - require.Error(t, err) - require.Equal(t, fakeErr, err) - }) - - t.Run("decode-error", func(t *testing.T) { - err := resource.DecodeAndMutate[*pbdemo.Album](func(dec *resource.DecodedResource[*pbdemo.Album]) (bool, error) { - require.Fail(t, "callback should not be called when decoding fails") - return false, nil - })(res) - - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) - }) -} - -func TestDecodeAndAuthorizeWrite(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("allowed", func(t *testing.T) { - err := resource.DecodeAndAuthorizeWrite[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - require.NotNil(t, a) - require.NotNil(t, c) - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - // access allowed - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, res) - - require.NoError(t, err) - }) - - t.Run("denied", func(t *testing.T) { - err := resource.DecodeAndAuthorizeWrite[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - return acl.PermissionDenied("fake") - })(acl.DenyAll(), nil, res) - - require.Error(t, err) - require.True(t, acl.IsErrPermissionDenied(err)) - }) - - t.Run("decode-error", func(t *testing.T) { - err := resource.DecodeAndAuthorizeWrite[*pbdemo.Album](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Album]) error { - require.Fail(t, "callback should not be called when decoding fails") - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, res) - - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) - }) -} - -func TestDecodeAndAuthorizeRead(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("allowed", func(t *testing.T) { - err := resource.DecodeAndAuthorizeRead[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - require.NotNil(t, a) - require.NotNil(t, c) - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - // access allowed - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, res) - - require.NoError(t, err) - }) - - t.Run("denied", func(t *testing.T) { - err := resource.DecodeAndAuthorizeRead[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - return acl.PermissionDenied("fake") - })(acl.DenyAll(), nil, nil, res) - - require.Error(t, err) - require.True(t, acl.IsErrPermissionDenied(err)) - }) - - t.Run("decode-error", func(t *testing.T) { - err := resource.DecodeAndAuthorizeRead[*pbdemo.Album](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Album]) error { - require.Fail(t, "callback should not be called when decoding fails") - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, res) - - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) - }) - - t.Run("err-need-resource", func(t *testing.T) { - err := resource.DecodeAndAuthorizeRead[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - require.Fail(t, "callback should not be called when no resource was provided to be decoded") - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, nil) - - require.Error(t, err) - require.ErrorIs(t, err, resource.ErrNeedResource) - }) -} - -func TestAuthorizeReadWithResource(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("allowed", func(t *testing.T) { - err := resource.AuthorizeReadWithResource(func(a acl.Authorizer, c *acl.AuthorizerContext, res *pbresource.Resource) error { - require.NotNil(t, a) - require.NotNil(t, c) - require.NotNil(t, res) - - // access allowed - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, res) - - require.NoError(t, err) - }) - - t.Run("denied", func(t *testing.T) { - err := resource.AuthorizeReadWithResource(func(a acl.Authorizer, c *acl.AuthorizerContext, res *pbresource.Resource) error { - return acl.PermissionDenied("fake") - })(acl.DenyAll(), nil, nil, res) - - require.Error(t, err) - require.True(t, acl.IsErrPermissionDenied(err)) - }) - - t.Run("err-need-resource", func(t *testing.T) { - err := resource.AuthorizeReadWithResource(func(a acl.Authorizer, c *acl.AuthorizerContext, res *pbresource.Resource) error { - require.Fail(t, "callback should not be called when no resource was provided to be decoded") - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, nil) - - require.Error(t, err) - require.ErrorIs(t, err, resource.ErrNeedResource) - }) -} diff --git a/internal/resource/http/http.go b/internal/resource/http/http.go deleted file mode 100644 index fd5d6adb7979c..0000000000000 --- a/internal/resource/http/http.go +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package http - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "path" - "strings" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - HeaderConsulToken = "x-consul-token" - HeaderConsistencyMode = "x-consul-consistency-mode" -) - -func NewHandler( - client pbresource.ResourceServiceClient, - registry resource.Registry, - parseToken func(req *http.Request, token *string), - logger hclog.Logger) http.Handler { - mux := http.NewServeMux() - for _, t := range registry.Types() { - // List Endpoint - base := strings.ToLower(fmt.Sprintf("/%s/%s/%s", t.Type.Group, t.Type.GroupVersion, t.Type.Kind)) - mux.Handle(base, http.StripPrefix(base, &listHandler{t, client, parseToken, logger})) - - // Individual Resource Endpoints - prefix := strings.ToLower(fmt.Sprintf("%s/", base)) - logger.Info("Registered resource endpoint", "endpoint", prefix) - mux.Handle(prefix, http.StripPrefix(prefix, &resourceHandler{t, client, parseToken, logger})) - } - - return mux -} - -type writeRequest struct { - Metadata map[string]string `json:"metadata"` - Data json.RawMessage `json:"data"` - Owner *pbresource.ID `json:"owner"` -} - -type resourceHandler struct { - reg resource.Registration - client pbresource.ResourceServiceClient - parseToken func(req *http.Request, token *string) - logger hclog.Logger -} - -func (h *resourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - var token string - h.parseToken(r, &token) - ctx := metadata.AppendToOutgoingContext(r.Context(), HeaderConsulToken, token) - switch r.Method { - case http.MethodPut: - h.handleWrite(w, r, ctx) - case http.MethodGet: - h.handleRead(w, r, ctx) - case http.MethodDelete: - h.handleDelete(w, r, ctx) - default: - w.WriteHeader(http.StatusMethodNotAllowed) - return - } -} - -func (h *resourceHandler) handleWrite(w http.ResponseWriter, r *http.Request, ctx context.Context) { - var req writeRequest - // convert req body to writeRequest - if err := json.NewDecoder(r.Body).Decode(&req); err != nil { - h.logger.Error("Failed to decode request body", "error", err) - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("Request body format is invalid")) - return - } - // convert data struct to proto message - data := h.reg.Proto.ProtoReflect().New().Interface() - if err := protojson.Unmarshal(req.Data, data); err != nil { - h.logger.Error("Failed to unmarshal to proto message", "error", err) - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte("Request body didn't follow the resource schema")) - return - } - // proto message to any - anyProtoMsg, err := anypb.New(data) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - h.logger.Error("Failed to convert proto message to any type", "error", err) - return - } - - tenancyInfo, params := parseParams(r) - - rsp, err := h.client.Write(ctx, &pbresource.WriteRequest{ - Resource: &pbresource.Resource{ - Id: &pbresource.ID{ - Type: h.reg.Type, - Tenancy: tenancyInfo, - Name: params["resourceName"], - }, - Owner: req.Owner, - Version: params["version"], - Metadata: req.Metadata, - Data: anyProtoMsg, - }, - }) - if err != nil { - handleResponseError(err, w, h.logger) - return - } - - output, err := jsonMarshal(rsp.Resource) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - h.logger.Error("Failed to unmarshal GRPC resource response", "error", err) - return - } - w.Write(output) -} - -func (h *resourceHandler) handleRead(w http.ResponseWriter, r *http.Request, ctx context.Context) { - tenancyInfo, params := parseParams(r) - if params["consistent"] != "" { - ctx = metadata.AppendToOutgoingContext(ctx, "x-consul-consistency-mode", "consistent") - } - - rsp, err := h.client.Read(ctx, &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Type: h.reg.Type, - Tenancy: tenancyInfo, - Name: params["resourceName"], - }, - }) - if err != nil { - handleResponseError(err, w, h.logger) - return - } - - output, err := jsonMarshal(rsp.Resource) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - h.logger.Error("Failed to unmarshal GRPC resource response", "error", err) - return - } - w.Write(output) -} - -// Note: The HTTP endpoints do not accept UID since it is quite unlikely that the user will have access to it -func (h *resourceHandler) handleDelete(w http.ResponseWriter, r *http.Request, ctx context.Context) { - tenancyInfo, params := parseParams(r) - _, err := h.client.Delete(ctx, &pbresource.DeleteRequest{ - Id: &pbresource.ID{ - Type: h.reg.Type, - Tenancy: tenancyInfo, - Name: params["resourceName"], - }, - Version: params["version"], - }) - if err != nil { - handleResponseError(err, w, h.logger) - return - } - w.WriteHeader(http.StatusNoContent) - w.Write([]byte("{}")) -} - -func parseParams(r *http.Request) (tenancy *pbresource.Tenancy, params map[string]string) { - query := r.URL.Query() - namespace := query.Get("namespace") - if namespace == "" { - namespace = query.Get("ns") - } - peer := query.Get("peer") - if peer == "" { - peer = query.Get("peer_name") - } - tenancy = &pbresource.Tenancy{ - Partition: query.Get("partition"), - PeerName: peer, - Namespace: namespace, - } - - resourceName := path.Base(r.URL.Path) - if resourceName == "." || resourceName == "/" { - resourceName = "" - } - - params = make(map[string]string) - params["resourceName"] = resourceName - params["version"] = query.Get("version") - params["namePrefix"] = query.Get("name_prefix") - // coming from command line - params["consistent"] = query.Get("RequireConsistent") - // coming from http client - if _, ok := query["consistent"]; ok { - params["consistent"] = "true" - } - - return tenancy, params -} - -func jsonMarshal(res *pbresource.Resource) ([]byte, error) { - output, err := protojson.Marshal(res) - if err != nil { - return nil, err - } - - var stuff map[string]any - if err := json.Unmarshal(output, &stuff); err != nil { - return nil, err - } - - delete(stuff["data"].(map[string]any), "@type") - return json.MarshalIndent(stuff, "", " ") -} - -func handleResponseError(err error, w http.ResponseWriter, logger hclog.Logger) { - if e, ok := status.FromError(err); ok { - switch e.Code() { - case codes.InvalidArgument: - w.WriteHeader(http.StatusBadRequest) - logger.Info("User has mal-formed request", "error", err) - case codes.NotFound: - w.WriteHeader(http.StatusNotFound) - logger.Info("Received error from resource service: Not found", "error", err) - case codes.PermissionDenied: - w.WriteHeader(http.StatusForbidden) - logger.Info("Received error from resource service: User not authenticated", "error", err) - case codes.Aborted: - w.WriteHeader(http.StatusConflict) - logger.Info("Received error from resource service: the request conflict with the current state of the target resource", "error", err) - default: - w.WriteHeader(http.StatusInternalServerError) - logger.Error("Received error from resource service", "error", err) - } - } else { - w.WriteHeader(http.StatusInternalServerError) - logger.Error("Received error from resource service: not able to parse error returned", "error", err) - } - w.Write([]byte(err.Error())) -} - -type listHandler struct { - reg resource.Registration - client pbresource.ResourceServiceClient - parseToken func(req *http.Request, token *string) - logger hclog.Logger -} - -func (h *listHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodGet { - w.WriteHeader(http.StatusMethodNotAllowed) - return - } - - var token string - h.parseToken(r, &token) - ctx := metadata.AppendToOutgoingContext(r.Context(), HeaderConsulToken, token) - - tenancyInfo, params := parseParams(r) - if params["consistent"] == "true" { - ctx = metadata.AppendToOutgoingContext(ctx, HeaderConsistencyMode, "consistent") - } - - rsp, err := h.client.List(ctx, &pbresource.ListRequest{ - Type: h.reg.Type, - Tenancy: tenancyInfo, - NamePrefix: params["namePrefix"], - }) - if err != nil { - handleResponseError(err, w, h.logger) - return - } - - output := make([]json.RawMessage, len(rsp.Resources)) - for idx, res := range rsp.Resources { - b, err := jsonMarshal(res) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - h.logger.Error("Failed to unmarshal GRPC resource response", "error", err) - return - } - output[idx] = b - } - - b, err := json.MarshalIndent(struct { - Resources []json.RawMessage `json:"resources"` - }{output}, "", " ") - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - h.logger.Error("Failed to correctly format the list response", "error", err) - return - } - w.Write(b) -} diff --git a/internal/resource/http/http_test.go b/internal/resource/http/http_test.go deleted file mode 100644 index aeb85f0b8332a..0000000000000 --- a/internal/resource/http/http_test.go +++ /dev/null @@ -1,618 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package http - -import ( - "encoding/json" - "fmt" - "io" - "net/http" - "net/http/httptest" - "strings" - "testing" - - "github.com/hashicorp/go-hclog" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - resourceSvc "github.com/hashicorp/consul/agent/grpc-external/services/resource" - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - pbdemov1 "github.com/hashicorp/consul/proto/private/pbdemo/v1" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/demo" - "github.com/hashicorp/consul/proto-public/pbresource" - pbdemov2 "github.com/hashicorp/consul/proto/private/pbdemo/v2" - "github.com/hashicorp/consul/sdk/testutil" -) - -const testACLTokenArtistReadPolicy = "00000000-0000-0000-0000-000000000001" -const testACLTokenArtistWritePolicy = "00000000-0000-0000-0000-000000000002" -const testACLTokenArtistListPolicy = "00000000-0000-0000-0000-000000000003" -const fakeToken = "fake-token" - -func parseToken(req *http.Request, token *string) { - *token = req.Header.Get("x-consul-token") -} - -func TestResourceHandler_InputValidation(t *testing.T) { - type testCase struct { - description string - request *http.Request - response *httptest.ResponseRecorder - expectedResponseCode int - responseBodyContains string - } - client := svctest.RunResourceService(t, demo.RegisterTypes) - resourceHandler := resourceHandler{ - resource.Registration{ - Type: demo.TypeV2Artist, - Proto: &pbdemov2.Artist{}, - Scope: resource.ScopeNamespace, - }, - client, - func(req *http.Request, token *string) { return }, - hclog.NewNullLogger(), - } - - testCases := []testCase{ - { - description: "missing resource name", - request: httptest.NewRequest("PUT", "/?partition=default&peer_name=local&namespace=default", strings.NewReader(` - { - "metadata": { - "foo": "bar" - }, - "data": { - "name": "Keith Urban", - "genre": "GENRE_COUNTRY" - } - } - `)), - response: httptest.NewRecorder(), - expectedResponseCode: http.StatusBadRequest, - responseBodyContains: "resource.id.name invalid", - }, - { - description: "wrong schema", - request: httptest.NewRequest("PUT", "/keith-urban?partition=default&peer_name=local&namespace=default", strings.NewReader(` - { - "metadata": { - "foo": "bar" - }, - "dada": { - "name": "Keith Urban", - "genre": "GENRE_COUNTRY" - } - } - `)), - response: httptest.NewRecorder(), - expectedResponseCode: http.StatusBadRequest, - responseBodyContains: "Request body didn't follow the resource schema", - }, - { - description: "invalid request body", - request: httptest.NewRequest("PUT", "/keith-urban?partition=default&peer_name=local&namespace=default", strings.NewReader("bad-input")), - response: httptest.NewRecorder(), - expectedResponseCode: http.StatusBadRequest, - responseBodyContains: "Request body format is invalid", - }, - { - description: "no id", - request: httptest.NewRequest("DELETE", "/?partition=default&peer_name=local&namespace=default", strings.NewReader("")), - response: httptest.NewRecorder(), - expectedResponseCode: http.StatusBadRequest, - responseBodyContains: "id.name invalid", - }, - } - - for _, tc := range testCases { - t.Run(tc.description, func(t *testing.T) { - resourceHandler.ServeHTTP(tc.response, tc.request) - - response := tc.response.Result() - - defer response.Body.Close() - - b, err := io.ReadAll(tc.response.Body) - require.NoError(t, err) - - require.Equal(t, tc.expectedResponseCode, tc.response.Result().StatusCode) - require.Contains(t, string(b), tc.responseBodyContains) - }) - } -} - -func TestResourceWriteHandler(t *testing.T) { - aclResolver := &resourceSvc.MockACLResolver{} - aclResolver.On("ResolveTokenAndDefaultMeta", testACLTokenArtistReadPolicy, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, demo.ArtistV1ReadPolicy, demo.ArtistV2ReadPolicy), nil) - aclResolver.On("ResolveTokenAndDefaultMeta", testACLTokenArtistWritePolicy, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, demo.ArtistV1WritePolicy, demo.ArtistV2WritePolicy), nil) - - client := svctest.RunResourceServiceWithConfig(t, resourceSvc.Config{ACLResolver: aclResolver}, demo.RegisterTypes) - - r := resource.NewRegistry() - demo.RegisterTypes(r) - handler := NewHandler(client, r, parseToken, hclog.NewNullLogger()) - - t.Run("should be blocked if the token is not authorized", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("PUT", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default", strings.NewReader(` - { - "metadata": { - "foo": "bar" - }, - "data": { - "name": "Keith Urban", - "genre": "GENRE_COUNTRY" - } - } - `)) - - req.Header.Add("x-consul-token", testACLTokenArtistReadPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusForbidden, rsp.Result().StatusCode) - }) - var readRsp *pbresource.ReadResponse - t.Run("should write to the resource backend", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("PUT", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default", strings.NewReader(` - { - "metadata": { - "foo": "bar" - }, - "data": { - "name": "Keith Urban", - "genre": "GENRE_COUNTRY" - } - } - `)) - - req.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - require.Equal(t, "Keith Urban", result["data"].(map[string]any)["name"]) - require.Equal(t, "keith-urban", result["id"].(map[string]any)["name"]) - - var err error - readRsp, err = client.Read(testutil.TestContext(t), &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "keith-urban", - }, - }) - require.NoError(t, err) - require.NotNil(t, readRsp.Resource) - - var artist pbdemov2.Artist - require.NoError(t, readRsp.Resource.Data.UnmarshalTo(&artist)) - require.Equal(t, "Keith Urban", artist.Name) - }) - - t.Run("should update the record with version parameter", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("PUT", fmt.Sprintf("/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default&version=%s", readRsp.Resource.Version), strings.NewReader(` - { - "metadata": { - "foo": "bar" - }, - "data": { - "name": "Keith Urban Two", - "genre": "GENRE_COUNTRY" - } - } - `)) - - req.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - require.Equal(t, "Keith Urban Two", result["data"].(map[string]any)["name"]) - require.Equal(t, "keith-urban", result["id"].(map[string]any)["name"]) - }) - - t.Run("should fail the update if the resource's version doesn't match the version of the existing resource", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("PUT", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default&version=1", strings.NewReader(` - { - "metadata": { - "foo": "bar" - }, - "data": { - "name": "Keith Urban", - "genre": "GENRE_COUNTRY" - } - } - `)) - - req.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusConflict, rsp.Result().StatusCode) - }) - - t.Run("should write to the resource backend with owner", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("PUT", "/demo/v1/artist/keith-urban-v1?partition=default&peer_name=local&namespace=default", strings.NewReader(` - { - "metadata": { - "foo": "bar" - }, - "data": { - "name": "Keith Urban V1", - "genre": "GENRE_COUNTRY" - }, - "owner": { - "name": "keith-urban", - "type": { - "group": "demo", - "group_version": "v2", - "kind": "Artist" - }, - "tenancy": { - "partition": "default", - "peer_name": "local", - "namespace": "default" - } - } - } - `)) - - req.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - require.Equal(t, "Keith Urban V1", result["data"].(map[string]any)["name"]) - require.Equal(t, "keith-urban-v1", result["id"].(map[string]any)["name"]) - - readRsp, err := client.Read(testutil.TestContext(t), &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Type: demo.TypeV1Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "keith-urban-v1", - }, - }) - require.NoError(t, err) - require.NotNil(t, readRsp.Resource) - require.Equal(t, "keith-urban", readRsp.Resource.Owner.Name) - - var artist pbdemov1.Artist - require.NoError(t, readRsp.Resource.Data.UnmarshalTo(&artist)) - require.Equal(t, "Keith Urban V1", artist.Name) - }) -} - -type ResourceUri struct { - group string - version string - kind string - resourceName string -} - -func createResource(t *testing.T, artistHandler http.Handler, resourceUri *ResourceUri) map[string]any { - rsp := httptest.NewRecorder() - - if resourceUri == nil { - resourceUri = &ResourceUri{group: "demo", version: "v2", kind: "artist", resourceName: "keith-urban"} - } - - req := httptest.NewRequest("PUT", fmt.Sprintf("/%s/%s/%s/%s?partition=default&peer_name=local&namespace=default", resourceUri.group, resourceUri.version, resourceUri.kind, resourceUri.resourceName), strings.NewReader(` - { - "metadata": { - "foo": "bar" - }, - "data": { - "name": "test", - "genre": "GENRE_COUNTRY" - } - } - `)) - - req.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - - artistHandler.ServeHTTP(rsp, req) - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - return result -} - -func deleteResource(t *testing.T, artistHandler http.Handler, resourceUri *ResourceUri) { - rsp := httptest.NewRecorder() - - if resourceUri == nil { - resourceUri = &ResourceUri{group: "demo", version: "v2", kind: "artist", resourceName: "keith-urban"} - } - - req := httptest.NewRequest("DELETE", fmt.Sprintf("/%s/%s/%s/%s?partition=default&peer_name=local&namespace=default", resourceUri.group, resourceUri.version, resourceUri.kind, resourceUri.resourceName), strings.NewReader("")) - - req.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - - artistHandler.ServeHTTP(rsp, req) - require.Equal(t, http.StatusNoContent, rsp.Result().StatusCode) -} - -func TestResourceReadHandler(t *testing.T) { - aclResolver := &resourceSvc.MockACLResolver{} - aclResolver.On("ResolveTokenAndDefaultMeta", testACLTokenArtistReadPolicy, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, demo.ArtistV1ReadPolicy, demo.ArtistV2ReadPolicy), nil) - aclResolver.On("ResolveTokenAndDefaultMeta", testACLTokenArtistWritePolicy, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, demo.ArtistV1WritePolicy, demo.ArtistV2WritePolicy), nil) - aclResolver.On("ResolveTokenAndDefaultMeta", fakeToken, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, ""), nil) - - client := svctest.RunResourceServiceWithConfig(t, resourceSvc.Config{ACLResolver: aclResolver}, demo.RegisterTypes) - - r := resource.NewRegistry() - demo.RegisterTypes(r) - handler := NewHandler(client, r, parseToken, hclog.NewNullLogger()) - - createdResource := createResource(t, handler, nil) - - t.Run("Read resource", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default&consistent", nil) - - req.Header.Add("x-consul-token", testACLTokenArtistReadPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - require.Equal(t, result, createdResource) - }) - - t.Run("should not be found if resource not exist", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/demo/v2/artist/keith-not-exist?partition=default&peer_name=local&namespace=default&consistent", nil) - - req.Header.Add("x-consul-token", testACLTokenArtistReadPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusNotFound, rsp.Result().StatusCode) - }) - - t.Run("should be blocked if the token is not authorized", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default&consistent", nil) - - req.Header.Add("x-consul-token", fakeToken) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusForbidden, rsp.Result().StatusCode) - }) -} - -func TestResourceDeleteHandler(t *testing.T) { - aclResolver := &resourceSvc.MockACLResolver{} - aclResolver.On("ResolveTokenAndDefaultMeta", testACLTokenArtistReadPolicy, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, demo.ArtistV2ReadPolicy), nil) - aclResolver.On("ResolveTokenAndDefaultMeta", testACLTokenArtistWritePolicy, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, demo.ArtistV2WritePolicy), nil) - - client := svctest.RunResourceServiceWithConfig(t, resourceSvc.Config{ACLResolver: aclResolver}, demo.RegisterTypes) - - r := resource.NewRegistry() - demo.RegisterTypes(r) - - handler := NewHandler(client, r, parseToken, hclog.NewNullLogger()) - - t.Run("should surface PermissionDenied error from resource service", func(t *testing.T) { - createResource(t, handler, nil) - - deleteRsp := httptest.NewRecorder() - deletReq := httptest.NewRequest("DELETE", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default", strings.NewReader("")) - - deletReq.Header.Add("x-consul-token", testACLTokenArtistReadPolicy) - - handler.ServeHTTP(deleteRsp, deletReq) - - require.Equal(t, http.StatusForbidden, deleteRsp.Result().StatusCode) - }) - - t.Run("should delete a resource without version", func(t *testing.T) { - createResource(t, handler, nil) - - deleteRsp := httptest.NewRecorder() - deletReq := httptest.NewRequest("DELETE", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default", strings.NewReader("")) - - deletReq.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - - handler.ServeHTTP(deleteRsp, deletReq) - - require.Equal(t, http.StatusNoContent, deleteRsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(deleteRsp.Body).Decode(&result)) - require.Empty(t, result) - - _, err := client.Read(testutil.TestContext(t), &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "keith-urban", - }, - }) - require.ErrorContains(t, err, "resource not found") - }) - - t.Run("should delete a resource with version", func(t *testing.T) { - createResource(t, handler, nil) - - rsp := httptest.NewRecorder() - req := httptest.NewRequest("DELETE", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default&version=1", strings.NewReader("")) - - req.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - req.Header.Add("x-consul-token", testACLTokenArtistListPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusNoContent, rsp.Result().StatusCode) - - _, err := client.Read(testutil.TestContext(t), &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - Name: "keith-urban", - }, - }) - require.ErrorContains(t, err, "resource not found") - }) -} - -func TestResourceListHandler(t *testing.T) { - aclResolver := &resourceSvc.MockACLResolver{} - aclResolver.On("ResolveTokenAndDefaultMeta", testACLTokenArtistListPolicy, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, demo.ArtistV2ListPolicy), nil) - aclResolver.On("ResolveTokenAndDefaultMeta", testACLTokenArtistWritePolicy, mock.Anything, mock.Anything). - Return(svctest.AuthorizerFrom(t, demo.ArtistV2WritePolicy), nil) - - client := svctest.RunResourceServiceWithConfig(t, resourceSvc.Config{ACLResolver: aclResolver}, demo.RegisterTypes) - - r := resource.NewRegistry() - demo.RegisterTypes(r) - - handler := NewHandler(client, r, parseToken, hclog.NewNullLogger()) - - t.Run("should return MethodNotAllowed", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("PUT", "/demo/v2/artist?partition=default&peer_name=local&namespace=default", strings.NewReader("")) - - req.Header.Add("x-consul-token", testACLTokenArtistListPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusMethodNotAllowed, rsp.Result().StatusCode) - }) - - t.Run("should be blocked if the token is not authorized", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/demo/v2/artist?partition=default&peer_name=local&namespace=default", strings.NewReader("")) - - req.Header.Add("x-consul-token", testACLTokenArtistWritePolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusForbidden, rsp.Result().StatusCode) - }) - - t.Run("should return list of resources", func(t *testing.T) { - resourceUri1 := &ResourceUri{group: "demo", version: "v2", kind: "artist", resourceName: "steve"} - resource1 := createResource(t, handler, resourceUri1) - resourceUri2 := &ResourceUri{group: "demo", version: "v2", kind: "artist", resourceName: "elvis"} - resource2 := createResource(t, handler, resourceUri2) - - rsp := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/demo/v2/artist?partition=default&peer_name=local&namespace=default", strings.NewReader("")) - - req.Header.Add("x-consul-token", testACLTokenArtistListPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - - resources, _ := result["resources"].([]any) - require.Len(t, resources, 2) - - expected := []map[string]any{resource1, resource2} - require.Contains(t, expected, resources[0]) - require.Contains(t, expected, resources[1]) - - // clean up - deleteResource(t, handler, resourceUri1) - deleteResource(t, handler, resourceUri2) - }) - - t.Run("should return empty list when no resources are found", func(t *testing.T) { - rsp := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/demo/v2/artist?partition=default&peer_name=local&namespace=default", strings.NewReader("")) - - req.Header.Add("x-consul-token", testACLTokenArtistListPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - - resources, _ := result["resources"].([]any) - require.Len(t, resources, 0) - }) - - t.Run("should return empty list when name prefix matches don't match", func(t *testing.T) { - createResource(t, handler, nil) - - rsp := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/demo/v2/artist?partition=default&peer_name=local&namespace=default&name_prefix=noname", strings.NewReader("")) - - req.Header.Add("x-consul-token", testACLTokenArtistListPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - - resources, _ := result["resources"].([]any) - require.Len(t, resources, 0) - - // clean up - deleteResource(t, handler, nil) - }) - - t.Run("should return list of resources matching name prefix", func(t *testing.T) { - resourceUri1 := &ResourceUri{group: "demo", version: "v2", kind: "artist", resourceName: "steve"} - resource1 := createResource(t, handler, resourceUri1) - resourceUri2 := &ResourceUri{group: "demo", version: "v2", kind: "artist", resourceName: "elvis"} - createResource(t, handler, resourceUri2) - - rsp := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/demo/v2/artist?partition=default&peer_name=local&namespace=default&name_prefix=steve", strings.NewReader("")) - - req.Header.Add("x-consul-token", testACLTokenArtistListPolicy) - - handler.ServeHTTP(rsp, req) - - require.Equal(t, http.StatusOK, rsp.Result().StatusCode) - - var result map[string]any - require.NoError(t, json.NewDecoder(rsp.Body).Decode(&result)) - - resources, _ := result["resources"].([]any) - require.Len(t, resources, 1) - - require.Equal(t, resource1, resources[0]) - - // clean up - deleteResource(t, handler, resourceUri1) - deleteResource(t, handler, resourceUri2) - }) -} diff --git a/internal/resource/mappers/bimapper/bimapper.go b/internal/resource/mappers/bimapper/bimapper.go deleted file mode 100644 index f1c2f5122676e..0000000000000 --- a/internal/resource/mappers/bimapper/bimapper.go +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package bimapper - -import ( - "context" - "fmt" - "sync" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -var wildcardType = &pbresource.Type{ - Group: "@@any@@", - GroupVersion: "@@any@@", - Kind: "@@any@@", -} - -// Mapper tracks bidirectional lookup for an item that contains references to -// other items. For example: an HTTPRoute has many references to Services. -// -// The primary object is called the "item" and an item has many "links". -// Tracking is done on items. -type Mapper struct { - itemType, linkType *pbresource.Type - wildcardLink bool - - lock sync.Mutex - itemToLink map[resource.ReferenceKey]map[resource.ReferenceKey]struct{} - linkToItem map[resource.ReferenceKey]map[resource.ReferenceKey]struct{} -} - -// New creates a bimapper between the two required provided types. -func New(itemType, linkType *pbresource.Type) *Mapper { - if itemType == nil { - panic("itemType is required") - } - if linkType == nil { - panic("linkType is required") - } - return &Mapper{ - itemType: itemType, - linkType: linkType, - itemToLink: make(map[resource.ReferenceKey]map[resource.ReferenceKey]struct{}), - linkToItem: make(map[resource.ReferenceKey]map[resource.ReferenceKey]struct{}), - } -} - -// NewWithWildcardLinkType creates a bimapper between the provided item type -// and can have a mixed set of link types. -func NewWithWildcardLinkType(itemType *pbresource.Type) *Mapper { - m := New(itemType, wildcardType) - m.wildcardLink = true - return m -} - -// Reset clears the internal mappings. -func (m *Mapper) Reset() { - m.lock.Lock() - defer m.lock.Unlock() - m.itemToLink = make(map[resource.ReferenceKey]map[resource.ReferenceKey]struct{}) - m.linkToItem = make(map[resource.ReferenceKey]map[resource.ReferenceKey]struct{}) -} - -// IsEmpty returns true if the internal structures are empty. -func (m *Mapper) IsEmpty() bool { - m.lock.Lock() - defer m.lock.Unlock() - return len(m.itemToLink) == 0 && len(m.linkToItem) == 0 -} - -// UntrackItem removes tracking for the provided item. The item type MUST match -// the type configured for the item. -func (m *Mapper) UntrackItem(item resource.ReferenceOrID) { - if !resource.EqualType(item.GetType(), m.itemType) { - panic(fmt.Sprintf("expected item type %q got %q", - resource.TypeToString(m.itemType), - resource.TypeToString(item.GetType()), - )) - } - m.untrackItem(resource.NewReferenceKey(item)) -} - -// UntrackLink removes tracking for the provided link. The link type MUST match -// the type configured for the link. -func (m *Mapper) UntrackLink(link resource.ReferenceOrID) { - if !m.wildcardLink && !resource.EqualType(link.GetType(), m.linkType) { - panic(fmt.Sprintf("expected link type %q got %q", - resource.TypeToString(m.linkType), - resource.TypeToString(link.GetType()), - )) - } - m.untrackLink(resource.NewReferenceKey(link)) -} - -func (m *Mapper) untrackLink(link resource.ReferenceKey) { - m.lock.Lock() - defer m.lock.Unlock() - m.removeLinkLocked(link) -} - -func (m *Mapper) untrackItem(item resource.ReferenceKey) { - m.lock.Lock() - defer m.lock.Unlock() - m.removeItemLocked(item) -} - -// TrackItem adds tracking for the provided item. The item and link types MUST -// match the types configured for the items and links. -func (m *Mapper) TrackItem(item resource.ReferenceOrID, links []resource.ReferenceOrID) { - if !resource.EqualType(item.GetType(), m.itemType) { - panic(fmt.Sprintf("expected item type %q got %q", - resource.TypeToString(m.itemType), - resource.TypeToString(item.GetType()), - )) - } - - linksAsKeys := make([]resource.ReferenceKey, 0, len(links)) - for _, link := range links { - if !m.wildcardLink && !resource.EqualType(link.GetType(), m.linkType) { - panic(fmt.Sprintf("expected link type %q got %q", - resource.TypeToString(m.linkType), - resource.TypeToString(link.GetType()), - )) - } - linksAsKeys = append(linksAsKeys, resource.NewReferenceKey(link)) - } - - m.trackItem(resource.NewReferenceKey(item), linksAsKeys) -} - -func (m *Mapper) trackItem(item resource.ReferenceKey, links []resource.ReferenceKey) { - m.lock.Lock() - defer m.lock.Unlock() - - m.removeItemLocked(item) - m.addItemLocked(item, links) -} - -// you must hold the lock before calling this function -func (m *Mapper) removeItemLocked(item resource.ReferenceKey) { - for link := range m.itemToLink[item] { - delete(m.linkToItem[link], item) - if len(m.linkToItem[link]) == 0 { - delete(m.linkToItem, link) - } - } - delete(m.itemToLink, item) -} - -func (m *Mapper) removeLinkLocked(link resource.ReferenceKey) { - for item := range m.linkToItem[link] { - delete(m.itemToLink[item], link) - if len(m.itemToLink[item]) == 0 { - delete(m.itemToLink, item) - } - } - delete(m.linkToItem, link) -} - -// you must hold the lock before calling this function -func (m *Mapper) addItemLocked(item resource.ReferenceKey, links []resource.ReferenceKey) { - if m.itemToLink[item] == nil { - m.itemToLink[item] = make(map[resource.ReferenceKey]struct{}) - } - for _, link := range links { - m.itemToLink[item][link] = struct{}{} - - if m.linkToItem[link] == nil { - m.linkToItem[link] = make(map[resource.ReferenceKey]struct{}) - } - m.linkToItem[link][item] = struct{}{} - } -} - -// LinksForItem returns references to links related to the requested item. -// Deprecated: use LinksRefs -func (m *Mapper) LinksForItem(item *pbresource.ID) []*pbresource.Reference { - return m.LinkRefsForItem(item) -} - -// LinkRefsForItem returns references to links related to the requested item. -func (m *Mapper) LinkRefsForItem(item *pbresource.ID) []*pbresource.Reference { - if !resource.EqualType(item.Type, m.itemType) { - panic(fmt.Sprintf("expected item type %q got %q", - resource.TypeToString(m.itemType), - resource.TypeToString(item.Type), - )) - } - - m.lock.Lock() - defer m.lock.Unlock() - - links, ok := m.itemToLink[resource.NewReferenceKey(item)] - if !ok { - return nil - } - - out := make([]*pbresource.Reference, 0, len(links)) - for link := range links { - out = append(out, link.ToReference()) - } - return out -} - -// LinkIDsForItem returns IDs to links related to the requested item. -func (m *Mapper) LinkIDsForItem(item *pbresource.ID) []*pbresource.ID { - if !resource.EqualType(item.Type, m.itemType) { - panic(fmt.Sprintf("expected item type %q got %q", - resource.TypeToString(m.itemType), - resource.TypeToString(item.Type), - )) - } - - m.lock.Lock() - defer m.lock.Unlock() - - links, ok := m.itemToLink[resource.NewReferenceKey(item)] - if !ok { - return nil - } - - out := make([]*pbresource.ID, 0, len(links)) - for l := range links { - out = append(out, l.ToID()) - } - return out -} - -// ItemsForLink returns item ids for items related to the provided link. -// Deprecated: use ItemIDsForLink -func (m *Mapper) ItemsForLink(link *pbresource.ID) []*pbresource.ID { - return m.ItemIDsForLink(link) -} - -// ItemIDsForLink returns item ids for items related to the provided link. -func (m *Mapper) ItemIDsForLink(link resource.ReferenceOrID) []*pbresource.ID { - if !m.wildcardLink && !resource.EqualType(link.GetType(), m.linkType) { - panic(fmt.Sprintf("expected link type %q got %q", - resource.TypeToString(m.linkType), - resource.TypeToString(link.GetType()), - )) - } - - return m.itemIDsByLink(resource.NewReferenceKey(link)) -} - -// ItemRefsForLink returns item references for items related to the provided link. -func (m *Mapper) ItemRefsForLink(link resource.ReferenceOrID) []*pbresource.Reference { - if !m.wildcardLink && !resource.EqualType(link.GetType(), m.linkType) { - panic(fmt.Sprintf("expected link type %q got %q", - resource.TypeToString(m.linkType), - resource.TypeToString(link.GetType()), - )) - } - - return m.itemRefsByLink(resource.NewReferenceKey(link)) -} - -// MapLink is suitable as a DependencyMapper to map the provided link event to its item. -func (m *Mapper) MapLink(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) { - link := res.Id - - if !m.wildcardLink && !resource.EqualType(link.Type, m.linkType) { - return nil, fmt.Errorf("expected type %q got %q", - resource.TypeToString(m.linkType), - resource.TypeToString(link.Type), - ) - } - - itemIDs := m.itemIDsByLink(resource.NewReferenceKey(link)) - - out := make([]controller.Request, 0, len(itemIDs)) - for _, item := range itemIDs { - if !resource.EqualType(item.Type, m.itemType) { - return nil, fmt.Errorf("expected type %q got %q", - resource.TypeToString(m.itemType), - resource.TypeToString(item.Type), - ) - } - out = append(out, controller.Request{ID: item}) - } - return out, nil -} - -func (m *Mapper) itemIDsByLink(link resource.ReferenceKey) []*pbresource.ID { - // a lock must be held both to read item from the map and to read the - // the returned items. - m.lock.Lock() - defer m.lock.Unlock() - - items, ok := m.linkToItem[link] - if !ok { - return nil - } - - out := make([]*pbresource.ID, 0, len(items)) - for item := range items { - out = append(out, item.ToID()) - } - return out -} - -func (m *Mapper) itemRefsByLink(link resource.ReferenceKey) []*pbresource.Reference { - // a lock must be held both to read item from the map and to read the - // the returned items. - m.lock.Lock() - defer m.lock.Unlock() - - items, ok := m.linkToItem[link] - if !ok { - return nil - } - - out := make([]*pbresource.Reference, 0, len(items)) - for item := range items { - out = append(out, item.ToReference()) - } - return out -} diff --git a/internal/resource/mappers/bimapper/bimapper_test.go b/internal/resource/mappers/bimapper/bimapper_test.go deleted file mode 100644 index 00dac874bc303..0000000000000 --- a/internal/resource/mappers/bimapper/bimapper_test.go +++ /dev/null @@ -1,489 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package bimapper - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -const ( - fakeGroupName = "catalog" - fakeVersion = "v1" -) - -var ( - fakeFooType = &pbresource.Type{ - Group: fakeGroupName, - GroupVersion: fakeVersion, - Kind: "Foo", - } - fakeBarType = &pbresource.Type{ - Group: fakeGroupName, - GroupVersion: fakeVersion, - Kind: "Bar", - } - fakeBazType = &pbresource.Type{ - Group: fakeGroupName, - GroupVersion: fakeVersion, - Kind: "Baz", - } -) - -func TestMapper(t *testing.T) { - // Create an advance pointer to some services. - - randoSvc := rtest.Resource(fakeBarType, "rando").WithTenancy(resource.DefaultNamespacedTenancy()).Build() - apiSvc := rtest.Resource(fakeBarType, "api").WithTenancy(resource.DefaultNamespacedTenancy()).Build() - fooSvc := rtest.Resource(fakeBarType, "foo").WithTenancy(resource.DefaultNamespacedTenancy()).Build() - barSvc := rtest.Resource(fakeBarType, "bar").WithTenancy(resource.DefaultNamespacedTenancy()).Build() - wwwSvc := rtest.Resource(fakeBarType, "www").WithTenancy(resource.DefaultNamespacedTenancy()).Build() - - apiRef := newRef(fakeBarType, "api") - fooRef := newRef(fakeBarType, "foo") - barRef := newRef(fakeBarType, "bar") - wwwRef := newRef(fakeBarType, "www") - - fail1 := rtest.Resource(fakeFooType, "api").WithTenancy(resource.DefaultNamespacedTenancy()).Build() - fail1Refs := []resource.ReferenceOrID{ - apiRef, - fooRef, - barRef, - } - - fail2 := rtest.Resource(fakeFooType, "www").WithTenancy(resource.DefaultNamespacedTenancy()).Build() - fail2Refs := []resource.ReferenceOrID{ - wwwRef, - fooRef, - } - - fail1UpdatedRefs := []resource.ReferenceOrID{ - apiRef, - barRef, - } - - m := New(fakeFooType, fakeBarType) - - // Nothing tracked yet so we assume nothing. - requireLinksForItem(t, m, fail1.Id) - requireLinksForItem(t, m, fail2.Id) - requireItemsForLink(t, m, apiRef) - requireItemsForLink(t, m, fooRef) - requireItemsForLink(t, m, barRef) - requireItemsForLink(t, m, wwwRef) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc) - requireServicesTracked(t, m, fooSvc) - requireServicesTracked(t, m, barSvc) - requireServicesTracked(t, m, wwwSvc) - - // no-ops - m.UntrackItem(fail1.Id) - - // still nothing - requireLinksForItem(t, m, fail1.Id) - requireLinksForItem(t, m, fail2.Id) - requireItemsForLink(t, m, apiRef) - requireItemsForLink(t, m, fooRef) - requireItemsForLink(t, m, barRef) - requireItemsForLink(t, m, wwwRef) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc) - requireServicesTracked(t, m, fooSvc) - requireServicesTracked(t, m, barSvc) - requireServicesTracked(t, m, wwwSvc) - - // Actually insert some data. - m.TrackItem(fail1.Id, fail1Refs) - - // Check links mapping - requireLinksForItem(t, m, fail1.Id, fail1Refs...) - - requireLinksForItem(t, m, fail1.Id, fail1Refs...) - requireItemsForLink(t, m, apiRef, fail1.Id) - requireItemsForLink(t, m, fooRef, fail1.Id) - requireItemsForLink(t, m, barRef, fail1.Id) - requireItemsForLink(t, m, wwwRef) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc, fail1.Id) - requireServicesTracked(t, m, fooSvc, fail1.Id) - requireServicesTracked(t, m, barSvc, fail1.Id) - requireServicesTracked(t, m, wwwSvc) - - // track it again, no change - m.TrackItem(fail1.Id, fail1Refs) - - requireLinksForItem(t, m, fail1.Id, fail1Refs...) - requireItemsForLink(t, m, apiRef, fail1.Id) - requireItemsForLink(t, m, fooRef, fail1.Id) - requireItemsForLink(t, m, barRef, fail1.Id) - requireItemsForLink(t, m, wwwRef) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc, fail1.Id) - requireServicesTracked(t, m, fooSvc, fail1.Id) - requireServicesTracked(t, m, barSvc, fail1.Id) - requireServicesTracked(t, m, wwwSvc) - - // track new one that overlaps slightly - m.TrackItem(fail2.Id, fail2Refs) - - // Check links mapping for the new one - requireLinksForItem(t, m, fail1.Id, fail1Refs...) - requireLinksForItem(t, m, fail2.Id, fail2Refs...) - requireItemsForLink(t, m, apiRef, fail1.Id) - requireItemsForLink(t, m, fooRef, fail1.Id, fail2.Id) - requireItemsForLink(t, m, barRef, fail1.Id) - requireItemsForLink(t, m, wwwRef, fail2.Id) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc, fail1.Id) - requireServicesTracked(t, m, fooSvc, fail1.Id, fail2.Id) - requireServicesTracked(t, m, barSvc, fail1.Id) - requireServicesTracked(t, m, wwwSvc, fail2.Id) - - // update the original to change it - m.TrackItem(fail1.Id, fail1UpdatedRefs) - - requireLinksForItem(t, m, fail1.Id, fail1UpdatedRefs...) - requireLinksForItem(t, m, fail2.Id, fail2Refs...) - requireItemsForLink(t, m, apiRef, fail1.Id) - requireItemsForLink(t, m, fooRef, fail2.Id) - requireItemsForLink(t, m, barRef, fail1.Id) - requireItemsForLink(t, m, wwwRef, fail2.Id) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc, fail1.Id) - requireServicesTracked(t, m, fooSvc, fail2.Id) - requireServicesTracked(t, m, barSvc, fail1.Id) - requireServicesTracked(t, m, wwwSvc, fail2.Id) - - // delete the original - m.UntrackItem(fail1.Id) - - requireLinksForItem(t, m, fail1.Id) - requireLinksForItem(t, m, fail2.Id, fail2Refs...) - requireItemsForLink(t, m, apiRef) - requireItemsForLink(t, m, fooRef, fail2.Id) - requireItemsForLink(t, m, barRef) - requireItemsForLink(t, m, wwwRef, fail2.Id) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc) - requireServicesTracked(t, m, fooSvc, fail2.Id) - requireServicesTracked(t, m, barSvc) - requireServicesTracked(t, m, wwwSvc, fail2.Id) - - // delete the link - m.UntrackLink(newRef(fakeBarType, "www")) - - requireLinksForItem(t, m, fail2.Id, newRef(fakeBarType, "foo")) - - m.UntrackLink(newRef(fakeBarType, "foo")) - - requireLinksForItem(t, m, fail2.Id) - - // delete another item - m.UntrackItem(fail2.Id) - - requireLinksForItem(t, m, fail1.Id) - requireLinksForItem(t, m, fail2.Id) - requireItemsForLink(t, m, apiRef) - requireItemsForLink(t, m, fooRef) - requireItemsForLink(t, m, barRef) - requireItemsForLink(t, m, wwwRef) - - requireServicesTracked(t, m, randoSvc) - requireServicesTracked(t, m, apiSvc) - requireServicesTracked(t, m, fooSvc) - requireServicesTracked(t, m, barSvc) - requireServicesTracked(t, m, wwwSvc) - - // Reset the mapper and check that its internal maps are empty. - m.Reset() - require.True(t, m.IsEmpty()) -} - -func TestMapper_Wildcard(t *testing.T) { - bar1Ref := newRef(fakeBarType, "uno") - bar2Ref := newRef(fakeBarType, "dos") - - baz1Ref := newRef(fakeBazType, "uno") - baz2Ref := newRef(fakeBazType, "dos") - - m := NewWithWildcardLinkType(fakeFooType) - - foo1 := rtest.Resource(fakeFooType, "foo1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - foo1Refs := []resource.ReferenceOrID{ - bar1Ref, - baz1Ref, - } - - foo2 := rtest.Resource(fakeFooType, "foo2"). - WithTenancy(resource.DefaultNamespacedTenancy()). - Build() - foo2Refs := []resource.ReferenceOrID{ - bar1Ref, - bar2Ref, - baz2Ref, - } - foo2UpdatedRefs := []resource.ReferenceOrID{ - bar2Ref, - baz2Ref, - } - - // Nothing tracked yet so we assume nothing. - requireLinksForItem(t, m, foo1.Id) - requireLinksForItem(t, m, foo2.Id) - requireItemsForLink(t, m, bar1Ref) - requireItemsForLink(t, m, bar2Ref) - requireItemsForLink(t, m, baz1Ref) - requireItemsForLink(t, m, baz2Ref) - - // no-ops - m.UntrackItem(foo1.Id) - - // still nothing - requireLinksForItem(t, m, foo1.Id) - requireLinksForItem(t, m, foo2.Id) - requireItemsForLink(t, m, bar1Ref) - requireItemsForLink(t, m, bar2Ref) - requireItemsForLink(t, m, baz1Ref) - requireItemsForLink(t, m, baz2Ref) - - // Actually insert some data. - m.TrackItem(foo1.Id, foo1Refs) - - // Check links mapping - requireLinksForItem(t, m, foo1.Id, foo1Refs...) - requireItemsForLink(t, m, bar1Ref, foo1.Id) - requireItemsForLink(t, m, bar2Ref) - requireItemsForLink(t, m, baz1Ref, foo1.Id) - requireItemsForLink(t, m, baz2Ref) - - // track it again, no change - m.TrackItem(foo1.Id, foo1Refs) - - requireLinksForItem(t, m, foo1.Id, foo1Refs...) - requireItemsForLink(t, m, bar1Ref, foo1.Id) - requireItemsForLink(t, m, bar2Ref) - requireItemsForLink(t, m, baz1Ref, foo1.Id) - requireItemsForLink(t, m, baz2Ref) - - // track new one that overlaps slightly - m.TrackItem(foo2.Id, foo2Refs) - - // Check links mapping for the new one - requireLinksForItem(t, m, foo1.Id, foo1Refs...) - requireLinksForItem(t, m, foo2.Id, foo2Refs...) - requireItemsForLink(t, m, bar1Ref, foo1.Id, foo2.Id) - requireItemsForLink(t, m, bar2Ref, foo2.Id) - requireItemsForLink(t, m, baz1Ref, foo1.Id) - requireItemsForLink(t, m, baz2Ref, foo2.Id) - - // update the original to change it - m.TrackItem(foo2.Id, foo2UpdatedRefs) - - requireLinksForItem(t, m, foo1.Id, foo1Refs...) - requireLinksForItem(t, m, foo2.Id, foo2UpdatedRefs...) - requireItemsForLink(t, m, bar1Ref, foo1.Id) - requireItemsForLink(t, m, bar2Ref, foo2.Id) - requireItemsForLink(t, m, baz1Ref, foo1.Id) - requireItemsForLink(t, m, baz2Ref, foo2.Id) - - // delete the original - m.UntrackItem(foo1.Id) - - requireLinksForItem(t, m, foo1.Id) - requireLinksForItem(t, m, foo2.Id, foo2UpdatedRefs...) - requireItemsForLink(t, m, bar1Ref) - requireItemsForLink(t, m, bar2Ref, foo2.Id) - requireItemsForLink(t, m, baz1Ref) - requireItemsForLink(t, m, baz2Ref, foo2.Id) - - // delete the link - m.UntrackLink(baz2Ref) - - foo2DoubleUpdatedRefs := []resource.ReferenceOrID{ - bar2Ref, - } - - requireLinksForItem(t, m, foo1.Id) - requireLinksForItem(t, m, foo2.Id, foo2DoubleUpdatedRefs...) - requireItemsForLink(t, m, bar1Ref) - requireItemsForLink(t, m, bar2Ref, foo2.Id) - requireItemsForLink(t, m, baz1Ref) - requireItemsForLink(t, m, baz2Ref) - - // delete another item - m.UntrackItem(foo2.Id) - - requireLinksForItem(t, m, foo1.Id) - requireLinksForItem(t, m, foo2.Id) - requireItemsForLink(t, m, bar1Ref) - requireItemsForLink(t, m, bar2Ref) - requireItemsForLink(t, m, baz1Ref) - requireItemsForLink(t, m, baz2Ref) - - // Reset the mapper and check that its internal maps are empty. - m.Reset() - require.True(t, m.IsEmpty()) -} - -func TestPanics(t *testing.T) { - t.Run("new mapper without types", func(t *testing.T) { - require.PanicsWithValue(t, "itemType is required", func() { - New(nil, nil) - }) - - require.PanicsWithValue(t, "itemType is required", func() { - New(nil, fakeBarType) - }) - - require.PanicsWithValue(t, "linkType is required", func() { - New(fakeFooType, nil) - }) - }) - - t.Run("UntrackItem: mismatched type", func(t *testing.T) { - m := New(fakeFooType, fakeBarType) - require.PanicsWithValue(t, "expected item type \"catalog.v1.Foo\" got \"catalog.v1.Bar\"", func() { - // Calling UntrackItem with link type instead of item type - m.UntrackItem(rtest.Resource(fakeBarType, "test").ID()) - }) - }) - - t.Run("TrackItem: mismatched item type", func(t *testing.T) { - m := New(fakeFooType, fakeBarType) - require.PanicsWithValue(t, "expected item type \"catalog.v1.Foo\" got \"catalog.v1.Bar\"", func() { - // Calling UntrackItem with link type instead of item type - m.TrackItem(rtest.Resource(fakeBarType, "test").ID(), nil) - }) - }) - - t.Run("TrackItem: mismatched link type", func(t *testing.T) { - m := New(fakeFooType, fakeBarType) - require.PanicsWithValue(t, "expected link type \"catalog.v1.Bar\" got \"catalog.v1.Foo\"", func() { - // Calling UntrackItem with link type instead of item type - links := []resource.ReferenceOrID{ - rtest.Resource(fakeFooType, "link").ID(), - } - m.TrackItem(rtest.Resource(fakeFooType, "test").ID(), links) - }) - }) - - t.Run("UntrackLink: mismatched type", func(t *testing.T) { - m := New(fakeFooType, fakeBarType) - require.PanicsWithValue(t, "expected link type \"catalog.v1.Bar\" got \"catalog.v1.Foo\"", func() { - m.UntrackLink(rtest.Resource(fakeFooType, "test").ID()) - }) - }) - - t.Run("LinkRefsForItem: mismatched type", func(t *testing.T) { - m := New(fakeFooType, fakeBarType) - require.PanicsWithValue(t, "expected item type \"catalog.v1.Foo\" got \"catalog.v1.Bar\"", func() { - m.LinkRefsForItem(rtest.Resource(fakeBarType, "test").ID()) - }) - }) - - t.Run("LinkRefsForItem: mismatched type", func(t *testing.T) { - m := New(fakeFooType, fakeBarType) - require.PanicsWithValue(t, "expected item type \"catalog.v1.Foo\" got \"catalog.v1.Bar\"", func() { - m.LinkIDsForItem(rtest.Resource(fakeBarType, "test").ID()) - }) - }) - - t.Run("ItemRefsForLink: mismatched type", func(t *testing.T) { - m := New(fakeFooType, fakeBarType) - require.PanicsWithValue(t, "expected link type \"catalog.v1.Bar\" got \"catalog.v1.Foo\"", func() { - m.ItemRefsForLink(rtest.Resource(fakeFooType, "test").ID()) - }) - }) - - t.Run("ItemIDsForLink: mismatched type", func(t *testing.T) { - m := New(fakeFooType, fakeBarType) - require.PanicsWithValue(t, "expected link type \"catalog.v1.Bar\" got \"catalog.v1.Foo\"", func() { - m.ItemIDsForLink(rtest.Resource(fakeFooType, "test").ID()) - }) - }) -} - -func requireServicesTracked(t *testing.T, mapper *Mapper, link *pbresource.Resource, items ...*pbresource.ID) { - t.Helper() - - reqs, err := mapper.MapLink( - context.Background(), - controller.Runtime{}, - link, - ) - require.NoError(t, err) - - require.Len(t, reqs, len(items)) - - // Also check items IDs and Refs for link. - ids := mapper.ItemIDsForLink(link.Id) - require.Len(t, ids, len(items)) - - refs := mapper.ItemRefsForLink(link.Id) - require.Len(t, refs, len(items)) - - for _, item := range items { - prototest.AssertContainsElement(t, reqs, controller.Request{ID: item}) - prototest.AssertContainsElement(t, ids, item) - prototest.AssertContainsElement(t, refs, resource.Reference(item, "")) - } -} - -func requireItemsForLink(t *testing.T, mapper *Mapper, link *pbresource.Reference, items ...*pbresource.ID) { - t.Helper() - - got := mapper.ItemIDsForLink(resource.IDFromReference(link)) - - prototest.AssertElementsMatch(t, items, got) -} - -func requireLinksForItem(t *testing.T, mapper *Mapper, item *pbresource.ID, links ...resource.ReferenceOrID) { - t.Helper() - - var expLinkRefs []*pbresource.Reference - var expLinkIDs []*pbresource.ID - - for _, l := range links { - expLinkRefs = append(expLinkRefs, &pbresource.Reference{ - Name: l.GetName(), - Tenancy: l.GetTenancy(), - Type: l.GetType(), - }) - expLinkIDs = append(expLinkIDs, &pbresource.ID{ - Name: l.GetName(), - Tenancy: l.GetTenancy(), - Type: l.GetType(), - }) - } - - refs := mapper.LinkRefsForItem(item) - require.Len(t, refs, len(links)) - prototest.AssertElementsMatch(t, expLinkRefs, refs) - - ids := mapper.LinkIDsForItem(item) - require.Len(t, refs, len(links)) - prototest.AssertElementsMatch(t, expLinkIDs, ids) -} - -func newRef(typ *pbresource.Type, name string) *pbresource.Reference { - return rtest.Resource(typ, name).WithTenancy(resource.DefaultNamespacedTenancy()).Reference("") -} diff --git a/internal/resource/mappers/selectiontracker/selection_tracker_test.go b/internal/resource/mappers/selectiontracker/selection_tracker_test.go deleted file mode 100644 index 345ac848ab40a..0000000000000 --- a/internal/resource/mappers/selectiontracker/selection_tracker_test.go +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package selectiontracker - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/radix" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -var ( - workloadData = &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - { - Host: "198.18.0.1", - }, - }, - Ports: map[string]*pbcatalog.WorkloadPort{ - "http": { - Port: 8080, - Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, - }, - }, - } - - tenancyCases = map[string]*pbresource.Tenancy{ - "default": resource.DefaultNamespacedTenancy(), - "bar ns, default partition, local peer": { - Partition: "default", - Namespace: "bar", - PeerName: "local", - }, - "default ns, baz partition, local peer": { - Partition: "baz", - Namespace: "default", - PeerName: "local", - }, - "bar ns, baz partition, local peer": { - Partition: "baz", - Namespace: "bar", - PeerName: "local", - }, - "bar ns, baz partition, non-local peer": { - Partition: "baz", - Namespace: "bar", - PeerName: "non-local", - }, - } -) - -func TestRemoveIDFromTreeAtPaths(t *testing.T) { - tree := radix.New[[]*pbresource.ID]() - - tenancy := resource.DefaultNamespacedTenancy() - toRemove := rtest.Resource(pbcatalog.ServiceEndpointsType, "blah").WithTenancy(tenancy).ID() - other1 := rtest.Resource(pbcatalog.ServiceEndpointsType, "other1").WithTenancy(tenancy).ID() - other2 := rtest.Resource(pbcatalog.ServiceEndpointsType, "other2").WithTenancy(tenancy).ID() - - // we are trying to create a tree such that removal of the toRemove id causes a - // few things to happen. - // - // * All the slice modification conditions are executed - // - removal from beginning of the list - // - removal from the end of the list - // - removal of only element in the list - // - removal from middle of the list - // * Paths without matching ids are ignored - - notMatching := []*pbresource.ID{ - other1, - other2, - } - - matchAtBeginning := []*pbresource.ID{ - toRemove, - other1, - other2, - } - - // For this case, we only add one other not matching to test that we don't remove - // non-matching ones. - matchAtEnd := []*pbresource.ID{ - other1, - toRemove, - } - - matchInMiddle := []*pbresource.ID{ - other1, - toRemove, - other2, - } - - matchOnly := []*pbresource.ID{ - toRemove, - } - - noMatchKey := treePathFromNameOrPrefix(tenancy, "no-match") - matchBeginningKey := treePathFromNameOrPrefix(tenancy, "match-beginning") - matchEndKey := treePathFromNameOrPrefix(tenancy, "match-end") - matchMiddleKey := treePathFromNameOrPrefix(tenancy, "match-middle") - matchOnlyKey := treePathFromNameOrPrefix(tenancy, "match-only") - - tree.Insert(noMatchKey, notMatching) - tree.Insert(matchBeginningKey, matchAtBeginning) - tree.Insert(matchEndKey, matchAtEnd) - tree.Insert(matchMiddleKey, matchInMiddle) - tree.Insert(matchOnlyKey, matchOnly) - - removeIDFromTreeAtPaths(tree, toRemove, []string{ - noMatchKey, - matchBeginningKey, - matchEndKey, - matchMiddleKey, - matchOnlyKey, - }) - - reqs, found := tree.Get(noMatchKey) - require.True(t, found) - require.Equal(t, notMatching, reqs) - - reqs, found = tree.Get(matchBeginningKey) - require.True(t, found) - require.Equal(t, notMatching, reqs) - - reqs, found = tree.Get(matchEndKey) - require.True(t, found) - require.Equal(t, []*pbresource.ID{other1}, reqs) - - reqs, found = tree.Get(matchMiddleKey) - require.True(t, found) - require.Equal(t, notMatching, reqs) - - // The last tracked request should cause removal from the tree - _, found = tree.Get(matchOnlyKey) - require.False(t, found) -} - -type selectionTrackerSuite struct { - suite.Suite - - rt controller.Runtime - tracker *WorkloadSelectionTracker - - // The test setup adds resources with various tenancy settings. Because tenancies are stored in a map, - // it adds "free" order randomization, and so we need to remember the order in which those tenancy were executed. - executedTenancies []*pbresource.Tenancy - - endpointsFoo []*pbresource.ID - endpointsBar []*pbresource.ID - workloadsAPI []*pbresource.Resource - workloadsWeb []*pbresource.Resource -} - -func (suite *selectionTrackerSuite) SetupTest() { - suite.tracker = New() - - for _, tenancy := range tenancyCases { - suite.executedTenancies = append(suite.executedTenancies, tenancy) - - endpointsFooID := rtest.Resource(pbcatalog.ServiceEndpointsType, "foo"). - WithTenancy(tenancy).ID() - suite.endpointsFoo = append(suite.endpointsFoo, endpointsFooID) - - endpointsBarID := rtest.Resource(pbcatalog.ServiceEndpointsType, "bar"). - WithTenancy(tenancy).ID() - suite.endpointsBar = append(suite.endpointsBar, endpointsBarID) - - suite.workloadsAPI = append(suite.workloadsAPI, rtest.Resource(pbcatalog.WorkloadType, "api-1"). - WithData(suite.T(), workloadData). - WithTenancy(tenancy). - Build()) - suite.workloadsWeb = append(suite.workloadsWeb, rtest.Resource(pbcatalog.WorkloadType, "web-1"). - WithData(suite.T(), workloadData). - WithTenancy(tenancy). - Build()) - } -} - -func (suite *selectionTrackerSuite) TearDownTest() { - suite.executedTenancies = nil - suite.workloadsAPI = nil - suite.workloadsWeb = nil - suite.endpointsFoo = nil - suite.endpointsBar = nil -} - -func (suite *selectionTrackerSuite) requireMappedIDs(t *testing.T, workload *pbresource.Resource, ids ...*pbresource.ID) { - t.Helper() - - reqs, err := suite.tracker.MapWorkload(context.Background(), suite.rt, workload) - require.NoError(suite.T(), err) - require.Len(t, reqs, len(ids)) - for _, id := range ids { - prototest.AssertContainsElement(t, reqs, controller.Request{ID: id}) - } -} - -func (suite *selectionTrackerSuite) requireMappedIDsAllTenancies(t *testing.T, workloads []*pbresource.Resource, ids ...[]*pbresource.ID) { - t.Helper() - - for i := range suite.executedTenancies { - reqs, err := suite.tracker.MapWorkload(context.Background(), suite.rt, workloads[i]) - require.NoError(suite.T(), err) - require.Len(t, reqs, len(ids)) - for _, id := range ids { - prototest.AssertContainsElement(t, reqs, controller.Request{ID: id[i]}) - } - } -} - -func (suite *selectionTrackerSuite) trackIDForSelectorInAllTenancies(ids []*pbresource.ID, selector *pbcatalog.WorkloadSelector) { - suite.T().Helper() - - for i := range suite.executedTenancies { - suite.tracker.TrackIDForSelector(ids[i], selector) - } -} - -func (suite *selectionTrackerSuite) TestMapWorkload_Empty() { - // If we aren't tracking anything than the default mapping behavior - // should be to return an empty list of requests. - suite.requireMappedIDs(suite.T(), - rtest.Resource(pbcatalog.WorkloadType, "api-1").WithData(suite.T(), workloadData).Build()) -} - -func (suite *selectionTrackerSuite) TestUntrackID_Empty() { - // this test has no assertions but mainly is here to prove that things - // don't explode if this is attempted. - suite.tracker.UntrackID(rtest.Resource(pbcatalog.ServiceEndpointsType, "foo").ID()) -} - -func (suite *selectionTrackerSuite) TestTrackAndMap_SingleResource_MultipleWorkloadMappings() { - // This test aims to prove that tracking a resources workload selector and - // then mapping a workload back to that resource works as expected when the - // result set is a single resource. This test will ensure that both prefix - // and exact match criteria are handle correctly and that one resource - // can be mapped from multiple distinct workloads. - - // Create resources for the test and track endpoints. - suite.trackIDForSelectorInAllTenancies(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ - Names: []string{"bar", "api", "web-1"}, - Prefixes: []string{"api-"}, - }) - - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsAPI, suite.endpointsFoo) - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsWeb, suite.endpointsFoo) -} - -func (suite *selectionTrackerSuite) TestTrackAndMap_MultiResource_SingleWorkloadMapping() { - // This test aims to prove that multiple resources selecting of a workload - // will result in multiple requests when mapping that workload. - - cases := map[string]struct { - selector *pbcatalog.WorkloadSelector - }{ - "names": { - selector: &pbcatalog.WorkloadSelector{ - Names: []string{"api-1"}, - }, - }, - "prefixes": { - selector: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api"}, - }, - }, - } - - for name, c := range cases { - suite.T().Run(name, func(t *testing.T) { - for i := range suite.executedTenancies { - // associate the foo endpoints with some workloads - suite.tracker.TrackIDForSelector(suite.endpointsFoo[i], c.selector) - - // associate the bar endpoints with some workloads - suite.tracker.TrackIDForSelector(suite.endpointsBar[i], c.selector) - } - - // now the mapping should return both endpoints resource ids - suite.requireMappedIDsAllTenancies(t, suite.workloadsAPI, suite.endpointsFoo, suite.endpointsBar) - }) - } -} - -func (suite *selectionTrackerSuite) TestDuplicateTracking() { - // This test aims to prove that tracking some ID multiple times doesn't - // result in multiple requests for the same ID - - // associate the foo endpoints with some workloads 3 times without changing - // the selection criteria. The second two times should be no-ops - workloadAPI1 := rtest.Resource(pbcatalog.WorkloadType, "api-1"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(suite.T(), workloadData).Build() - endpointsFoo := rtest.Resource(pbcatalog.ServiceEndpointsType, "foo"). - WithTenancy(resource.DefaultNamespacedTenancy()).ID() - - suite.tracker.TrackIDForSelector(endpointsFoo, &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }) - - suite.tracker.TrackIDForSelector(endpointsFoo, &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }) - - suite.tracker.TrackIDForSelector(endpointsFoo, &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }) - - // regardless of the number of times tracked we should only see a single request - suite.requireMappedIDs(suite.T(), workloadAPI1, endpointsFoo) -} - -func (suite *selectionTrackerSuite) TestModifyTracking() { - // This test aims to prove that modifying selection criteria for a resource - // works as expected. Adding new criteria results in all being tracked. - // Removal of some criteria doesn't result in removal of all etc. More or - // less we want to ensure that updating selection criteria leaves the - // tracker in a consistent/expected state. - - // Create resources for the test and track endpoints. - suite.trackIDForSelectorInAllTenancies(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ - Names: []string{"web-1"}, - }) - - // ensure that api-1 isn't mapped but web-1 is - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsAPI) - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsWeb, suite.endpointsFoo) - - // now also track the api- prefix - suite.trackIDForSelectorInAllTenancies(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ - Names: []string{"web-1"}, - Prefixes: []string{"api-"}, - }) - - // ensure that both workloads are mapped appropriately - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsAPI, suite.endpointsFoo) - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsWeb, suite.endpointsFoo) - - // now remove the web tracking - suite.trackIDForSelectorInAllTenancies(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ - Prefixes: []string{"api-"}, - }) - - // ensure that only api-1 is mapped - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsAPI, suite.endpointsFoo) - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsWeb) -} - -func (suite *selectionTrackerSuite) TestRemove() { - // This test aims to prove that removal of a resource from tracking - // actually prevents subsequent mapping calls from returning the - // workload. - - // track the web-1 workload - suite.trackIDForSelectorInAllTenancies(suite.endpointsFoo, &pbcatalog.WorkloadSelector{ - Names: []string{"web-1"}, - }) - - // ensure web-1 is mapped - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsWeb, suite.endpointsFoo) - - for i := range suite.executedTenancies { - // untrack the resource - suite.tracker.UntrackID(suite.endpointsFoo[i]) - } - - // ensure that we no longer map the previous workload to the resource - suite.requireMappedIDsAllTenancies(suite.T(), suite.workloadsWeb) -} - -func TestWorkloadSelectionSuite(t *testing.T) { - suite.Run(t, new(selectionTrackerSuite)) -} diff --git a/internal/resource/protoc-gen-deepcopy/internal/generate/generate.go b/internal/resource/protoc-gen-deepcopy/internal/generate/generate.go deleted file mode 100644 index afa8dda7f621b..0000000000000 --- a/internal/resource/protoc-gen-deepcopy/internal/generate/generate.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package generate - -import ( - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/types/descriptorpb" -) - -func Generate(gen *protogen.Plugin) error { - for _, file := range gen.Files { - if file.Generate != true { - continue - } - if len(file.Messages) == 0 { - continue - } - filename := file.GeneratedFilenamePrefix + "_deepcopy.gen.go" - p := gen.NewGeneratedFile(filename, file.GoImportPath) - - protoIdent := protogen.GoIdent{ - GoName: "Clone", - GoImportPath: "google.golang.org/protobuf/proto", - } - p.P("// Code generated by protoc-gen-deepcopy. DO NOT EDIT.") - p.P("package ", file.GoPackageName) - var process func([]*protogen.Message) - - process = func(messages []*protogen.Message) { - for _, message := range messages { - // skip maps in protos. - if message.Desc.Options().(*descriptorpb.MessageOptions).GetMapEntry() { - continue - } - typeName := message.GoIdent.GoName - // Generate DeepCopyInto() method for this type - p.P(`// DeepCopyInto supports using `, typeName, ` within kubernetes types, where deepcopy-gen is used.`) - p.P(`func (in *`, typeName, `) DeepCopyInto(out *`, typeName, `) {`) - p.P(`proto.Reset(out)`) - p.P(`proto.Merge(out,`, protoIdent, `(in))`) - p.P(`}`) - - // Generate DeepCopy() method for this type - p.P(`// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new `, typeName, `. Required by controller-gen.`) - p.P(`func (in *`, typeName, `) DeepCopy() *`, typeName, ` {`) - p.P(`if in == nil { return nil }`) - p.P(`out := new(`, typeName, `)`) - p.P(`in.DeepCopyInto(out)`) - p.P(`return out`) - p.P(`}`) - - // Generate DeepCopyInterface() method for this type - p.P(`// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new `, typeName, `. Required by controller-gen.`) - p.P(`func (in *`, typeName, `) DeepCopyInterface() interface{} {`) - p.P(`return in.DeepCopy()`) - p.P(`}`) - process(message.Messages) - } - } - process(file.Messages) - } - return nil -} diff --git a/internal/resource/protoc-gen-deepcopy/main.go b/internal/resource/protoc-gen-deepcopy/main.go deleted file mode 100644 index 2e700c4ed90ff..0000000000000 --- a/internal/resource/protoc-gen-deepcopy/main.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package main - -import ( - "flag" - - "google.golang.org/protobuf/compiler/protogen" - plugin "google.golang.org/protobuf/types/pluginpb" - - "github.com/hashicorp/consul/internal/resource/protoc-gen-deepcopy/internal/generate" -) - -var ( - file = flag.String("file", "-", "where to load data from") -) - -// This file is responsible for generating a DeepCopy and DeepCopyInto overwrite for proto -// structs which allows Kubernetes CRDs to get created directly from the proto-types. -func main() { - flag.Parse() - - protogen.Options{ - ParamFunc: flag.CommandLine.Set, - }.Run(func(gp *protogen.Plugin) error { - gp.SupportedFeatures = uint64(plugin.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) - return generate.Generate(gp) - }) -} diff --git a/internal/resource/protoc-gen-json-shim/internal/generate/generate.go b/internal/resource/protoc-gen-json-shim/internal/generate/generate.go deleted file mode 100644 index 1c02c5df4ac8b..0000000000000 --- a/internal/resource/protoc-gen-json-shim/internal/generate/generate.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package generate - -import ( - "path" - "strings" - - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/types/descriptorpb" -) - -func Generate(gen *protogen.Plugin) error { - for _, file := range gen.Files { - if file.Generate != true { - continue - } - if len(file.Messages) == 0 { - continue - } - filename := file.GeneratedFilenamePrefix + "_json.gen.go" - genFile := gen.NewGeneratedFile(filename, file.GoImportPath) - - genFile.P("// Code generated by protoc-json-shim. DO NOT EDIT.") - genFile.P("package ", file.GoPackageName) - var process func([]*protogen.Message) - - marshalerName := FileName(file) + "Marshaler" - unmarshalerName := FileName(file) + "Unmarshaler" - - process = func(messages []*protogen.Message) { - for _, message := range messages { - // skip maps in protos. - if message.Desc.Options().(*descriptorpb.MessageOptions).GetMapEntry() { - continue - } - typeName := message.GoIdent.GoName - genFile.P(`// MarshalJSON is a custom marshaler for `, typeName) - genFile.P(`func (this *`, typeName, `) MarshalJSON() ([]byte, error) {`) - genFile.P(`str, err := `, marshalerName, `.Marshal(this)`) - genFile.P(`return []byte(str), err`) - genFile.P(`}`) - // Generate UnmarshalJSON() method for this type - genFile.P(`// UnmarshalJSON is a custom unmarshaler for `, typeName) - genFile.P(`func (this *`, typeName, `) UnmarshalJSON(b []byte) error {`) - genFile.P(`return `, unmarshalerName, `.Unmarshal(b, this)`) - genFile.P(`}`) - process(message.Messages) - } - } - process(file.Messages) - - // write out globals - genFile.P(`var (`) - genFile.P(marshalerName, ` = &`, protogen.GoIdent{GoName: "MarshalOptions", GoImportPath: "google.golang.org/protobuf/encoding/protojson"}, `{}`) - genFile.P(unmarshalerName, ` = &`, protogen.GoIdent{GoName: "UnmarshalOptions", GoImportPath: "google.golang.org/protobuf/encoding/protojson"}, `{DiscardUnknown: false}`) - genFile.P(`)`) - } - return nil -} - -func FileName(file *protogen.File) string { - fname := path.Base(file.Proto.GetName()) - fname = strings.Replace(fname, ".proto", "", -1) - fname = strings.Replace(fname, "-", "_", -1) - fname = strings.Replace(fname, ".", "_", -1) - return toCamelInitCase(fname, true) -} - -// Converts a string to CamelCase -func toCamelInitCase(s string, initCase bool) string { - s = strings.TrimSpace(s) - if s == "" { - return s - } - - n := strings.Builder{} - n.Grow(len(s)) - capNext := initCase - prevIsCap := false - for i, v := range []byte(s) { - vIsCap := v >= 'A' && v <= 'Z' - vIsLow := v >= 'a' && v <= 'z' - if capNext { - if vIsLow { - v += 'A' - v -= 'a' - } - } else if i == 0 { - if vIsCap { - v += 'a' - v -= 'A' - } - } else if prevIsCap && vIsCap { - v += 'a' - v -= 'A' - } - prevIsCap = vIsCap - - if vIsCap || vIsLow { - n.WriteByte(v) - capNext = false - } else if vIsNum := v >= '0' && v <= '9'; vIsNum { - n.WriteByte(v) - capNext = true - } else { - capNext = v == '_' || v == ' ' || v == '-' || v == '.' - } - } - return n.String() -} diff --git a/internal/resource/protoc-gen-json-shim/main.go b/internal/resource/protoc-gen-json-shim/main.go deleted file mode 100644 index e81bc6c17af05..0000000000000 --- a/internal/resource/protoc-gen-json-shim/main.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package main - -import ( - "flag" - - "google.golang.org/protobuf/compiler/protogen" - plugin "google.golang.org/protobuf/types/pluginpb" - - "github.com/hashicorp/consul/internal/resource/protoc-gen-json-shim/internal/generate" -) - -var ( - file = flag.String("file", "-", "where to load data from") -) - -// This file is responsible for generating a JSON marhsal/unmarshal overwrite for proto -// structs which allows Kubernetes CRDs to get created directly from the proto-types. -func main() { - flag.Parse() - - protogen.Options{ - ParamFunc: flag.CommandLine.Set, - }.Run(func(gp *protogen.Plugin) error { - gp.SupportedFeatures = uint64(plugin.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) - return generate.Generate(gp) - }) -} diff --git a/internal/resource/protoc-gen-resource-types/internal/generate/generate.go b/internal/resource/protoc-gen-resource-types/internal/generate/generate.go deleted file mode 100644 index 3d74077da93b0..0000000000000 --- a/internal/resource/protoc-gen-resource-types/internal/generate/generate.go +++ /dev/null @@ -1,158 +0,0 @@ -package generate - -import ( - "fmt" - "path/filepath" - "sort" - "strings" - "text/template" - - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func Generate(gp *protogen.Plugin) error { - g := newGenerator() - - for _, file := range gp.Files { - err := g.addResourceKindsFromFile(file) - if err != nil { - return err - } - } - - return g.generateTypes(gp) -} - -type apiGroupVersion struct { - Group string - Version string -} - -type groupInfo struct { - Name string - Version string - - Kinds []kind - ImportPath protogen.GoImportPath - PackageName protogen.GoPackageName - Directory string -} - -type kind struct { - Name string - Comments protogen.CommentSet -} - -type generator struct { - resources map[apiGroupVersion]*groupInfo -} - -func newGenerator() *generator { - return &generator{ - resources: make(map[apiGroupVersion]*groupInfo), - } -} - -func (g *generator) addResourceKindsFromFile(f *protogen.File) error { - if !f.Generate { - return nil - } - - for _, m := range f.Messages { - ext := proto.GetExtension(m.Desc.Options(), pbresource.E_Spec).(*pbresource.ResourceTypeSpec) - if ext == nil { - continue - } - - gvkString := strings.TrimPrefix(string(m.Desc.FullName()), "hashicorp.consul.") - rtype, err := resource.ParseGVK(gvkString) - if err != nil { - return err - } - - apiGroupDir := filepath.Dir(f.Proto.GetName()) - - gv := apiGroupVersion{ - Group: rtype.Group, - Version: rtype.GroupVersion, - } - - grp, err := g.ensureAPIGroup(gv, f.GoImportPath, f.GoPackageName, apiGroupDir) - if err != nil { - return err - } - - grp.Kinds = append(grp.Kinds, kind{Name: rtype.Kind, Comments: m.Comments}) - } - - return nil -} - -func (g *generator) ensureAPIGroup(gv apiGroupVersion, importPath protogen.GoImportPath, pkg protogen.GoPackageName, dir string) (*groupInfo, error) { - grp, found := g.resources[gv] - if !found { - grp = &groupInfo{ - Name: gv.Group, - Version: gv.Version, - - ImportPath: importPath, - PackageName: pkg, - Directory: dir, - } - g.resources[gv] = grp - } else if grp.ImportPath != importPath { - return nil, fmt.Errorf("resources from the same api group must share the same import path") - } - - return grp, nil -} - -func (g *generator) generateTypes(gp *protogen.Plugin) error { - for _, info := range g.resources { - f := gp.NewGeneratedFile(filepath.Join(info.Directory, "resource_types.gen.go"), info.ImportPath) - - sort.Slice(info.Kinds, func(a, b int) bool { - return info.Kinds[a].Name < info.Kinds[b].Name - }) - - if err := typesTemplate.Execute(f, info); err != nil { - return err - } - } - return nil -} - -var ( - typesTemplate = template.Must(template.New("types").Parse(` -// Code generated by protoc-gen-resource-types. DO NOT EDIT. - -package {{.PackageName}} - -import ( - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - GroupName = "{{.Name}}" - Version = "{{.Version}}" - -{{range $kind := .Kinds}} - {{$kind.Name}}Kind = "{{$kind.Name}}" -{{- end}} -) - -var ( -{{range $kind := .Kinds}} - {{$kind.Name}}Type = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: {{$kind.Name}}Kind, - } -{{end}} -) -`)) -) diff --git a/internal/resource/protoc-gen-resource-types/main.go b/internal/resource/protoc-gen-resource-types/main.go deleted file mode 100644 index 26e5c8ab693c9..0000000000000 --- a/internal/resource/protoc-gen-resource-types/main.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package main - -import ( - "flag" - - "github.com/hashicorp/consul/internal/resource/protoc-gen-resource-types/internal/generate" - "google.golang.org/protobuf/compiler/protogen" - plugin "google.golang.org/protobuf/types/pluginpb" -) - -var ( - file = flag.String("file", "-", "where to load data from") -) - -func main() { - flag.Parse() - - protogen.Options{ - ParamFunc: flag.CommandLine.Set, - }.Run(func(gp *protogen.Plugin) error { - gp.SupportedFeatures = uint64(plugin.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) - return generate.Generate(gp) - }) -} diff --git a/internal/resource/reaper/controller.go b/internal/resource/reaper/controller.go index f8de86f92196e..7a7789f986a0d 100644 --- a/internal/resource/reaper/controller.go +++ b/internal/resource/reaper/controller.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package reaper diff --git a/internal/resource/reaper/controller_test.go b/internal/resource/reaper/controller_test.go index c06ccedab582d..9e6f0f3d5a07f 100644 --- a/internal/resource/reaper/controller_test.go +++ b/internal/resource/reaper/controller_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package reaper diff --git a/internal/resource/reference.go b/internal/resource/reference.go index a2ff0588acf03..80492c98787a2 100644 --- a/internal/resource/reference.go +++ b/internal/resource/reference.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource @@ -14,48 +14,3 @@ func Reference(id *pbresource.ID, section string) *pbresource.Reference { Section: section, } } - -// IDFromReference returns a Reference converted into an ID. NOTE: the UID -// field is not populated, and the Section field of a reference is dropped. -func IDFromReference(ref *pbresource.Reference) *pbresource.ID { - return &pbresource.ID{ - Type: ref.Type, - Tenancy: ref.Tenancy, - Name: ref.Name, - } -} - -// ReferenceOrID is the common accessors shared by pbresource.Reference and -// pbresource.ID. -type ReferenceOrID interface { - GetType() *pbresource.Type - GetTenancy() *pbresource.Tenancy - GetName() string -} - -var ( - _ ReferenceOrID = (*pbresource.ID)(nil) - _ ReferenceOrID = (*pbresource.Reference)(nil) -) - -func ReferenceFromReferenceOrID(ref ReferenceOrID) *pbresource.Reference { - switch x := ref.(type) { - case *pbresource.Reference: - return x - default: - return &pbresource.Reference{ - Type: ref.GetType(), - Tenancy: ref.GetTenancy(), - Name: ref.GetName(), - Section: "", - } - } -} - -func ReplaceType(typ *pbresource.Type, id *pbresource.ID) *pbresource.ID { - return &pbresource.ID{ - Type: typ, - Name: id.Name, - Tenancy: id.Tenancy, - } -} diff --git a/internal/resource/refkey.go b/internal/resource/refkey.go deleted file mode 100644 index 44f0765c206c0..0000000000000 --- a/internal/resource/refkey.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "fmt" - "strings" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// ReferenceKey is the pointer-free representation of a ReferenceOrID -// suitable for a go map key. -type ReferenceKey struct { - GVK string - Partition string // Tenancy.* - Namespace string // Tenancy.* - PeerName string // Tenancy.* - Name string -} - -// String returns a string representation of the ReferenceKey. This should not -// be relied upon nor parsed and is provided just for debugging and logging -// reasons. -// -// This format should be aligned with IDToString and ReferenceToString. -func (r ReferenceKey) String() string { - return fmt.Sprintf("%s/%s.%s.%s/%s", - r.GVK, - orDefault(r.Partition, "default"), - orDefault(r.PeerName, "local"), - orDefault(r.Namespace, "default"), - r.Name, - ) -} - -func (r ReferenceKey) GetTenancy() *pbresource.Tenancy { - return &pbresource.Tenancy{ - Partition: r.Partition, - PeerName: r.PeerName, - Namespace: r.Namespace, - } -} - -// ToReference converts this back into a pbresource.ID. -func (r ReferenceKey) ToID() *pbresource.ID { - return &pbresource.ID{ - Type: GVKToType(r.GVK), - Tenancy: r.GetTenancy(), - Name: r.Name, - } -} - -// ToReference converts this back into a pbresource.Reference. -func (r ReferenceKey) ToReference() *pbresource.Reference { - return &pbresource.Reference{ - Type: GVKToType(r.GVK), - Tenancy: r.GetTenancy(), - Name: r.Name, - } -} - -func (r ReferenceKey) GoString() string { return r.String() } - -func NewReferenceKey(refOrID ReferenceOrID) ReferenceKey { - return ReferenceKey{ - GVK: ToGVK(refOrID.GetType()), - Partition: orDefault(refOrID.GetTenancy().GetPartition(), "default"), - Namespace: orDefault(refOrID.GetTenancy().GetNamespace(), "default"), - PeerName: orDefault(refOrID.GetTenancy().GetPeerName(), "local"), - Name: refOrID.GetName(), - } -} - -func orDefault(v, def string) string { - if v == "" { - return def - } - return v -} - -func GVKToType(gvk string) *pbresource.Type { - parts := strings.Split(gvk, ".") - if len(parts) != 3 { - panic("bad gvk") - } - return &pbresource.Type{ - Group: parts[0], - GroupVersion: parts[1], - Kind: parts[2], - } -} diff --git a/internal/resource/refkey_test.go b/internal/resource/refkey_test.go deleted file mode 100644 index 8c4b5eaf92b2f..0000000000000 --- a/internal/resource/refkey_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/demo" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestReferenceKey(t *testing.T) { - tenancy1 := &pbresource.Tenancy{} - tenancy1_actual := defaultTenancy() - tenancy2 := &pbresource.Tenancy{ - Partition: "ap1", - Namespace: "ns-billing", - PeerName: "peer-dc4", - } - tenancy3 := &pbresource.Tenancy{ - Partition: "ap2", - Namespace: "ns-intern", - PeerName: "peer-sea", - } - - res1, err := demo.GenerateV2Artist() - require.NoError(t, err) - res1.Id.Tenancy = tenancy1 - - res2, err := demo.GenerateV2Artist() - require.NoError(t, err) - res2.Id.Tenancy = tenancy2 - - res3, err := demo.GenerateV2Artist() - require.NoError(t, err) - res3.Id.Tenancy = tenancy3 - - id1 := res1.Id - id2 := res2.Id - id3 := res3.Id - - ref1 := resource.Reference(id1, "") - ref2 := resource.Reference(id2, "") - ref3 := resource.Reference(id3, "") - - idRK1 := resource.NewReferenceKey(id1) - idRK2 := resource.NewReferenceKey(id2) - idRK3 := resource.NewReferenceKey(id3) - - refRK1 := resource.NewReferenceKey(ref1) - refRK2 := resource.NewReferenceKey(ref2) - refRK3 := resource.NewReferenceKey(ref3) - - require.Equal(t, idRK1, refRK1) - require.Equal(t, idRK2, refRK2) - require.Equal(t, idRK3, refRK3) - - prototest.AssertDeepEqual(t, tenancy1_actual, idRK1.GetTenancy()) - prototest.AssertDeepEqual(t, tenancy2, idRK2.GetTenancy()) - prototest.AssertDeepEqual(t, tenancy3, idRK3.GetTenancy()) - - // Now that we tested the defaulting, swap out the tenancy in the id so - // that the comparisons work. - id1.Tenancy = tenancy1_actual - ref1.Tenancy = tenancy1_actual - - prototest.AssertDeepEqual(t, id1, idRK1.ToID()) - prototest.AssertDeepEqual(t, id2, idRK2.ToID()) - prototest.AssertDeepEqual(t, id3, idRK3.ToID()) - - prototest.AssertDeepEqual(t, ref1, refRK1.ToReference()) - prototest.AssertDeepEqual(t, ref2, refRK2.ToReference()) - prototest.AssertDeepEqual(t, ref3, refRK3.ToReference()) -} - -func defaultTenancy() *pbresource.Tenancy { - return &pbresource.Tenancy{ - Partition: "default", - Namespace: "default", - PeerName: "local", - } -} diff --git a/internal/resource/registry.go b/internal/resource/registry.go index 7897ffb1b4bce..0004acfff4c6a 100644 --- a/internal/resource/registry.go +++ b/internal/resource/registry.go @@ -1,19 +1,16 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource import ( - "errors" "fmt" "regexp" - "strings" "sync" "google.golang.org/protobuf/proto" "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -21,38 +18,16 @@ var ( groupRegexp = regexp.MustCompile(`^[a-z][a-z\d_]+$`) groupVersionRegexp = regexp.MustCompile(`^v([a-z\d]+)?\d$`) kindRegexp = regexp.MustCompile(`^[A-Z][A-Za-z\d]+$`) - // Track resource types that are allowed to have an undefined scope. These are usually - // non-customer facing or internal types. - undefinedScopeAllowed = map[string]bool{ - storage.UnversionedTypeFrom(TypeV1Tombstone).String(): true, - } ) -func isUndefinedScopeAllowed(t *pbresource.Type) bool { - return undefinedScopeAllowed[storage.UnversionedTypeFrom(t).String()] -} - type Registry interface { // Register the given resource type and its hooks. Register(reg Registration) // Resolve the given resource type and its hooks. Resolve(typ *pbresource.Type) (reg Registration, ok bool) - - Types() []Registration } -// ValidationHook is the function signature for a validation hook. These hooks can inspect -// the data as they see fit but are expected to not mutate the data in any way. If Go -// supported it, we would pass something akin to a const pointer into the callback to have -// the compiler enforce this immutability. -type ValidationHook func(*pbresource.Resource) error - -// MutationHook is the function signature for a validation hook. These hooks can inspect -// and mutate the resource. If modifying the resources Data, the hook needs to ensure that -// the data gets reencoded and stored back to the Data field. -type MutationHook func(*pbresource.Resource) error - type Registration struct { // Type is the GVK of the resource type. Type *pbresource.Type @@ -61,50 +36,35 @@ type Registration struct { Proto proto.Message // ACLs are hooks called to perform authorization on RPCs. - // The hooks can assume that Validate has been called. ACLs *ACLHooks // Validate is called to structurally validate the resource (e.g. - // check for required fields). Validate can assume that Mutate - // has been called. - Validate ValidationHook - - // Mutate is called to fill out any autogenerated fields (e.g. UUIDs) or - // apply defaults before validation. Mutate can assume that - // Resource.ID is populated and has non-empty tenancy fields. This does - // not mean those tenancy fields actually exist. - Mutate MutationHook - - // Scope describes the tenancy scope of a resource. - Scope Scope -} + // check for required fields). + Validate func(*pbresource.Resource) error -var ErrNeedResource = errors.New("authorization check requires the entire resource") + // Mutate is called to fill out any autogenerated fields (e.g. UUIDs). + Mutate func(*pbresource.Resource) error -type ACLAuthorizeReadHook func(acl.Authorizer, *acl.AuthorizerContext, *pbresource.ID, *pbresource.Resource) error -type ACLAuthorizeWriteHook func(acl.Authorizer, *acl.AuthorizerContext, *pbresource.Resource) error -type ACLAuthorizeListHook func(acl.Authorizer, *acl.AuthorizerContext) error + // In the future, we'll add hooks, the controller etc. here. + // TODO: https://github.com/hashicorp/consul/pull/16622#discussion_r1134515909 +} type ACLHooks struct { // Read is used to authorize Read RPCs and to filter results in List // RPCs. // - // It can be called an ID and possibly a Resource. The check will first - // attempt to use the ID and if the hook returns ErrNeedResource, then the - // check will be deferred until the data is fetched from the storage layer. - // // If it is omitted, `operator:read` permission is assumed. - Read ACLAuthorizeReadHook + Read func(acl.Authorizer, *pbresource.ID) error // Write is used to authorize Write and Delete RPCs. // // If it is omitted, `operator:write` permission is assumed. - Write ACLAuthorizeWriteHook + Write func(acl.Authorizer, *pbresource.ID) error // List is used to authorize List RPCs. // // If it is omitted, we only filter the results using Read. - List ACLAuthorizeListHook + List func(acl.Authorizer, *pbresource.Tenancy) error } // Resource type registry @@ -138,19 +98,11 @@ func (r *TypeRegistry) Register(registration Registration) { case !groupRegexp.MatchString(typ.Group): panic(fmt.Sprintf("Type.Group must be in snake_case. Got: %q", typ.Group)) case !groupVersionRegexp.MatchString(typ.GroupVersion): - panic(fmt.Sprintf("Type.GroupVersion must be lowercase, start with `v`, and end with a number (e.g. `v2` or `v2beta1`). Got: %q", typ.Group)) + panic(fmt.Sprintf("Type.GroupVersion must be lowercase, start with `v`, and end with a number (e.g. `v2` or `v1alpha1`). Got: %q", typ.Group)) case !kindRegexp.MatchString(typ.Kind): panic(fmt.Sprintf("Type.Kind must be in PascalCase. Got: %q", typ.Kind)) } - if registration.Proto == nil { - panic("Proto field is required.") - } - - if registration.Scope == ScopeUndefined && !isUndefinedScopeAllowed(typ) { - panic(fmt.Sprintf("scope required for %s. Got: %q", typ, registration.Scope)) - } - r.lock.Lock() defer r.lock.Unlock() @@ -164,17 +116,17 @@ func (r *TypeRegistry) Register(registration Registration) { registration.ACLs = &ACLHooks{} } if registration.ACLs.Read == nil { - registration.ACLs.Read = func(authz acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { - return authz.ToAllowAuthorizer().OperatorReadAllowed(authzContext) + registration.ACLs.Read = func(authz acl.Authorizer, id *pbresource.ID) error { + return authz.ToAllowAuthorizer().OperatorReadAllowed(&acl.AuthorizerContext{}) } } if registration.ACLs.Write == nil { - registration.ACLs.Write = func(authz acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.Resource) error { - return authz.ToAllowAuthorizer().OperatorWriteAllowed(authzContext) + registration.ACLs.Write = func(authz acl.Authorizer, id *pbresource.ID) error { + return authz.ToAllowAuthorizer().OperatorWriteAllowed(&acl.AuthorizerContext{}) } } if registration.ACLs.List == nil { - registration.ACLs.List = func(authz acl.Authorizer, authzContext *acl.AuthorizerContext) error { + registration.ACLs.List = func(authz acl.Authorizer, tenancy *pbresource.Tenancy) error { return authz.ToAllowAuthorizer().OperatorReadAllowed(&acl.AuthorizerContext{}) } } @@ -202,29 +154,6 @@ func (r *TypeRegistry) Resolve(typ *pbresource.Type) (reg Registration, ok bool) return Registration{}, false } -func (r *TypeRegistry) Types() []Registration { - r.lock.RLock() - defer r.lock.RUnlock() - - types := make([]Registration, 0, len(r.registrations)) - for _, v := range r.registrations { - types = append(types, v) - } - return types -} - func ToGVK(resourceType *pbresource.Type) string { return fmt.Sprintf("%s.%s.%s", resourceType.Group, resourceType.GroupVersion, resourceType.Kind) } - -func ParseGVK(gvk string) (*pbresource.Type, error) { - parts := strings.Split(gvk, ".") - if len(parts) != 3 { - return nil, fmt.Errorf("GVK string must be in the form .., got: %s", gvk) - } - return &pbresource.Type{ - Group: parts[0], - GroupVersion: parts[1], - Kind: parts[2], - }, nil -} diff --git a/internal/resource/registry_test.go b/internal/resource/registry_test.go index 8ecfcd7661d17..c9d1777159f8c 100644 --- a/internal/resource/registry_test.go +++ b/internal/resource/registry_test.go @@ -1,33 +1,27 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package resource_test import ( "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/grpc-external/testutils" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/proto-public/pbresource" - pbdemov1 "github.com/hashicorp/consul/proto/private/pbdemo/v1" - demov2 "github.com/hashicorp/consul/proto/private/pbdemo/v2" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" ) func TestRegister(t *testing.T) { r := resource.NewRegistry() // register success - reg := resource.Registration{ - Type: demo.TypeV2Artist, - Proto: &demov2.Artist{}, - Scope: resource.ScopeNamespace, - } + reg := resource.Registration{Type: demo.TypeV2Artist} r.Register(reg) actual, ok := r.Resolve(demo.TypeV2Artist) require.True(t, ok) @@ -37,18 +31,11 @@ func TestRegister(t *testing.T) { require.PanicsWithValue(t, "resource type demo.v2.Artist already registered", func() { r.Register(reg) }) - - // register success when scope undefined and type exempt from scope - // skip: can't test this because tombstone type is registered as part of NewRegistry() } func TestRegister_Defaults(t *testing.T) { r := resource.NewRegistry() - r.Register(resource.Registration{ - Type: demo.TypeV2Artist, - Proto: &demov2.Artist{}, - Scope: resource.ScopeNamespace, - }) + r.Register(resource.Registration{Type: demo.TypeV2Artist}) artist, err := demo.GenerateV2Artist() require.NoError(t, err) @@ -56,16 +43,16 @@ func TestRegister_Defaults(t *testing.T) { require.True(t, ok) // verify default read hook requires operator:read - require.NoError(t, reg.ACLs.Read(testutils.ACLOperatorRead(t), nil, artist.Id, nil)) - require.True(t, acl.IsErrPermissionDenied(reg.ACLs.Read(testutils.ACLNoPermissions(t), nil, artist.Id, nil))) + require.NoError(t, reg.ACLs.Read(testutils.ACLOperatorRead(t), artist.Id)) + require.True(t, acl.IsErrPermissionDenied(reg.ACLs.Read(testutils.ACLNoPermissions(t), artist.Id))) // verify default write hook requires operator:write - require.NoError(t, reg.ACLs.Write(testutils.ACLOperatorWrite(t), nil, artist)) - require.True(t, acl.IsErrPermissionDenied(reg.ACLs.Write(testutils.ACLNoPermissions(t), nil, artist))) + require.NoError(t, reg.ACLs.Write(testutils.ACLOperatorWrite(t), artist.Id)) + require.True(t, acl.IsErrPermissionDenied(reg.ACLs.Write(testutils.ACLNoPermissions(t), artist.Id))) // verify default list hook requires operator:read - require.NoError(t, reg.ACLs.List(testutils.ACLOperatorRead(t), nil)) - require.True(t, acl.IsErrPermissionDenied(reg.ACLs.List(testutils.ACLNoPermissions(t), nil))) + require.NoError(t, reg.ACLs.List(testutils.ACLOperatorRead(t), artist.Id.Tenancy)) + require.True(t, acl.IsErrPermissionDenied(reg.ACLs.List(testutils.ACLNoPermissions(t), artist.Id.Tenancy))) // verify default validate is a no-op require.NoError(t, reg.Validate(nil)) @@ -85,19 +72,21 @@ func TestNewRegistry(t *testing.T) { func TestResolve(t *testing.T) { r := resource.NewRegistry() + serviceType := &pbresource.Type{ + Group: "mesh", + GroupVersion: "v1", + Kind: "Service", + } + // not found - _, ok := r.Resolve(demo.TypeV1Album) + _, ok := r.Resolve(serviceType) assert.False(t, ok) // found - r.Register(resource.Registration{ - Type: demo.TypeV1Album, - Proto: &pbdemov1.Album{}, - Scope: resource.ScopeNamespace, - }) - registration, ok := r.Resolve(demo.TypeV1Album) + r.Register(resource.Registration{Type: serviceType}) + registration, ok := r.Resolve(serviceType) assert.True(t, ok) - assert.Equal(t, registration.Type, demo.TypeV1Album) + assert.Equal(t, registration.Type, serviceType) } func TestRegister_TypeValidation(t *testing.T) { @@ -174,10 +163,6 @@ func TestRegister_TypeValidation(t *testing.T) { } registry.Register(resource.Registration{ Type: typ, - // Just pass anything since proto is a required field. - Proto: &pbdemov1.Artist{}, - // Scope is also required - Scope: resource.ScopeNamespace, }) } diff --git a/internal/resource/resource.go b/internal/resource/resource.go deleted file mode 100644 index b5100f002955f..0000000000000 --- a/internal/resource/resource.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "fmt" - "strings" - - "github.com/hashicorp/consul/agent/dns" -) - -const MaxNameLength = 63 - -// ValidateName returns an error a name is not a valid resource name. -// The error will contain reference to what constitutes a valid resource name. -func ValidateName(name string) error { - if !dns.IsValidLabel(name) || strings.ToLower(name) != name || len(name) > MaxNameLength { - return fmt.Errorf("a resource name must consist of lower case alphanumeric characters or '-', must start and end with an alphanumeric character and be less than %d characters, got: %q", MaxNameLength+1, name) - } - return nil -} diff --git a/internal/resource/resourcetest/acls.go b/internal/resource/resourcetest/acls.go deleted file mode 100644 index 3f77c7fec4909..0000000000000 --- a/internal/resource/resourcetest/acls.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resourcetest - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/reflect/protoreflect" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - DENY = "deny" - ALLOW = "allow" - DEFAULT = "default" -) - -var checkF = func(t *testing.T, expect string, got error) { - switch expect { - case ALLOW: - if acl.IsErrPermissionDenied(got) { - t.Fatal("should be allowed") - } - case DENY: - if !acl.IsErrPermissionDenied(got) { - t.Fatal("should be denied") - } - case DEFAULT: - require.Nil(t, got, "expected fallthrough decision") - default: - t.Fatalf("unexpected expectation: %q", expect) - } -} - -type ACLTestCase struct { - Rules string - - // AuthCtx is optional. If not provided an empty one will be used. - AuthCtx *acl.AuthorizerContext - - // One of either Res or Data/Owner/Typ should be set. - Res *pbresource.Resource - Data protoreflect.ProtoMessage - Owner *pbresource.ID - Typ *pbresource.Type - - ReadOK string - WriteOK string - ListOK string - - ReadHookRequiresResource bool -} - -func RunACLTestCase(t *testing.T, tc ACLTestCase, registry resource.Registry) { - var ( - typ *pbresource.Type - res *pbresource.Resource - ) - if tc.Res != nil { - require.Nil(t, tc.Data) - require.Nil(t, tc.Owner) - require.Nil(t, tc.Typ) - typ = tc.Res.Id.GetType() - res = tc.Res - } else { - require.NotNil(t, tc.Data) - require.NotNil(t, tc.Typ) - typ = tc.Typ - - resolvedType, ok := registry.Resolve(typ) - require.True(t, ok) - - res = Resource(tc.Typ, "test"). - WithTenancy(DefaultTenancyForType(t, resolvedType)). - WithOwner(tc.Owner). - WithData(t, tc.Data). - Build() - } - - reg, ok := registry.Resolve(typ) - require.True(t, ok) - - ValidateAndNormalize(t, registry, res) - - config := acl.Config{ - WildcardName: structs.WildcardSpecifier, - } - authz, err := acl.NewAuthorizerFromRules(tc.Rules, &config, nil) - require.NoError(t, err) - authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) - - if tc.AuthCtx == nil { - tc.AuthCtx = &acl.AuthorizerContext{} - } - - if tc.ReadHookRequiresResource { - err = reg.ACLs.Read(authz, tc.AuthCtx, res.Id, nil) - require.ErrorIs(t, err, resource.ErrNeedResource, "read hook should require the data payload") - } - - t.Run("read", func(t *testing.T) { - err := reg.ACLs.Read(authz, tc.AuthCtx, res.Id, res) - checkF(t, tc.ReadOK, err) - }) - t.Run("write", func(t *testing.T) { - err := reg.ACLs.Write(authz, tc.AuthCtx, res) - checkF(t, tc.WriteOK, err) - }) - t.Run("list", func(t *testing.T) { - err := reg.ACLs.List(authz, tc.AuthCtx) - checkF(t, tc.ListOK, err) - }) -} diff --git a/internal/resource/resourcetest/builder.go b/internal/resource/resourcetest/builder.go index 3de836a71db34..7355f38824ec1 100644 --- a/internal/resource/resourcetest/builder.go +++ b/internal/resource/resourcetest/builder.go @@ -1,25 +1,14 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package resourcetest import ( "context" - "strings" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/oklog/ulid/v2" "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/storage" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" ) type resourceBuilder struct { @@ -37,25 +26,17 @@ func Resource(rtype *pbresource.Type, name string) *resourceBuilder { GroupVersion: rtype.GroupVersion, Kind: rtype.Kind, }, + Tenancy: &pbresource.Tenancy{ + Partition: "default", + Namespace: "default", + PeerName: "local", + }, Name: name, }, }, } } -func ResourceID(id *pbresource.ID) *resourceBuilder { - return &resourceBuilder{ - resource: &pbresource.Resource{ - Id: id, - }, - } -} - -func (b *resourceBuilder) WithTenancy(tenant *pbresource.Tenancy) *resourceBuilder { - b.resource.Id.Tenancy = tenant - return b -} - func (b *resourceBuilder) WithData(t T, data protoreflect.ProtoMessage) *resourceBuilder { t.Helper() @@ -124,61 +105,25 @@ func (b *resourceBuilder) ID() *pbresource.ID { return b.resource.Id } -func (b *resourceBuilder) Reference(section string) *pbresource.Reference { - return resource.Reference(b.ID(), section) -} - -func (b *resourceBuilder) ReferenceNoSection() *pbresource.Reference { - return resource.Reference(b.ID(), "") -} - func (b *resourceBuilder) Write(t T, client pbresource.ResourceServiceClient) *pbresource.Resource { t.Helper() - var ctx context.Context - rtestClient, ok := client.(*Client) - if ok { - ctx = rtestClient.Context(t) - } else { - ctx = testutil.TestContext(t) - rtestClient = NewClient(client) - } - res := b.resource - var rsp *pbresource.WriteResponse - var err error - - // Retry any writes where the error is a UID mismatch and the UID was not specified. This is indicative - // of using a follower to rewrite an object who is not perfectly in-sync with the leader. - retry.Run(t, func(r *retry.R) { - rsp, err = client.Write(ctx, &pbresource.WriteRequest{ - Resource: res, - }) - - if err == nil || res.Id.Uid != "" || status.Code(err) != codes.FailedPrecondition { - if err != nil { - t.Logf("write saw error: %v", err) - } - return - } - - if strings.Contains(err.Error(), storage.ErrWrongUid.Error()) { - r.Fatalf("resource write failed due to uid mismatch - most likely a transient issue when talking to a non-leader") - } else { - // other errors are unexpected and should cause an immediate failure - r.Stop(err) - } + rsp, err := client.Write(context.Background(), &pbresource.WriteRequest{ + Resource: res, }) require.NoError(t, err) - require.NotNil(t, rsp) if !b.dontCleanup { - id := proto.Clone(rsp.Resource.Id).(*pbresource.ID) - id.Uid = "" - t.Cleanup(func() { - rtestClient.MustDelete(t, id) + cleaner, ok := t.(CleanupT) + require.True(t, ok, "T does not implement a Cleanup method and cannot be used with automatic resource cleanup") + cleaner.Cleanup(func() { + _, err := client.Delete(context.Background(), &pbresource.DeleteRequest{ + Id: rsp.Resource.Id, + }) + require.NoError(t, err) }) } @@ -191,7 +136,7 @@ func (b *resourceBuilder) Write(t T, client pbresource.ResourceServiceClient) *p ObservedGeneration: rsp.Resource.Generation, Conditions: original.Conditions, } - _, err := client.WriteStatus(ctx, &pbresource.WriteStatusRequest{ + _, err := client.WriteStatus(context.Background(), &pbresource.WriteStatusRequest{ Id: rsp.Resource.Id, Key: key, Status: status, @@ -199,7 +144,7 @@ func (b *resourceBuilder) Write(t T, client pbresource.ResourceServiceClient) *p require.NoError(t, err) } - readResp, err := client.Read(ctx, &pbresource.ReadRequest{ + readResp, err := client.Read(context.Background(), &pbresource.ReadRequest{ Id: rsp.Resource.Id, }) diff --git a/internal/resource/resourcetest/client.go b/internal/resource/resourcetest/client.go index 8983a858ac87b..dab5b03c3adbe 100644 --- a/internal/resource/resourcetest/client.go +++ b/internal/resource/resourcetest/client.go @@ -1,24 +1,17 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package resourcetest import ( "context" - "fmt" "math/rand" "time" + "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" ) type Client struct { @@ -26,19 +19,13 @@ type Client struct { timeout time.Duration wait time.Duration - token string } func NewClient(client pbresource.ResourceServiceClient) *Client { - return NewClientWithACLToken(client, "") -} - -func NewClientWithACLToken(client pbresource.ResourceServiceClient, token string) *Client { return &Client{ ResourceServiceClient: client, timeout: 7 * time.Second, wait: 25 * time.Millisecond, - token: token, } } @@ -48,14 +35,11 @@ func (client *Client) SetRetryerConfig(timeout time.Duration, wait time.Duration } func (client *Client) retry(t T, fn func(r *retry.R)) { - t.Helper() retryer := &retry.Timer{Timeout: client.timeout, Wait: client.wait} retry.RunWith(retryer, t, fn) } func (client *Client) PublishResources(t T, resources []*pbresource.Resource) { - ctx := client.Context(t) - // Randomize the order of insertion. Generally insertion order shouldn't matter as the // controllers should eventually converge on the desired state. The exception to this // is that you cannot insert resources with owner refs before the resource they are @@ -90,17 +74,12 @@ func (client *Client) PublishResources(t T, resources []*pbresource.Resource) { } t.Logf("Writing resource %s with type %s", res.Id.Name, resource.ToGVK(res.Id.Type)) - rsp, err := client.Write(ctx, &pbresource.WriteRequest{ + _, err := client.Write(context.Background(), &pbresource.WriteRequest{ Resource: res, }) require.NoError(t, err) - id := rsp.Resource.Id - t.Cleanup(func() { - client.MustDelete(t, id) - }) - - // track the number of resources published + // track the number o published += 1 written = append(written, res.Id) } @@ -119,23 +98,10 @@ func (client *Client) PublishResources(t T, resources []*pbresource.Resource) { require.Empty(t, resources, "Could not publish all resources - some resources have invalid owner references") } -func (client *Client) Context(t T) context.Context { - ctx := testutil.TestContext(t) - - if client.token != "" { - md := metadata.New(map[string]string{ - "x-consul-token": client.token, - }) - ctx = metadata.NewOutgoingContext(ctx, md) - } - - return ctx -} - func (client *Client) RequireResourceNotFound(t T, id *pbresource.ID) { t.Helper() - rsp, err := client.Read(client.Context(t), &pbresource.ReadRequest{Id: id}) + rsp, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: id}) require.Error(t, err) require.Equal(t, codes.NotFound, status.Code(err)) require.Nil(t, rsp) @@ -144,7 +110,7 @@ func (client *Client) RequireResourceNotFound(t T, id *pbresource.ID) { func (client *Client) RequireResourceExists(t T, id *pbresource.ID) *pbresource.Resource { t.Helper() - rsp, err := client.Read(client.Context(t), &pbresource.ReadRequest{Id: id}) + rsp, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: id}) require.NoError(t, err, "error reading %s with type %s", id.Name, resource.ToGVK(id.Type)) require.NotNil(t, rsp) return rsp.Resource @@ -182,16 +148,6 @@ func (client *Client) RequireStatusConditionForCurrentGen(t T, id *pbresource.ID return res } -func (client *Client) RequireStatusConditionsForCurrentGen(t T, id *pbresource.ID, statusKey string, conditions []*pbresource.Condition) *pbresource.Resource { - t.Helper() - - res := client.RequireResourceExists(t, id) - for _, condition := range conditions { - RequireStatusConditionForCurrentGen(t, res, statusKey, condition) - } - return res -} - func (client *Client) RequireResourceMeta(t T, id *pbresource.ID, key string, value string) *pbresource.Resource { t.Helper() @@ -225,18 +181,7 @@ func (client *Client) WaitForStatusCondition(t T, id *pbresource.ID, statusKey s var res *pbresource.Resource client.retry(t, func(r *retry.R) { - res = client.RequireStatusConditionForCurrentGen(r, id, statusKey, condition) - }) - - return res -} - -func (client *Client) WaitForStatusConditions(t T, id *pbresource.ID, statusKey string, conditions ...*pbresource.Condition) *pbresource.Resource { - t.Helper() - - var res *pbresource.Resource - client.retry(t, func(r *retry.R) { - res = client.RequireStatusConditionsForCurrentGen(r, id, statusKey, conditions) + res = client.RequireStatusConditionForCurrentGen(t, id, statusKey, condition) }) return res @@ -264,14 +209,6 @@ func (client *Client) WaitForResourceState(t T, id *pbresource.ID, verify func(T return res } -func (client *Client) WaitForDeletion(t T, id *pbresource.ID) { - t.Helper() - - client.retry(t, func(r *retry.R) { - client.RequireResourceNotFound(r, id) - }) -} - // ResolveResourceID will read the specified resource and returns its full ID. // This is mainly useful to get the ID with the Uid filled out. func (client *Client) ResolveResourceID(t T, id *pbresource.ID) *pbresource.ID { @@ -279,24 +216,3 @@ func (client *Client) ResolveResourceID(t T, id *pbresource.ID) *pbresource.ID { return client.RequireResourceExists(t, id).Id } - -func (client *Client) MustDelete(t T, id *pbresource.ID) { - t.Helper() - ctx := client.Context(t) - - client.retry(t, func(r *retry.R) { - _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: id}) - if status.Code(err) == codes.NotFound { - return - } - - // codes.Aborted indicates a CAS failure and that the delete request should - // be retried. Anything else should be considered an unrecoverable error. - if err != nil && status.Code(err) != codes.Aborted { - r.Stop(fmt.Errorf("failed to delete the resource: %w", err)) - return - } - - require.NoError(r, err) - }) -} diff --git a/internal/resource/resourcetest/decode.go b/internal/resource/resourcetest/decode.go deleted file mode 100644 index 109ad39ceb753..0000000000000 --- a/internal/resource/resourcetest/decode.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resourcetest - -import ( - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func MustDecode[Tp proto.Message](t T, res *pbresource.Resource) *resource.DecodedResource[Tp] { - dec, err := resource.Decode[Tp](res) - require.NoError(t, err) - return dec -} diff --git a/internal/resource/resourcetest/fs.go b/internal/resource/resourcetest/fs.go index a31ac0f10c4b7..e7a1417a59083 100644 --- a/internal/resource/resourcetest/fs.go +++ b/internal/resource/resourcetest/fs.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package resourcetest import ( diff --git a/internal/resource/resourcetest/require.go b/internal/resource/resourcetest/require.go index b57bab8b2e3a2..fff8cb2aebf2c 100644 --- a/internal/resource/resourcetest/require.go +++ b/internal/resource/resourcetest/require.go @@ -1,42 +1,13 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package resourcetest import ( "github.com/google/go-cmp/cmp" - "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" "github.com/stretchr/testify/require" "google.golang.org/protobuf/testing/protocmp" ) -// CompareErrorString is a helper to generate a custom go-cmp comparer method -// that will perform an equality check on the error message. This is mainly -// useful to get around not being able to see unexported data within errors. -func CompareErrorString[T error]() cmp.Option { - return cmp.Comparer(func(e1, e2 T) bool { - return e1.Error() == e2.Error() - }) -} - -// default comparers for known types that don't play well with go-cmp -var comparers = []cmp.Option{ - CompareErrorString[resource.ConstError](), -} - -// RequireError is useful for asserting that some chained multierror contains a specific error. -func RequireError[E error](t T, err error, expected E, opts ...cmp.Option) { - t.Helper() - - var actual E - require.ErrorAs(t, err, &actual) - - opts = append(opts, comparers...) - prototest.AssertDeepEqual(t, expected, actual, opts...) -} - func RequireVersionUnchanged(t T, res *pbresource.Resource, version string) { t.Helper() require.Equal(t, version, res.Version) diff --git a/internal/resource/resourcetest/tenancy.go b/internal/resource/resourcetest/tenancy.go deleted file mode 100644 index 5f5c0525b6f43..0000000000000 --- a/internal/resource/resourcetest/tenancy.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resourcetest - -import ( - "strings" - "testing" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// Tenancy constructs a pbresource.Tenancy from a concise string representation -// suitable for use in unit tests. -// -// - "" : partition="" namespace="" peerName="local" -// - "foo" : partition="foo" namespace="" peerName="local" -// - "foo.bar" : partition="foo" namespace="bar" peerName="local" -// - : partition="BAD" namespace="BAD" peerName="BAD" -func Tenancy(s string) *pbresource.Tenancy { - parts := strings.Split(s, ".") - switch len(parts) { - case 0: - return resource.DefaultClusteredTenancy() - case 1: - v := resource.DefaultPartitionedTenancy() - v.Partition = parts[0] - return v - case 2: - v := resource.DefaultNamespacedTenancy() - v.Partition = parts[0] - v.Namespace = parts[1] - return v - default: - return &pbresource.Tenancy{Partition: "BAD", Namespace: "BAD", PeerName: "BAD"} - } -} - -func DefaultTenancyForType(t *testing.T, reg resource.Registration) *pbresource.Tenancy { - switch reg.Scope { - case resource.ScopeNamespace: - return resource.DefaultNamespacedTenancy() - case resource.ScopePartition: - return resource.DefaultPartitionedTenancy() - case resource.ScopeCluster: - return resource.DefaultClusteredTenancy() - default: - t.Fatalf("unsupported resource scope: %v", reg.Scope) - return nil - } -} diff --git a/internal/resource/resourcetest/testing.go b/internal/resource/resourcetest/testing.go index 1be9947226bd2..d02b70da9d039 100644 --- a/internal/resource/resourcetest/testing.go +++ b/internal/resource/resourcetest/testing.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package resourcetest // T represents the subset of testing.T methods that will be used @@ -12,5 +9,9 @@ type T interface { Errorf(format string, args ...interface{}) Fatalf(format string, args ...interface{}) FailNow() +} + +type CleanupT interface { + T Cleanup(func()) } diff --git a/internal/resource/resourcetest/validation.go b/internal/resource/resourcetest/validation.go deleted file mode 100644 index 1ba6a080484fb..0000000000000 --- a/internal/resource/resourcetest/validation.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resourcetest - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func ValidateAndNormalize(t *testing.T, registry resource.Registry, res *pbresource.Resource) { - t.Helper() - typ := res.Id.Type - - typeInfo, ok := registry.Resolve(typ) - if !ok { - t.Fatalf("unhandled resource type: %q", resource.ToGVK(typ)) - } - - if typeInfo.Mutate != nil { - require.NoError(t, typeInfo.Mutate(res), "failed to apply type mutation to resource") - } - - if typeInfo.Validate != nil { - require.NoError(t, typeInfo.Validate(res), "failed to validate resource") - } -} diff --git a/internal/resource/sort.go b/internal/resource/sort.go deleted file mode 100644 index 1373f08e14213..0000000000000 --- a/internal/resource/sort.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import "github.com/hashicorp/consul/proto-public/pbresource" - -func LessReference(a, b *pbresource.Reference) bool { - return compareReference(a, b) < 0 -} - -func compareReference(a, b *pbresource.Reference) int { - if a == nil || b == nil { - panic("nil references cannot be compared") - } - - diff := compareType(a.Type, b.Type) - if diff != 0 { - return diff - } - diff = compareTenancy(a.Tenancy, b.Tenancy) - if diff != 0 { - return diff - } - diff = compareString(a.Name, b.Name) - if diff != 0 { - return diff - } - return compareString(a.Section, b.Section) -} - -func compareType(a, b *pbresource.Type) int { - if a == nil || b == nil { - panic("nil types cannot be compared") - } - diff := compareString(a.Group, b.Group) - if diff != 0 { - return diff - } - diff = compareString(a.GroupVersion, b.GroupVersion) - if diff != 0 { - return diff - } - return compareString(a.Kind, b.Kind) -} - -func compareTenancy(a, b *pbresource.Tenancy) int { - if a == nil || b == nil { - panic("nil tenancies cannot be compared") - } - diff := compareString(a.Partition, b.Partition) - if diff != 0 { - return diff - } - diff = compareString(a.PeerName, b.PeerName) - if diff != 0 { - return diff - } - return compareString(a.Namespace, b.Namespace) -} - -func compareString(a, b string) int { - switch { - case a < b: - return -1 - case a > b: - return 1 - default: - return 0 - } -} diff --git a/internal/resource/sort_test.go b/internal/resource/sort_test.go deleted file mode 100644 index e319266d9a925..0000000000000 --- a/internal/resource/sort_test.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "fmt" - "math/rand" - "sort" - "strings" - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func TestLessReference(t *testing.T) { - parseTenancy := func(s string) *pbresource.Tenancy { - // format is: .. - parts := strings.Split(s, ".") - if len(parts) != 3 { - panic("bad tenancy") - } - return &pbresource.Tenancy{ - Partition: parts[0], - PeerName: parts[1], - Namespace: parts[2], - } - } - - makeRef := func(s string) *pbresource.Reference { - // format is: - // - //@
- // - // - // - // type = (gvk style) - // tenancy = .. - - parts := strings.Split(s, "/") - require.Len(t, parts, 3) - - name, section, _ := strings.Cut(parts[2], "@") - - return &pbresource.Reference{ - Type: GVKToType(parts[0]), - Tenancy: parseTenancy(parts[1]), - Name: name, - Section: section, - } - } - - var inputs []*pbresource.Reference - - stringify := func(all []*pbresource.Reference) []string { - var out []string - for _, ref := range all { - out = append(out, ReferenceToString(ref)) - } - return out - } - - // We generate pre-sorted data. - vals := []string{"a", "aa", "b", "bb"} - sectionVals := append([]string{""}, vals...) - for _, group := range vals { - for _, version := range vals { - for _, kind := range vals { - for _, partition := range vals { - for _, peer := range vals { - for _, namespace := range vals { - for _, name := range vals { - for _, section := range sectionVals { - if section != "" { - section = "@" + section - } - inputs = append(inputs, makeRef( - fmt.Sprintf( - "%s.%s.%s/%s.%s.%s/%s%s", - group, version, kind, - partition, peer, namespace, - name, section, - ), - )) - } - } - } - } - } - } - } - } - - require.True(t, sort.IsSorted(sortedReferences(inputs))) - - const randomTrials = 5 - - mixed := protoSliceClone(inputs) - for i := 0; i < randomTrials; i++ { - rand.Shuffle(len(mixed), func(i, j int) { - mixed[i], mixed[j] = mixed[j], mixed[i] - }) - - // We actually got a permuted list out of this. - require.NotEqual(t, stringify(inputs), stringify(mixed)) - - sort.Slice(mixed, func(i, j int) bool { - return LessReference(mixed[i], mixed[j]) - }) - - // And it sorted. - require.Equal(t, stringify(inputs), stringify(mixed)) - } - -} - -type sortedReferences []*pbresource.Reference - -func (r sortedReferences) Len() int { - return len(r) -} - -func (r sortedReferences) Less(i, j int) bool { - return LessReference(r[i], r[j]) -} - -func (r sortedReferences) Swap(i, j int) { - r[i], r[j] = r[j], r[i] -} - -func protoClone[T proto.Message](v T) T { - return proto.Clone(v).(T) -} - -func protoSliceClone[T proto.Message](in []T) []T { - if in == nil { - return nil - } - out := make([]T, 0, len(in)) - for _, v := range in { - out = append(out, protoClone[T](v)) - } - return out -} diff --git a/internal/resource/stringer.go b/internal/resource/stringer.go deleted file mode 100644 index 075c08ac0d9c4..0000000000000 --- a/internal/resource/stringer.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "fmt" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// IDToString returns a string representation of pbresource.ID. This should not -// be relied upon nor parsed and is provided just for debugging and logging -// reasons. -// -// This format should be aligned with ReferenceToString and -// (ReferenceKey).String. -func IDToString(id *pbresource.ID) string { - s := fmt.Sprintf("%s/%s/%s", - TypeToString(id.Type), - TenancyToString(id.Tenancy), - id.Name, - ) - if id.Uid != "" { - return s + "?uid=" + id.Uid - } - return s -} - -// ReferenceToString returns a string representation of pbresource.Reference. -// This should not be relied upon nor parsed and is provided just for debugging -// and logging reasons. -// -// This format should be aligned with IDToString and (ReferenceKey).String. -func ReferenceToString(ref *pbresource.Reference) string { - s := fmt.Sprintf("%s/%s/%s", - TypeToString(ref.Type), - TenancyToString(ref.Tenancy), - ref.Name, - ) - - if ref.Section != "" { - return s + "?section=" + ref.Section - } - return s -} - -// TenancyToString returns a string representation of pbresource.Tenancy. This -// should not be relied upon nor parsed and is provided just for debugging and -// logging reasons. -func TenancyToString(tenancy *pbresource.Tenancy) string { - return fmt.Sprintf("%s.%s.%s", tenancy.Partition, tenancy.PeerName, tenancy.Namespace) -} - -// TypeToString returns a string representation of pbresource.Type. This should -// not be relied upon nor parsed and is provided just for debugging and logging -// reasons. -func TypeToString(typ *pbresource.Type) string { - return ToGVK(typ) -} diff --git a/internal/resource/tenancy.go b/internal/resource/tenancy.go deleted file mode 100644 index 597253aa8dc13..0000000000000 --- a/internal/resource/tenancy.go +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "fmt" - - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type TenancyBridge interface { - PartitionExists(partition string) (bool, error) - IsPartitionMarkedForDeletion(partition string) (bool, error) - NamespaceExists(partition, namespace string) (bool, error) - IsNamespaceMarkedForDeletion(partition, namespace string) (bool, error) -} - -const ( - DefaultPartitionName = "default" - DefaultNamespaceName = "default" - DefaultPeerName = "local" -) - -// Scope describes the tenancy scope of a resource. -type Scope int - -const ( - // There is no default scope, it must be set explicitly. - ScopeUndefined Scope = iota - // ScopeCluster describes a resource that is scoped to a cluster. - ScopeCluster - // ScopePartition describes a resource that is scoped to a partition. - ScopePartition - // ScopeNamespace applies to a resource that is scoped to a partition and namespace. - ScopeNamespace -) - -func (s Scope) String() string { - switch s { - case ScopeUndefined: - return "undefined" - case ScopeCluster: - return "cluster" - case ScopePartition: - return "partition" - case ScopeNamespace: - return "namespace" - } - panic(fmt.Sprintf("string mapping missing for scope %v", int(s))) -} - -// DefaultClusteredTenancy returns the default tenancy for a cluster scoped resource. -func DefaultClusteredTenancy() *pbresource.Tenancy { - return &pbresource.Tenancy{ - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - PeerName: DefaultPeerName, - } -} - -// DefaultPartitionedTenancy returns the default tenancy for a partition scoped resource. -func DefaultPartitionedTenancy() *pbresource.Tenancy { - return &pbresource.Tenancy{ - Partition: DefaultPartitionName, - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - PeerName: DefaultPeerName, - } -} - -// DefaultNamespedTenancy returns the default tenancy for a namespace scoped resource. -func DefaultNamespacedTenancy() *pbresource.Tenancy { - return &pbresource.Tenancy{ - Partition: DefaultPartitionName, - Namespace: DefaultNamespaceName, - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - PeerName: DefaultPeerName, - } -} - -// DefaultIDTenancy will default/normalize the Tenancy of the provided -// ID in the context of some parent resource containing that ID. -// The default tenancy for the ID's type is also provided in cases where -// "default" is needed selectively or the parent is more precise than the -// child. -func DefaultIDTenancy(id *pbresource.ID, parentTenancy, scopeTenancy *pbresource.Tenancy) { - if id == nil { - return - } - if id.Tenancy == nil { - id.Tenancy = &pbresource.Tenancy{} - } - - if parentTenancy != nil { - dup := proto.Clone(parentTenancy).(*pbresource.Tenancy) - parentTenancy = dup - } - - defaultTenancy(id.Tenancy, parentTenancy, scopeTenancy) -} - -// DefaultReferenceTenancy will default/normalize the Tenancy of the provided -// Reference in the context of some parent resource containing that Reference. -// The default tenancy for the Reference's type is also provided in cases where -// "default" is needed selectively or the parent is more precise than the -// child. -func DefaultReferenceTenancy(ref *pbresource.Reference, parentTenancy, scopeTenancy *pbresource.Tenancy) { - if ref == nil { - return - } - if ref.Tenancy == nil { - ref.Tenancy = &pbresource.Tenancy{} - } - - if parentTenancy != nil { - dup := proto.Clone(parentTenancy).(*pbresource.Tenancy) - parentTenancy = dup - } - - defaultTenancy(ref.Tenancy, parentTenancy, scopeTenancy) -} - -func defaultTenancy(itemTenancy, parentTenancy, scopeTenancy *pbresource.Tenancy) { - if itemTenancy == nil { - panic("item tenancy is required") - } - if scopeTenancy == nil { - panic("scope tenancy is required") - } - - if itemTenancy.PeerName == "" { - itemTenancy.PeerName = DefaultPeerName - } - - if parentTenancy != nil { - // Recursively normalize this tenancy as well. - defaultTenancy(parentTenancy, nil, scopeTenancy) - } - - // use scope defaults for parent - if parentTenancy == nil { - parentTenancy = scopeTenancy - } - - if !equalOrEmpty(itemTenancy.PeerName, DefaultPeerName) { - panic("peering is not supported yet for resource tenancies") - } - if !equalOrEmpty(parentTenancy.PeerName, DefaultPeerName) { - panic("peering is not supported yet for parent tenancies") - } - if !equalOrEmpty(scopeTenancy.PeerName, DefaultPeerName) { - panic("peering is not supported yet for scopes") - } - - // Only retain the parts of the parent that apply to this resource. - if scopeTenancy.Partition == "" { - parentTenancy.Partition = "" - itemTenancy.Partition = "" - } - if scopeTenancy.Namespace == "" { - parentTenancy.Namespace = "" - itemTenancy.Namespace = "" - } - - if parentTenancy.Partition == "" { - // (cluster scoped) - } else { - if itemTenancy.Partition == "" { - itemTenancy.Partition = parentTenancy.Partition - } - if parentTenancy.Namespace == "" { - // (partition scoped) - } else { - // (namespace scoped) - - if itemTenancy.Namespace == "" { - if itemTenancy.Partition == parentTenancy.Partition { - // safe to copy the namespace - itemTenancy.Namespace = parentTenancy.Namespace - } else { - // cross-peer, the namespace must come from the scope default - itemTenancy.Namespace = scopeTenancy.Namespace - } - } - } - } -} - -func equalOrEmpty(a, b string) bool { - return (a == b) || (a == "") || (b == "") -} diff --git a/internal/resource/tenancy_test.go b/internal/resource/tenancy_test.go deleted file mode 100644 index 654ebb183d1dd..0000000000000 --- a/internal/resource/tenancy_test.go +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "strings" - "testing" - - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestDefaultReferenceTenancy(t *testing.T) { - // Just do a few small tests here and let the more complicated cases be covered by - // TestDefaultTenancy below. - - t.Run("partition inference", func(t *testing.T) { - ref := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "fake", - GroupVersion: "v1fake", - Kind: "artificial", - }, - Name: "blah", - Tenancy: &pbresource.Tenancy{ - Namespace: "zim", - }, - } - - expect := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "fake", - GroupVersion: "v1fake", - Kind: "artificial", - }, - Name: "blah", - Tenancy: newTestTenancy("gir.zim"), - } - - parent := newTestTenancy("gir.gaz") - - DefaultReferenceTenancy(ref, parent, DefaultNamespacedTenancy()) - prototest.AssertDeepEqual(t, expect, ref) - }) - - t.Run("full default", func(t *testing.T) { - ref := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "fake", - GroupVersion: "v1fake", - Kind: "artificial", - }, - Name: "blah", - } - - expect := &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "fake", - GroupVersion: "v1fake", - Kind: "artificial", - }, - Name: "blah", - Tenancy: newTestTenancy("gir.gaz"), - } - - parent := newTestTenancy("gir.gaz") - - DefaultReferenceTenancy(ref, parent, DefaultNamespacedTenancy()) - prototest.AssertDeepEqual(t, expect, ref) - }) -} - -func TestDefaultTenancy(t *testing.T) { - type testcase struct { - ref *pbresource.Tenancy - parent *pbresource.Tenancy - scope *pbresource.Tenancy - expect *pbresource.Tenancy - } - - run := func(t *testing.T, tc testcase) { - got := proto.Clone(tc.ref).(*pbresource.Tenancy) - - defaultTenancy(got, tc.parent, tc.scope) - prototest.AssertDeepEqual(t, tc.expect, got) - } - - cases := map[string]testcase{ - // Completely empty values get backfilled from the scope. - "clustered/empty/no-parent": { - ref: newTestTenancy(""), - parent: nil, - scope: DefaultClusteredTenancy(), - expect: DefaultClusteredTenancy(), - }, - "partitioned/empty/no-parent": { - ref: newTestTenancy(""), - parent: nil, - scope: DefaultPartitionedTenancy(), - expect: DefaultPartitionedTenancy(), - }, - "namespaced/empty/no-parent": { - ref: newTestTenancy(""), - parent: nil, - scope: DefaultNamespacedTenancy(), - expect: DefaultNamespacedTenancy(), - }, - // Completely provided values are limited by the scope. - "clustered/full/no-parent": { - ref: newTestTenancy("foo.bar"), - parent: nil, - scope: DefaultClusteredTenancy(), - expect: DefaultClusteredTenancy(), - }, - "partitioned/full/no-parent": { - ref: newTestTenancy("foo.bar"), - parent: nil, - scope: DefaultPartitionedTenancy(), - expect: newTestTenancy("foo"), - }, - "namespaced/full/no-parent": { - ref: newTestTenancy("foo.bar"), - parent: nil, - scope: DefaultNamespacedTenancy(), - expect: newTestTenancy("foo.bar"), - }, - // Completely provided parent values are limited by the scope before - // being blindly used for to fill in for the empty provided value. - "clustered/empty/full-parent": { - ref: newTestTenancy(""), - parent: newTestTenancy("foo.bar"), - scope: DefaultClusteredTenancy(), - expect: DefaultClusteredTenancy(), - }, - "partitioned/empty/full-parent": { - ref: newTestTenancy(""), - parent: newTestTenancy("foo.bar"), - scope: DefaultPartitionedTenancy(), - expect: newTestTenancy("foo"), - }, - "namespaced/empty/full-parent": { - ref: newTestTenancy(""), - parent: newTestTenancy("foo.bar"), - scope: DefaultNamespacedTenancy(), - expect: newTestTenancy("foo.bar"), - }, - // (1) Partially filled values are only partially populated by parents. - "clustered/part-only/full-parent": { - ref: newTestTenancy("zim"), - parent: newTestTenancy("foo.bar"), - scope: DefaultClusteredTenancy(), - expect: DefaultClusteredTenancy(), - }, - "partitioned/part-only/full-parent": { - ref: newTestTenancy("zim"), - parent: newTestTenancy("foo.bar"), - scope: DefaultPartitionedTenancy(), - expect: newTestTenancy("zim"), - }, - "namespaced/part-only/full-parent": { - ref: newTestTenancy("zim"), - parent: newTestTenancy("foo.bar"), - scope: DefaultNamespacedTenancy(), - // partitions don't match so the namespace comes from the scope - expect: newTestTenancy("zim.default"), - }, - // (2) Partially filled values are only partially populated by parents. - "clustered/ns-only/full-parent": { - // Leading dot implies no partition - ref: newTestTenancy(".gir"), - parent: newTestTenancy("foo.bar"), - scope: DefaultClusteredTenancy(), - expect: DefaultClusteredTenancy(), - }, - "partitioned/ns-only/full-parent": { - // Leading dot implies no partition - ref: newTestTenancy(".gir"), - parent: newTestTenancy("foo.bar"), - scope: DefaultPartitionedTenancy(), - expect: newTestTenancy("foo"), - }, - "namespaced/ns-only/full-parent": { - // Leading dot implies no partition - ref: newTestTenancy(".gir"), - parent: newTestTenancy("foo.bar"), - scope: DefaultNamespacedTenancy(), - expect: newTestTenancy("foo.gir"), - }, - // Fully specified ignores parent. - "clustered/full/full-parent": { - ref: newTestTenancy("foo.bar"), - parent: newTestTenancy("zim.gir"), - scope: DefaultClusteredTenancy(), - expect: DefaultClusteredTenancy(), - }, - "partitioned/full/full-parent": { - ref: newTestTenancy("foo.bar"), - parent: newTestTenancy("zim.gir"), - scope: DefaultPartitionedTenancy(), - expect: newTestTenancy("foo"), - }, - "namespaced/full/full-parent": { - ref: newTestTenancy("foo.bar"), - parent: newTestTenancy("zim.gir"), - scope: DefaultNamespacedTenancy(), - expect: newTestTenancy("foo.bar"), - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func newTestTenancy(s string) *pbresource.Tenancy { - parts := strings.Split(s, ".") - switch len(parts) { - case 0: - return DefaultClusteredTenancy() - case 1: - v := DefaultPartitionedTenancy() - v.Partition = parts[0] - return v - case 2: - v := DefaultNamespacedTenancy() - v.Partition = parts[0] - v.Namespace = parts[1] - return v - default: - return &pbresource.Tenancy{Partition: "BAD", Namespace: "BAD", PeerName: "BAD"} - } -} diff --git a/internal/resource/tombstone.go b/internal/resource/tombstone.go index d86ae96ec4d50..6d0285c602de9 100644 --- a/internal/resource/tombstone.go +++ b/internal/resource/tombstone.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package resource import "github.com/hashicorp/consul/proto-public/pbresource" diff --git a/internal/resourcehcl/any.go b/internal/resourcehcl/any.go deleted file mode 100644 index 71086f655de06..0000000000000 --- a/internal/resourcehcl/any.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resourcehcl - -import ( - "errors" - "fmt" - - "google.golang.org/protobuf/reflect/protoreflect" - - "github.com/hashicorp/consul/internal/protohcl" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// anyProvider implements protohcl.AnyTypeProvider to infer the `Data` block -// type from `ID.Type`. -type anyProvider struct { - base protohcl.AnyTypeProvider - reg resource.Registry -} - -func (p anyProvider) AnyType(ctx *protohcl.UnmarshalContext, decoder protohcl.MessageDecoder) (protoreflect.FullName, protohcl.MessageDecoder, error) { - if ctx.Name != "Data" { - return p.base.AnyType(ctx, decoder) - } - - if ctx.Parent == nil || ctx.Parent.Message == nil { - return p.base.AnyType(ctx, decoder) - } - - res, isResource := ctx.Parent.Message.Interface().(*pbresource.Resource) - if !isResource { - return p.base.AnyType(ctx, decoder) - } - if res == nil { - return "", nil, errors.New("ID.Type not found") - } - - resourceType := res.GetId().GetType() - if resourceType == nil { - return "", nil, errors.New("ID.Type is nil") - } - - reg, ok := p.reg.Resolve(resourceType) - if !ok { - return "", nil, fmt.Errorf("unknown resource type: %s", resource.ToGVK(resourceType)) - } - - return reg.Proto.ProtoReflect().Descriptor().FullName(), decoder, nil -} diff --git a/internal/resourcehcl/naming.go b/internal/resourcehcl/naming.go deleted file mode 100644 index 590ea067886df..0000000000000 --- a/internal/resourcehcl/naming.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resourcehcl - -import ( - "strings" - - "google.golang.org/protobuf/reflect/protoreflect" -) - -// fieldNamer implements protohcl.FieldNamer to name fields using PascalCase -// with support for acroynms (e.g. ID, TCP). -type fieldNamer struct{ acroynms []string } - -func (n fieldNamer) NameField(fd protoreflect.FieldDescriptor) string { - camel := fd.JSONName() - upper := strings.ToUpper(camel) - - for _, a := range n.acroynms { - if upper == a { - return a - } - } - - return strings.ToUpper(camel[:1]) + camel[1:] -} - -func (n fieldNamer) GetField(fds protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor { - for _, a := range n.acroynms { - if name == a { - return fds.ByJSONName(strings.ToLower(a)) - } - } - - if len(name) <= 1 { - return fds.ByJSONName(name) - } - camel := strings.ToLower(name[:1]) + name[1:] - return fds.ByJSONName(camel) -} diff --git a/internal/resourcehcl/testdata/destinations.golden b/internal/resourcehcl/testdata/destinations.golden deleted file mode 100644 index b6ffce953751f..0000000000000 --- a/internal/resourcehcl/testdata/destinations.golden +++ /dev/null @@ -1 +0,0 @@ -{"id":{"name":"api","type":{"group":"mesh","groupVersion":"v2beta1","kind":"Destinations"}},"data":{"@type":"hashicorp.consul.mesh.v2beta1.Destinations","workloads":{"prefixes":["api"]},"destinations":[{"destinationRef":{"name":"db","type":{"group":"catalog","groupVersion":"v2beta1","kind":"Service"}},"destinationPort":"tcp","ipPort":{"port":1234}}]}} diff --git a/internal/resourcehcl/testdata/destinations.hcl b/internal/resourcehcl/testdata/destinations.hcl deleted file mode 100644 index fa62538abb44b..0000000000000 --- a/internal/resourcehcl/testdata/destinations.hcl +++ /dev/null @@ -1,25 +0,0 @@ -ID { - Type = gvk("mesh.v2beta1.Destinations") - Name = "api" -} - -Data { - Workloads { - Prefixes = ["api"] - } - - Destinations = [ - { - DestinationRef = { - Type = gvk("catalog.v2beta1.Service") - Name = "db" - } - - DestinationPort = "tcp" - - IpPort = { - Port = 1234 - } - } - ] -} diff --git a/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/0e4b8ec300611dbc b/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/0e4b8ec300611dbc deleted file mode 100644 index 7f8a2357c7385..0000000000000 --- a/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/0e4b8ec300611dbc +++ /dev/null @@ -1,2 +0,0 @@ -go test fuzz v1 -[]byte("Data{}") diff --git a/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/c800420b7494c6d1 b/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/c800420b7494c6d1 deleted file mode 100644 index 3d99674458c26..0000000000000 --- a/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/c800420b7494c6d1 +++ /dev/null @@ -1,2 +0,0 @@ -go test fuzz v1 -[]byte("ID={\"\"=\"\"}") diff --git a/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/eaba8205942c3f31 b/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/eaba8205942c3f31 deleted file mode 100644 index b63214c55a5fd..0000000000000 --- a/internal/resourcehcl/testdata/fuzz/FuzzUnmarshall/eaba8205942c3f31 +++ /dev/null @@ -1,2 +0,0 @@ -go test fuzz v1 -[]byte("ID {\nType = gvk(\"demo.v1.Artist\")\n} \nData {\nGenre = \"\"\n} ") diff --git a/internal/resourcehcl/testdata/gvk-no-arguments.error b/internal/resourcehcl/testdata/gvk-no-arguments.error deleted file mode 100644 index 1c290dd3d6135..0000000000000 --- a/internal/resourcehcl/testdata/gvk-no-arguments.error +++ /dev/null @@ -1 +0,0 @@ -gvk-no-arguments.hcl:2,14-15: Not enough function arguments; Function "gvk" expects 1 argument(s). Missing value for "GVK String". \ No newline at end of file diff --git a/internal/resourcehcl/testdata/gvk-no-arguments.hcl b/internal/resourcehcl/testdata/gvk-no-arguments.hcl deleted file mode 100644 index 69aee02b2cfa8..0000000000000 --- a/internal/resourcehcl/testdata/gvk-no-arguments.hcl +++ /dev/null @@ -1,4 +0,0 @@ -ID { - Type = gvk() - Name = "foo" -} diff --git a/internal/resourcehcl/testdata/invalid-group.error b/internal/resourcehcl/testdata/invalid-group.error deleted file mode 100644 index 6db3a339c2a18..0000000000000 --- a/internal/resourcehcl/testdata/invalid-group.error +++ /dev/null @@ -1 +0,0 @@ -invalid-group.hcl:3,13-17: Failed to unmarshal argument Group: expected value of type string but actual type is number \ No newline at end of file diff --git a/internal/resourcehcl/testdata/invalid-group.hcl b/internal/resourcehcl/testdata/invalid-group.hcl deleted file mode 100644 index ca6920163ecce..0000000000000 --- a/internal/resourcehcl/testdata/invalid-group.hcl +++ /dev/null @@ -1,8 +0,0 @@ -ID { - Type { - Group = 1234 - GroupVersion = "v1" - Kind = "Artist" - } - Name = "foo" -} diff --git a/internal/resourcehcl/testdata/invalid-gvk.error b/internal/resourcehcl/testdata/invalid-gvk.error deleted file mode 100644 index 92ebca5eb0c12..0000000000000 --- a/internal/resourcehcl/testdata/invalid-gvk.error +++ /dev/null @@ -1 +0,0 @@ -invalid-gvk.hcl:2,10-14: Error in function call; Call to function "gvk" failed: GVK string must be in the form .., got: nope. \ No newline at end of file diff --git a/internal/resourcehcl/testdata/invalid-gvk.hcl b/internal/resourcehcl/testdata/invalid-gvk.hcl deleted file mode 100644 index 565a4cc3f9c84..0000000000000 --- a/internal/resourcehcl/testdata/invalid-gvk.hcl +++ /dev/null @@ -1,4 +0,0 @@ -ID { - Type = gvk("nope") - Name = "foo" -} diff --git a/internal/resourcehcl/testdata/invalid-metadata.error b/internal/resourcehcl/testdata/invalid-metadata.error deleted file mode 100644 index 352f2ffa056c6..0000000000000 --- a/internal/resourcehcl/testdata/invalid-metadata.error +++ /dev/null @@ -1 +0,0 @@ -invalid-metadata.hcl:6,12-8,2: Failed to unmarshal argument Metadata["foo"]: expected value of type string but actual type is tuple \ No newline at end of file diff --git a/internal/resourcehcl/testdata/invalid-metadata.hcl b/internal/resourcehcl/testdata/invalid-metadata.hcl deleted file mode 100644 index aa10b5686e7f1..0000000000000 --- a/internal/resourcehcl/testdata/invalid-metadata.hcl +++ /dev/null @@ -1,8 +0,0 @@ -ID { - Type = gvk("demo.v1.Artist") - Name = "korn" -} - -Metadata = { - "foo" = ["bar"] -} diff --git a/internal/resourcehcl/testdata/invalid-name.error b/internal/resourcehcl/testdata/invalid-name.error deleted file mode 100644 index ba977a2e279c7..0000000000000 --- a/internal/resourcehcl/testdata/invalid-name.error +++ /dev/null @@ -1 +0,0 @@ -invalid-name.hcl:3,10-14: Failed to unmarshal argument Name: expected value of type string but actual type is number \ No newline at end of file diff --git a/internal/resourcehcl/testdata/invalid-name.hcl b/internal/resourcehcl/testdata/invalid-name.hcl deleted file mode 100644 index 54ca6b186bbcf..0000000000000 --- a/internal/resourcehcl/testdata/invalid-name.hcl +++ /dev/null @@ -1,4 +0,0 @@ -ID { - Type = gvk("demo.v1.Artist") - Name = 1234 -} diff --git a/internal/resourcehcl/testdata/no-blocks-any-first.golden b/internal/resourcehcl/testdata/no-blocks-any-first.golden deleted file mode 100644 index 18a7cfd9aeecb..0000000000000 --- a/internal/resourcehcl/testdata/no-blocks-any-first.golden +++ /dev/null @@ -1 +0,0 @@ -{"id":{"name":"korn","type":{"group":"demo","groupVersion":"v1","kind":"Artist"}},"data":{"@type":"hashicorp.consul.internal.demo.v1.Artist","name":"Korn"}} \ No newline at end of file diff --git a/internal/resourcehcl/testdata/no-blocks-any-first.hcl b/internal/resourcehcl/testdata/no-blocks-any-first.hcl deleted file mode 100644 index 8eb8d75f43170..0000000000000 --- a/internal/resourcehcl/testdata/no-blocks-any-first.hcl +++ /dev/null @@ -1,8 +0,0 @@ -Data = { - Name = "Korn" -} - -ID = { - Type = gvk("demo.v1.Artist") - Name = "korn" -} diff --git a/internal/resourcehcl/testdata/no-blocks.golden b/internal/resourcehcl/testdata/no-blocks.golden deleted file mode 100644 index 5e3bff82bd883..0000000000000 --- a/internal/resourcehcl/testdata/no-blocks.golden +++ /dev/null @@ -1 +0,0 @@ -{"id":{"type":{"group":"mesh","groupVersion":"v2beta1","kind":"Destinations"}},"data":{"@type":"hashicorp.consul.mesh.v2beta1.Destinations","workloads":{"prefixes":["api"]},"destinations":[{"destinationRef":{"name":"db","type":{"group":"catalog","groupVersion":"v2beta1","kind":"Service"}},"destinationPort":"tcp","ipPort":{"port":1234}}]}} diff --git a/internal/resourcehcl/testdata/no-blocks.hcl b/internal/resourcehcl/testdata/no-blocks.hcl deleted file mode 100644 index 197fd43f8776b..0000000000000 --- a/internal/resourcehcl/testdata/no-blocks.hcl +++ /dev/null @@ -1,33 +0,0 @@ -ID = { - Type = { - Group = "mesh" - GroupVersion = "v2beta1" - Kind = "Destinations" - } -} - -Data = { - Workloads = { - Prefixes = ["api"] - } - - Destinations = [ - { - DestinationRef = { - Type = { - Group = "catalog" - GroupVersion = "v2beta1" - Kind = "Service" - } - - Name = "db" - } - - DestinationPort = "tcp" - - IpPort = { - Port = 1234 - } - } - ] -} diff --git a/internal/resourcehcl/testdata/owner.golden b/internal/resourcehcl/testdata/owner.golden deleted file mode 100644 index 9054db09bfd35..0000000000000 --- a/internal/resourcehcl/testdata/owner.golden +++ /dev/null @@ -1 +0,0 @@ -{"id":{"name":"twisted-transistor","type":{"group":"demo","groupVersion":"v1","kind":"Album"}},"owner":{"name":"korn","type":{"group":"demo","groupVersion":"v1","kind":"Artist"}}} \ No newline at end of file diff --git a/internal/resourcehcl/testdata/owner.hcl b/internal/resourcehcl/testdata/owner.hcl deleted file mode 100644 index 2cc65e4c66582..0000000000000 --- a/internal/resourcehcl/testdata/owner.hcl +++ /dev/null @@ -1,9 +0,0 @@ -ID { - Type = gvk("demo.v1.Album") - Name = "twisted-transistor" -} - -Owner { - Type = gvk("demo.v1.Artist") - Name = "korn" -} diff --git a/internal/resourcehcl/testdata/simple-gvk.golden b/internal/resourcehcl/testdata/simple-gvk.golden deleted file mode 100644 index ba3fddcd6d176..0000000000000 --- a/internal/resourcehcl/testdata/simple-gvk.golden +++ /dev/null @@ -1 +0,0 @@ -{"id":{"name":"korn","type":{"group":"demo","groupVersion":"v1","kind":"Artist"}},"metadata":{"foo":"bar"},"data":{"@type":"hashicorp.consul.internal.demo.v1.Artist","name":"Korn","genre":"GENRE_METAL"}} \ No newline at end of file diff --git a/internal/resourcehcl/testdata/simple-gvk.hcl b/internal/resourcehcl/testdata/simple-gvk.hcl deleted file mode 100644 index adddcd42c8c1c..0000000000000 --- a/internal/resourcehcl/testdata/simple-gvk.hcl +++ /dev/null @@ -1,13 +0,0 @@ -ID { - Type = gvk("demo.v1.Artist") - Name = "korn" -} - -Data { - Name = "Korn" - Genre = "GENRE_METAL" -} - -Metadata = { - "foo" = "bar" -} diff --git a/internal/resourcehcl/testdata/type-block.golden b/internal/resourcehcl/testdata/type-block.golden deleted file mode 100644 index 963695616bee8..0000000000000 --- a/internal/resourcehcl/testdata/type-block.golden +++ /dev/null @@ -1 +0,0 @@ -{"id":{"name":"korn","type":{"group":"demo","groupVersion":"v1","kind":"Artist"}}} \ No newline at end of file diff --git a/internal/resourcehcl/testdata/type-block.hcl b/internal/resourcehcl/testdata/type-block.hcl deleted file mode 100644 index f927fbe2fe613..0000000000000 --- a/internal/resourcehcl/testdata/type-block.hcl +++ /dev/null @@ -1,8 +0,0 @@ -ID { - Type { - Group = "demo" - GroupVersion = "v1" - Kind = "Artist" - } - Name = "korn" -} diff --git a/internal/resourcehcl/testdata/unknown-field-block.error b/internal/resourcehcl/testdata/unknown-field-block.error deleted file mode 100644 index 602212543d66a..0000000000000 --- a/internal/resourcehcl/testdata/unknown-field-block.error +++ /dev/null @@ -1 +0,0 @@ -unknown-field-block.hcl:2,3-6: Unsupported argument; An argument named "Foo" is not expected here. \ No newline at end of file diff --git a/internal/resourcehcl/testdata/unknown-field-block.hcl b/internal/resourcehcl/testdata/unknown-field-block.hcl deleted file mode 100644 index 534fdb11b8d25..0000000000000 --- a/internal/resourcehcl/testdata/unknown-field-block.hcl +++ /dev/null @@ -1,3 +0,0 @@ -ID { - Foo = "bar" -} diff --git a/internal/resourcehcl/testdata/unknown-field-object.error b/internal/resourcehcl/testdata/unknown-field-object.error deleted file mode 100644 index b7651d5eb0d59..0000000000000 --- a/internal/resourcehcl/testdata/unknown-field-object.error +++ /dev/null @@ -1 +0,0 @@ -unknown-field-object.hcl:1,6-3,2: Unsupported argument; An argument named "Foo" is not expected here. \ No newline at end of file diff --git a/internal/resourcehcl/testdata/unknown-field-object.hcl b/internal/resourcehcl/testdata/unknown-field-object.hcl deleted file mode 100644 index 43220099bb0a3..0000000000000 --- a/internal/resourcehcl/testdata/unknown-field-object.hcl +++ /dev/null @@ -1,3 +0,0 @@ -ID = { - Foo = "bar" -} diff --git a/internal/resourcehcl/testdata/unknown-type.error b/internal/resourcehcl/testdata/unknown-type.error deleted file mode 100644 index 81e0ea1c81597..0000000000000 --- a/internal/resourcehcl/testdata/unknown-type.error +++ /dev/null @@ -1 +0,0 @@ -error getting type for Any field: unknown resource type: foo.bar.Baz \ No newline at end of file diff --git a/internal/resourcehcl/testdata/unknown-type.hcl b/internal/resourcehcl/testdata/unknown-type.hcl deleted file mode 100644 index f1669b8ba882b..0000000000000 --- a/internal/resourcehcl/testdata/unknown-type.hcl +++ /dev/null @@ -1,8 +0,0 @@ -ID { - Type = gvk("foo.bar.Baz") - Name = "qux" -} - -Data { - Foo = "bar" -} diff --git a/internal/resourcehcl/unmarshal.go b/internal/resourcehcl/unmarshal.go deleted file mode 100644 index 610ebc641b825..0000000000000 --- a/internal/resourcehcl/unmarshal.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resourcehcl - -import ( - "reflect" - - "github.com/zclconf/go-cty/cty" - "github.com/zclconf/go-cty/cty/function" - - "github.com/hashicorp/consul/internal/protohcl" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// Unmarshal the given HCL source into a resource. -func Unmarshal(src []byte, reg resource.Registry) (*pbresource.Resource, error) { - return UnmarshalOptions{}.Unmarshal(src, reg) -} - -type UnmarshalOptions struct{ SourceFileName string } - -// Unmarshal the given HCL source into a resource. -func (u UnmarshalOptions) Unmarshal(src []byte, reg resource.Registry) (*pbresource.Resource, error) { - var out pbresource.Resource - err := (protohcl.UnmarshalOptions{ - SourceFileName: u.SourceFileName, - AnyTypeProvider: anyProvider{ - base: &protohcl.AnyTypeURLProvider{TypeURLFieldName: "Type"}, - reg: reg, - }, - FieldNamer: fieldNamer{acroynms: []string{"ID", "TCP", "UDP", "HTTP"}}, - Functions: map[string]function.Function{"gvk": gvk}, - }).Unmarshal(src, &out) - return &out, err -} - -var ( - typeType = cty.Capsule("type", reflect.TypeOf(pbresource.Type{})) - - gvk = function.New(&function.Spec{ - Params: []function.Parameter{ - {Name: "GVK String", Type: cty.String}, - }, - Type: function.StaticReturnType(typeType), - Impl: func(args []cty.Value, _ cty.Type) (cty.Value, error) { - t, err := resource.ParseGVK(args[0].AsString()) - if err != nil { - return cty.NilVal, err - } - return cty.CapsuleVal(typeType, t), nil - }, - }) -) diff --git a/internal/resourcehcl/unmarshal_test.go b/internal/resourcehcl/unmarshal_test.go deleted file mode 100644 index e5b6506744723..0000000000000 --- a/internal/resourcehcl/unmarshal_test.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resourcehcl_test - -import ( - "flag" - "fmt" - "os" - "path" - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/encoding/protojson" - - "github.com/hashicorp/consul/internal/mesh" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/demo" - "github.com/hashicorp/consul/internal/resourcehcl" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/proto/private/prototest" -) - -var update = flag.Bool("update", false, "update golden files") - -func FuzzUnmarshall(f *testing.F) { - entries, err := os.ReadDir("./testdata") - require.NoError(f, err) - - read := func(t *testing.F, path string) ([]byte, bool) { - t.Helper() - - bytes, err := os.ReadFile(fmt.Sprintf("./testdata/%s", path)) - switch { - case err == nil: - return bytes, true - case os.IsNotExist(err): - return nil, false - } - - t.Fatalf("failed to read file %s %v", path, err) - return nil, false - } - for _, entry := range entries { - ext := path.Ext(entry.Name()) - - if ext != ".hcl" { - continue - } - input, _ := read(f, entry.Name()) - f.Add(input) - } - registry := resource.NewRegistry() - demo.RegisterTypes(registry) - mesh.RegisterTypes(registry) - - f.Fuzz(func(t *testing.T, input []byte) { - got, err := resourcehcl.Unmarshal(input, registry) - if err != nil { - return - } - require.NotNil(t, got) - }) - -} - -func TestUnmarshal(t *testing.T) { - entries, err := os.ReadDir("./testdata") - require.NoError(t, err) - - read := func(t *testing.T, path string) ([]byte, bool) { - t.Helper() - - bytes, err := os.ReadFile(fmt.Sprintf("./testdata/%s", path)) - switch { - case err == nil: - return bytes, true - case os.IsNotExist(err): - return nil, false - } - - t.Fatalf("failed to read file %s %v", path, err) - return nil, false - } - - write := func(t *testing.T, path string, src []byte) { - t.Helper() - - require.NoError(t, os.WriteFile(fmt.Sprintf("./testdata/%s", path), src, 0o600)) - } - - for _, entry := range entries { - name := entry.Name() - ext := path.Ext(name) - - if ext != ".hcl" { - continue - } - - base := name[0 : len(name)-len(ext)] - - t.Run(base, func(t *testing.T) { - input, _ := read(t, name) - - registry := resource.NewRegistry() - demo.RegisterTypes(registry) - mesh.RegisterTypes(registry) - - output, err := resourcehcl.UnmarshalOptions{SourceFileName: name}. - Unmarshal(input, registry) - - if *update { - if err == nil { - json, err := protojson.Marshal(output) - require.NoError(t, err) - write(t, base+".golden", json) - } else { - write(t, base+".error", []byte(err.Error())) - } - } - - goldenJSON, haveGoldenJSON := read(t, base+".golden") - goldenError, haveGoldenError := read(t, base+".error") - - if haveGoldenError && haveGoldenJSON { - t.Fatalf("both %s.golden and %s.error exist, delete one", base, base) - } - - if !haveGoldenError && !haveGoldenJSON && !*update { - t.Fatalf("neither %s.golden or %s.error exist, run the tests again with the -update flag to create one", base, base) - } - - if haveGoldenError { - require.Error(t, err) - require.Equal(t, string(goldenError), err.Error()) - } - - if haveGoldenJSON { - require.NoError(t, err) - - var exp pbresource.Resource - require.NoError(t, protojson.Unmarshal(goldenJSON, &exp)) - prototest.AssertDeepEqual(t, &exp, output) - } - }) - } -} diff --git a/internal/storage/conformance/conformance.go b/internal/storage/conformance/conformance.go index 543a574fb5a60..22356a88a9c15 100644 --- a/internal/storage/conformance/conformance.go +++ b/internal/storage/conformance/conformance.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package conformance diff --git a/internal/storage/inmem/backend.go b/internal/storage/inmem/backend.go index bf256e508f4d6..fc22aa5ace81b 100644 --- a/internal/storage/inmem/backend.go +++ b/internal/storage/inmem/backend.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inmem diff --git a/internal/storage/inmem/backend_test.go b/internal/storage/inmem/backend_test.go index 7978dcdf29935..e37de15afab44 100644 --- a/internal/storage/inmem/backend_test.go +++ b/internal/storage/inmem/backend_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inmem_test diff --git a/internal/storage/inmem/event_index.go b/internal/storage/inmem/event_index.go index f71e809289aca..68d9ec13b142a 100644 --- a/internal/storage/inmem/event_index.go +++ b/internal/storage/inmem/event_index.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inmem diff --git a/internal/storage/inmem/schema.go b/internal/storage/inmem/schema.go index 37e39dbc57076..6a58eacd586b1 100644 --- a/internal/storage/inmem/schema.go +++ b/internal/storage/inmem/schema.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inmem diff --git a/internal/storage/inmem/snapshot.go b/internal/storage/inmem/snapshot.go index 36739ac65b20e..6233f4d30bfe4 100644 --- a/internal/storage/inmem/snapshot.go +++ b/internal/storage/inmem/snapshot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inmem diff --git a/internal/storage/inmem/snapshot_test.go b/internal/storage/inmem/snapshot_test.go index f3e1bdbaa79e5..b703495d2c7fa 100644 --- a/internal/storage/inmem/snapshot_test.go +++ b/internal/storage/inmem/snapshot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inmem_test diff --git a/internal/storage/inmem/store.go b/internal/storage/inmem/store.go index d9c27d339fa3d..5c50b1c138a3f 100644 --- a/internal/storage/inmem/store.go +++ b/internal/storage/inmem/store.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inmem diff --git a/internal/storage/inmem/watch.go b/internal/storage/inmem/watch.go index bdab0fc5ee864..85c657e3a3c6c 100644 --- a/internal/storage/inmem/watch.go +++ b/internal/storage/inmem/watch.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package inmem diff --git a/internal/storage/raft/backend.go b/internal/storage/raft/backend.go index 8a7a973c3e7cf..4e1cd05bbb18a 100644 --- a/internal/storage/raft/backend.go +++ b/internal/storage/raft/backend.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package raft diff --git a/internal/storage/raft/conformance_test.go b/internal/storage/raft/conformance_test.go index 6c75e462d21c3..ef79087e171d2 100644 --- a/internal/storage/raft/conformance_test.go +++ b/internal/storage/raft/conformance_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package raft_test diff --git a/internal/storage/raft/forwarding.go b/internal/storage/raft/forwarding.go index 2700339afbe58..798ca58465d5e 100644 --- a/internal/storage/raft/forwarding.go +++ b/internal/storage/raft/forwarding.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package raft diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 4411bc77caf03..24a763e395473 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package storage @@ -298,10 +298,6 @@ func UnversionedTypeFrom(t *pbresource.Type) UnversionedType { } } -func (u UnversionedType) String() string { - return fmt.Sprintf("%s.%s", u.Group, u.Kind) -} - // GroupVersionMismatchError is returned when a resource is stored as a type // with a different GroupVersion than was requested. type GroupVersionMismatchError struct { diff --git a/internal/tenancy/exports.go b/internal/tenancy/exports.go deleted file mode 100644 index 806e85b7b076f..0000000000000 --- a/internal/tenancy/exports.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tenancy - -import ( - "github.com/hashicorp/consul/internal/controller" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/tenancy/internal/bridge" - "github.com/hashicorp/consul/internal/tenancy/internal/controllers" - "github.com/hashicorp/consul/internal/tenancy/internal/types" -) - -type ( - V2TenancyBridge = bridge.V2TenancyBridge -) - -// RegisterTypes adds all resource types within the "tenancy" API group -// to the given type registry -func RegisterTypes(r resource.Registry) { - types.Register(r) -} - -// RegisterControllers registers controllers for the tenancy types with -// the given controller manager. -func RegisterControllers(mgr *controller.Manager) { - controllers.Register(mgr) -} - -func NewV2TenancyBridge() *V2TenancyBridge { - return bridge.NewV2TenancyBridge() -} diff --git a/internal/tenancy/internal/bridge/tenancy_bridge.go b/internal/tenancy/internal/bridge/tenancy_bridge.go deleted file mode 100644 index db6a4dd53a176..0000000000000 --- a/internal/tenancy/internal/bridge/tenancy_bridge.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package bridge - -import ( - "context" - - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" -) - -// V2TenancyBridge is used by the resource service to access V2 implementations of -// partitions and namespaces. -type V2TenancyBridge struct { - client pbresource.ResourceServiceClient -} - -// WithClient inject a ResourceServiceClient in the V2TenancyBridge. -// This is needed to break a circular dependency between -// the ResourceServiceServer, ResourceServiceClient and the TenancyBridge -func (b *V2TenancyBridge) WithClient(client pbresource.ResourceServiceClient) *V2TenancyBridge { - b.client = client - return b -} - -func NewV2TenancyBridge() *V2TenancyBridge { - return &V2TenancyBridge{} -} - -func (b *V2TenancyBridge) NamespaceExists(partition, namespace string) (bool, error) { - read, err := b.client.Read(context.Background(), &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Name: namespace, - Tenancy: &pbresource.Tenancy{ - Partition: partition, - }, - Type: pbtenancy.NamespaceType, - }, - }) - return read != nil && read.Resource != nil, err -} - -func (b *V2TenancyBridge) IsNamespaceMarkedForDeletion(partition, namespace string) (bool, error) { - read, err := b.client.Read(context.Background(), &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Name: namespace, - Tenancy: &pbresource.Tenancy{ - Partition: partition, - }, - Type: pbtenancy.NamespaceType, - }, - }) - return read.Resource != nil, err -} diff --git a/internal/tenancy/internal/bridge/tenancy_bridge_ce.go b/internal/tenancy/internal/bridge/tenancy_bridge_ce.go deleted file mode 100644 index dcf4df663cc73..0000000000000 --- a/internal/tenancy/internal/bridge/tenancy_bridge_ce.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package bridge - -func (b *V2TenancyBridge) PartitionExists(partition string) (bool, error) { - if partition == "default" { - return true, nil - } - return false, nil -} - -func (b *V2TenancyBridge) IsPartitionMarkedForDeletion(partition string) (bool, error) { - return false, nil -} diff --git a/internal/tenancy/internal/controllers/register_ce.go b/internal/tenancy/internal/controllers/register_ce.go deleted file mode 100644 index 324f1bcfc0345..0000000000000 --- a/internal/tenancy/internal/controllers/register_ce.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package controllers - -import ( - "github.com/hashicorp/consul/internal/controller" -) - -func Register(mgr *controller.Manager) { - //mgr.Register(namespace.NamespaceController()) -} diff --git a/internal/tenancy/internal/types/errors.go b/internal/tenancy/internal/types/errors.go deleted file mode 100644 index 42df9b319fb7c..0000000000000 --- a/internal/tenancy/internal/types/errors.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import "errors" - -var ( - errInvalidName = errors.New("invalid namespace name provided") - errOwnerNonEmpty = errors.New("namespace should not have an owner") -) diff --git a/internal/tenancy/internal/types/namespace.go b/internal/tenancy/internal/types/namespace.go deleted file mode 100644 index c45b405e8b325..0000000000000 --- a/internal/tenancy/internal/types/namespace.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - "strings" - - "github.com/hashicorp/consul/agent/dns" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" -) - -func RegisterNamespace(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbtenancy.NamespaceType, - Proto: &pbtenancy.Namespace{}, - Scope: resource.ScopePartition, - Validate: ValidateNamespace, - // ACLs: TODO - }) -} - -func ValidateNamespace(res *pbresource.Resource) error { - var ns pbtenancy.Namespace - - if err := res.Data.UnmarshalTo(&ns); err != nil { - return resource.NewErrDataParse(&ns, err) - } - if res.Owner != nil { - return errOwnerNonEmpty - } - - // it's not allowed to create default/default tenancy - if res.Id.Name == resource.DefaultNamespaceName && res.Id.Tenancy.Partition == resource.DefaultPartitionName { - return errInvalidName - } - - if !dns.IsValidLabel(res.Id.Name) { - return fmt.Errorf("namespace name %q is not a valid DNS hostname", res.Id.Name) - } - - switch strings.ToLower(res.Id.Name) { - case "system", "universal", "operator", "root": - return fmt.Errorf("namespace %q is reserved for future internal use", res.Id.Name) - default: - - return nil - } -} diff --git a/internal/tenancy/internal/types/types.go b/internal/tenancy/internal/types/types.go deleted file mode 100644 index 5955ade8a5d7b..0000000000000 --- a/internal/tenancy/internal/types/types.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -const ( - GroupName = "tenancy" - VersionV2Beta1 = "v2beta1" - CurrentVersion = VersionV2Beta1 -) diff --git a/internal/tenancy/internal/types/types_ce.go b/internal/tenancy/internal/types/types_ce.go deleted file mode 100644 index 8d475789710c3..0000000000000 --- a/internal/tenancy/internal/types/types_ce.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package types - -import "github.com/hashicorp/consul/internal/resource" - -func Register(r resource.Registry) { - RegisterNamespace(r) -} diff --git a/internal/tenancy/internal/types/types_test.go b/internal/tenancy/internal/types/types_test.go deleted file mode 100644 index df22b71f13a27..0000000000000 --- a/internal/tenancy/internal/types/types_test.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" -) - -func createNamespaceResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { - res := &pbresource.Resource{ - Id: &pbresource.ID{ - Type: pbtenancy.NamespaceType, - Tenancy: resource.DefaultPartitionedTenancy(), - Name: "ns1234", - }, - } - - var err error - res.Data, err = anypb.New(data) - require.NoError(t, err) - return res -} - -func TestValidateNamespace_Ok(t *testing.T) { - res := createNamespaceResource(t, validNamespace()) - - err := ValidateNamespace(res) - require.NoError(t, err) -} - -func TestValidateNamespace_defaultNamespace(t *testing.T) { - res := createNamespaceResource(t, validNamespace()) - res.Id.Name = resource.DefaultNamespaceName - - err := ValidateNamespace(res) - require.Error(t, err) - require.ErrorAs(t, err, &errInvalidName) -} - -func TestValidateNamespace_defaultNamespaceNonDefaultPartition(t *testing.T) { - res := createNamespaceResource(t, validNamespace()) - res.Id.Name = resource.DefaultNamespaceName - res.Id.Tenancy.Partition = "foo" - - err := ValidateNamespace(res) - require.NoError(t, err) -} - -func TestValidateNamespace_InvalidName(t *testing.T) { - res := createNamespaceResource(t, validNamespace()) - res.Id.Name = "-invalid" - - err := ValidateNamespace(res) - require.Error(t, err) - require.ErrorAs(t, err, &errInvalidName) -} - -func TestValidateNamespace_InvalidOwner(t *testing.T) { - res := createNamespaceResource(t, validNamespace()) - res.Owner = &pbresource.ID{} - err := ValidateNamespace(res) - - require.Error(t, err) - require.ErrorAs(t, err, &errOwnerNonEmpty) -} - -func TestValidateNamespace_ParseError(t *testing.T) { - // Any type other than the Namespace type would work - // to cause the error we are expecting - data := &pbcatalog.IP{Address: "198.18.0.1"} - - res := createNamespaceResource(t, data) - - err := ValidateNamespace(res) - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) -} - -func TestValidateNamespace(t *testing.T) { - tests := []struct { - name string - namespaceName string - err string - }{ - {"system", "System", "namespace \"System\" is reserved for future internal use"}, - {"invalid", "-inval", "namespace name \"-inval\" is not a valid DNS hostname"}, - {"valid", "ns1", ""}, - {"space prefix", " foo", "namespace name \" foo\" is not a valid DNS hostname"}, - {"space suffix", "bar ", "namespace name \"bar \" is not a valid DNS hostname"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - a, err := anypb.New(&pbtenancy.Namespace{}) - require.NoError(t, err) - res := &pbresource.Resource{Id: &pbresource.ID{Name: tt.namespaceName}, Data: a} - err = ValidateNamespace(res) - if tt.err == "" { - require.NoError(t, err) - } else { - require.Equal(t, err.Error(), tt.err) - } - - }) - } -} - -func validNamespace() *pbtenancy.Namespace { - return &pbtenancy.Namespace{ - Description: "ns namespace", - } -} diff --git a/internal/tenancy/tenancytest/namespace_test.go b/internal/tenancy/tenancytest/namespace_test.go deleted file mode 100644 index e2461c254cd20..0000000000000 --- a/internal/tenancy/tenancytest/namespace_test.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tenancytest - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - svc "github.com/hashicorp/consul/agent/grpc-external/services/resource" - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/internal/tenancy" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestWriteNamespace_Success(t *testing.T) { - v2TenancyBridge := tenancy.NewV2TenancyBridge() - config := svc.Config{TenancyBridge: v2TenancyBridge, UseV2Tenancy: true} - client := svctest.RunResourceServiceWithConfig(t, config, tenancy.RegisterTypes) - cl := rtest.NewClient(client) - - res := rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithTenancy(resource.DefaultPartitionedTenancy()). - WithData(t, validNamespace()). - Build() - - writeRsp, err := cl.Write(context.Background(), &pbresource.WriteRequest{Resource: res}) - require.NoError(t, err) - prototest.AssertDeepEqual(t, res.Id.Type, writeRsp.Resource.Id.Type) - prototest.AssertDeepEqual(t, res.Id.Tenancy, writeRsp.Resource.Id.Tenancy) - prototest.AssertDeepEqual(t, res.Id.Name, writeRsp.Resource.Id.Name) - prototest.AssertDeepEqual(t, res.Data, writeRsp.Resource.Data) -} - -func TestReadNamespace_Success(t *testing.T) { - v2TenancyBridge := tenancy.NewV2TenancyBridge() - config := svc.Config{TenancyBridge: v2TenancyBridge, UseV2Tenancy: true} - client := svctest.RunResourceServiceWithConfig(t, config, tenancy.RegisterTypes) - cl := rtest.NewClient(client) - - res := rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithData(t, validNamespace()). - Write(t, cl) - - cases := []struct { - name string - resource *pbresource.Resource - errMsg string - }{ - { - name: "read namespace", - resource: rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithData(t, validNamespace()). - Build(), - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - readRsp, err := cl.Read(context.Background(), &pbresource.ReadRequest{Id: tc.resource.Id}) - require.NoError(t, err) - prototest.AssertDeepEqual(t, res.Id, readRsp.Resource.Id) - prototest.AssertDeepEqual(t, res.Data, readRsp.Resource.Data) - }) - } -} - -func TestDeleteNamespace_Success(t *testing.T) { - v2TenancyBridge := tenancy.NewV2TenancyBridge() - config := svc.Config{TenancyBridge: v2TenancyBridge, UseV2Tenancy: true} - client := svctest.RunResourceServiceWithConfig(t, config, tenancy.RegisterTypes) - cl := rtest.NewClient(client) - - res := rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithData(t, validNamespace()).Write(t, cl) - - readRsp, err := cl.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - prototest.AssertDeepEqual(t, res.Id, readRsp.Resource.Id) - - _, err = cl.Delete(context.Background(), &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) - - _, err = cl.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) - require.Error(t, err) - require.Equal(t, codes.NotFound.String(), status.Code(err).String()) - -} - -func TestListNamespace_Success(t *testing.T) { - v2TenancyBridge := tenancy.NewV2TenancyBridge() - config := svc.Config{TenancyBridge: v2TenancyBridge, UseV2Tenancy: true} - client := svctest.RunResourceServiceWithConfig(t, config, tenancy.RegisterTypes) - cl := rtest.NewClient(client) - - res := rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithData(t, validNamespace()).Write(t, cl) - - require.NotNil(t, res) - res = rtest.Resource(pbtenancy.NamespaceType, "ns2"). - WithData(t, validNamespace()).Write(t, cl) - - require.NotNil(t, res) - - listRsp, err := cl.List(context.Background(), &pbresource.ListRequest{Type: pbtenancy.NamespaceType, Tenancy: resource.DefaultPartitionedTenancy()}) - require.NoError(t, err) - require.Len(t, listRsp.Resources, 3) - names := []string{ - listRsp.Resources[0].Id.Name, - listRsp.Resources[1].Id.Name, - listRsp.Resources[2].Id.Name, - } - require.Contains(t, names, "default") - require.Contains(t, names, "ns1") - require.Contains(t, names, "ns2") -} - -func validNamespace() *pbtenancy.Namespace { - return &pbtenancy.Namespace{ - Description: "ns namespace", - } -} diff --git a/internal/testing/golden/golden.go b/internal/testing/golden/golden.go index a4d971d0d0960..079f69f02aa5a 100644 --- a/internal/testing/golden/golden.go +++ b/internal/testing/golden/golden.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package golden @@ -22,16 +22,6 @@ var update = flag.Bool("update", false, "update golden files") // to the value of actual. func Get(t *testing.T, actual, filename string) string { t.Helper() - return string(GetBytes(t, actual, filename)) -} - -// GetBytes reads the expected value from the file at filename and returns the -// value as a byte array. filename is relative to the ./testdata directory. -// -// If the `-update` flag is used with `go test`, the golden file will be updated -// to the value of actual. -func GetBytes(t *testing.T, actual, filename string) []byte { - t.Helper() path := filepath.Join("testdata", filename) if *update { @@ -42,15 +32,7 @@ func GetBytes(t *testing.T, actual, filename string) []byte { require.NoError(t, err) } - return GetBytesAtFilePath(t, path) -} - -// GetBytes reads the expected value from the file at filepath and returns the -// value as a byte array. filepath is relative to the ./testdata directory. -func GetBytesAtFilePath(t *testing.T, filepath string) []byte { - t.Helper() - - expected, err := os.ReadFile(filepath) + expected, err := os.ReadFile(path) require.NoError(t, err) - return expected + return string(expected) } diff --git a/internal/tools/proto-gen-rpc-glue/e2e/consul/agent/structs/structs.go b/internal/tools/proto-gen-rpc-glue/e2e/consul/agent/structs/structs.go index 6e76027299ded..59d2a19b8c9bb 100644 --- a/internal/tools/proto-gen-rpc-glue/e2e/consul/agent/structs/structs.go +++ b/internal/tools/proto-gen-rpc-glue/e2e/consul/agent/structs/structs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package structs diff --git a/internal/tools/proto-gen-rpc-glue/e2e/consul/proto/pbcommon/common.go b/internal/tools/proto-gen-rpc-glue/e2e/consul/proto/pbcommon/common.go index 1395e682edd3c..5c1b497e55185 100644 --- a/internal/tools/proto-gen-rpc-glue/e2e/consul/proto/pbcommon/common.go +++ b/internal/tools/proto-gen-rpc-glue/e2e/consul/proto/pbcommon/common.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbcommon diff --git a/internal/tools/proto-gen-rpc-glue/e2e/source.pb.go b/internal/tools/proto-gen-rpc-glue/e2e/source.pb.go index c69dac63b5c08..3a83b84317526 100644 --- a/internal/tools/proto-gen-rpc-glue/e2e/source.pb.go +++ b/internal/tools/proto-gen-rpc-glue/e2e/source.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build example // +build example diff --git a/internal/tools/proto-gen-rpc-glue/main.go b/internal/tools/proto-gen-rpc-glue/main.go index 2412c3386208d..65a25122bc708 100644 --- a/internal/tools/proto-gen-rpc-glue/main.go +++ b/internal/tools/proto-gen-rpc-glue/main.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package main diff --git a/internal/tools/proto-gen-rpc-glue/main_test.go b/internal/tools/proto-gen-rpc-glue/main_test.go index 01eb28e92a31d..87ed4e3917ede 100644 --- a/internal/tools/proto-gen-rpc-glue/main_test.go +++ b/internal/tools/proto-gen-rpc-glue/main_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package main diff --git a/internal/tools/protoc-gen-consul-rate-limit/main.go b/internal/tools/protoc-gen-consul-rate-limit/main.go index 61d46dd8c77c8..b4bf5711584a6 100644 --- a/internal/tools/protoc-gen-consul-rate-limit/main.go +++ b/internal/tools/protoc-gen-consul-rate-limit/main.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // protoc-gen-consul-rate-limit // This protoc plugin maintains the mapping of gRPC method names to @@ -93,7 +93,7 @@ func main() { } if len(specs) == 0 { - continue + return nil } outputPath := filepath.Join(filepath.Dir(path), outputFileName) diff --git a/internal/tools/protoc-gen-consul-rate-limit/postprocess/main.go b/internal/tools/protoc-gen-consul-rate-limit/postprocess/main.go index 570e2ebdac72b..bd9ea5779ce14 100644 --- a/internal/tools/protoc-gen-consul-rate-limit/postprocess/main.go +++ b/internal/tools/protoc-gen-consul-rate-limit/postprocess/main.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package main @@ -27,6 +27,7 @@ import "github.com/hashicorp/consul/agent/consul/rate" ` entTags = `//go:build consulent +// +build consulent ` ) diff --git a/ipaddr/detect.go b/ipaddr/detect.go index bc2bf56c350cb..e208b13ed5be5 100644 --- a/ipaddr/detect.go +++ b/ipaddr/detect.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ipaddr diff --git a/ipaddr/detect_test.go b/ipaddr/detect_test.go index c199492c174f9..865421e10cf00 100644 --- a/ipaddr/detect_test.go +++ b/ipaddr/detect_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ipaddr diff --git a/ipaddr/ipaddr.go b/ipaddr/ipaddr.go index 89f8c70a4ceba..92a04e80181d2 100644 --- a/ipaddr/ipaddr.go +++ b/ipaddr/ipaddr.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ipaddr diff --git a/ipaddr/ipaddr_test.go b/ipaddr/ipaddr_test.go index 009144c2de25d..a8aae7f32dde1 100644 --- a/ipaddr/ipaddr_test.go +++ b/ipaddr/ipaddr_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ipaddr diff --git a/lib/cluster.go b/lib/cluster.go index a97ceea722e97..3b121da59835c 100644 --- a/lib/cluster.go +++ b/lib/cluster.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/cluster_test.go b/lib/cluster_test.go index 3493a6fb39f12..44b77332dfec1 100644 --- a/lib/cluster_test.go +++ b/lib/cluster_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/decode/decode.go b/lib/decode/decode.go index 645916d2d6654..fc1558a9f7890 100644 --- a/lib/decode/decode.go +++ b/lib/decode/decode.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 /* Package decode provides tools for customizing the decoding of configuration, diff --git a/lib/decode/decode_test.go b/lib/decode/decode_test.go index 3219e96b4bf9a..b1250ebcc81aa 100644 --- a/lib/decode/decode_test.go +++ b/lib/decode/decode_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package decode diff --git a/lib/eof.go b/lib/eof.go index e208ca73d7535..b8f6ac0e240ec 100644 --- a/lib/eof.go +++ b/lib/eof.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/eof_test.go b/lib/eof_test.go index 330a1152a8eb7..373846a72c942 100644 --- a/lib/eof_test.go +++ b/lib/eof_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/file/atomic.go b/lib/file/atomic.go index 4053f443d8b36..3fa5890052c8d 100644 --- a/lib/file/atomic.go +++ b/lib/file/atomic.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package file diff --git a/lib/file/atomic_test.go b/lib/file/atomic_test.go index baf4bc1771f8e..a74b2d2ecd497 100644 --- a/lib/file/atomic_test.go +++ b/lib/file/atomic_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package file diff --git a/lib/hoststats/collector.go b/lib/hoststats/collector.go index fb316e0dce38f..c4c57b35c5c25 100644 --- a/lib/hoststats/collector.go +++ b/lib/hoststats/collector.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package hoststats import ( diff --git a/lib/hoststats/cpu.go b/lib/hoststats/cpu.go index 420a80ef94240..45633b40df064 100644 --- a/lib/hoststats/cpu.go +++ b/lib/hoststats/cpu.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package hoststats import ( diff --git a/lib/hoststats/cpu_test.go b/lib/hoststats/cpu_test.go index dcc1df9aab50e..5d5efbe9769a1 100644 --- a/lib/hoststats/cpu_test.go +++ b/lib/hoststats/cpu_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package hoststats import ( diff --git a/lib/hoststats/host.go b/lib/hoststats/host.go index 3a44618d20f16..426cf43ea21e5 100644 --- a/lib/hoststats/host.go +++ b/lib/hoststats/host.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package hoststats import ( diff --git a/lib/hoststats/metrics.go b/lib/hoststats/metrics.go index 95055cea43fb3..c89d40b813ff1 100644 --- a/lib/hoststats/metrics.go +++ b/lib/hoststats/metrics.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package hoststats import ( diff --git a/lib/json.go b/lib/json.go index 7e58942a823de..c5ae22b2f90c7 100644 --- a/lib/json.go +++ b/lib/json.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/map_walker.go b/lib/map_walker.go index 1be33b61f15fd..3e8cec77ca643 100644 --- a/lib/map_walker.go +++ b/lib/map_walker.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/map_walker_test.go b/lib/map_walker_test.go index 6156abe4624f8..2a3b4c189d9ec 100644 --- a/lib/map_walker_test.go +++ b/lib/map_walker_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/maps/maps.go b/lib/maps/maps.go index ae19d030a2c01..1996d5f4cd9a9 100644 --- a/lib/maps/maps.go +++ b/lib/maps/maps.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package maps diff --git a/lib/maps/maps_test.go b/lib/maps/maps_test.go index 5d0f4edbc44ef..bebb9afb5f155 100644 --- a/lib/maps/maps_test.go +++ b/lib/maps/maps_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package maps diff --git a/lib/math.go b/lib/math.go index 673dfb84e99cf..75859a2a65801 100644 --- a/lib/math.go +++ b/lib/math.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/math_test.go b/lib/math_test.go index 2ce631fe75dce..7ac4141a268c8 100644 --- a/lib/math_test.go +++ b/lib/math_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib_test diff --git a/lib/mutex/mutex.go b/lib/mutex/mutex.go index 8101204c2e006..a28290c0b3b44 100644 --- a/lib/mutex/mutex.go +++ b/lib/mutex/mutex.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 /* Package mutex implements the sync.Locker interface using x/sync/semaphore. It diff --git a/lib/mutex/mutex_test.go b/lib/mutex/mutex_test.go index 2d51706e4e855..000681d03e86f 100644 --- a/lib/mutex/mutex_test.go +++ b/lib/mutex/mutex_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package mutex diff --git a/lib/path.go b/lib/path.go index fd45378ec1804..347de0cbde09b 100644 --- a/lib/path.go +++ b/lib/path.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/retry/retry.go b/lib/retry/retry.go index e0605f89c4a89..ee9a8b2354e63 100644 --- a/lib/retry/retry.go +++ b/lib/retry/retry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package retry diff --git a/lib/retry/retry_test.go b/lib/retry/retry_test.go index d8a822f6b606a..74bb982b91edc 100644 --- a/lib/retry/retry_test.go +++ b/lib/retry/retry_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package retry diff --git a/lib/routine/routine.go b/lib/routine/routine.go index b5ebe85e22f14..3bcbd1fbee452 100644 --- a/lib/routine/routine.go +++ b/lib/routine/routine.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package routine diff --git a/lib/routine/routine_test.go b/lib/routine/routine_test.go index c04311ac59f49..cfb98d98c3c84 100644 --- a/lib/routine/routine_test.go +++ b/lib/routine/routine_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package routine diff --git a/lib/rtt.go b/lib/rtt.go index d716e6fcbe1c5..5d90431f5d65a 100644 --- a/lib/rtt.go +++ b/lib/rtt.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/rtt_test.go b/lib/rtt_test.go index 1e7779b9addeb..a8a6786ecf622 100644 --- a/lib/rtt_test.go +++ b/lib/rtt_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/semaphore/semaphore.go b/lib/semaphore/semaphore.go index fdfbbb34db021..662d21152868a 100644 --- a/lib/semaphore/semaphore.go +++ b/lib/semaphore/semaphore.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Package semaphore implements a simple semaphore that is based on // golang.org/x/sync/semaphore but doesn't support weights. It's advantage over diff --git a/lib/semaphore/semaphore_test.go b/lib/semaphore/semaphore_test.go index b3182e1107af7..d7da1979b00f4 100644 --- a/lib/semaphore/semaphore_test.go +++ b/lib/semaphore/semaphore_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package semaphore diff --git a/lib/serf/serf.go b/lib/serf/serf.go index 932fed427ba94..ad5297e58b616 100644 --- a/lib/serf/serf.go +++ b/lib/serf/serf.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package serf diff --git a/lib/stop_context.go b/lib/stop_context.go index 98bde25e452b5..ea560e0929e96 100644 --- a/lib/stop_context.go +++ b/lib/stop_context.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/stop_context_test.go b/lib/stop_context_test.go index b62749513f2f7..6da3a6fc61aea 100644 --- a/lib/stop_context_test.go +++ b/lib/stop_context_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/strings.go b/lib/strings.go index 7213a93259141..d268845acc9c4 100644 --- a/lib/strings.go +++ b/lib/strings.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/stringslice/stringslice.go b/lib/stringslice/stringslice.go index 7c32864b9458c..325f603d778dc 100644 --- a/lib/stringslice/stringslice.go +++ b/lib/stringslice/stringslice.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stringslice diff --git a/lib/stringslice/stringslice_test.go b/lib/stringslice/stringslice_test.go index dd25071757442..975fe34976ec2 100644 --- a/lib/stringslice/stringslice_test.go +++ b/lib/stringslice/stringslice_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package stringslice diff --git a/lib/telemetry.go b/lib/telemetry.go index e06341eefb05b..b66ec721b1dc0 100644 --- a/lib/telemetry.go +++ b/lib/telemetry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/telemetry_test.go b/lib/telemetry_test.go index ab0f7e5b91411..a2c0075598ecc 100644 --- a/lib/telemetry_test.go +++ b/lib/telemetry_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/template/hil.go b/lib/template/hil.go index 502f10d258b20..5b9cc0e2cf148 100644 --- a/lib/template/hil.go +++ b/lib/template/hil.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package template diff --git a/lib/template/hil_test.go b/lib/template/hil_test.go index 4f582f61d1685..84f3558a4a6a4 100644 --- a/lib/template/hil_test.go +++ b/lib/template/hil_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package template diff --git a/lib/translate.go b/lib/translate.go index 6fd49010fc81e..adb58539c0fd9 100644 --- a/lib/translate.go +++ b/lib/translate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/translate_test.go b/lib/translate_test.go index f36588b7404b1..36d113004a749 100644 --- a/lib/translate_test.go +++ b/lib/translate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/ttlcache/eviction.go b/lib/ttlcache/eviction.go index 5d5012e7dbacb..3e20bb09b6276 100644 --- a/lib/ttlcache/eviction.go +++ b/lib/ttlcache/eviction.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 /* Package ttlcache provides an ExpiryHeap that can be used by a cache to track the diff --git a/lib/ttlcache/eviction_test.go b/lib/ttlcache/eviction_test.go index 18bf2fbbc78bf..fe55b68cf1760 100644 --- a/lib/ttlcache/eviction_test.go +++ b/lib/ttlcache/eviction_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ttlcache diff --git a/lib/useragent.go b/lib/useragent.go index 89c73dec55297..e967ed11ffc74 100644 --- a/lib/useragent.go +++ b/lib/useragent.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/useragent_test.go b/lib/useragent_test.go index 23df537c9d4ac..4890e454a598b 100644 --- a/lib/useragent_test.go +++ b/lib/useragent_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/lib/uuid.go b/lib/uuid.go index 2c0d657f5b062..8db9517d70228 100644 --- a/lib/uuid.go +++ b/lib/uuid.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package lib diff --git a/logging/gated_writer.go b/logging/gated_writer.go index 5a28c8cf52339..2e0023369a770 100644 --- a/logging/gated_writer.go +++ b/logging/gated_writer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/gated_writer_test.go b/logging/gated_writer_test.go index cc44ad04b2b94..f0adc8de85a18 100644 --- a/logging/gated_writer_test.go +++ b/logging/gated_writer_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/grpc.go b/logging/grpc.go index ebe2207e454b8..f565b865fbd93 100644 --- a/logging/grpc.go +++ b/logging/grpc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/grpc_test.go b/logging/grpc_test.go index 0a90f11066093..29f1c976e555d 100644 --- a/logging/grpc_test.go +++ b/logging/grpc_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/log_levels.go b/logging/log_levels.go index 5ed830ee30503..dc3bb8b530b8f 100644 --- a/logging/log_levels.go +++ b/logging/log_levels.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/logfile.go b/logging/logfile.go index a4d48da2d6311..f84d12de4b199 100644 --- a/logging/logfile.go +++ b/logging/logfile.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/logfile_bsd.go b/logging/logfile_bsd.go index df599358d0478..d81d065be1ce5 100644 --- a/logging/logfile_bsd.go +++ b/logging/logfile_bsd.go @@ -1,7 +1,5 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - //go:build darwin || freebsd || netbsd || openbsd +// +build darwin freebsd netbsd openbsd package logging diff --git a/logging/logfile_linux.go b/logging/logfile_linux.go index 1e8f19b1da721..6cdacfe80e227 100644 --- a/logging/logfile_linux.go +++ b/logging/logfile_linux.go @@ -1,7 +1,5 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - //go:build dragonfly || linux +// +build dragonfly linux package logging diff --git a/logging/logfile_solaris.go b/logging/logfile_solaris.go index ba92442084a94..b64610cc38fc6 100644 --- a/logging/logfile_solaris.go +++ b/logging/logfile_solaris.go @@ -1,7 +1,5 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - //go:build solaris +// +build solaris package logging diff --git a/logging/logfile_test.go b/logging/logfile_test.go index 26c23439f20b2..6f97305662974 100644 --- a/logging/logfile_test.go +++ b/logging/logfile_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/logfile_windows.go b/logging/logfile_windows.go index d60f8d2a99e3c..688a8351cdbea 100644 --- a/logging/logfile_windows.go +++ b/logging/logfile_windows.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package logging import ( diff --git a/logging/logger.go b/logging/logger.go index 8d63ed7e15eb3..fb5128790fd0a 100644 --- a/logging/logger.go +++ b/logging/logger.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/logger_test.go b/logging/logger_test.go index 5cb0c1e44189a..ca5f1eecd2481 100644 --- a/logging/logger_test.go +++ b/logging/logger_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/monitor/monitor.go b/logging/monitor/monitor.go index 6a812a879f642..7440a6586f632 100644 --- a/logging/monitor/monitor.go +++ b/logging/monitor/monitor.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package monitor diff --git a/logging/monitor/monitor_test.go b/logging/monitor/monitor_test.go index 5f834f4f2322e..ba77eab36fdd7 100644 --- a/logging/monitor/monitor_test.go +++ b/logging/monitor/monitor_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package monitor diff --git a/logging/names.go b/logging/names.go index 69a859443cfb9..1c7ecc4487872 100644 --- a/logging/names.go +++ b/logging/names.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/syslog.go b/logging/syslog.go index ceb0ae0ac2f2d..8eb1391fcb3b3 100644 --- a/logging/syslog.go +++ b/logging/syslog.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package logging diff --git a/logging/syslog_test.go b/logging/syslog_test.go index 0e814a84fb01a..fdef92b5284b4 100644 --- a/logging/syslog_test.go +++ b/logging/syslog_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd || solaris +// +build linux darwin dragonfly freebsd netbsd openbsd solaris package logging diff --git a/logging/syslog_unsupported_test.go b/logging/syslog_unsupported_test.go index 650fc2225d0c3..d616580d2f220 100644 --- a/logging/syslog_unsupported_test.go +++ b/logging/syslog_unsupported_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build windows || plan9 || nacl +// +build windows plan9 nacl package logging diff --git a/main.go b/main.go index d29454035b12f..63f5a4f26dd84 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package main diff --git a/proto-public/LICENSE b/proto-public/LICENSE deleted file mode 100644 index 7c5baa45e1c29..0000000000000 --- a/proto-public/LICENSE +++ /dev/null @@ -1,365 +0,0 @@ -Copyright (c) 2020 HashiCorp, Inc. - -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/proto-public/annotations/ratelimit/ratelimit_deepcopy.gen.go b/proto-public/annotations/ratelimit/ratelimit_deepcopy.gen.go deleted file mode 100644 index 6c1c696337342..0000000000000 --- a/proto-public/annotations/ratelimit/ratelimit_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package ratelimit - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Spec within kubernetes types, where deepcopy-gen is used. -func (in *Spec) DeepCopyInto(out *Spec) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Spec. Required by controller-gen. -func (in *Spec) DeepCopy() *Spec { - if in == nil { - return nil - } - out := new(Spec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Spec. Required by controller-gen. -func (in *Spec) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/annotations/ratelimit/ratelimit_json.gen.go b/proto-public/annotations/ratelimit/ratelimit_json.gen.go deleted file mode 100644 index 93cb514be9a31..0000000000000 --- a/proto-public/annotations/ratelimit/ratelimit_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package ratelimit - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Spec -func (this *Spec) MarshalJSON() ([]byte, error) { - str, err := RatelimitMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Spec -func (this *Spec) UnmarshalJSON(b []byte) error { - return RatelimitUnmarshaler.Unmarshal(b, this) -} - -var ( - RatelimitMarshaler = &protojson.MarshalOptions{} - RatelimitUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/buf.gen.yaml b/proto-public/buf.gen.yaml index a58bd2511935f..738828ad87acc 100644 --- a/proto-public/buf.gen.yaml +++ b/proto-public/buf.gen.yaml @@ -19,18 +19,7 @@ plugins: out: . opt: - paths=source_relative - - name: resource-types - out: . - opt: - - paths=source_relative - strategy: all - name: consul-rate-limit out: . opt: - paths=source_relative - - name: deepcopy - out: . - opt: paths=source_relative - - name: json-shim - out: . - opt: paths=source_relative diff --git a/proto-public/go.mod b/proto-public/go.mod index ab00c6c62e2ce..63a8f91ca4b01 100644 --- a/proto-public/go.mod +++ b/proto-public/go.mod @@ -4,7 +4,6 @@ go 1.19 require ( github.com/stretchr/testify v1.8.3 - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 google.golang.org/grpc v1.56.3 google.golang.org/protobuf v1.30.0 ) diff --git a/proto-public/go.sum b/proto-public/go.sum index f11647a8490ed..21631b77b0603 100644 --- a/proto-public/go.sum +++ b/proto-public/go.sum @@ -30,8 +30,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -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/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= diff --git a/proto-public/pbacl/acl_deepcopy.gen.go b/proto-public/pbacl/acl_deepcopy.gen.go deleted file mode 100644 index b3b069fe1fc8a..0000000000000 --- a/proto-public/pbacl/acl_deepcopy.gen.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbacl - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using LogoutResponse within kubernetes types, where deepcopy-gen is used. -func (in *LogoutResponse) DeepCopyInto(out *LogoutResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LogoutResponse. Required by controller-gen. -func (in *LogoutResponse) DeepCopy() *LogoutResponse { - if in == nil { - return nil - } - out := new(LogoutResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LogoutResponse. Required by controller-gen. -func (in *LogoutResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LoginRequest within kubernetes types, where deepcopy-gen is used. -func (in *LoginRequest) DeepCopyInto(out *LoginRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginRequest. Required by controller-gen. -func (in *LoginRequest) DeepCopy() *LoginRequest { - if in == nil { - return nil - } - out := new(LoginRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LoginRequest. Required by controller-gen. -func (in *LoginRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LoginResponse within kubernetes types, where deepcopy-gen is used. -func (in *LoginResponse) DeepCopyInto(out *LoginResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginResponse. Required by controller-gen. -func (in *LoginResponse) DeepCopy() *LoginResponse { - if in == nil { - return nil - } - out := new(LoginResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LoginResponse. Required by controller-gen. -func (in *LoginResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LoginToken within kubernetes types, where deepcopy-gen is used. -func (in *LoginToken) DeepCopyInto(out *LoginToken) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginToken. Required by controller-gen. -func (in *LoginToken) DeepCopy() *LoginToken { - if in == nil { - return nil - } - out := new(LoginToken) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LoginToken. Required by controller-gen. -func (in *LoginToken) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LogoutRequest within kubernetes types, where deepcopy-gen is used. -func (in *LogoutRequest) DeepCopyInto(out *LogoutRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LogoutRequest. Required by controller-gen. -func (in *LogoutRequest) DeepCopy() *LogoutRequest { - if in == nil { - return nil - } - out := new(LogoutRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LogoutRequest. Required by controller-gen. -func (in *LogoutRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbacl/acl_json.gen.go b/proto-public/pbacl/acl_json.gen.go deleted file mode 100644 index 8e0b49eb9abdf..0000000000000 --- a/proto-public/pbacl/acl_json.gen.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbacl - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for LogoutResponse -func (this *LogoutResponse) MarshalJSON() ([]byte, error) { - str, err := AclMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LogoutResponse -func (this *LogoutResponse) UnmarshalJSON(b []byte) error { - return AclUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LoginRequest -func (this *LoginRequest) MarshalJSON() ([]byte, error) { - str, err := AclMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LoginRequest -func (this *LoginRequest) UnmarshalJSON(b []byte) error { - return AclUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LoginResponse -func (this *LoginResponse) MarshalJSON() ([]byte, error) { - str, err := AclMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LoginResponse -func (this *LoginResponse) UnmarshalJSON(b []byte) error { - return AclUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LoginToken -func (this *LoginToken) MarshalJSON() ([]byte, error) { - str, err := AclMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LoginToken -func (this *LoginToken) UnmarshalJSON(b []byte) error { - return AclUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LogoutRequest -func (this *LogoutRequest) MarshalJSON() ([]byte, error) { - str, err := AclMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LogoutRequest -func (this *LogoutRequest) UnmarshalJSON(b []byte) error { - return AclUnmarshaler.Unmarshal(b, this) -} - -var ( - AclMarshaler = &protojson.MarshalOptions{} - AclUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.binary.go b/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.binary.go deleted file mode 100644 index 2e1f9bd899644..0000000000000 --- a/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbauth/v2beta1/computed_traffic_permissions.proto - -package authv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedTrafficPermissions) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedTrafficPermissions) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.go b/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.go deleted file mode 100644 index b88c2e86bd037..0000000000000 --- a/proto-public/pbauth/v2beta1/computed_traffic_permissions.pb.go +++ /dev/null @@ -1,201 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbauth/v2beta1/computed_traffic_permissions.proto - -package authv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ComputedTrafficPermissions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AllowPermissions []*Permission `protobuf:"bytes,1,rep,name=allow_permissions,json=allowPermissions,proto3" json:"allow_permissions,omitempty"` - DenyPermissions []*Permission `protobuf:"bytes,2,rep,name=deny_permissions,json=denyPermissions,proto3" json:"deny_permissions,omitempty"` - IsDefault bool `protobuf:"varint,3,opt,name=is_default,json=isDefault,proto3" json:"is_default,omitempty"` -} - -func (x *ComputedTrafficPermissions) Reset() { - *x = ComputedTrafficPermissions{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_computed_traffic_permissions_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedTrafficPermissions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedTrafficPermissions) ProtoMessage() {} - -func (x *ComputedTrafficPermissions) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_computed_traffic_permissions_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedTrafficPermissions.ProtoReflect.Descriptor instead. -func (*ComputedTrafficPermissions) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDescGZIP(), []int{0} -} - -func (x *ComputedTrafficPermissions) GetAllowPermissions() []*Permission { - if x != nil { - return x.AllowPermissions - } - return nil -} - -func (x *ComputedTrafficPermissions) GetDenyPermissions() []*Permission { - if x != nil { - return x.DenyPermissions - } - return nil -} - -func (x *ComputedTrafficPermissions) GetIsDefault() bool { - if x != nil { - return x.IsDefault - } - return false -} - -var File_pbauth_v2beta1_computed_traffic_permissions_proto protoreflect.FileDescriptor - -var file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDesc = []byte{ - 0x0a, 0x31, 0x70, 0x62, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, - 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x1a, 0x28, 0x70, 0x62, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2f, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf1, 0x01, 0x0a, 0x1a, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x56, 0x0a, 0x11, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x10, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x54, 0x0a, 0x10, 0x64, 0x65, 0x6e, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, - 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x64, 0x65, 0x6e, 0x79, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x42, 0xa0, - 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x1f, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x72, - 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x2f, 0x70, 0x62, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x3b, 0x61, 0x75, 0x74, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, - 0x43, 0x41, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x3a, 0x3a, 0x41, 0x75, 0x74, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDescOnce sync.Once - file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDescData = file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDesc -) - -func file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDescGZIP() []byte { - file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDescOnce.Do(func() { - file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDescData) - }) - return file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDescData -} - -var file_pbauth_v2beta1_computed_traffic_permissions_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbauth_v2beta1_computed_traffic_permissions_proto_goTypes = []interface{}{ - (*ComputedTrafficPermissions)(nil), // 0: hashicorp.consul.auth.v2beta1.ComputedTrafficPermissions - (*Permission)(nil), // 1: hashicorp.consul.auth.v2beta1.Permission -} -var file_pbauth_v2beta1_computed_traffic_permissions_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.auth.v2beta1.ComputedTrafficPermissions.allow_permissions:type_name -> hashicorp.consul.auth.v2beta1.Permission - 1, // 1: hashicorp.consul.auth.v2beta1.ComputedTrafficPermissions.deny_permissions:type_name -> hashicorp.consul.auth.v2beta1.Permission - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_pbauth_v2beta1_computed_traffic_permissions_proto_init() } -func file_pbauth_v2beta1_computed_traffic_permissions_proto_init() { - if File_pbauth_v2beta1_computed_traffic_permissions_proto != nil { - return - } - file_pbauth_v2beta1_traffic_permissions_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbauth_v2beta1_computed_traffic_permissions_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedTrafficPermissions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbauth_v2beta1_computed_traffic_permissions_proto_goTypes, - DependencyIndexes: file_pbauth_v2beta1_computed_traffic_permissions_proto_depIdxs, - MessageInfos: file_pbauth_v2beta1_computed_traffic_permissions_proto_msgTypes, - }.Build() - File_pbauth_v2beta1_computed_traffic_permissions_proto = out.File - file_pbauth_v2beta1_computed_traffic_permissions_proto_rawDesc = nil - file_pbauth_v2beta1_computed_traffic_permissions_proto_goTypes = nil - file_pbauth_v2beta1_computed_traffic_permissions_proto_depIdxs = nil -} diff --git a/proto-public/pbauth/v2beta1/computed_traffic_permissions.proto b/proto-public/pbauth/v2beta1/computed_traffic_permissions.proto deleted file mode 100644 index 24127cc6a4684..0000000000000 --- a/proto-public/pbauth/v2beta1/computed_traffic_permissions.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package hashicorp.consul.auth.v2beta1; - -import "pbauth/v2beta1/traffic_permissions.proto"; -import "pbresource/annotations.proto"; - -message ComputedTrafficPermissions { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - repeated Permission allow_permissions = 1; - repeated Permission deny_permissions = 2; - bool is_default = 3; -} diff --git a/proto-public/pbauth/v2beta1/computed_traffic_permissions_deepcopy.gen.go b/proto-public/pbauth/v2beta1/computed_traffic_permissions_deepcopy.gen.go deleted file mode 100644 index 7c22d2285c2df..0000000000000 --- a/proto-public/pbauth/v2beta1/computed_traffic_permissions_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package authv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ComputedTrafficPermissions within kubernetes types, where deepcopy-gen is used. -func (in *ComputedTrafficPermissions) DeepCopyInto(out *ComputedTrafficPermissions) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTrafficPermissions. Required by controller-gen. -func (in *ComputedTrafficPermissions) DeepCopy() *ComputedTrafficPermissions { - if in == nil { - return nil - } - out := new(ComputedTrafficPermissions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTrafficPermissions. Required by controller-gen. -func (in *ComputedTrafficPermissions) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbauth/v2beta1/computed_traffic_permissions_json.gen.go b/proto-public/pbauth/v2beta1/computed_traffic_permissions_json.gen.go deleted file mode 100644 index cc81cf5ce2b2c..0000000000000 --- a/proto-public/pbauth/v2beta1/computed_traffic_permissions_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package authv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ComputedTrafficPermissions -func (this *ComputedTrafficPermissions) MarshalJSON() ([]byte, error) { - str, err := ComputedTrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedTrafficPermissions -func (this *ComputedTrafficPermissions) UnmarshalJSON(b []byte) error { - return ComputedTrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -var ( - ComputedTrafficPermissionsMarshaler = &protojson.MarshalOptions{} - ComputedTrafficPermissionsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbauth/v2beta1/resource_types.gen.go b/proto-public/pbauth/v2beta1/resource_types.gen.go deleted file mode 100644 index 850dcaa9d6612..0000000000000 --- a/proto-public/pbauth/v2beta1/resource_types.gen.go +++ /dev/null @@ -1,50 +0,0 @@ -// Code generated by protoc-gen-resource-types. DO NOT EDIT. - -package authv2beta1 - -import ( - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - GroupName = "auth" - Version = "v2beta1" - - ComputedTrafficPermissionsKind = "ComputedTrafficPermissions" - NamespaceTrafficPermissionsKind = "NamespaceTrafficPermissions" - PartitionTrafficPermissionsKind = "PartitionTrafficPermissions" - TrafficPermissionsKind = "TrafficPermissions" - WorkloadIdentityKind = "WorkloadIdentity" -) - -var ( - ComputedTrafficPermissionsType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ComputedTrafficPermissionsKind, - } - - NamespaceTrafficPermissionsType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: NamespaceTrafficPermissionsKind, - } - - PartitionTrafficPermissionsType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: PartitionTrafficPermissionsKind, - } - - TrafficPermissionsType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: TrafficPermissionsKind, - } - - WorkloadIdentityType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: WorkloadIdentityKind, - } -) diff --git a/proto-public/pbauth/v2beta1/traffic_permissions.pb.binary.go b/proto-public/pbauth/v2beta1/traffic_permissions.pb.binary.go deleted file mode 100644 index c1af15492ae71..0000000000000 --- a/proto-public/pbauth/v2beta1/traffic_permissions.pb.binary.go +++ /dev/null @@ -1,108 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbauth/v2beta1/traffic_permissions.proto - -package authv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TrafficPermissions) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TrafficPermissions) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *NamespaceTrafficPermissions) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *NamespaceTrafficPermissions) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *PartitionTrafficPermissions) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PartitionTrafficPermissions) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Destination) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Destination) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Permission) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Permission) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Source) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Source) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ExcludeSource) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ExcludeSource) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ExcludePermissionRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ExcludePermissionRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationRuleHeader) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationRuleHeader) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbauth/v2beta1/traffic_permissions.pb.go b/proto-public/pbauth/v2beta1/traffic_permissions.pb.go deleted file mode 100644 index 4226925386ac2..0000000000000 --- a/proto-public/pbauth/v2beta1/traffic_permissions.pb.go +++ /dev/null @@ -1,1182 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbauth/v2beta1/traffic_permissions.proto - -package authv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=ACTION_ALLOW;ACTION_DENY;ACTION_UNKNOWN -// +kubebuilder:validation:Type=string -type Action int32 - -const ( - Action_ACTION_UNSPECIFIED Action = 0 - Action_ACTION_DENY Action = 1 - Action_ACTION_ALLOW Action = 2 -) - -// Enum value maps for Action. -var ( - Action_name = map[int32]string{ - 0: "ACTION_UNSPECIFIED", - 1: "ACTION_DENY", - 2: "ACTION_ALLOW", - } - Action_value = map[string]int32{ - "ACTION_UNSPECIFIED": 0, - "ACTION_DENY": 1, - "ACTION_ALLOW": 2, - } -) - -func (x Action) Enum() *Action { - p := new(Action) - *p = x - return p -} - -func (x Action) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Action) Descriptor() protoreflect.EnumDescriptor { - return file_pbauth_v2beta1_traffic_permissions_proto_enumTypes[0].Descriptor() -} - -func (Action) Type() protoreflect.EnumType { - return &file_pbauth_v2beta1_traffic_permissions_proto_enumTypes[0] -} - -func (x Action) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Action.Descriptor instead. -func (Action) EnumDescriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{0} -} - -type TrafficPermissions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Destination is a configuration of the destination proxies - // where these traffic permissions should apply. - Destination *Destination `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"` - // Action can be either allow or deny for the entire object. It will default to allow. - // - // If action is allow, we will allow the connection if one of the rules in Rules matches, in other words, we will deny - // all requests except for the ones that match Rules. If Consul is in default allow mode, then allow - // actions have no effect without a deny permission as everything is allowed by default. - // - // If action is deny, we will deny the connection if one of the rules in Rules match, in other words, - // we will allow all requests except for the ones that match Rules. If Consul is default deny mode, - // then deny permissions have no effect without an allow permission as everything is denied by default. - // - // Action unspecified is reserved for compatibility with the addition of future actions. - Action Action `protobuf:"varint,2,opt,name=action,proto3,enum=hashicorp.consul.auth.v2beta1.Action" json:"action,omitempty"` - // Permissions is a list of permissions to match on. They are applied using OR semantics. - Permissions []*Permission `protobuf:"bytes,3,rep,name=permissions,proto3" json:"permissions,omitempty"` -} - -func (x *TrafficPermissions) Reset() { - *x = TrafficPermissions{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TrafficPermissions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TrafficPermissions) ProtoMessage() {} - -func (x *TrafficPermissions) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TrafficPermissions.ProtoReflect.Descriptor instead. -func (*TrafficPermissions) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{0} -} - -func (x *TrafficPermissions) GetDestination() *Destination { - if x != nil { - return x.Destination - } - return nil -} - -func (x *TrafficPermissions) GetAction() Action { - if x != nil { - return x.Action - } - return Action_ACTION_UNSPECIFIED -} - -func (x *TrafficPermissions) GetPermissions() []*Permission { - if x != nil { - return x.Permissions - } - return nil -} - -type NamespaceTrafficPermissions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Action Action `protobuf:"varint,1,opt,name=action,proto3,enum=hashicorp.consul.auth.v2beta1.Action" json:"action,omitempty"` - Permissions []*Permission `protobuf:"bytes,2,rep,name=permissions,proto3" json:"permissions,omitempty"` -} - -func (x *NamespaceTrafficPermissions) Reset() { - *x = NamespaceTrafficPermissions{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NamespaceTrafficPermissions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NamespaceTrafficPermissions) ProtoMessage() {} - -func (x *NamespaceTrafficPermissions) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NamespaceTrafficPermissions.ProtoReflect.Descriptor instead. -func (*NamespaceTrafficPermissions) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{1} -} - -func (x *NamespaceTrafficPermissions) GetAction() Action { - if x != nil { - return x.Action - } - return Action_ACTION_UNSPECIFIED -} - -func (x *NamespaceTrafficPermissions) GetPermissions() []*Permission { - if x != nil { - return x.Permissions - } - return nil -} - -type PartitionTrafficPermissions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Action Action `protobuf:"varint,1,opt,name=action,proto3,enum=hashicorp.consul.auth.v2beta1.Action" json:"action,omitempty"` - Permissions []*Permission `protobuf:"bytes,2,rep,name=permissions,proto3" json:"permissions,omitempty"` -} - -func (x *PartitionTrafficPermissions) Reset() { - *x = PartitionTrafficPermissions{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PartitionTrafficPermissions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PartitionTrafficPermissions) ProtoMessage() {} - -func (x *PartitionTrafficPermissions) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PartitionTrafficPermissions.ProtoReflect.Descriptor instead. -func (*PartitionTrafficPermissions) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{2} -} - -func (x *PartitionTrafficPermissions) GetAction() Action { - if x != nil { - return x.Action - } - return Action_ACTION_UNSPECIFIED -} - -func (x *PartitionTrafficPermissions) GetPermissions() []*Permission { - if x != nil { - return x.Permissions - } - return nil -} - -// Destination contains the name or name-prefix of the WorkloadIdentity. -// The WorkloadIdentity resource must be in the same tenancy as the TrafficPermissions resource. -type Destination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IdentityName string `protobuf:"bytes,1,opt,name=identity_name,json=identityName,proto3" json:"identity_name,omitempty"` -} - -func (x *Destination) Reset() { - *x = Destination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Destination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Destination) ProtoMessage() {} - -func (x *Destination) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Destination.ProtoReflect.Descriptor instead. -func (*Destination) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{3} -} - -func (x *Destination) GetIdentityName() string { - if x != nil { - return x.IdentityName - } - return "" -} - -// Permissions is a list of permissions to match on. -type Permission struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Sources is a list of sources in this traffic permission. - Sources []*Source `protobuf:"bytes,1,rep,name=sources,proto3" json:"sources,omitempty"` - // DestinationRules is a list of rules to apply for matching sources in this Permission. - // These rules are specific to the request or connection that is going to the destination(s) - // selected by the TrafficPermissions resource. - DestinationRules []*DestinationRule `protobuf:"bytes,2,rep,name=destination_rules,json=destinationRules,proto3" json:"destination_rules,omitempty"` -} - -func (x *Permission) Reset() { - *x = Permission{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Permission) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Permission) ProtoMessage() {} - -func (x *Permission) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Permission.ProtoReflect.Descriptor instead. -func (*Permission) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{4} -} - -func (x *Permission) GetSources() []*Source { - if x != nil { - return x.Sources - } - return nil -} - -func (x *Permission) GetDestinationRules() []*DestinationRule { - if x != nil { - return x.DestinationRules - } - return nil -} - -// Source represents the source identity. -// To specify any of the wildcard sources, the specific fields need to be omitted. -// For example, for a wildcard namespace, identity_name should be omitted. -type Source struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IdentityName string `protobuf:"bytes,1,opt,name=identity_name,json=identityName,proto3" json:"identity_name,omitempty"` - Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` - Partition string `protobuf:"bytes,3,opt,name=partition,proto3" json:"partition,omitempty"` - Peer string `protobuf:"bytes,4,opt,name=peer,proto3" json:"peer,omitempty"` - SamenessGroup string `protobuf:"bytes,5,opt,name=sameness_group,json=samenessGroup,proto3" json:"sameness_group,omitempty"` - // Exclude is a list of sources to exclude from this source. - Exclude []*ExcludeSource `protobuf:"bytes,6,rep,name=exclude,proto3" json:"exclude,omitempty"` -} - -func (x *Source) Reset() { - *x = Source{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Source) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Source) ProtoMessage() {} - -func (x *Source) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Source.ProtoReflect.Descriptor instead. -func (*Source) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{5} -} - -func (x *Source) GetIdentityName() string { - if x != nil { - return x.IdentityName - } - return "" -} - -func (x *Source) GetNamespace() string { - if x != nil { - return x.Namespace - } - return "" -} - -func (x *Source) GetPartition() string { - if x != nil { - return x.Partition - } - return "" -} - -func (x *Source) GetPeer() string { - if x != nil { - return x.Peer - } - return "" -} - -func (x *Source) GetSamenessGroup() string { - if x != nil { - return x.SamenessGroup - } - return "" -} - -func (x *Source) GetExclude() []*ExcludeSource { - if x != nil { - return x.Exclude - } - return nil -} - -// ExcludeSource is almost the same as source but it prevents the addition of -// matching sources. -type ExcludeSource struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IdentityName string `protobuf:"bytes,1,opt,name=identity_name,json=identityName,proto3" json:"identity_name,omitempty"` - Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` - Partition string `protobuf:"bytes,3,opt,name=partition,proto3" json:"partition,omitempty"` - Peer string `protobuf:"bytes,4,opt,name=peer,proto3" json:"peer,omitempty"` - SamenessGroup string `protobuf:"bytes,5,opt,name=sameness_group,json=samenessGroup,proto3" json:"sameness_group,omitempty"` -} - -func (x *ExcludeSource) Reset() { - *x = ExcludeSource{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExcludeSource) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExcludeSource) ProtoMessage() {} - -func (x *ExcludeSource) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExcludeSource.ProtoReflect.Descriptor instead. -func (*ExcludeSource) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{6} -} - -func (x *ExcludeSource) GetIdentityName() string { - if x != nil { - return x.IdentityName - } - return "" -} - -func (x *ExcludeSource) GetNamespace() string { - if x != nil { - return x.Namespace - } - return "" -} - -func (x *ExcludeSource) GetPartition() string { - if x != nil { - return x.Partition - } - return "" -} - -func (x *ExcludeSource) GetPeer() string { - if x != nil { - return x.Peer - } - return "" -} - -func (x *ExcludeSource) GetSamenessGroup() string { - if x != nil { - return x.SamenessGroup - } - return "" -} - -// DestinationRule contains rules rules to apply to the incoming connection. -type DestinationRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PathExact string `protobuf:"bytes,1,opt,name=path_exact,json=pathExact,proto3" json:"path_exact,omitempty"` - PathPrefix string `protobuf:"bytes,2,opt,name=path_prefix,json=pathPrefix,proto3" json:"path_prefix,omitempty"` - PathRegex string `protobuf:"bytes,3,opt,name=path_regex,json=pathRegex,proto3" json:"path_regex,omitempty"` - // Methods is the list of HTTP methods. If no methods are specified, - // this rule will apply to all methods. - Methods []string `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` - Header *DestinationRuleHeader `protobuf:"bytes,5,opt,name=header,proto3" json:"header,omitempty"` - PortNames []string `protobuf:"bytes,6,rep,name=port_names,json=portNames,proto3" json:"port_names,omitempty"` - // Exclude contains a list of rules to exclude when evaluating rules for the incoming connection. - Exclude []*ExcludePermissionRule `protobuf:"bytes,7,rep,name=exclude,proto3" json:"exclude,omitempty"` -} - -func (x *DestinationRule) Reset() { - *x = DestinationRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationRule) ProtoMessage() {} - -func (x *DestinationRule) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationRule.ProtoReflect.Descriptor instead. -func (*DestinationRule) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{7} -} - -func (x *DestinationRule) GetPathExact() string { - if x != nil { - return x.PathExact - } - return "" -} - -func (x *DestinationRule) GetPathPrefix() string { - if x != nil { - return x.PathPrefix - } - return "" -} - -func (x *DestinationRule) GetPathRegex() string { - if x != nil { - return x.PathRegex - } - return "" -} - -func (x *DestinationRule) GetMethods() []string { - if x != nil { - return x.Methods - } - return nil -} - -func (x *DestinationRule) GetHeader() *DestinationRuleHeader { - if x != nil { - return x.Header - } - return nil -} - -func (x *DestinationRule) GetPortNames() []string { - if x != nil { - return x.PortNames - } - return nil -} - -func (x *DestinationRule) GetExclude() []*ExcludePermissionRule { - if x != nil { - return x.Exclude - } - return nil -} - -type ExcludePermissionRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PathExact string `protobuf:"bytes,1,opt,name=path_exact,json=pathExact,proto3" json:"path_exact,omitempty"` - PathPrefix string `protobuf:"bytes,2,opt,name=path_prefix,json=pathPrefix,proto3" json:"path_prefix,omitempty"` - PathRegex string `protobuf:"bytes,3,opt,name=path_regex,json=pathRegex,proto3" json:"path_regex,omitempty"` - // Methods is the list of HTTP methods. - Methods []string `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` - Header *DestinationRuleHeader `protobuf:"bytes,5,opt,name=header,proto3" json:"header,omitempty"` - // PortNames is a list of workload ports to apply this rule to. The ports specified here - // must be the ports used in the connection. - PortNames []string `protobuf:"bytes,6,rep,name=port_names,json=portNames,proto3" json:"port_names,omitempty"` -} - -func (x *ExcludePermissionRule) Reset() { - *x = ExcludePermissionRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExcludePermissionRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExcludePermissionRule) ProtoMessage() {} - -func (x *ExcludePermissionRule) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExcludePermissionRule.ProtoReflect.Descriptor instead. -func (*ExcludePermissionRule) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{8} -} - -func (x *ExcludePermissionRule) GetPathExact() string { - if x != nil { - return x.PathExact - } - return "" -} - -func (x *ExcludePermissionRule) GetPathPrefix() string { - if x != nil { - return x.PathPrefix - } - return "" -} - -func (x *ExcludePermissionRule) GetPathRegex() string { - if x != nil { - return x.PathRegex - } - return "" -} - -func (x *ExcludePermissionRule) GetMethods() []string { - if x != nil { - return x.Methods - } - return nil -} - -func (x *ExcludePermissionRule) GetHeader() *DestinationRuleHeader { - if x != nil { - return x.Header - } - return nil -} - -func (x *ExcludePermissionRule) GetPortNames() []string { - if x != nil { - return x.PortNames - } - return nil -} - -type DestinationRuleHeader struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Present bool `protobuf:"varint,2,opt,name=present,proto3" json:"present,omitempty"` - Exact string `protobuf:"bytes,3,opt,name=exact,proto3" json:"exact,omitempty"` - Prefix string `protobuf:"bytes,4,opt,name=prefix,proto3" json:"prefix,omitempty"` - Suffix string `protobuf:"bytes,5,opt,name=suffix,proto3" json:"suffix,omitempty"` - Regex string `protobuf:"bytes,6,opt,name=regex,proto3" json:"regex,omitempty"` - Invert bool `protobuf:"varint,7,opt,name=invert,proto3" json:"invert,omitempty"` -} - -func (x *DestinationRuleHeader) Reset() { - *x = DestinationRuleHeader{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationRuleHeader) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationRuleHeader) ProtoMessage() {} - -func (x *DestinationRuleHeader) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationRuleHeader.ProtoReflect.Descriptor instead. -func (*DestinationRuleHeader) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP(), []int{9} -} - -func (x *DestinationRuleHeader) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *DestinationRuleHeader) GetPresent() bool { - if x != nil { - return x.Present - } - return false -} - -func (x *DestinationRuleHeader) GetExact() string { - if x != nil { - return x.Exact - } - return "" -} - -func (x *DestinationRuleHeader) GetPrefix() string { - if x != nil { - return x.Prefix - } - return "" -} - -func (x *DestinationRuleHeader) GetSuffix() string { - if x != nil { - return x.Suffix - } - return "" -} - -func (x *DestinationRuleHeader) GetRegex() string { - if x != nil { - return x.Regex - } - return "" -} - -func (x *DestinationRuleHeader) GetInvert() bool { - if x != nil { - return x.Invert - } - return false -} - -var File_pbauth_v2beta1_traffic_permissions_proto protoreflect.FileDescriptor - -var file_pbauth_v2beta1_traffic_permissions_proto_rawDesc = []byte{ - 0x0a, 0x28, 0x70, 0x62, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf6, 0x01, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x66, - 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x06, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4b, 0x0a, 0x0b, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, - 0x22, 0xb1, 0x01, 0x0a, 0x1b, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, - 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x3d, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x25, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x4b, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x06, 0xa2, 0x93, - 0x04, 0x02, 0x08, 0x03, 0x22, 0xb1, 0x01, 0x0a, 0x1b, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3d, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x4b, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x22, 0x32, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xaa, 0x01, 0x0a, - 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x07, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x11, - 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x75, 0x6c, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x06, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6d, - 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x12, 0x46, 0x0a, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x22, 0xab, 0x01, 0x0a, 0x0d, 0x45, 0x78, 0x63, - 0x6c, 0x75, 0x64, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, - 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, - 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xc7, 0x02, 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x70, 0x61, 0x74, 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x74, - 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x61, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x70, 0x61, 0x74, 0x68, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x12, 0x4e, 0x0a, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x22, 0xfd, 0x01, 0x0a, 0x15, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x70, 0x61, 0x74, 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x74, - 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x61, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x70, 0x61, 0x74, 0x68, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x22, 0xb9, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x14, - 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, - 0x65, 0x67, 0x65, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x2a, 0x43, 0x0a, 0x06, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, - 0x0a, 0x0b, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x01, 0x12, - 0x10, 0x0a, 0x0c, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, - 0x02, 0x42, 0x98, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x17, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, - 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x61, - 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x61, 0x75, 0x74, 0x68, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x41, 0xaa, 0x02, 0x1d, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x41, 0x75, 0x74, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x41, - 0x75, 0x74, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbauth_v2beta1_traffic_permissions_proto_rawDescOnce sync.Once - file_pbauth_v2beta1_traffic_permissions_proto_rawDescData = file_pbauth_v2beta1_traffic_permissions_proto_rawDesc -) - -func file_pbauth_v2beta1_traffic_permissions_proto_rawDescGZIP() []byte { - file_pbauth_v2beta1_traffic_permissions_proto_rawDescOnce.Do(func() { - file_pbauth_v2beta1_traffic_permissions_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbauth_v2beta1_traffic_permissions_proto_rawDescData) - }) - return file_pbauth_v2beta1_traffic_permissions_proto_rawDescData -} - -var file_pbauth_v2beta1_traffic_permissions_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbauth_v2beta1_traffic_permissions_proto_msgTypes = make([]protoimpl.MessageInfo, 10) -var file_pbauth_v2beta1_traffic_permissions_proto_goTypes = []interface{}{ - (Action)(0), // 0: hashicorp.consul.auth.v2beta1.Action - (*TrafficPermissions)(nil), // 1: hashicorp.consul.auth.v2beta1.TrafficPermissions - (*NamespaceTrafficPermissions)(nil), // 2: hashicorp.consul.auth.v2beta1.NamespaceTrafficPermissions - (*PartitionTrafficPermissions)(nil), // 3: hashicorp.consul.auth.v2beta1.PartitionTrafficPermissions - (*Destination)(nil), // 4: hashicorp.consul.auth.v2beta1.Destination - (*Permission)(nil), // 5: hashicorp.consul.auth.v2beta1.Permission - (*Source)(nil), // 6: hashicorp.consul.auth.v2beta1.Source - (*ExcludeSource)(nil), // 7: hashicorp.consul.auth.v2beta1.ExcludeSource - (*DestinationRule)(nil), // 8: hashicorp.consul.auth.v2beta1.DestinationRule - (*ExcludePermissionRule)(nil), // 9: hashicorp.consul.auth.v2beta1.ExcludePermissionRule - (*DestinationRuleHeader)(nil), // 10: hashicorp.consul.auth.v2beta1.DestinationRuleHeader -} -var file_pbauth_v2beta1_traffic_permissions_proto_depIdxs = []int32{ - 4, // 0: hashicorp.consul.auth.v2beta1.TrafficPermissions.destination:type_name -> hashicorp.consul.auth.v2beta1.Destination - 0, // 1: hashicorp.consul.auth.v2beta1.TrafficPermissions.action:type_name -> hashicorp.consul.auth.v2beta1.Action - 5, // 2: hashicorp.consul.auth.v2beta1.TrafficPermissions.permissions:type_name -> hashicorp.consul.auth.v2beta1.Permission - 0, // 3: hashicorp.consul.auth.v2beta1.NamespaceTrafficPermissions.action:type_name -> hashicorp.consul.auth.v2beta1.Action - 5, // 4: hashicorp.consul.auth.v2beta1.NamespaceTrafficPermissions.permissions:type_name -> hashicorp.consul.auth.v2beta1.Permission - 0, // 5: hashicorp.consul.auth.v2beta1.PartitionTrafficPermissions.action:type_name -> hashicorp.consul.auth.v2beta1.Action - 5, // 6: hashicorp.consul.auth.v2beta1.PartitionTrafficPermissions.permissions:type_name -> hashicorp.consul.auth.v2beta1.Permission - 6, // 7: hashicorp.consul.auth.v2beta1.Permission.sources:type_name -> hashicorp.consul.auth.v2beta1.Source - 8, // 8: hashicorp.consul.auth.v2beta1.Permission.destination_rules:type_name -> hashicorp.consul.auth.v2beta1.DestinationRule - 7, // 9: hashicorp.consul.auth.v2beta1.Source.exclude:type_name -> hashicorp.consul.auth.v2beta1.ExcludeSource - 10, // 10: hashicorp.consul.auth.v2beta1.DestinationRule.header:type_name -> hashicorp.consul.auth.v2beta1.DestinationRuleHeader - 9, // 11: hashicorp.consul.auth.v2beta1.DestinationRule.exclude:type_name -> hashicorp.consul.auth.v2beta1.ExcludePermissionRule - 10, // 12: hashicorp.consul.auth.v2beta1.ExcludePermissionRule.header:type_name -> hashicorp.consul.auth.v2beta1.DestinationRuleHeader - 13, // [13:13] is the sub-list for method output_type - 13, // [13:13] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name -} - -func init() { file_pbauth_v2beta1_traffic_permissions_proto_init() } -func file_pbauth_v2beta1_traffic_permissions_proto_init() { - if File_pbauth_v2beta1_traffic_permissions_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TrafficPermissions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamespaceTrafficPermissions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PartitionTrafficPermissions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Destination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Permission); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Source); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExcludeSource); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExcludePermissionRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbauth_v2beta1_traffic_permissions_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationRuleHeader); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbauth_v2beta1_traffic_permissions_proto_rawDesc, - NumEnums: 1, - NumMessages: 10, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbauth_v2beta1_traffic_permissions_proto_goTypes, - DependencyIndexes: file_pbauth_v2beta1_traffic_permissions_proto_depIdxs, - EnumInfos: file_pbauth_v2beta1_traffic_permissions_proto_enumTypes, - MessageInfos: file_pbauth_v2beta1_traffic_permissions_proto_msgTypes, - }.Build() - File_pbauth_v2beta1_traffic_permissions_proto = out.File - file_pbauth_v2beta1_traffic_permissions_proto_rawDesc = nil - file_pbauth_v2beta1_traffic_permissions_proto_goTypes = nil - file_pbauth_v2beta1_traffic_permissions_proto_depIdxs = nil -} diff --git a/proto-public/pbauth/v2beta1/traffic_permissions.proto b/proto-public/pbauth/v2beta1/traffic_permissions.proto deleted file mode 100644 index c36da643f4d19..0000000000000 --- a/proto-public/pbauth/v2beta1/traffic_permissions.proto +++ /dev/null @@ -1,129 +0,0 @@ -syntax = "proto3"; - -package hashicorp.consul.auth.v2beta1; - -import "pbresource/annotations.proto"; - -message TrafficPermissions { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // Destination is a configuration of the destination proxies - // where these traffic permissions should apply. - Destination destination = 1; - - // Action can be either allow or deny for the entire object. It will default to allow. - // - // If action is allow, we will allow the connection if one of the rules in Rules matches, in other words, we will deny - // all requests except for the ones that match Rules. If Consul is in default allow mode, then allow - // actions have no effect without a deny permission as everything is allowed by default. - // - // If action is deny, we will deny the connection if one of the rules in Rules match, in other words, - // we will allow all requests except for the ones that match Rules. If Consul is default deny mode, - // then deny permissions have no effect without an allow permission as everything is denied by default. - // - // Action unspecified is reserved for compatibility with the addition of future actions. - Action action = 2; - - // Permissions is a list of permissions to match on. They are applied using OR semantics. - repeated Permission permissions = 3; -} - -message NamespaceTrafficPermissions { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - Action action = 1; - repeated Permission permissions = 2; -} - -message PartitionTrafficPermissions { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_PARTITION}; - - Action action = 1; - repeated Permission permissions = 2; -} - -// Destination contains the name or name-prefix of the WorkloadIdentity. -// The WorkloadIdentity resource must be in the same tenancy as the TrafficPermissions resource. -message Destination { - string identity_name = 1; -} - -// +kubebuilder:validation:Enum=ACTION_ALLOW;ACTION_DENY;ACTION_UNKNOWN -// +kubebuilder:validation:Type=string -enum Action { - ACTION_UNSPECIFIED = 0; - ACTION_DENY = 1; - ACTION_ALLOW = 2; -} - -// Permissions is a list of permissions to match on. -message Permission { - // Sources is a list of sources in this traffic permission. - repeated Source sources = 1; - // DestinationRules is a list of rules to apply for matching sources in this Permission. - // These rules are specific to the request or connection that is going to the destination(s) - // selected by the TrafficPermissions resource. - repeated DestinationRule destination_rules = 2; -} - -// Source represents the source identity. -// To specify any of the wildcard sources, the specific fields need to be omitted. -// For example, for a wildcard namespace, identity_name should be omitted. -message Source { - string identity_name = 1; - string namespace = 2; - string partition = 3; - string peer = 4; - string sameness_group = 5; - - // Exclude is a list of sources to exclude from this source. - repeated ExcludeSource exclude = 6; -} - -// ExcludeSource is almost the same as source but it prevents the addition of -// matching sources. -message ExcludeSource { - string identity_name = 1; - string namespace = 2; - string partition = 3; - string peer = 4; - string sameness_group = 5; -} - -// DestinationRule contains rules rules to apply to the incoming connection. -message DestinationRule { - string path_exact = 1; - string path_prefix = 2; - string path_regex = 3; - // Methods is the list of HTTP methods. If no methods are specified, - // this rule will apply to all methods. - repeated string methods = 4; - DestinationRuleHeader header = 5; - repeated string port_names = 6; - // Exclude contains a list of rules to exclude when evaluating rules for the incoming connection. - repeated ExcludePermissionRule exclude = 7; -} - -message ExcludePermissionRule { - string path_exact = 1; - string path_prefix = 2; - string path_regex = 3; - // Methods is the list of HTTP methods. - repeated string methods = 4; - - DestinationRuleHeader header = 5; - - // PortNames is a list of workload ports to apply this rule to. The ports specified here - // must be the ports used in the connection. - repeated string port_names = 6; -} - -message DestinationRuleHeader { - string name = 1; - bool present = 2; - string exact = 3; - string prefix = 4; - string suffix = 5; - string regex = 6; - bool invert = 7; -} diff --git a/proto-public/pbauth/v2beta1/traffic_permissions_addon.go b/proto-public/pbauth/v2beta1/traffic_permissions_addon.go deleted file mode 100644 index 9f778504f7574..0000000000000 --- a/proto-public/pbauth/v2beta1/traffic_permissions_addon.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package authv2beta1 - -import "github.com/hashicorp/consul/proto-public/pbresource" - -type SourceToSpiffe interface { - GetIdentityName() string - GetPartition() string - GetNamespace() string - GetPeer() string - GetSamenessGroup() string -} - -var _ SourceToSpiffe = (*Source)(nil) -var _ SourceToSpiffe = (*ExcludeSource)(nil) - -func SourceToTenancy(s SourceToSpiffe) *pbresource.Tenancy { - return &pbresource.Tenancy{ - Partition: s.GetPartition(), - Namespace: s.GetNamespace(), - PeerName: s.GetPeer(), - } -} diff --git a/proto-public/pbauth/v2beta1/traffic_permissions_deepcopy.gen.go b/proto-public/pbauth/v2beta1/traffic_permissions_deepcopy.gen.go deleted file mode 100644 index b954d00b407f0..0000000000000 --- a/proto-public/pbauth/v2beta1/traffic_permissions_deepcopy.gen.go +++ /dev/null @@ -1,216 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package authv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using TrafficPermissions within kubernetes types, where deepcopy-gen is used. -func (in *TrafficPermissions) DeepCopyInto(out *TrafficPermissions) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficPermissions. Required by controller-gen. -func (in *TrafficPermissions) DeepCopy() *TrafficPermissions { - if in == nil { - return nil - } - out := new(TrafficPermissions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TrafficPermissions. Required by controller-gen. -func (in *TrafficPermissions) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using NamespaceTrafficPermissions within kubernetes types, where deepcopy-gen is used. -func (in *NamespaceTrafficPermissions) DeepCopyInto(out *NamespaceTrafficPermissions) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceTrafficPermissions. Required by controller-gen. -func (in *NamespaceTrafficPermissions) DeepCopy() *NamespaceTrafficPermissions { - if in == nil { - return nil - } - out := new(NamespaceTrafficPermissions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceTrafficPermissions. Required by controller-gen. -func (in *NamespaceTrafficPermissions) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using PartitionTrafficPermissions within kubernetes types, where deepcopy-gen is used. -func (in *PartitionTrafficPermissions) DeepCopyInto(out *PartitionTrafficPermissions) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartitionTrafficPermissions. Required by controller-gen. -func (in *PartitionTrafficPermissions) DeepCopy() *PartitionTrafficPermissions { - if in == nil { - return nil - } - out := new(PartitionTrafficPermissions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new PartitionTrafficPermissions. Required by controller-gen. -func (in *PartitionTrafficPermissions) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Destination within kubernetes types, where deepcopy-gen is used. -func (in *Destination) DeepCopyInto(out *Destination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Destination. Required by controller-gen. -func (in *Destination) DeepCopy() *Destination { - if in == nil { - return nil - } - out := new(Destination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Destination. Required by controller-gen. -func (in *Destination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Permission within kubernetes types, where deepcopy-gen is used. -func (in *Permission) DeepCopyInto(out *Permission) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Permission. Required by controller-gen. -func (in *Permission) DeepCopy() *Permission { - if in == nil { - return nil - } - out := new(Permission) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Permission. Required by controller-gen. -func (in *Permission) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Source within kubernetes types, where deepcopy-gen is used. -func (in *Source) DeepCopyInto(out *Source) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Source. Required by controller-gen. -func (in *Source) DeepCopy() *Source { - if in == nil { - return nil - } - out := new(Source) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Source. Required by controller-gen. -func (in *Source) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ExcludeSource within kubernetes types, where deepcopy-gen is used. -func (in *ExcludeSource) DeepCopyInto(out *ExcludeSource) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExcludeSource. Required by controller-gen. -func (in *ExcludeSource) DeepCopy() *ExcludeSource { - if in == nil { - return nil - } - out := new(ExcludeSource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ExcludeSource. Required by controller-gen. -func (in *ExcludeSource) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DestinationRule within kubernetes types, where deepcopy-gen is used. -func (in *DestinationRule) DeepCopyInto(out *DestinationRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRule. Required by controller-gen. -func (in *DestinationRule) DeepCopy() *DestinationRule { - if in == nil { - return nil - } - out := new(DestinationRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRule. Required by controller-gen. -func (in *DestinationRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ExcludePermissionRule within kubernetes types, where deepcopy-gen is used. -func (in *ExcludePermissionRule) DeepCopyInto(out *ExcludePermissionRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExcludePermissionRule. Required by controller-gen. -func (in *ExcludePermissionRule) DeepCopy() *ExcludePermissionRule { - if in == nil { - return nil - } - out := new(ExcludePermissionRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ExcludePermissionRule. Required by controller-gen. -func (in *ExcludePermissionRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DestinationRuleHeader within kubernetes types, where deepcopy-gen is used. -func (in *DestinationRuleHeader) DeepCopyInto(out *DestinationRuleHeader) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRuleHeader. Required by controller-gen. -func (in *DestinationRuleHeader) DeepCopy() *DestinationRuleHeader { - if in == nil { - return nil - } - out := new(DestinationRuleHeader) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRuleHeader. Required by controller-gen. -func (in *DestinationRuleHeader) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbauth/v2beta1/traffic_permissions_json.gen.go b/proto-public/pbauth/v2beta1/traffic_permissions_json.gen.go deleted file mode 100644 index 7f6ddde2904d1..0000000000000 --- a/proto-public/pbauth/v2beta1/traffic_permissions_json.gen.go +++ /dev/null @@ -1,121 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package authv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for TrafficPermissions -func (this *TrafficPermissions) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TrafficPermissions -func (this *TrafficPermissions) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for NamespaceTrafficPermissions -func (this *NamespaceTrafficPermissions) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for NamespaceTrafficPermissions -func (this *NamespaceTrafficPermissions) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for PartitionTrafficPermissions -func (this *PartitionTrafficPermissions) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for PartitionTrafficPermissions -func (this *PartitionTrafficPermissions) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Destination -func (this *Destination) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Destination -func (this *Destination) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Permission -func (this *Permission) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Permission -func (this *Permission) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Source -func (this *Source) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Source -func (this *Source) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ExcludeSource -func (this *ExcludeSource) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ExcludeSource -func (this *ExcludeSource) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DestinationRule -func (this *DestinationRule) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationRule -func (this *DestinationRule) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ExcludePermissionRule -func (this *ExcludePermissionRule) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ExcludePermissionRule -func (this *ExcludePermissionRule) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DestinationRuleHeader -func (this *DestinationRuleHeader) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationRuleHeader -func (this *DestinationRuleHeader) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -var ( - TrafficPermissionsMarshaler = &protojson.MarshalOptions{} - TrafficPermissionsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbauth/v2beta1/workload_identity.pb.binary.go b/proto-public/pbauth/v2beta1/workload_identity.pb.binary.go deleted file mode 100644 index 5161f35d9562e..0000000000000 --- a/proto-public/pbauth/v2beta1/workload_identity.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbauth/v2beta1/workload_identity.proto - -package authv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *WorkloadIdentity) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *WorkloadIdentity) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbauth/v2beta1/workload_identity.pb.go b/proto-public/pbauth/v2beta1/workload_identity.pb.go deleted file mode 100644 index c24f45c776eac..0000000000000 --- a/proto-public/pbauth/v2beta1/workload_identity.pb.go +++ /dev/null @@ -1,155 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbauth/v2beta1/workload_identity.proto - -package authv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type WorkloadIdentity struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *WorkloadIdentity) Reset() { - *x = WorkloadIdentity{} - if protoimpl.UnsafeEnabled { - mi := &file_pbauth_v2beta1_workload_identity_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *WorkloadIdentity) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*WorkloadIdentity) ProtoMessage() {} - -func (x *WorkloadIdentity) ProtoReflect() protoreflect.Message { - mi := &file_pbauth_v2beta1_workload_identity_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use WorkloadIdentity.ProtoReflect.Descriptor instead. -func (*WorkloadIdentity) Descriptor() ([]byte, []int) { - return file_pbauth_v2beta1_workload_identity_proto_rawDescGZIP(), []int{0} -} - -var File_pbauth_v2beta1_workload_identity_proto protoreflect.FileDescriptor - -var file_pbauth_v2beta1_workload_identity_proto_rawDesc = []byte{ - 0x0a, 0x26, 0x70, 0x62, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1a, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, - 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, - 0x03, 0x42, 0x96, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, - 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x61, 0x75, 0x74, - 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x41, 0xaa, 0x02, 0x1d, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x41, - 0x75, 0x74, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, - 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, - 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x41, 0x75, 0x74, - 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_pbauth_v2beta1_workload_identity_proto_rawDescOnce sync.Once - file_pbauth_v2beta1_workload_identity_proto_rawDescData = file_pbauth_v2beta1_workload_identity_proto_rawDesc -) - -func file_pbauth_v2beta1_workload_identity_proto_rawDescGZIP() []byte { - file_pbauth_v2beta1_workload_identity_proto_rawDescOnce.Do(func() { - file_pbauth_v2beta1_workload_identity_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbauth_v2beta1_workload_identity_proto_rawDescData) - }) - return file_pbauth_v2beta1_workload_identity_proto_rawDescData -} - -var file_pbauth_v2beta1_workload_identity_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbauth_v2beta1_workload_identity_proto_goTypes = []interface{}{ - (*WorkloadIdentity)(nil), // 0: hashicorp.consul.auth.v2beta1.WorkloadIdentity -} -var file_pbauth_v2beta1_workload_identity_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbauth_v2beta1_workload_identity_proto_init() } -func file_pbauth_v2beta1_workload_identity_proto_init() { - if File_pbauth_v2beta1_workload_identity_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbauth_v2beta1_workload_identity_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WorkloadIdentity); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbauth_v2beta1_workload_identity_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbauth_v2beta1_workload_identity_proto_goTypes, - DependencyIndexes: file_pbauth_v2beta1_workload_identity_proto_depIdxs, - MessageInfos: file_pbauth_v2beta1_workload_identity_proto_msgTypes, - }.Build() - File_pbauth_v2beta1_workload_identity_proto = out.File - file_pbauth_v2beta1_workload_identity_proto_rawDesc = nil - file_pbauth_v2beta1_workload_identity_proto_goTypes = nil - file_pbauth_v2beta1_workload_identity_proto_depIdxs = nil -} diff --git a/proto-public/pbauth/v2beta1/workload_identity.proto b/proto-public/pbauth/v2beta1/workload_identity.proto deleted file mode 100644 index 32347810182fc..0000000000000 --- a/proto-public/pbauth/v2beta1/workload_identity.proto +++ /dev/null @@ -1,9 +0,0 @@ -syntax = "proto3"; - -package hashicorp.consul.auth.v2beta1; - -import "pbresource/annotations.proto"; - -message WorkloadIdentity { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; -} diff --git a/proto-public/pbauth/v2beta1/workload_identity_deepcopy.gen.go b/proto-public/pbauth/v2beta1/workload_identity_deepcopy.gen.go deleted file mode 100644 index 7a25aba74a489..0000000000000 --- a/proto-public/pbauth/v2beta1/workload_identity_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package authv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using WorkloadIdentity within kubernetes types, where deepcopy-gen is used. -func (in *WorkloadIdentity) DeepCopyInto(out *WorkloadIdentity) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadIdentity. Required by controller-gen. -func (in *WorkloadIdentity) DeepCopy() *WorkloadIdentity { - if in == nil { - return nil - } - out := new(WorkloadIdentity) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadIdentity. Required by controller-gen. -func (in *WorkloadIdentity) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbauth/v2beta1/workload_identity_json.gen.go b/proto-public/pbauth/v2beta1/workload_identity_json.gen.go deleted file mode 100644 index 8c49cd53e1405..0000000000000 --- a/proto-public/pbauth/v2beta1/workload_identity_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package authv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for WorkloadIdentity -func (this *WorkloadIdentity) MarshalJSON() ([]byte, error) { - str, err := WorkloadIdentityMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WorkloadIdentity -func (this *WorkloadIdentity) UnmarshalJSON(b []byte) error { - return WorkloadIdentityUnmarshaler.Unmarshal(b, this) -} - -var ( - WorkloadIdentityMarshaler = &protojson.MarshalOptions{} - WorkloadIdentityUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/dns.pb.binary.go b/proto-public/pbcatalog/v1alpha1/dns.pb.binary.go similarity index 91% rename from proto-public/pbcatalog/v2beta1/dns.pb.binary.go rename to proto-public/pbcatalog/v1alpha1/dns.pb.binary.go index 41ad32c0ef6d0..21c190584f9ae 100644 --- a/proto-public/pbcatalog/v2beta1/dns.pb.binary.go +++ b/proto-public/pbcatalog/v1alpha1/dns.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/dns.proto +// source: pbcatalog/v1alpha1/dns.proto -package catalogv2beta1 +package catalogv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbcatalog/v1alpha1/dns.pb.go b/proto-public/pbcatalog/v1alpha1/dns.pb.go new file mode 100644 index 0000000000000..9f6ed584dfcc4 --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/dns.pb.go @@ -0,0 +1,259 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbcatalog/v1alpha1/dns.proto + +package catalogv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type DNSPolicy struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Workloads *WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` + Weights *Weights `protobuf:"bytes,2,opt,name=weights,proto3" json:"weights,omitempty"` +} + +func (x *DNSPolicy) Reset() { + *x = DNSPolicy{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_dns_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DNSPolicy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DNSPolicy) ProtoMessage() {} + +func (x *DNSPolicy) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_dns_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DNSPolicy.ProtoReflect.Descriptor instead. +func (*DNSPolicy) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_dns_proto_rawDescGZIP(), []int{0} +} + +func (x *DNSPolicy) GetWorkloads() *WorkloadSelector { + if x != nil { + return x.Workloads + } + return nil +} + +func (x *DNSPolicy) GetWeights() *Weights { + if x != nil { + return x.Weights + } + return nil +} + +type Weights struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Passing uint32 `protobuf:"varint,1,opt,name=passing,proto3" json:"passing,omitempty"` + Warning uint32 `protobuf:"varint,2,opt,name=warning,proto3" json:"warning,omitempty"` +} + +func (x *Weights) Reset() { + *x = Weights{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_dns_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Weights) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Weights) ProtoMessage() {} + +func (x *Weights) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_dns_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Weights.ProtoReflect.Descriptor instead. +func (*Weights) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_dns_proto_rawDescGZIP(), []int{1} +} + +func (x *Weights) GetPassing() uint32 { + if x != nil { + return x.Passing + } + return 0 +} + +func (x *Weights) GetWarning() uint32 { + if x != nil { + return x.Warning + } + return 0 +} + +var File_pbcatalog_v1alpha1_dns_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_dns_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x64, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x1a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x01, 0x0a, 0x09, 0x44, 0x4e, 0x53, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x51, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x44, 0x0a, 0x07, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, + 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x52, 0x07, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x3d, 0x0a, 0x07, 0x57, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x70, 0x61, 0x73, 0x73, 0x69, 0x6e, 0x67, + 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x42, 0xa5, 0x02, 0x0a, 0x25, 0x63, + 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x42, 0x08, 0x44, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x63, 0x61, + 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, + 0x48, 0x43, 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, + 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbcatalog_v1alpha1_dns_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_dns_proto_rawDescData = file_pbcatalog_v1alpha1_dns_proto_rawDesc +) + +func file_pbcatalog_v1alpha1_dns_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_dns_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_dns_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_dns_proto_rawDescData) + }) + return file_pbcatalog_v1alpha1_dns_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_dns_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pbcatalog_v1alpha1_dns_proto_goTypes = []interface{}{ + (*DNSPolicy)(nil), // 0: hashicorp.consul.catalog.v1alpha1.DNSPolicy + (*Weights)(nil), // 1: hashicorp.consul.catalog.v1alpha1.Weights + (*WorkloadSelector)(nil), // 2: hashicorp.consul.catalog.v1alpha1.WorkloadSelector +} +var file_pbcatalog_v1alpha1_dns_proto_depIdxs = []int32{ + 2, // 0: hashicorp.consul.catalog.v1alpha1.DNSPolicy.workloads:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadSelector + 1, // 1: hashicorp.consul.catalog.v1alpha1.DNSPolicy.weights:type_name -> hashicorp.consul.catalog.v1alpha1.Weights + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_pbcatalog_v1alpha1_dns_proto_init() } +func file_pbcatalog_v1alpha1_dns_proto_init() { + if File_pbcatalog_v1alpha1_dns_proto != nil { + return + } + file_pbcatalog_v1alpha1_selector_proto_init() + if !protoimpl.UnsafeEnabled { + file_pbcatalog_v1alpha1_dns_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DNSPolicy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbcatalog_v1alpha1_dns_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Weights); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbcatalog_v1alpha1_dns_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbcatalog_v1alpha1_dns_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_dns_proto_depIdxs, + MessageInfos: file_pbcatalog_v1alpha1_dns_proto_msgTypes, + }.Build() + File_pbcatalog_v1alpha1_dns_proto = out.File + file_pbcatalog_v1alpha1_dns_proto_rawDesc = nil + file_pbcatalog_v1alpha1_dns_proto_goTypes = nil + file_pbcatalog_v1alpha1_dns_proto_depIdxs = nil +} diff --git a/proto-public/pbcatalog/v2beta1/dns.proto b/proto-public/pbcatalog/v1alpha1/dns.proto similarity index 54% rename from proto-public/pbcatalog/v2beta1/dns.proto rename to proto-public/pbcatalog/v1alpha1/dns.proto index b62cc8e10e90d..35ca336b11fd9 100644 --- a/proto-public/pbcatalog/v2beta1/dns.proto +++ b/proto-public/pbcatalog/v1alpha1/dns.proto @@ -3,14 +3,11 @@ syntax = "proto3"; -package hashicorp.consul.catalog.v2beta1; +package hashicorp.consul.catalog.v1alpha1; -import "pbcatalog/v2beta1/selector.proto"; -import "pbresource/annotations.proto"; +import "pbcatalog/v1alpha1/selector.proto"; message DNSPolicy { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - WorkloadSelector workloads = 1; Weights weights = 2; } diff --git a/proto-public/pbcatalog/v2beta1/health.pb.binary.go b/proto-public/pbcatalog/v1alpha1/health.pb.binary.go similarity index 97% rename from proto-public/pbcatalog/v2beta1/health.pb.binary.go rename to proto-public/pbcatalog/v1alpha1/health.pb.binary.go index b5592db6c4647..9953a0e71633f 100644 --- a/proto-public/pbcatalog/v2beta1/health.pb.binary.go +++ b/proto-public/pbcatalog/v1alpha1/health.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/health.proto +// source: pbcatalog/v1alpha1/health.proto -package catalogv2beta1 +package catalogv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbcatalog/v2beta1/health.pb.go b/proto-public/pbcatalog/v1alpha1/health.pb.go similarity index 53% rename from proto-public/pbcatalog/v2beta1/health.pb.go rename to proto-public/pbcatalog/v1alpha1/health.pb.go index 93b045b017fde..071c405d99419 100644 --- a/proto-public/pbcatalog/v2beta1/health.pb.go +++ b/proto-public/pbcatalog/v1alpha1/health.pb.go @@ -5,12 +5,11 @@ // versions: // protoc-gen-go v1.30.0 // protoc (unknown) -// source: pbcatalog/v2beta1/health.proto +// source: pbcatalog/v1alpha1/health.proto -package catalogv2beta1 +package catalogv1alpha1 import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" durationpb "google.golang.org/protobuf/types/known/durationpb" @@ -65,11 +64,11 @@ func (x Health) String() string { } func (Health) Descriptor() protoreflect.EnumDescriptor { - return file_pbcatalog_v2beta1_health_proto_enumTypes[0].Descriptor() + return file_pbcatalog_v1alpha1_health_proto_enumTypes[0].Descriptor() } func (Health) Type() protoreflect.EnumType { - return &file_pbcatalog_v2beta1_health_proto_enumTypes[0] + return &file_pbcatalog_v1alpha1_health_proto_enumTypes[0] } func (x Health) Number() protoreflect.EnumNumber { @@ -78,7 +77,7 @@ func (x Health) Number() protoreflect.EnumNumber { // Deprecated: Use Health.Descriptor instead. func (Health) EnumDescriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{0} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{0} } // This resource will belong to a workload or a node and will have an ownership relationship. @@ -90,7 +89,7 @@ type HealthStatus struct { // Type is the type of this health check, such as http, tcp, or kubernetes-readiness Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Health is the status. This maps to existing health check statuses. - Status Health `protobuf:"varint,2,opt,name=status,proto3,enum=hashicorp.consul.catalog.v2beta1.Health" json:"status,omitempty"` + Status Health `protobuf:"varint,2,opt,name=status,proto3,enum=hashicorp.consul.catalog.v1alpha1.Health" json:"status,omitempty"` // Description is the description for this status. Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` // Output is the output from running the check that resulted in this status @@ -100,7 +99,7 @@ type HealthStatus struct { func (x *HealthStatus) Reset() { *x = HealthStatus{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[0] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -113,7 +112,7 @@ func (x *HealthStatus) String() string { func (*HealthStatus) ProtoMessage() {} func (x *HealthStatus) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[0] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -126,7 +125,7 @@ func (x *HealthStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthStatus.ProtoReflect.Descriptor instead. func (*HealthStatus) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{0} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{0} } func (x *HealthStatus) GetType() string { @@ -169,7 +168,7 @@ type HealthChecks struct { func (x *HealthChecks) Reset() { *x = HealthChecks{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[1] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -182,7 +181,7 @@ func (x *HealthChecks) String() string { func (*HealthChecks) ProtoMessage() {} func (x *HealthChecks) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[1] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -195,7 +194,7 @@ func (x *HealthChecks) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthChecks.ProtoReflect.Descriptor instead. func (*HealthChecks) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{1} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{1} } func (x *HealthChecks) GetWorkloads() *WorkloadSelector { @@ -225,19 +224,16 @@ type HealthCheck struct { // *HealthCheck_Udp // *HealthCheck_Grpc // *HealthCheck_OsService - Definition isHealthCheck_Definition `protobuf_oneof:"definition"` - // +kubebuilder:validation:Format=duration - Interval *durationpb.Duration `protobuf:"bytes,7,opt,name=interval,proto3" json:"interval,omitempty"` - // +kubebuilder:validation:Format=duration - Timeout *durationpb.Duration `protobuf:"bytes,8,opt,name=timeout,proto3" json:"timeout,omitempty"` - // +kubebuilder:validation:Format=duration - DeregisterCriticalAfter *durationpb.Duration `protobuf:"bytes,9,opt,name=deregister_critical_after,json=deregisterCriticalAfter,proto3" json:"deregister_critical_after,omitempty"` + Definition isHealthCheck_Definition `protobuf_oneof:"definition"` + Interval *durationpb.Duration `protobuf:"bytes,7,opt,name=interval,proto3" json:"interval,omitempty"` + Timeout *durationpb.Duration `protobuf:"bytes,8,opt,name=timeout,proto3" json:"timeout,omitempty"` + DeregisterCriticalAfter *durationpb.Duration `protobuf:"bytes,9,opt,name=deregister_critical_after,json=deregisterCriticalAfter,proto3" json:"deregister_critical_after,omitempty"` } func (x *HealthCheck) Reset() { *x = HealthCheck{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[2] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -250,7 +246,7 @@ func (x *HealthCheck) String() string { func (*HealthCheck) ProtoMessage() {} func (x *HealthCheck) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[2] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -263,7 +259,7 @@ func (x *HealthCheck) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthCheck.ProtoReflect.Descriptor instead. func (*HealthCheck) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{2} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{2} } func (x *HealthCheck) GetName() string { @@ -386,7 +382,7 @@ type HTTPCheck struct { func (x *HTTPCheck) Reset() { *x = HTTPCheck{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[3] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -399,7 +395,7 @@ func (x *HTTPCheck) String() string { func (*HTTPCheck) ProtoMessage() {} func (x *HTTPCheck) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[3] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -412,7 +408,7 @@ func (x *HTTPCheck) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPCheck.ProtoReflect.Descriptor instead. func (*HTTPCheck) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{3} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{3} } func (x *HTTPCheck) GetUrl() string { @@ -468,7 +464,7 @@ type TCPCheck struct { func (x *TCPCheck) Reset() { *x = TCPCheck{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[4] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -481,7 +477,7 @@ func (x *TCPCheck) String() string { func (*TCPCheck) ProtoMessage() {} func (x *TCPCheck) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[4] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -494,7 +490,7 @@ func (x *TCPCheck) ProtoReflect() protoreflect.Message { // Deprecated: Use TCPCheck.ProtoReflect.Descriptor instead. func (*TCPCheck) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{4} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{4} } func (x *TCPCheck) GetAddress() string { @@ -515,7 +511,7 @@ type UDPCheck struct { func (x *UDPCheck) Reset() { *x = UDPCheck{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[5] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -528,7 +524,7 @@ func (x *UDPCheck) String() string { func (*UDPCheck) ProtoMessage() {} func (x *UDPCheck) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[5] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -541,7 +537,7 @@ func (x *UDPCheck) ProtoReflect() protoreflect.Message { // Deprecated: Use UDPCheck.ProtoReflect.Descriptor instead. func (*UDPCheck) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{5} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{5} } func (x *UDPCheck) GetAddress() string { @@ -563,7 +559,7 @@ type GRPCCheck struct { func (x *GRPCCheck) Reset() { *x = GRPCCheck{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[6] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -576,7 +572,7 @@ func (x *GRPCCheck) String() string { func (*GRPCCheck) ProtoMessage() {} func (x *GRPCCheck) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[6] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -589,7 +585,7 @@ func (x *GRPCCheck) ProtoReflect() protoreflect.Message { // Deprecated: Use GRPCCheck.ProtoReflect.Descriptor instead. func (*GRPCCheck) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{6} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{6} } func (x *GRPCCheck) GetAddress() string { @@ -617,7 +613,7 @@ type OSServiceCheck struct { func (x *OSServiceCheck) Reset() { *x = OSServiceCheck{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[7] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -630,7 +626,7 @@ func (x *OSServiceCheck) String() string { func (*OSServiceCheck) ProtoMessage() {} func (x *OSServiceCheck) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[7] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -643,7 +639,7 @@ func (x *OSServiceCheck) ProtoReflect() protoreflect.Message { // Deprecated: Use OSServiceCheck.ProtoReflect.Descriptor instead. func (*OSServiceCheck) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{7} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{7} } func (x *OSServiceCheck) GetAddress() string { @@ -666,7 +662,7 @@ type CheckTLSConfig struct { func (x *CheckTLSConfig) Reset() { *x = CheckTLSConfig{} if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[8] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -679,7 +675,7 @@ func (x *CheckTLSConfig) String() string { func (*CheckTLSConfig) ProtoMessage() {} func (x *CheckTLSConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_health_proto_msgTypes[8] + mi := &file_pbcatalog_v1alpha1_health_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -692,7 +688,7 @@ func (x *CheckTLSConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use CheckTLSConfig.ProtoReflect.Descriptor instead. func (*CheckTLSConfig) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_health_proto_rawDescGZIP(), []int{8} + return file_pbcatalog_v1alpha1_health_proto_rawDescGZIP(), []int{8} } func (x *CheckTLSConfig) GetTlsServerName() string { @@ -716,110 +712,108 @@ func (x *CheckTLSConfig) GetUseTls() bool { return false } -var File_pbcatalog_v2beta1_health_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_health_proto_rawDesc = []byte{ - 0x0a, 0x1e, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xa6, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xbc, 0x01, 0x0a, 0x0c, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x50, 0x0a, 0x09, - 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x52, - 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, - 0x68, 0x65, 0x63, 0x6b, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xcb, 0x04, 0x0a, 0x0b, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x41, - 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, +var File_pbcatalog_v1alpha1_health_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_health_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x21, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9f, 0x01, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x48, 0x54, 0x54, 0x50, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x04, 0x68, 0x74, 0x74, - 0x70, 0x12, 0x3e, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x54, 0x43, 0x50, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x03, 0x74, 0x63, - 0x70, 0x12, 0x3e, 0x0a, 0x03, 0x75, 0x64, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x55, 0x44, 0x50, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x03, 0x75, 0x64, - 0x70, 0x12, 0x41, 0x0a, 0x04, 0x67, 0x72, 0x70, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x04, - 0x67, 0x72, 0x70, 0x63, 0x12, 0x51, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xb6, 0x01, 0x0a, 0x0c, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x51, 0x0a, 0x09, 0x77, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x53, 0x0a, + 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x73, 0x22, 0xd0, 0x04, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x48, 0x00, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x3f, 0x0a, 0x03, 0x74, 0x63, + 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x43, 0x50, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x3f, 0x0a, 0x03, 0x75, + 0x64, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x53, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x09, 0x6f, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x33, - 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x12, 0x55, 0x0a, 0x19, 0x64, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x5f, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x44, 0x50, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x03, 0x75, 0x64, 0x70, 0x12, 0x42, 0x0a, 0x04, + 0x67, 0x72, 0x70, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, + 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x47, + 0x52, 0x50, 0x43, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x04, 0x67, 0x72, 0x70, 0x63, + 0x12, 0x52, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x53, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x09, 0x6f, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x17, 0x64, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x72, 0x69, - 0x74, 0x69, 0x63, 0x61, 0x6c, 0x41, 0x66, 0x74, 0x65, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x64, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc6, 0x02, 0x0a, 0x09, 0x48, 0x54, 0x54, - 0x50, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x4f, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x10, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x73, 0x12, 0x42, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x24, 0x0a, 0x08, 0x54, 0x43, 0x50, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x18, 0x0a, - 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x24, 0x0a, 0x08, 0x55, 0x44, 0x50, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x69, 0x0a, - 0x09, 0x47, 0x52, 0x50, 0x43, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x42, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, + 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x33, 0x0a, 0x07, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x12, 0x55, 0x0a, 0x19, 0x64, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x63, + 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x17, + 0x64, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x41, 0x66, 0x74, 0x65, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc8, 0x02, 0x0a, 0x09, 0x48, 0x54, 0x54, 0x50, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x50, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, + 0x6f, 0x64, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, + 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x73, + 0x12, 0x43, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x03, 0x74, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x24, 0x0a, 0x08, 0x54, 0x43, 0x50, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x24, 0x0a, 0x08, 0x55, 0x44, 0x50, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x6a, 0x0a, 0x09, + 0x47, 0x52, 0x50, 0x43, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x43, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x22, 0x2a, 0x0a, 0x0e, 0x4f, 0x53, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, @@ -837,72 +831,73 @@ var file_pbcatalog_v2beta1_health_proto_rawDesc = []byte{ 0x0e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x04, 0x42, 0xa1, - 0x02, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x4e, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x04, 0x42, 0xa8, + 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, - 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, + 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, + 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( - file_pbcatalog_v2beta1_health_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_health_proto_rawDescData = file_pbcatalog_v2beta1_health_proto_rawDesc + file_pbcatalog_v1alpha1_health_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_health_proto_rawDescData = file_pbcatalog_v1alpha1_health_proto_rawDesc ) -func file_pbcatalog_v2beta1_health_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_health_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_health_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_health_proto_rawDescData) +func file_pbcatalog_v1alpha1_health_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_health_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_health_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_health_proto_rawDescData) }) - return file_pbcatalog_v2beta1_health_proto_rawDescData -} - -var file_pbcatalog_v2beta1_health_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbcatalog_v2beta1_health_proto_msgTypes = make([]protoimpl.MessageInfo, 10) -var file_pbcatalog_v2beta1_health_proto_goTypes = []interface{}{ - (Health)(0), // 0: hashicorp.consul.catalog.v2beta1.Health - (*HealthStatus)(nil), // 1: hashicorp.consul.catalog.v2beta1.HealthStatus - (*HealthChecks)(nil), // 2: hashicorp.consul.catalog.v2beta1.HealthChecks - (*HealthCheck)(nil), // 3: hashicorp.consul.catalog.v2beta1.HealthCheck - (*HTTPCheck)(nil), // 4: hashicorp.consul.catalog.v2beta1.HTTPCheck - (*TCPCheck)(nil), // 5: hashicorp.consul.catalog.v2beta1.TCPCheck - (*UDPCheck)(nil), // 6: hashicorp.consul.catalog.v2beta1.UDPCheck - (*GRPCCheck)(nil), // 7: hashicorp.consul.catalog.v2beta1.GRPCCheck - (*OSServiceCheck)(nil), // 8: hashicorp.consul.catalog.v2beta1.OSServiceCheck - (*CheckTLSConfig)(nil), // 9: hashicorp.consul.catalog.v2beta1.CheckTLSConfig - nil, // 10: hashicorp.consul.catalog.v2beta1.HTTPCheck.HeaderEntry - (*WorkloadSelector)(nil), // 11: hashicorp.consul.catalog.v2beta1.WorkloadSelector + return file_pbcatalog_v1alpha1_health_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_health_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_pbcatalog_v1alpha1_health_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_pbcatalog_v1alpha1_health_proto_goTypes = []interface{}{ + (Health)(0), // 0: hashicorp.consul.catalog.v1alpha1.Health + (*HealthStatus)(nil), // 1: hashicorp.consul.catalog.v1alpha1.HealthStatus + (*HealthChecks)(nil), // 2: hashicorp.consul.catalog.v1alpha1.HealthChecks + (*HealthCheck)(nil), // 3: hashicorp.consul.catalog.v1alpha1.HealthCheck + (*HTTPCheck)(nil), // 4: hashicorp.consul.catalog.v1alpha1.HTTPCheck + (*TCPCheck)(nil), // 5: hashicorp.consul.catalog.v1alpha1.TCPCheck + (*UDPCheck)(nil), // 6: hashicorp.consul.catalog.v1alpha1.UDPCheck + (*GRPCCheck)(nil), // 7: hashicorp.consul.catalog.v1alpha1.GRPCCheck + (*OSServiceCheck)(nil), // 8: hashicorp.consul.catalog.v1alpha1.OSServiceCheck + (*CheckTLSConfig)(nil), // 9: hashicorp.consul.catalog.v1alpha1.CheckTLSConfig + nil, // 10: hashicorp.consul.catalog.v1alpha1.HTTPCheck.HeaderEntry + (*WorkloadSelector)(nil), // 11: hashicorp.consul.catalog.v1alpha1.WorkloadSelector (*durationpb.Duration)(nil), // 12: google.protobuf.Duration } -var file_pbcatalog_v2beta1_health_proto_depIdxs = []int32{ - 0, // 0: hashicorp.consul.catalog.v2beta1.HealthStatus.status:type_name -> hashicorp.consul.catalog.v2beta1.Health - 11, // 1: hashicorp.consul.catalog.v2beta1.HealthChecks.workloads:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadSelector - 3, // 2: hashicorp.consul.catalog.v2beta1.HealthChecks.health_checks:type_name -> hashicorp.consul.catalog.v2beta1.HealthCheck - 4, // 3: hashicorp.consul.catalog.v2beta1.HealthCheck.http:type_name -> hashicorp.consul.catalog.v2beta1.HTTPCheck - 5, // 4: hashicorp.consul.catalog.v2beta1.HealthCheck.tcp:type_name -> hashicorp.consul.catalog.v2beta1.TCPCheck - 6, // 5: hashicorp.consul.catalog.v2beta1.HealthCheck.udp:type_name -> hashicorp.consul.catalog.v2beta1.UDPCheck - 7, // 6: hashicorp.consul.catalog.v2beta1.HealthCheck.grpc:type_name -> hashicorp.consul.catalog.v2beta1.GRPCCheck - 8, // 7: hashicorp.consul.catalog.v2beta1.HealthCheck.os_service:type_name -> hashicorp.consul.catalog.v2beta1.OSServiceCheck - 12, // 8: hashicorp.consul.catalog.v2beta1.HealthCheck.interval:type_name -> google.protobuf.Duration - 12, // 9: hashicorp.consul.catalog.v2beta1.HealthCheck.timeout:type_name -> google.protobuf.Duration - 12, // 10: hashicorp.consul.catalog.v2beta1.HealthCheck.deregister_critical_after:type_name -> google.protobuf.Duration - 10, // 11: hashicorp.consul.catalog.v2beta1.HTTPCheck.header:type_name -> hashicorp.consul.catalog.v2beta1.HTTPCheck.HeaderEntry - 9, // 12: hashicorp.consul.catalog.v2beta1.HTTPCheck.tls:type_name -> hashicorp.consul.catalog.v2beta1.CheckTLSConfig - 9, // 13: hashicorp.consul.catalog.v2beta1.GRPCCheck.tls:type_name -> hashicorp.consul.catalog.v2beta1.CheckTLSConfig +var file_pbcatalog_v1alpha1_health_proto_depIdxs = []int32{ + 0, // 0: hashicorp.consul.catalog.v1alpha1.HealthStatus.status:type_name -> hashicorp.consul.catalog.v1alpha1.Health + 11, // 1: hashicorp.consul.catalog.v1alpha1.HealthChecks.workloads:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadSelector + 3, // 2: hashicorp.consul.catalog.v1alpha1.HealthChecks.health_checks:type_name -> hashicorp.consul.catalog.v1alpha1.HealthCheck + 4, // 3: hashicorp.consul.catalog.v1alpha1.HealthCheck.http:type_name -> hashicorp.consul.catalog.v1alpha1.HTTPCheck + 5, // 4: hashicorp.consul.catalog.v1alpha1.HealthCheck.tcp:type_name -> hashicorp.consul.catalog.v1alpha1.TCPCheck + 6, // 5: hashicorp.consul.catalog.v1alpha1.HealthCheck.udp:type_name -> hashicorp.consul.catalog.v1alpha1.UDPCheck + 7, // 6: hashicorp.consul.catalog.v1alpha1.HealthCheck.grpc:type_name -> hashicorp.consul.catalog.v1alpha1.GRPCCheck + 8, // 7: hashicorp.consul.catalog.v1alpha1.HealthCheck.os_service:type_name -> hashicorp.consul.catalog.v1alpha1.OSServiceCheck + 12, // 8: hashicorp.consul.catalog.v1alpha1.HealthCheck.interval:type_name -> google.protobuf.Duration + 12, // 9: hashicorp.consul.catalog.v1alpha1.HealthCheck.timeout:type_name -> google.protobuf.Duration + 12, // 10: hashicorp.consul.catalog.v1alpha1.HealthCheck.deregister_critical_after:type_name -> google.protobuf.Duration + 10, // 11: hashicorp.consul.catalog.v1alpha1.HTTPCheck.header:type_name -> hashicorp.consul.catalog.v1alpha1.HTTPCheck.HeaderEntry + 9, // 12: hashicorp.consul.catalog.v1alpha1.HTTPCheck.tls:type_name -> hashicorp.consul.catalog.v1alpha1.CheckTLSConfig + 9, // 13: hashicorp.consul.catalog.v1alpha1.GRPCCheck.tls:type_name -> hashicorp.consul.catalog.v1alpha1.CheckTLSConfig 14, // [14:14] is the sub-list for method output_type 14, // [14:14] is the sub-list for method input_type 14, // [14:14] is the sub-list for extension type_name @@ -910,14 +905,14 @@ var file_pbcatalog_v2beta1_health_proto_depIdxs = []int32{ 0, // [0:14] is the sub-list for field type_name } -func init() { file_pbcatalog_v2beta1_health_proto_init() } -func file_pbcatalog_v2beta1_health_proto_init() { - if File_pbcatalog_v2beta1_health_proto != nil { +func init() { file_pbcatalog_v1alpha1_health_proto_init() } +func file_pbcatalog_v1alpha1_health_proto_init() { + if File_pbcatalog_v1alpha1_health_proto != nil { return } - file_pbcatalog_v2beta1_selector_proto_init() + file_pbcatalog_v1alpha1_selector_proto_init() if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_health_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HealthStatus); i { case 0: return &v.state @@ -929,7 +924,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { return nil } } - file_pbcatalog_v2beta1_health_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HealthChecks); i { case 0: return &v.state @@ -941,7 +936,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { return nil } } - file_pbcatalog_v2beta1_health_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HealthCheck); i { case 0: return &v.state @@ -953,7 +948,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { return nil } } - file_pbcatalog_v2beta1_health_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPCheck); i { case 0: return &v.state @@ -965,7 +960,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { return nil } } - file_pbcatalog_v2beta1_health_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TCPCheck); i { case 0: return &v.state @@ -977,7 +972,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { return nil } } - file_pbcatalog_v2beta1_health_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UDPCheck); i { case 0: return &v.state @@ -989,7 +984,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { return nil } } - file_pbcatalog_v2beta1_health_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GRPCCheck); i { case 0: return &v.state @@ -1001,7 +996,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { return nil } } - file_pbcatalog_v2beta1_health_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OSServiceCheck); i { case 0: return &v.state @@ -1013,7 +1008,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { return nil } } - file_pbcatalog_v2beta1_health_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_pbcatalog_v1alpha1_health_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CheckTLSConfig); i { case 0: return &v.state @@ -1026,7 +1021,7 @@ func file_pbcatalog_v2beta1_health_proto_init() { } } } - file_pbcatalog_v2beta1_health_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_pbcatalog_v1alpha1_health_proto_msgTypes[2].OneofWrappers = []interface{}{ (*HealthCheck_Http)(nil), (*HealthCheck_Tcp)(nil), (*HealthCheck_Udp)(nil), @@ -1037,19 +1032,19 @@ func file_pbcatalog_v2beta1_health_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_health_proto_rawDesc, + RawDescriptor: file_pbcatalog_v1alpha1_health_proto_rawDesc, NumEnums: 1, NumMessages: 10, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_pbcatalog_v2beta1_health_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_health_proto_depIdxs, - EnumInfos: file_pbcatalog_v2beta1_health_proto_enumTypes, - MessageInfos: file_pbcatalog_v2beta1_health_proto_msgTypes, + GoTypes: file_pbcatalog_v1alpha1_health_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_health_proto_depIdxs, + EnumInfos: file_pbcatalog_v1alpha1_health_proto_enumTypes, + MessageInfos: file_pbcatalog_v1alpha1_health_proto_msgTypes, }.Build() - File_pbcatalog_v2beta1_health_proto = out.File - file_pbcatalog_v2beta1_health_proto_rawDesc = nil - file_pbcatalog_v2beta1_health_proto_goTypes = nil - file_pbcatalog_v2beta1_health_proto_depIdxs = nil + File_pbcatalog_v1alpha1_health_proto = out.File + file_pbcatalog_v1alpha1_health_proto_rawDesc = nil + file_pbcatalog_v1alpha1_health_proto_goTypes = nil + file_pbcatalog_v1alpha1_health_proto_depIdxs = nil } diff --git a/proto-public/pbcatalog/v2beta1/health.proto b/proto-public/pbcatalog/v1alpha1/health.proto similarity index 81% rename from proto-public/pbcatalog/v2beta1/health.proto rename to proto-public/pbcatalog/v1alpha1/health.proto index 316c58d5d197f..477aa15fc517a 100644 --- a/proto-public/pbcatalog/v2beta1/health.proto +++ b/proto-public/pbcatalog/v1alpha1/health.proto @@ -3,16 +3,13 @@ syntax = "proto3"; -package hashicorp.consul.catalog.v2beta1; +package hashicorp.consul.catalog.v1alpha1; import "google/protobuf/duration.proto"; -import "pbcatalog/v2beta1/selector.proto"; -import "pbresource/annotations.proto"; +import "pbcatalog/v1alpha1/selector.proto"; // This resource will belong to a workload or a node and will have an ownership relationship. message HealthStatus { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - // Type is the type of this health check, such as http, tcp, or kubernetes-readiness string type = 1; // Health is the status. This maps to existing health check statuses. @@ -33,8 +30,6 @@ enum Health { } message HealthChecks { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - WorkloadSelector workloads = 1; repeated HealthCheck health_checks = 2; } @@ -48,11 +43,8 @@ message HealthCheck { GRPCCheck grpc = 5; OSServiceCheck os_service = 6; } - // +kubebuilder:validation:Format=duration google.protobuf.Duration interval = 7; - // +kubebuilder:validation:Format=duration google.protobuf.Duration timeout = 8; - // +kubebuilder:validation:Format=duration google.protobuf.Duration deregister_critical_after = 9; } diff --git a/proto-public/pbcatalog/v2beta1/node.pb.binary.go b/proto-public/pbcatalog/v1alpha1/node.pb.binary.go similarity index 91% rename from proto-public/pbcatalog/v2beta1/node.pb.binary.go rename to proto-public/pbcatalog/v1alpha1/node.pb.binary.go index 984bc57b71d02..d654f1c433b42 100644 --- a/proto-public/pbcatalog/v2beta1/node.pb.binary.go +++ b/proto-public/pbcatalog/v1alpha1/node.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/node.proto +// source: pbcatalog/v1alpha1/node.proto -package catalogv2beta1 +package catalogv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbcatalog/v1alpha1/node.pb.go b/proto-public/pbcatalog/v1alpha1/node.pb.go new file mode 100644 index 0000000000000..b59d03bb9131f --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/node.pb.go @@ -0,0 +1,244 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbcatalog/v1alpha1/node.proto + +package catalogv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Node struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Addresses []*NodeAddress `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` +} + +func (x *Node) Reset() { + *x = Node{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_node_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Node) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Node) ProtoMessage() {} + +func (x *Node) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_node_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Node.ProtoReflect.Descriptor instead. +func (*Node) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_node_proto_rawDescGZIP(), []int{0} +} + +func (x *Node) GetAddresses() []*NodeAddress { + if x != nil { + return x.Addresses + } + return nil +} + +type NodeAddress struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // host can be an IP or DNS name.Í + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` + // external indicates whether this address should be used for external communication + // (aka a WAN address). + External bool `protobuf:"varint,3,opt,name=external,proto3" json:"external,omitempty"` +} + +func (x *NodeAddress) Reset() { + *x = NodeAddress{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_node_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NodeAddress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NodeAddress) ProtoMessage() {} + +func (x *NodeAddress) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_node_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NodeAddress.ProtoReflect.Descriptor instead. +func (*NodeAddress) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_node_proto_rawDescGZIP(), []int{1} +} + +func (x *NodeAddress) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *NodeAddress) GetExternal() bool { + if x != nil { + return x.External + } + return false +} + +var File_pbcatalog_v1alpha1_node_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_node_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x21, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x22, 0x54, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x3d, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x42, 0xa6, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, + 0x6c, 0x6f, 0x67, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, + 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbcatalog_v1alpha1_node_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_node_proto_rawDescData = file_pbcatalog_v1alpha1_node_proto_rawDesc +) + +func file_pbcatalog_v1alpha1_node_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_node_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_node_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_node_proto_rawDescData) + }) + return file_pbcatalog_v1alpha1_node_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pbcatalog_v1alpha1_node_proto_goTypes = []interface{}{ + (*Node)(nil), // 0: hashicorp.consul.catalog.v1alpha1.Node + (*NodeAddress)(nil), // 1: hashicorp.consul.catalog.v1alpha1.NodeAddress +} +var file_pbcatalog_v1alpha1_node_proto_depIdxs = []int32{ + 1, // 0: hashicorp.consul.catalog.v1alpha1.Node.addresses:type_name -> hashicorp.consul.catalog.v1alpha1.NodeAddress + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_pbcatalog_v1alpha1_node_proto_init() } +func file_pbcatalog_v1alpha1_node_proto_init() { + if File_pbcatalog_v1alpha1_node_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pbcatalog_v1alpha1_node_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Node); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbcatalog_v1alpha1_node_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NodeAddress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbcatalog_v1alpha1_node_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbcatalog_v1alpha1_node_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_node_proto_depIdxs, + MessageInfos: file_pbcatalog_v1alpha1_node_proto_msgTypes, + }.Build() + File_pbcatalog_v1alpha1_node_proto = out.File + file_pbcatalog_v1alpha1_node_proto_rawDesc = nil + file_pbcatalog_v1alpha1_node_proto_goTypes = nil + file_pbcatalog_v1alpha1_node_proto_depIdxs = nil +} diff --git a/proto-public/pbcatalog/v2beta1/node.proto b/proto-public/pbcatalog/v1alpha1/node.proto similarity index 57% rename from proto-public/pbcatalog/v2beta1/node.proto rename to proto-public/pbcatalog/v1alpha1/node.proto index 99c54ae48b749..56a7ce3a2cfa5 100644 --- a/proto-public/pbcatalog/v2beta1/node.proto +++ b/proto-public/pbcatalog/v1alpha1/node.proto @@ -3,16 +3,9 @@ syntax = "proto3"; -package hashicorp.consul.catalog.v2beta1; - -import "pbresource/annotations.proto"; +package hashicorp.consul.catalog.v1alpha1; message Node { - option (hashicorp.consul.resource.spec) = { - // TODO: This should eventually be SCOPE_PARTITION but that will require further changes to code - scope: SCOPE_NAMESPACE, - }; - repeated NodeAddress addresses = 1; } diff --git a/proto-public/pbcatalog/v1alpha1/protocol.pb.go b/proto-public/pbcatalog/v1alpha1/protocol.pb.go new file mode 100644 index 0000000000000..71e89aab4aa5a --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/protocol.pb.go @@ -0,0 +1,166 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbcatalog/v1alpha1/protocol.proto + +package catalogv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Protocol int32 + +const ( + // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX + Protocol_PROTOCOL_TCP Protocol = 0 + Protocol_PROTOCOL_HTTP Protocol = 1 + Protocol_PROTOCOL_HTTP2 Protocol = 2 + Protocol_PROTOCOL_GRPC Protocol = 3 + // Protocol Mesh indicates that this port can speak Consul's mTLS based mesh protocol. + Protocol_PROTOCOL_MESH Protocol = 4 +) + +// Enum value maps for Protocol. +var ( + Protocol_name = map[int32]string{ + 0: "PROTOCOL_TCP", + 1: "PROTOCOL_HTTP", + 2: "PROTOCOL_HTTP2", + 3: "PROTOCOL_GRPC", + 4: "PROTOCOL_MESH", + } + Protocol_value = map[string]int32{ + "PROTOCOL_TCP": 0, + "PROTOCOL_HTTP": 1, + "PROTOCOL_HTTP2": 2, + "PROTOCOL_GRPC": 3, + "PROTOCOL_MESH": 4, + } +) + +func (x Protocol) Enum() *Protocol { + p := new(Protocol) + *p = x + return p +} + +func (x Protocol) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Protocol) Descriptor() protoreflect.EnumDescriptor { + return file_pbcatalog_v1alpha1_protocol_proto_enumTypes[0].Descriptor() +} + +func (Protocol) Type() protoreflect.EnumType { + return &file_pbcatalog_v1alpha1_protocol_proto_enumTypes[0] +} + +func (x Protocol) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Protocol.Descriptor instead. +func (Protocol) EnumDescriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_protocol_proto_rawDescGZIP(), []int{0} +} + +var File_pbcatalog_v1alpha1_protocol_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_protocol_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2a, 0x69, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, + 0x43, 0x50, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, + 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x54, 0x4f, + 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, + 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x03, 0x12, 0x11, + 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x4d, 0x45, 0x53, 0x48, 0x10, + 0x04, 0x42, 0xaa, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0d, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, + 0x67, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, + 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbcatalog_v1alpha1_protocol_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_protocol_proto_rawDescData = file_pbcatalog_v1alpha1_protocol_proto_rawDesc +) + +func file_pbcatalog_v1alpha1_protocol_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_protocol_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_protocol_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_protocol_proto_rawDescData) + }) + return file_pbcatalog_v1alpha1_protocol_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_protocol_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_pbcatalog_v1alpha1_protocol_proto_goTypes = []interface{}{ + (Protocol)(0), // 0: hashicorp.consul.catalog.v1alpha1.Protocol +} +var file_pbcatalog_v1alpha1_protocol_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_pbcatalog_v1alpha1_protocol_proto_init() } +func file_pbcatalog_v1alpha1_protocol_proto_init() { + if File_pbcatalog_v1alpha1_protocol_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbcatalog_v1alpha1_protocol_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbcatalog_v1alpha1_protocol_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_protocol_proto_depIdxs, + EnumInfos: file_pbcatalog_v1alpha1_protocol_proto_enumTypes, + }.Build() + File_pbcatalog_v1alpha1_protocol_proto = out.File + file_pbcatalog_v1alpha1_protocol_proto_rawDesc = nil + file_pbcatalog_v1alpha1_protocol_proto_goTypes = nil + file_pbcatalog_v1alpha1_protocol_proto_depIdxs = nil +} diff --git a/proto-public/pbcatalog/v1alpha1/protocol.proto b/proto-public/pbcatalog/v1alpha1/protocol.proto new file mode 100644 index 0000000000000..a18351c5d6d8f --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/protocol.proto @@ -0,0 +1,17 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +syntax = "proto3"; + +package hashicorp.consul.catalog.v1alpha1; + +enum Protocol { + // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX + PROTOCOL_TCP = 0; + PROTOCOL_HTTP = 1; + PROTOCOL_HTTP2 = 2; + PROTOCOL_GRPC = 3; + + // Protocol Mesh indicates that this port can speak Consul's mTLS based mesh protocol. + PROTOCOL_MESH = 4; +} diff --git a/proto-public/pbcatalog/v2beta1/selector.pb.binary.go b/proto-public/pbcatalog/v1alpha1/selector.pb.binary.go similarity index 85% rename from proto-public/pbcatalog/v2beta1/selector.pb.binary.go rename to proto-public/pbcatalog/v1alpha1/selector.pb.binary.go index cb55c9be5be6e..b3afb21d4799e 100644 --- a/proto-public/pbcatalog/v2beta1/selector.pb.binary.go +++ b/proto-public/pbcatalog/v1alpha1/selector.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/selector.proto +// source: pbcatalog/v1alpha1/selector.proto -package catalogv2beta1 +package catalogv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbcatalog/v1alpha1/selector.pb.go b/proto-public/pbcatalog/v1alpha1/selector.pb.go new file mode 100644 index 0000000000000..a6f5a3ef880d3 --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/selector.pb.go @@ -0,0 +1,177 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbcatalog/v1alpha1/selector.proto + +package catalogv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// WorkloadSelector represents criteria for selecting a subset of workloads. +type WorkloadSelector struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Prefixes []string `protobuf:"bytes,1,rep,name=prefixes,proto3" json:"prefixes,omitempty"` + Names []string `protobuf:"bytes,2,rep,name=names,proto3" json:"names,omitempty"` +} + +func (x *WorkloadSelector) Reset() { + *x = WorkloadSelector{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_selector_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkloadSelector) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadSelector) ProtoMessage() {} + +func (x *WorkloadSelector) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_selector_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadSelector.ProtoReflect.Descriptor instead. +func (*WorkloadSelector) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_selector_proto_rawDescGZIP(), []int{0} +} + +func (x *WorkloadSelector) GetPrefixes() []string { + if x != nil { + return x.Prefixes + } + return nil +} + +func (x *WorkloadSelector) GetNames() []string { + if x != nil { + return x.Names + } + return nil +} + +var File_pbcatalog_v1alpha1_selector_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_selector_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x44, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x42, 0xaa, 0x02, 0x0a, + 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0d, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, + 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, + 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_pbcatalog_v1alpha1_selector_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_selector_proto_rawDescData = file_pbcatalog_v1alpha1_selector_proto_rawDesc +) + +func file_pbcatalog_v1alpha1_selector_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_selector_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_selector_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_selector_proto_rawDescData) + }) + return file_pbcatalog_v1alpha1_selector_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_selector_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_pbcatalog_v1alpha1_selector_proto_goTypes = []interface{}{ + (*WorkloadSelector)(nil), // 0: hashicorp.consul.catalog.v1alpha1.WorkloadSelector +} +var file_pbcatalog_v1alpha1_selector_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_pbcatalog_v1alpha1_selector_proto_init() } +func file_pbcatalog_v1alpha1_selector_proto_init() { + if File_pbcatalog_v1alpha1_selector_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pbcatalog_v1alpha1_selector_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkloadSelector); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbcatalog_v1alpha1_selector_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbcatalog_v1alpha1_selector_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_selector_proto_depIdxs, + MessageInfos: file_pbcatalog_v1alpha1_selector_proto_msgTypes, + }.Build() + File_pbcatalog_v1alpha1_selector_proto = out.File + file_pbcatalog_v1alpha1_selector_proto_rawDesc = nil + file_pbcatalog_v1alpha1_selector_proto_goTypes = nil + file_pbcatalog_v1alpha1_selector_proto_depIdxs = nil +} diff --git a/proto-public/pbcatalog/v2beta1/selector.proto b/proto-public/pbcatalog/v1alpha1/selector.proto similarity index 80% rename from proto-public/pbcatalog/v2beta1/selector.proto rename to proto-public/pbcatalog/v1alpha1/selector.proto index 6786e7faf9868..b1b39409ba3a6 100644 --- a/proto-public/pbcatalog/v2beta1/selector.proto +++ b/proto-public/pbcatalog/v1alpha1/selector.proto @@ -3,11 +3,10 @@ syntax = "proto3"; -package hashicorp.consul.catalog.v2beta1; +package hashicorp.consul.catalog.v1alpha1; // WorkloadSelector represents criteria for selecting a subset of workloads. message WorkloadSelector { repeated string prefixes = 1; repeated string names = 2; - string filter = 3; } diff --git a/proto-public/pbcatalog/v2beta1/service.pb.binary.go b/proto-public/pbcatalog/v1alpha1/service.pb.binary.go similarity index 90% rename from proto-public/pbcatalog/v2beta1/service.pb.binary.go rename to proto-public/pbcatalog/v1alpha1/service.pb.binary.go index a017a7bf37212..1dd7eca1d2e83 100644 --- a/proto-public/pbcatalog/v2beta1/service.pb.binary.go +++ b/proto-public/pbcatalog/v1alpha1/service.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/service.proto +// source: pbcatalog/v1alpha1/service.proto -package catalogv2beta1 +package catalogv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbcatalog/v1alpha1/service.pb.go b/proto-public/pbcatalog/v1alpha1/service.pb.go new file mode 100644 index 0000000000000..cd72ccf268ff8 --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/service.pb.go @@ -0,0 +1,301 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbcatalog/v1alpha1/service.proto + +package catalogv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Service struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // workloads is a selector for the workloads this service should represent. + Workloads *WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` + // ports is the list of mappings of workload ports that this service + // represents. + Ports []*ServicePort `protobuf:"bytes,2,rep,name=ports,proto3" json:"ports,omitempty"` + // virtual_ips is a list of virtual IPs for this service. This is useful when you need to set + // an IP from an external system (like Kubernetes). This can be an IPv4 or IPv6 string. + VirtualIps []string `protobuf:"bytes,3,rep,name=virtual_ips,json=virtualIps,proto3" json:"virtual_ips,omitempty"` +} + +func (x *Service) Reset() { + *x = Service{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Service) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Service) ProtoMessage() {} + +func (x *Service) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Service.ProtoReflect.Descriptor instead. +func (*Service) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_service_proto_rawDescGZIP(), []int{0} +} + +func (x *Service) GetWorkloads() *WorkloadSelector { + if x != nil { + return x.Workloads + } + return nil +} + +func (x *Service) GetPorts() []*ServicePort { + if x != nil { + return x.Ports + } + return nil +} + +func (x *Service) GetVirtualIps() []string { + if x != nil { + return x.VirtualIps + } + return nil +} + +type ServicePort struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // virtual_port is the port that could only be used when transparent + // proxy is used alongside a virtual IP or a virtual DNS address. + // This value is ignored in other cases. Whether or not using transparent + // proxy, this value is optional. + VirtualPort uint32 `protobuf:"varint,1,opt,name=virtual_port,json=virtualPort,proto3" json:"virtual_port,omitempty"` + // target_port is the name of the workload port. + TargetPort string `protobuf:"bytes,2,opt,name=target_port,json=targetPort,proto3" json:"target_port,omitempty"` + // protocol is the port's protocol. This should be set to "mesh" + // if the target port is the proxy's inbound port. + Protocol Protocol `protobuf:"varint,3,opt,name=protocol,proto3,enum=hashicorp.consul.catalog.v1alpha1.Protocol" json:"protocol,omitempty"` +} + +func (x *ServicePort) Reset() { + *x = ServicePort{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServicePort) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServicePort) ProtoMessage() {} + +func (x *ServicePort) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServicePort.ProtoReflect.Descriptor instead. +func (*ServicePort) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_service_proto_rawDescGZIP(), []int{1} +} + +func (x *ServicePort) GetVirtualPort() uint32 { + if x != nil { + return x.VirtualPort + } + return 0 +} + +func (x *ServicePort) GetTargetPort() string { + if x != nil { + return x.TargetPort + } + return "" +} + +func (x *ServicePort) GetProtocol() Protocol { + if x != nil { + return x.Protocol + } + return Protocol_PROTOCOL_TCP +} + +var File_pbcatalog_v1alpha1_service_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_service_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x21, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, + 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x01, 0x0a, 0x07, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x51, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, + 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, + 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x44, 0x0a, 0x05, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x69, 0x70, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x49, 0x70, + 0x73, 0x22, 0x9a, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x47, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x42, 0xa9, + 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, + 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, + 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_pbcatalog_v1alpha1_service_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_service_proto_rawDescData = file_pbcatalog_v1alpha1_service_proto_rawDesc +) + +func file_pbcatalog_v1alpha1_service_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_service_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_service_proto_rawDescData) + }) + return file_pbcatalog_v1alpha1_service_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pbcatalog_v1alpha1_service_proto_goTypes = []interface{}{ + (*Service)(nil), // 0: hashicorp.consul.catalog.v1alpha1.Service + (*ServicePort)(nil), // 1: hashicorp.consul.catalog.v1alpha1.ServicePort + (*WorkloadSelector)(nil), // 2: hashicorp.consul.catalog.v1alpha1.WorkloadSelector + (Protocol)(0), // 3: hashicorp.consul.catalog.v1alpha1.Protocol +} +var file_pbcatalog_v1alpha1_service_proto_depIdxs = []int32{ + 2, // 0: hashicorp.consul.catalog.v1alpha1.Service.workloads:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadSelector + 1, // 1: hashicorp.consul.catalog.v1alpha1.Service.ports:type_name -> hashicorp.consul.catalog.v1alpha1.ServicePort + 3, // 2: hashicorp.consul.catalog.v1alpha1.ServicePort.protocol:type_name -> hashicorp.consul.catalog.v1alpha1.Protocol + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_pbcatalog_v1alpha1_service_proto_init() } +func file_pbcatalog_v1alpha1_service_proto_init() { + if File_pbcatalog_v1alpha1_service_proto != nil { + return + } + file_pbcatalog_v1alpha1_protocol_proto_init() + file_pbcatalog_v1alpha1_selector_proto_init() + if !protoimpl.UnsafeEnabled { + file_pbcatalog_v1alpha1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Service); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbcatalog_v1alpha1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServicePort); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbcatalog_v1alpha1_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbcatalog_v1alpha1_service_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_service_proto_depIdxs, + MessageInfos: file_pbcatalog_v1alpha1_service_proto_msgTypes, + }.Build() + File_pbcatalog_v1alpha1_service_proto = out.File + file_pbcatalog_v1alpha1_service_proto_rawDesc = nil + file_pbcatalog_v1alpha1_service_proto_goTypes = nil + file_pbcatalog_v1alpha1_service_proto_depIdxs = nil +} diff --git a/proto-public/pbcatalog/v2beta1/service.proto b/proto-public/pbcatalog/v1alpha1/service.proto similarity index 82% rename from proto-public/pbcatalog/v2beta1/service.proto rename to proto-public/pbcatalog/v1alpha1/service.proto index fd03768b907f3..4d4d681308d9d 100644 --- a/proto-public/pbcatalog/v2beta1/service.proto +++ b/proto-public/pbcatalog/v1alpha1/service.proto @@ -3,15 +3,12 @@ syntax = "proto3"; -package hashicorp.consul.catalog.v2beta1; +package hashicorp.consul.catalog.v1alpha1; -import "pbcatalog/v2beta1/protocol.proto"; -import "pbcatalog/v2beta1/selector.proto"; -import "pbresource/annotations.proto"; +import "pbcatalog/v1alpha1/protocol.proto"; +import "pbcatalog/v1alpha1/selector.proto"; message Service { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - // workloads is a selector for the workloads this service should represent. WorkloadSelector workloads = 1; // ports is the list of mappings of workload ports that this service diff --git a/proto-public/pbcatalog/v2beta1/service_endpoints.pb.binary.go b/proto-public/pbcatalog/v1alpha1/service_endpoints.pb.binary.go similarity index 89% rename from proto-public/pbcatalog/v2beta1/service_endpoints.pb.binary.go rename to proto-public/pbcatalog/v1alpha1/service_endpoints.pb.binary.go index 1e5fd4a834cd7..f20a805a4d2b6 100644 --- a/proto-public/pbcatalog/v2beta1/service_endpoints.pb.binary.go +++ b/proto-public/pbcatalog/v1alpha1/service_endpoints.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/service_endpoints.proto +// source: pbcatalog/v1alpha1/service_endpoints.proto -package catalogv2beta1 +package catalogv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbcatalog/v1alpha1/service_endpoints.pb.go b/proto-public/pbcatalog/v1alpha1/service_endpoints.pb.go new file mode 100644 index 0000000000000..903de0706bf23 --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/service_endpoints.pb.go @@ -0,0 +1,308 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbcatalog/v1alpha1/service_endpoints.proto + +package catalogv1alpha1 + +import ( + pbresource "github.com/hashicorp/consul/proto-public/pbresource" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ServiceEndpoints struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Endpoints []*Endpoint `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"` +} + +func (x *ServiceEndpoints) Reset() { + *x = ServiceEndpoints{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_service_endpoints_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServiceEndpoints) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceEndpoints) ProtoMessage() {} + +func (x *ServiceEndpoints) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_service_endpoints_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ServiceEndpoints.ProtoReflect.Descriptor instead. +func (*ServiceEndpoints) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescGZIP(), []int{0} +} + +func (x *ServiceEndpoints) GetEndpoints() []*Endpoint { + if x != nil { + return x.Endpoints + } + return nil +} + +type Endpoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // target_ref is the reference to the resource + // for this endpoint endpoint. This currently must be a workload. + TargetRef *pbresource.ID `protobuf:"bytes,1,opt,name=target_ref,json=targetRef,proto3" json:"target_ref,omitempty"` + // addresses is the list of addresses for this endpoint. + // This has the same structure as the workload addresses. + Addresses []*WorkloadAddress `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"` + // ports is the map of ports for this endpoint. + // This has the same structure as the workload ports but + // will be filtered to just the ports selected by the service. + Ports map[string]*WorkloadPort `protobuf:"bytes,3,rep,name=ports,proto3" json:"ports,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // health_status is the aggregated health status of this endpoint. + HealthStatus Health `protobuf:"varint,4,opt,name=health_status,json=healthStatus,proto3,enum=hashicorp.consul.catalog.v1alpha1.Health" json:"health_status,omitempty"` +} + +func (x *Endpoint) Reset() { + *x = Endpoint{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_service_endpoints_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Endpoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Endpoint) ProtoMessage() {} + +func (x *Endpoint) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_service_endpoints_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Endpoint.ProtoReflect.Descriptor instead. +func (*Endpoint) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescGZIP(), []int{1} +} + +func (x *Endpoint) GetTargetRef() *pbresource.ID { + if x != nil { + return x.TargetRef + } + return nil +} + +func (x *Endpoint) GetAddresses() []*WorkloadAddress { + if x != nil { + return x.Addresses + } + return nil +} + +func (x *Endpoint) GetPorts() map[string]*WorkloadPort { + if x != nil { + return x.Ports + } + return nil +} + +func (x *Endpoint) GetHealthStatus() Health { + if x != nil { + return x.HealthStatus + } + return Health_HEALTH_ANY +} + +var File_pbcatalog_v1alpha1_service_endpoints_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_service_endpoints_proto_rawDesc = []byte{ + 0x0a, 0x2a, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, + 0x1f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, + 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x73, 0x12, 0x49, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0xa3, 0x03, + 0x0a, 0x08, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x49, 0x44, 0x52, 0x09, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x50, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, + 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x05, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6e, + 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x4e, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x69, 0x0a, 0x0a, 0x50, 0x6f, 0x72, 0x74, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x42, 0xb2, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x15, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x21, + 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, + 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescData = file_pbcatalog_v1alpha1_service_endpoints_proto_rawDesc +) + +func file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescData) + }) + return file_pbcatalog_v1alpha1_service_endpoints_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_service_endpoints_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_pbcatalog_v1alpha1_service_endpoints_proto_goTypes = []interface{}{ + (*ServiceEndpoints)(nil), // 0: hashicorp.consul.catalog.v1alpha1.ServiceEndpoints + (*Endpoint)(nil), // 1: hashicorp.consul.catalog.v1alpha1.Endpoint + nil, // 2: hashicorp.consul.catalog.v1alpha1.Endpoint.PortsEntry + (*pbresource.ID)(nil), // 3: hashicorp.consul.resource.ID + (*WorkloadAddress)(nil), // 4: hashicorp.consul.catalog.v1alpha1.WorkloadAddress + (Health)(0), // 5: hashicorp.consul.catalog.v1alpha1.Health + (*WorkloadPort)(nil), // 6: hashicorp.consul.catalog.v1alpha1.WorkloadPort +} +var file_pbcatalog_v1alpha1_service_endpoints_proto_depIdxs = []int32{ + 1, // 0: hashicorp.consul.catalog.v1alpha1.ServiceEndpoints.endpoints:type_name -> hashicorp.consul.catalog.v1alpha1.Endpoint + 3, // 1: hashicorp.consul.catalog.v1alpha1.Endpoint.target_ref:type_name -> hashicorp.consul.resource.ID + 4, // 2: hashicorp.consul.catalog.v1alpha1.Endpoint.addresses:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadAddress + 2, // 3: hashicorp.consul.catalog.v1alpha1.Endpoint.ports:type_name -> hashicorp.consul.catalog.v1alpha1.Endpoint.PortsEntry + 5, // 4: hashicorp.consul.catalog.v1alpha1.Endpoint.health_status:type_name -> hashicorp.consul.catalog.v1alpha1.Health + 6, // 5: hashicorp.consul.catalog.v1alpha1.Endpoint.PortsEntry.value:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadPort + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_pbcatalog_v1alpha1_service_endpoints_proto_init() } +func file_pbcatalog_v1alpha1_service_endpoints_proto_init() { + if File_pbcatalog_v1alpha1_service_endpoints_proto != nil { + return + } + file_pbcatalog_v1alpha1_health_proto_init() + file_pbcatalog_v1alpha1_workload_proto_init() + if !protoimpl.UnsafeEnabled { + file_pbcatalog_v1alpha1_service_endpoints_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceEndpoints); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbcatalog_v1alpha1_service_endpoints_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Endpoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbcatalog_v1alpha1_service_endpoints_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbcatalog_v1alpha1_service_endpoints_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_service_endpoints_proto_depIdxs, + MessageInfos: file_pbcatalog_v1alpha1_service_endpoints_proto_msgTypes, + }.Build() + File_pbcatalog_v1alpha1_service_endpoints_proto = out.File + file_pbcatalog_v1alpha1_service_endpoints_proto_rawDesc = nil + file_pbcatalog_v1alpha1_service_endpoints_proto_goTypes = nil + file_pbcatalog_v1alpha1_service_endpoints_proto_depIdxs = nil +} diff --git a/proto-public/pbcatalog/v2beta1/service_endpoints.proto b/proto-public/pbcatalog/v1alpha1/service_endpoints.proto similarity index 72% rename from proto-public/pbcatalog/v2beta1/service_endpoints.proto rename to proto-public/pbcatalog/v1alpha1/service_endpoints.proto index cd205a001e404..df3c70e0312f3 100644 --- a/proto-public/pbcatalog/v2beta1/service_endpoints.proto +++ b/proto-public/pbcatalog/v1alpha1/service_endpoints.proto @@ -3,16 +3,13 @@ syntax = "proto3"; -package hashicorp.consul.catalog.v2beta1; +package hashicorp.consul.catalog.v1alpha1; -import "pbcatalog/v2beta1/health.proto"; -import "pbcatalog/v2beta1/workload.proto"; -import "pbresource/annotations.proto"; +import "pbcatalog/v1alpha1/health.proto"; +import "pbcatalog/v1alpha1/workload.proto"; import "pbresource/resource.proto"; message ServiceEndpoints { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - repeated Endpoint endpoints = 1; } @@ -32,7 +29,4 @@ message Endpoint { // health_status is the aggregated health status of this endpoint. Health health_status = 4; - - // identity is the name of the workload identity for this endpoint. - string identity = 5; } diff --git a/proto-public/pbcatalog/v2beta1/vip.pb.binary.go b/proto-public/pbcatalog/v1alpha1/vip.pb.binary.go similarity index 91% rename from proto-public/pbcatalog/v2beta1/vip.pb.binary.go rename to proto-public/pbcatalog/v1alpha1/vip.pb.binary.go index 2702cdae21e0b..fa7cf2dec2747 100644 --- a/proto-public/pbcatalog/v2beta1/vip.pb.binary.go +++ b/proto-public/pbcatalog/v1alpha1/vip.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/vip.proto +// source: pbcatalog/v1alpha1/vip.proto -package catalogv2beta1 +package catalogv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbcatalog/v1alpha1/vip.pb.go b/proto-public/pbcatalog/v1alpha1/vip.pb.go new file mode 100644 index 0000000000000..7ba05aa850966 --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/vip.pb.go @@ -0,0 +1,244 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbcatalog/v1alpha1/vip.proto + +package catalogv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type VirtualIPs struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ips []*IP `protobuf:"bytes,1,rep,name=ips,proto3" json:"ips,omitempty"` +} + +func (x *VirtualIPs) Reset() { + *x = VirtualIPs{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_vip_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VirtualIPs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VirtualIPs) ProtoMessage() {} + +func (x *VirtualIPs) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_vip_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VirtualIPs.ProtoReflect.Descriptor instead. +func (*VirtualIPs) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_vip_proto_rawDescGZIP(), []int{0} +} + +func (x *VirtualIPs) GetIps() []*IP { + if x != nil { + return x.Ips + } + return nil +} + +type IP struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // address is the string IPv4 address. + // This could also store IPv6 in the future. + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // generated indicates whether Consul generated or it is user-provided + // (e.g. a ClusterIP of the Kubernetes service). + Generated bool `protobuf:"varint,2,opt,name=generated,proto3" json:"generated,omitempty"` +} + +func (x *IP) Reset() { + *x = IP{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_vip_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IP) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IP) ProtoMessage() {} + +func (x *IP) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_vip_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IP.ProtoReflect.Descriptor instead. +func (*IP) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_vip_proto_rawDescGZIP(), []int{1} +} + +func (x *IP) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *IP) GetGenerated() bool { + if x != nil { + return x.Generated + } + return false +} + +var File_pbcatalog_v1alpha1_vip_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_vip_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x22, 0x45, 0x0a, 0x0a, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x49, 0x50, 0x73, 0x12, + 0x37, 0x0a, 0x03, 0x69, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x49, 0x50, 0x52, 0x03, 0x69, 0x70, 0x73, 0x22, 0x3c, 0x0a, 0x02, 0x49, 0x50, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x42, 0xa5, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x42, 0x08, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, + 0x67, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, + 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbcatalog_v1alpha1_vip_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_vip_proto_rawDescData = file_pbcatalog_v1alpha1_vip_proto_rawDesc +) + +func file_pbcatalog_v1alpha1_vip_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_vip_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_vip_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_vip_proto_rawDescData) + }) + return file_pbcatalog_v1alpha1_vip_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_vip_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pbcatalog_v1alpha1_vip_proto_goTypes = []interface{}{ + (*VirtualIPs)(nil), // 0: hashicorp.consul.catalog.v1alpha1.VirtualIPs + (*IP)(nil), // 1: hashicorp.consul.catalog.v1alpha1.IP +} +var file_pbcatalog_v1alpha1_vip_proto_depIdxs = []int32{ + 1, // 0: hashicorp.consul.catalog.v1alpha1.VirtualIPs.ips:type_name -> hashicorp.consul.catalog.v1alpha1.IP + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_pbcatalog_v1alpha1_vip_proto_init() } +func file_pbcatalog_v1alpha1_vip_proto_init() { + if File_pbcatalog_v1alpha1_vip_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pbcatalog_v1alpha1_vip_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VirtualIPs); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbcatalog_v1alpha1_vip_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IP); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbcatalog_v1alpha1_vip_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbcatalog_v1alpha1_vip_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_vip_proto_depIdxs, + MessageInfos: file_pbcatalog_v1alpha1_vip_proto_msgTypes, + }.Build() + File_pbcatalog_v1alpha1_vip_proto = out.File + file_pbcatalog_v1alpha1_vip_proto_rawDesc = nil + file_pbcatalog_v1alpha1_vip_proto_goTypes = nil + file_pbcatalog_v1alpha1_vip_proto_depIdxs = nil +} diff --git a/proto-public/pbcatalog/v2beta1/vip.proto b/proto-public/pbcatalog/v1alpha1/vip.proto similarity index 72% rename from proto-public/pbcatalog/v2beta1/vip.proto rename to proto-public/pbcatalog/v1alpha1/vip.proto index 386ce58f16b98..5efee624fcaab 100644 --- a/proto-public/pbcatalog/v2beta1/vip.proto +++ b/proto-public/pbcatalog/v1alpha1/vip.proto @@ -3,13 +3,9 @@ syntax = "proto3"; -package hashicorp.consul.catalog.v2beta1; - -import "pbresource/annotations.proto"; +package hashicorp.consul.catalog.v1alpha1; message VirtualIPs { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - repeated IP ips = 1; } diff --git a/proto-public/pbcatalog/v2beta1/workload.pb.binary.go b/proto-public/pbcatalog/v1alpha1/workload.pb.binary.go similarity index 94% rename from proto-public/pbcatalog/v2beta1/workload.pb.binary.go rename to proto-public/pbcatalog/v1alpha1/workload.pb.binary.go index cb083b46e7969..ffc54f0726193 100644 --- a/proto-public/pbcatalog/v2beta1/workload.pb.binary.go +++ b/proto-public/pbcatalog/v1alpha1/workload.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/workload.proto +// source: pbcatalog/v1alpha1/workload.proto -package catalogv2beta1 +package catalogv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbcatalog/v1alpha1/workload.pb.go b/proto-public/pbcatalog/v1alpha1/workload.pb.go new file mode 100644 index 0000000000000..e1f75d810cb81 --- /dev/null +++ b/proto-public/pbcatalog/v1alpha1/workload.pb.go @@ -0,0 +1,520 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbcatalog/v1alpha1/workload.proto + +package catalogv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Workload is the representation of a unit of addressable work. This could +// represent a process on a VM, a Kubernetes pod or something else entirely. +type Workload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // addresses has a list of all workload addresses. This should include + // LAN and WAN addresses as well as any addresses a proxy would need + // to bind to (if different from the default address). + Addresses []*WorkloadAddress `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` + // ports is a map from port name to workload port’s number and protocol. + Ports map[string]*WorkloadPort `protobuf:"bytes,2,rep,name=ports,proto3" json:"ports,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // node_name is the name of the node this workload belongs to. + NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` + // identity is the name of the workload identity this workload is associated with. + Identity string `protobuf:"bytes,4,opt,name=identity,proto3" json:"identity,omitempty"` + // Locality specifies workload locality. + Locality *Locality `protobuf:"bytes,5,opt,name=locality,proto3" json:"locality,omitempty"` + // deprecated: tags correspond to service tags that you can add to a service for DNS resolution. + // + // Deprecated: Marked as deprecated in pbcatalog/v1alpha1/workload.proto. + Tags []string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty"` + // deprecated: enable_tag_override indicates whether agents should be overriding tags during anti-entropy syncs. + // + // Deprecated: Marked as deprecated in pbcatalog/v1alpha1/workload.proto. + EnableTagOverride bool `protobuf:"varint,7,opt,name=enable_tag_override,json=enableTagOverride,proto3" json:"enable_tag_override,omitempty"` + // deprecated: connect_native indicates whether this workload is connect native which will allow it to be + // part of MeshEndpoints without having the corresponding Proxy resource. + // + // Deprecated: Marked as deprecated in pbcatalog/v1alpha1/workload.proto. + ConnectNative bool `protobuf:"varint,8,opt,name=connect_native,json=connectNative,proto3" json:"connect_native,omitempty"` +} + +func (x *Workload) Reset() { + *x = Workload{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_workload_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Workload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Workload) ProtoMessage() {} + +func (x *Workload) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_workload_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Workload.ProtoReflect.Descriptor instead. +func (*Workload) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_workload_proto_rawDescGZIP(), []int{0} +} + +func (x *Workload) GetAddresses() []*WorkloadAddress { + if x != nil { + return x.Addresses + } + return nil +} + +func (x *Workload) GetPorts() map[string]*WorkloadPort { + if x != nil { + return x.Ports + } + return nil +} + +func (x *Workload) GetNodeName() string { + if x != nil { + return x.NodeName + } + return "" +} + +func (x *Workload) GetIdentity() string { + if x != nil { + return x.Identity + } + return "" +} + +func (x *Workload) GetLocality() *Locality { + if x != nil { + return x.Locality + } + return nil +} + +// Deprecated: Marked as deprecated in pbcatalog/v1alpha1/workload.proto. +func (x *Workload) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +// Deprecated: Marked as deprecated in pbcatalog/v1alpha1/workload.proto. +func (x *Workload) GetEnableTagOverride() bool { + if x != nil { + return x.EnableTagOverride + } + return false +} + +// Deprecated: Marked as deprecated in pbcatalog/v1alpha1/workload.proto. +func (x *Workload) GetConnectNative() bool { + if x != nil { + return x.ConnectNative + } + return false +} + +type WorkloadAddress struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // host can be an IP, DNS name or a unix socket. + // If it's a unix socket, only one port can be provided. + Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` + // ports is a list of names of ports that this host binds to. + // If no ports are provided, we will assume all ports from the ports map. + Ports []string `protobuf:"bytes,2,rep,name=ports,proto3" json:"ports,omitempty"` + // external indicates whether this address should be used for external communication + // (aka a WAN address). + External bool `protobuf:"varint,3,opt,name=external,proto3" json:"external,omitempty"` +} + +func (x *WorkloadAddress) Reset() { + *x = WorkloadAddress{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_workload_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkloadAddress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadAddress) ProtoMessage() {} + +func (x *WorkloadAddress) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_workload_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadAddress.ProtoReflect.Descriptor instead. +func (*WorkloadAddress) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_workload_proto_rawDescGZIP(), []int{1} +} + +func (x *WorkloadAddress) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +func (x *WorkloadAddress) GetPorts() []string { + if x != nil { + return x.Ports + } + return nil +} + +func (x *WorkloadAddress) GetExternal() bool { + if x != nil { + return x.External + } + return false +} + +type WorkloadPort struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Port uint32 `protobuf:"varint,1,opt,name=port,proto3" json:"port,omitempty"` + Protocol Protocol `protobuf:"varint,2,opt,name=protocol,proto3,enum=hashicorp.consul.catalog.v1alpha1.Protocol" json:"protocol,omitempty"` +} + +func (x *WorkloadPort) Reset() { + *x = WorkloadPort{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_workload_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkloadPort) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkloadPort) ProtoMessage() {} + +func (x *WorkloadPort) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_workload_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkloadPort.ProtoReflect.Descriptor instead. +func (*WorkloadPort) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_workload_proto_rawDescGZIP(), []int{2} +} + +func (x *WorkloadPort) GetPort() uint32 { + if x != nil { + return x.Port + } + return 0 +} + +func (x *WorkloadPort) GetProtocol() Protocol { + if x != nil { + return x.Protocol + } + return Protocol_PROTOCOL_TCP +} + +type Locality struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Region is region the zone belongs to. + Region string `protobuf:"bytes,1,opt,name=region,proto3" json:"region,omitempty"` + // Zone is the zone the entity is running in. + Zone string `protobuf:"bytes,2,opt,name=zone,proto3" json:"zone,omitempty"` +} + +func (x *Locality) Reset() { + *x = Locality{} + if protoimpl.UnsafeEnabled { + mi := &file_pbcatalog_v1alpha1_workload_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Locality) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Locality) ProtoMessage() {} + +func (x *Locality) ProtoReflect() protoreflect.Message { + mi := &file_pbcatalog_v1alpha1_workload_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Locality.ProtoReflect.Descriptor instead. +func (*Locality) Descriptor() ([]byte, []int) { + return file_pbcatalog_v1alpha1_workload_proto_rawDescGZIP(), []int{3} +} + +func (x *Locality) GetRegion() string { + if x != nil { + return x.Region + } + return "" +} + +func (x *Locality) GetZone() string { + if x != nil { + return x.Zone + } + return "" +} + +var File_pbcatalog_v1alpha1_workload_proto protoreflect.FileDescriptor + +var file_pbcatalog_v1alpha1_workload_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, + 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8e, 0x04, 0x0a, 0x08, 0x57, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x50, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, + 0x47, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x08, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, + 0x12, 0x32, 0x0a, 0x13, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x6f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, + 0x01, 0x52, 0x11, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x61, 0x67, 0x4f, 0x76, 0x65, 0x72, + 0x72, 0x69, 0x64, 0x65, 0x12, 0x29, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, + 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, + 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x1a, + 0x69, 0x0a, 0x0a, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x57, 0x0a, 0x0f, 0x57, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, + 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, + 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x22, 0x6b, 0x0a, 0x0c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x47, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x22, 0x36, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, + 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x42, 0xaa, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x42, 0x0d, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, + 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, + 0x67, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, + 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbcatalog_v1alpha1_workload_proto_rawDescOnce sync.Once + file_pbcatalog_v1alpha1_workload_proto_rawDescData = file_pbcatalog_v1alpha1_workload_proto_rawDesc +) + +func file_pbcatalog_v1alpha1_workload_proto_rawDescGZIP() []byte { + file_pbcatalog_v1alpha1_workload_proto_rawDescOnce.Do(func() { + file_pbcatalog_v1alpha1_workload_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v1alpha1_workload_proto_rawDescData) + }) + return file_pbcatalog_v1alpha1_workload_proto_rawDescData +} + +var file_pbcatalog_v1alpha1_workload_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_pbcatalog_v1alpha1_workload_proto_goTypes = []interface{}{ + (*Workload)(nil), // 0: hashicorp.consul.catalog.v1alpha1.Workload + (*WorkloadAddress)(nil), // 1: hashicorp.consul.catalog.v1alpha1.WorkloadAddress + (*WorkloadPort)(nil), // 2: hashicorp.consul.catalog.v1alpha1.WorkloadPort + (*Locality)(nil), // 3: hashicorp.consul.catalog.v1alpha1.Locality + nil, // 4: hashicorp.consul.catalog.v1alpha1.Workload.PortsEntry + (Protocol)(0), // 5: hashicorp.consul.catalog.v1alpha1.Protocol +} +var file_pbcatalog_v1alpha1_workload_proto_depIdxs = []int32{ + 1, // 0: hashicorp.consul.catalog.v1alpha1.Workload.addresses:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadAddress + 4, // 1: hashicorp.consul.catalog.v1alpha1.Workload.ports:type_name -> hashicorp.consul.catalog.v1alpha1.Workload.PortsEntry + 3, // 2: hashicorp.consul.catalog.v1alpha1.Workload.locality:type_name -> hashicorp.consul.catalog.v1alpha1.Locality + 5, // 3: hashicorp.consul.catalog.v1alpha1.WorkloadPort.protocol:type_name -> hashicorp.consul.catalog.v1alpha1.Protocol + 2, // 4: hashicorp.consul.catalog.v1alpha1.Workload.PortsEntry.value:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadPort + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_pbcatalog_v1alpha1_workload_proto_init() } +func file_pbcatalog_v1alpha1_workload_proto_init() { + if File_pbcatalog_v1alpha1_workload_proto != nil { + return + } + file_pbcatalog_v1alpha1_protocol_proto_init() + if !protoimpl.UnsafeEnabled { + file_pbcatalog_v1alpha1_workload_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Workload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbcatalog_v1alpha1_workload_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkloadAddress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbcatalog_v1alpha1_workload_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkloadPort); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbcatalog_v1alpha1_workload_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Locality); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbcatalog_v1alpha1_workload_proto_rawDesc, + NumEnums: 0, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbcatalog_v1alpha1_workload_proto_goTypes, + DependencyIndexes: file_pbcatalog_v1alpha1_workload_proto_depIdxs, + MessageInfos: file_pbcatalog_v1alpha1_workload_proto_msgTypes, + }.Build() + File_pbcatalog_v1alpha1_workload_proto = out.File + file_pbcatalog_v1alpha1_workload_proto_rawDesc = nil + file_pbcatalog_v1alpha1_workload_proto_goTypes = nil + file_pbcatalog_v1alpha1_workload_proto_depIdxs = nil +} diff --git a/proto-public/pbcatalog/v2beta1/workload.proto b/proto-public/pbcatalog/v1alpha1/workload.proto similarity index 91% rename from proto-public/pbcatalog/v2beta1/workload.proto rename to proto-public/pbcatalog/v1alpha1/workload.proto index 67dd8b72d2728..00c82b8eebd37 100644 --- a/proto-public/pbcatalog/v2beta1/workload.proto +++ b/proto-public/pbcatalog/v1alpha1/workload.proto @@ -3,16 +3,13 @@ syntax = "proto3"; -package hashicorp.consul.catalog.v2beta1; +package hashicorp.consul.catalog.v1alpha1; -import "pbcatalog/v2beta1/protocol.proto"; -import "pbresource/annotations.proto"; +import "pbcatalog/v1alpha1/protocol.proto"; // Workload is the representation of a unit of addressable work. This could // represent a process on a VM, a Kubernetes pod or something else entirely. message Workload { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - // addresses has a list of all workload addresses. This should include // LAN and WAN addresses as well as any addresses a proxy would need // to bind to (if different from the default address). diff --git a/proto-public/pbcatalog/v2beta1/dns.pb.go b/proto-public/pbcatalog/v2beta1/dns.pb.go deleted file mode 100644 index 446e788d3e955..0000000000000 --- a/proto-public/pbcatalog/v2beta1/dns.pb.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/dns.proto - -package catalogv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type DNSPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Workloads *WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` - Weights *Weights `protobuf:"bytes,2,opt,name=weights,proto3" json:"weights,omitempty"` -} - -func (x *DNSPolicy) Reset() { - *x = DNSPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_dns_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DNSPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DNSPolicy) ProtoMessage() {} - -func (x *DNSPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_dns_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DNSPolicy.ProtoReflect.Descriptor instead. -func (*DNSPolicy) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_dns_proto_rawDescGZIP(), []int{0} -} - -func (x *DNSPolicy) GetWorkloads() *WorkloadSelector { - if x != nil { - return x.Workloads - } - return nil -} - -func (x *DNSPolicy) GetWeights() *Weights { - if x != nil { - return x.Weights - } - return nil -} - -type Weights struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Passing uint32 `protobuf:"varint,1,opt,name=passing,proto3" json:"passing,omitempty"` - Warning uint32 `protobuf:"varint,2,opt,name=warning,proto3" json:"warning,omitempty"` -} - -func (x *Weights) Reset() { - *x = Weights{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_dns_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Weights) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Weights) ProtoMessage() {} - -func (x *Weights) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_dns_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Weights.ProtoReflect.Descriptor instead. -func (*Weights) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_dns_proto_rawDescGZIP(), []int{1} -} - -func (x *Weights) GetPassing() uint32 { - if x != nil { - return x.Passing - } - return 0 -} - -func (x *Weights) GetWarning() uint32 { - if x != nil { - return x.Warning - } - return 0 -} - -var File_pbcatalog_v2beta1_dns_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_dns_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x64, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, - 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xaa, 0x01, 0x0a, 0x09, 0x44, 0x4e, 0x53, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x50, 0x0a, - 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, - 0x43, 0x0a, 0x07, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x52, 0x07, 0x77, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x3d, 0x0a, 0x07, - 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x73, 0x73, 0x69, - 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x70, 0x61, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x42, 0x9e, 0x02, 0x0a, 0x24, - 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x08, 0x44, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, - 0x43, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_dns_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_dns_proto_rawDescData = file_pbcatalog_v2beta1_dns_proto_rawDesc -) - -func file_pbcatalog_v2beta1_dns_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_dns_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_dns_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_dns_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_dns_proto_rawDescData -} - -var file_pbcatalog_v2beta1_dns_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbcatalog_v2beta1_dns_proto_goTypes = []interface{}{ - (*DNSPolicy)(nil), // 0: hashicorp.consul.catalog.v2beta1.DNSPolicy - (*Weights)(nil), // 1: hashicorp.consul.catalog.v2beta1.Weights - (*WorkloadSelector)(nil), // 2: hashicorp.consul.catalog.v2beta1.WorkloadSelector -} -var file_pbcatalog_v2beta1_dns_proto_depIdxs = []int32{ - 2, // 0: hashicorp.consul.catalog.v2beta1.DNSPolicy.workloads:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadSelector - 1, // 1: hashicorp.consul.catalog.v2beta1.DNSPolicy.weights:type_name -> hashicorp.consul.catalog.v2beta1.Weights - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_dns_proto_init() } -func file_pbcatalog_v2beta1_dns_proto_init() { - if File_pbcatalog_v2beta1_dns_proto != nil { - return - } - file_pbcatalog_v2beta1_selector_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_dns_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DNSPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_dns_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Weights); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_dns_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_dns_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_dns_proto_depIdxs, - MessageInfos: file_pbcatalog_v2beta1_dns_proto_msgTypes, - }.Build() - File_pbcatalog_v2beta1_dns_proto = out.File - file_pbcatalog_v2beta1_dns_proto_rawDesc = nil - file_pbcatalog_v2beta1_dns_proto_goTypes = nil - file_pbcatalog_v2beta1_dns_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/dns_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/dns_deepcopy.gen.go deleted file mode 100644 index 9a3d883b8cec9..0000000000000 --- a/proto-public/pbcatalog/v2beta1/dns_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using DNSPolicy within kubernetes types, where deepcopy-gen is used. -func (in *DNSPolicy) DeepCopyInto(out *DNSPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSPolicy. Required by controller-gen. -func (in *DNSPolicy) DeepCopy() *DNSPolicy { - if in == nil { - return nil - } - out := new(DNSPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DNSPolicy. Required by controller-gen. -func (in *DNSPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Weights within kubernetes types, where deepcopy-gen is used. -func (in *Weights) DeepCopyInto(out *Weights) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Weights. Required by controller-gen. -func (in *Weights) DeepCopy() *Weights { - if in == nil { - return nil - } - out := new(Weights) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Weights. Required by controller-gen. -func (in *Weights) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/dns_json.gen.go b/proto-public/pbcatalog/v2beta1/dns_json.gen.go deleted file mode 100644 index fd320300a309a..0000000000000 --- a/proto-public/pbcatalog/v2beta1/dns_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for DNSPolicy -func (this *DNSPolicy) MarshalJSON() ([]byte, error) { - str, err := DnsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DNSPolicy -func (this *DNSPolicy) UnmarshalJSON(b []byte) error { - return DnsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Weights -func (this *Weights) MarshalJSON() ([]byte, error) { - str, err := DnsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Weights -func (this *Weights) UnmarshalJSON(b []byte) error { - return DnsUnmarshaler.Unmarshal(b, this) -} - -var ( - DnsMarshaler = &protojson.MarshalOptions{} - DnsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/failover_policy.pb.binary.go b/proto-public/pbcatalog/v2beta1/failover_policy.pb.binary.go deleted file mode 100644 index d6733fa876982..0000000000000 --- a/proto-public/pbcatalog/v2beta1/failover_policy.pb.binary.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbcatalog/v2beta1/failover_policy.proto - -package catalogv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *FailoverPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *FailoverPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *FailoverConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *FailoverConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *FailoverDestination) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *FailoverDestination) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbcatalog/v2beta1/failover_policy.pb.go b/proto-public/pbcatalog/v2beta1/failover_policy.pb.go deleted file mode 100644 index 58e70174a1e86..0000000000000 --- a/proto-public/pbcatalog/v2beta1/failover_policy.pb.go +++ /dev/null @@ -1,458 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/failover_policy.proto - -package catalogv2beta1 - -import ( - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type FailoverMode int32 - -const ( - FailoverMode_FAILOVER_MODE_UNSPECIFIED FailoverMode = 0 - FailoverMode_FAILOVER_MODE_SEQUENTIAL FailoverMode = 1 - FailoverMode_FAILOVER_MODE_ORDER_BY_LOCALITY FailoverMode = 2 -) - -// Enum value maps for FailoverMode. -var ( - FailoverMode_name = map[int32]string{ - 0: "FAILOVER_MODE_UNSPECIFIED", - 1: "FAILOVER_MODE_SEQUENTIAL", - 2: "FAILOVER_MODE_ORDER_BY_LOCALITY", - } - FailoverMode_value = map[string]int32{ - "FAILOVER_MODE_UNSPECIFIED": 0, - "FAILOVER_MODE_SEQUENTIAL": 1, - "FAILOVER_MODE_ORDER_BY_LOCALITY": 2, - } -) - -func (x FailoverMode) Enum() *FailoverMode { - p := new(FailoverMode) - *p = x - return p -} - -func (x FailoverMode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (FailoverMode) Descriptor() protoreflect.EnumDescriptor { - return file_pbcatalog_v2beta1_failover_policy_proto_enumTypes[0].Descriptor() -} - -func (FailoverMode) Type() protoreflect.EnumType { - return &file_pbcatalog_v2beta1_failover_policy_proto_enumTypes[0] -} - -func (x FailoverMode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use FailoverMode.Descriptor instead. -func (FailoverMode) EnumDescriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_failover_policy_proto_rawDescGZIP(), []int{0} -} - -// This is a Resource type. -type FailoverPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Config defines failover for any named port not present in PortConfigs. - Config *FailoverConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` - // PortConfigs defines failover for a specific port on this service and takes - // precedence over Config. - PortConfigs map[string]*FailoverConfig `protobuf:"bytes,2,rep,name=port_configs,json=portConfigs,proto3" json:"port_configs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *FailoverPolicy) Reset() { - *x = FailoverPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FailoverPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FailoverPolicy) ProtoMessage() {} - -func (x *FailoverPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FailoverPolicy.ProtoReflect.Descriptor instead. -func (*FailoverPolicy) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_failover_policy_proto_rawDescGZIP(), []int{0} -} - -func (x *FailoverPolicy) GetConfig() *FailoverConfig { - if x != nil { - return x.Config - } - return nil -} - -func (x *FailoverPolicy) GetPortConfigs() map[string]*FailoverConfig { - if x != nil { - return x.PortConfigs - } - return nil -} - -type FailoverConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Destinations specifies a fixed list of failover destinations to try. We - // never try a destination multiple times, so those are subtracted from this - // list before proceeding. - Destinations []*FailoverDestination `protobuf:"bytes,1,rep,name=destinations,proto3" json:"destinations,omitempty"` - // Mode specifies the type of failover that will be performed. Valid values are - // "sequential", "" (equivalent to "sequential") and "order-by-locality". - Mode FailoverMode `protobuf:"varint,2,opt,name=mode,proto3,enum=hashicorp.consul.catalog.v2beta1.FailoverMode" json:"mode,omitempty"` - Regions []string `protobuf:"bytes,3,rep,name=regions,proto3" json:"regions,omitempty"` - // SamenessGroup specifies the sameness group to failover to. - SamenessGroup string `protobuf:"bytes,4,opt,name=sameness_group,json=samenessGroup,proto3" json:"sameness_group,omitempty"` -} - -func (x *FailoverConfig) Reset() { - *x = FailoverConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FailoverConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FailoverConfig) ProtoMessage() {} - -func (x *FailoverConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FailoverConfig.ProtoReflect.Descriptor instead. -func (*FailoverConfig) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_failover_policy_proto_rawDescGZIP(), []int{1} -} - -func (x *FailoverConfig) GetDestinations() []*FailoverDestination { - if x != nil { - return x.Destinations - } - return nil -} - -func (x *FailoverConfig) GetMode() FailoverMode { - if x != nil { - return x.Mode - } - return FailoverMode_FAILOVER_MODE_UNSPECIFIED -} - -func (x *FailoverConfig) GetRegions() []string { - if x != nil { - return x.Regions - } - return nil -} - -func (x *FailoverConfig) GetSamenessGroup() string { - if x != nil { - return x.SamenessGroup - } - return "" -} - -type FailoverDestination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // This must be a Service. - Ref *pbresource.Reference `protobuf:"bytes,1,opt,name=ref,proto3" json:"ref,omitempty"` - // TODO: what should an empty port mean? - Port string `protobuf:"bytes,2,opt,name=port,proto3" json:"port,omitempty"` - Datacenter string `protobuf:"bytes,3,opt,name=datacenter,proto3" json:"datacenter,omitempty"` -} - -func (x *FailoverDestination) Reset() { - *x = FailoverDestination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FailoverDestination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FailoverDestination) ProtoMessage() {} - -func (x *FailoverDestination) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FailoverDestination.ProtoReflect.Descriptor instead. -func (*FailoverDestination) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_failover_policy_proto_rawDescGZIP(), []int{2} -} - -func (x *FailoverDestination) GetRef() *pbresource.Reference { - if x != nil { - return x.Ref - } - return nil -} - -func (x *FailoverDestination) GetPort() string { - if x != nil { - return x.Port - } - return "" -} - -func (x *FailoverDestination) GetDatacenter() string { - if x != nil { - return x.Datacenter - } - return "" -} - -var File_pbcatalog_v2beta1_failover_policy_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_failover_policy_proto_rawDesc = []byte{ - 0x0a, 0x27, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x70, 0x62, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xba, 0x02, 0x0a, 0x0e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, - 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x48, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, - 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x64, 0x0a, 0x0c, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, - 0x76, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x70, 0x6f, 0x72, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x1a, 0x70, 0x0a, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, - 0x03, 0x22, 0xf0, 0x01, 0x0a, 0x0e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, - 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x46, 0x61, - 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x42, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, - 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, - 0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x22, 0x81, 0x01, 0x0a, 0x13, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, - 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x03, - 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, - 0x03, 0x72, 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, - 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, - 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2a, 0x70, 0x0a, 0x0c, 0x46, 0x61, 0x69, 0x6c, - 0x6f, 0x76, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x41, 0x49, 0x4c, - 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x46, 0x41, 0x49, 0x4c, 0x4f, - 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x54, - 0x49, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x46, 0x41, 0x49, 0x4c, 0x4f, 0x56, 0x45, - 0x52, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x42, 0x59, 0x5f, - 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x02, 0x42, 0xa9, 0x02, 0x0a, 0x24, 0x63, - 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x13, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x20, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, - 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, - 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_failover_policy_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_failover_policy_proto_rawDescData = file_pbcatalog_v2beta1_failover_policy_proto_rawDesc -) - -func file_pbcatalog_v2beta1_failover_policy_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_failover_policy_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_failover_policy_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_failover_policy_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_failover_policy_proto_rawDescData -} - -var file_pbcatalog_v2beta1_failover_policy_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbcatalog_v2beta1_failover_policy_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pbcatalog_v2beta1_failover_policy_proto_goTypes = []interface{}{ - (FailoverMode)(0), // 0: hashicorp.consul.catalog.v2beta1.FailoverMode - (*FailoverPolicy)(nil), // 1: hashicorp.consul.catalog.v2beta1.FailoverPolicy - (*FailoverConfig)(nil), // 2: hashicorp.consul.catalog.v2beta1.FailoverConfig - (*FailoverDestination)(nil), // 3: hashicorp.consul.catalog.v2beta1.FailoverDestination - nil, // 4: hashicorp.consul.catalog.v2beta1.FailoverPolicy.PortConfigsEntry - (*pbresource.Reference)(nil), // 5: hashicorp.consul.resource.Reference -} -var file_pbcatalog_v2beta1_failover_policy_proto_depIdxs = []int32{ - 2, // 0: hashicorp.consul.catalog.v2beta1.FailoverPolicy.config:type_name -> hashicorp.consul.catalog.v2beta1.FailoverConfig - 4, // 1: hashicorp.consul.catalog.v2beta1.FailoverPolicy.port_configs:type_name -> hashicorp.consul.catalog.v2beta1.FailoverPolicy.PortConfigsEntry - 3, // 2: hashicorp.consul.catalog.v2beta1.FailoverConfig.destinations:type_name -> hashicorp.consul.catalog.v2beta1.FailoverDestination - 0, // 3: hashicorp.consul.catalog.v2beta1.FailoverConfig.mode:type_name -> hashicorp.consul.catalog.v2beta1.FailoverMode - 5, // 4: hashicorp.consul.catalog.v2beta1.FailoverDestination.ref:type_name -> hashicorp.consul.resource.Reference - 2, // 5: hashicorp.consul.catalog.v2beta1.FailoverPolicy.PortConfigsEntry.value:type_name -> hashicorp.consul.catalog.v2beta1.FailoverConfig - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_failover_policy_proto_init() } -func file_pbcatalog_v2beta1_failover_policy_proto_init() { - if File_pbcatalog_v2beta1_failover_policy_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailoverPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailoverConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_failover_policy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailoverDestination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_failover_policy_proto_rawDesc, - NumEnums: 1, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_failover_policy_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_failover_policy_proto_depIdxs, - EnumInfos: file_pbcatalog_v2beta1_failover_policy_proto_enumTypes, - MessageInfos: file_pbcatalog_v2beta1_failover_policy_proto_msgTypes, - }.Build() - File_pbcatalog_v2beta1_failover_policy_proto = out.File - file_pbcatalog_v2beta1_failover_policy_proto_rawDesc = nil - file_pbcatalog_v2beta1_failover_policy_proto_goTypes = nil - file_pbcatalog_v2beta1_failover_policy_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/failover_policy.proto b/proto-public/pbcatalog/v2beta1/failover_policy.proto deleted file mode 100644 index dec86807f7543..0000000000000 --- a/proto-public/pbcatalog/v2beta1/failover_policy.proto +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.catalog.v2beta1; - -import "pbresource/annotations.proto"; -import "pbresource/resource.proto"; - -// This is a Resource type. -message FailoverPolicy { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // Config defines failover for any named port not present in PortConfigs. - FailoverConfig config = 1; - - // PortConfigs defines failover for a specific port on this service and takes - // precedence over Config. - map port_configs = 2; -} - -message FailoverConfig { - // Destinations specifies a fixed list of failover destinations to try. We - // never try a destination multiple times, so those are subtracted from this - // list before proceeding. - repeated FailoverDestination destinations = 1; - - // Mode specifies the type of failover that will be performed. Valid values are - // "sequential", "" (equivalent to "sequential") and "order-by-locality". - FailoverMode mode = 2; - repeated string regions = 3; - - // SamenessGroup specifies the sameness group to failover to. - string sameness_group = 4; -} - -message FailoverDestination { - // This must be a Service. - hashicorp.consul.resource.Reference ref = 1; - // TODO: what should an empty port mean? - string port = 2; - string datacenter = 3; -} - -enum FailoverMode { - FAILOVER_MODE_UNSPECIFIED = 0; - FAILOVER_MODE_SEQUENTIAL = 1; - FAILOVER_MODE_ORDER_BY_LOCALITY = 2; -} diff --git a/proto-public/pbcatalog/v2beta1/failover_policy_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/failover_policy_deepcopy.gen.go deleted file mode 100644 index fabe3f9e30a68..0000000000000 --- a/proto-public/pbcatalog/v2beta1/failover_policy_deepcopy.gen.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using FailoverPolicy within kubernetes types, where deepcopy-gen is used. -func (in *FailoverPolicy) DeepCopyInto(out *FailoverPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverPolicy. Required by controller-gen. -func (in *FailoverPolicy) DeepCopy() *FailoverPolicy { - if in == nil { - return nil - } - out := new(FailoverPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new FailoverPolicy. Required by controller-gen. -func (in *FailoverPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using FailoverConfig within kubernetes types, where deepcopy-gen is used. -func (in *FailoverConfig) DeepCopyInto(out *FailoverConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverConfig. Required by controller-gen. -func (in *FailoverConfig) DeepCopy() *FailoverConfig { - if in == nil { - return nil - } - out := new(FailoverConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new FailoverConfig. Required by controller-gen. -func (in *FailoverConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using FailoverDestination within kubernetes types, where deepcopy-gen is used. -func (in *FailoverDestination) DeepCopyInto(out *FailoverDestination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverDestination. Required by controller-gen. -func (in *FailoverDestination) DeepCopy() *FailoverDestination { - if in == nil { - return nil - } - out := new(FailoverDestination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new FailoverDestination. Required by controller-gen. -func (in *FailoverDestination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/failover_policy_extras.go b/proto-public/pbcatalog/v2beta1/failover_policy_extras.go deleted file mode 100644 index 1187e93d7ae73..0000000000000 --- a/proto-public/pbcatalog/v2beta1/failover_policy_extras.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package catalogv2beta1 - -import "github.com/hashicorp/consul/proto-public/pbresource" - -// GetUnderlyingDestinations will collect FailoverDestinations from all -// internal fields and bundle them up in one slice. -// -// NOTE: no deduplication occurs. -func (x *FailoverPolicy) GetUnderlyingDestinations() []*FailoverDestination { - if x == nil { - return nil - } - - estimate := 0 - if x.Config != nil { - estimate += len(x.Config.Destinations) - } - for _, pc := range x.PortConfigs { - estimate += len(pc.Destinations) - } - - out := make([]*FailoverDestination, 0, estimate) - if x.Config != nil { - out = append(out, x.Config.Destinations...) - } - for _, pc := range x.PortConfigs { - out = append(out, pc.Destinations...) - } - return out -} - -// GetUnderlyingDestinationRefs is like GetUnderlyingDestinations except it -// returns a slice of References. -// -// NOTE: no deduplication occurs. -func (x *FailoverPolicy) GetUnderlyingDestinationRefs() []*pbresource.Reference { - if x == nil { - return nil - } - - dests := x.GetUnderlyingDestinations() - - out := make([]*pbresource.Reference, 0, len(dests)) - for _, dest := range dests { - if dest.Ref != nil { - out = append(out, dest.Ref) - } - } - - return out -} - -// IsEmpty returns true if a config has no definition. -func (x *FailoverConfig) IsEmpty() bool { - if x == nil { - return true - } - return len(x.Destinations) == 0 && - x.Mode == 0 && - len(x.Regions) == 0 && - x.SamenessGroup == "" -} diff --git a/proto-public/pbcatalog/v2beta1/failover_policy_extras_test.go b/proto-public/pbcatalog/v2beta1/failover_policy_extras_test.go deleted file mode 100644 index 073573e857ffc..0000000000000 --- a/proto-public/pbcatalog/v2beta1/failover_policy_extras_test.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package catalogv2beta1 - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func TestFailoverPolicy_IsEmpty(t *testing.T) { - t.Run("nil", func(t *testing.T) { - var fc *FailoverConfig - require.True(t, fc.IsEmpty()) - }) - t.Run("empty", func(t *testing.T) { - fc := &FailoverConfig{} - require.True(t, fc.IsEmpty()) - }) - t.Run("dest", func(t *testing.T) { - fc := &FailoverConfig{ - Destinations: []*FailoverDestination{ - newFailoverDestination("foo"), - }, - } - require.False(t, fc.IsEmpty()) - }) - t.Run("regions", func(t *testing.T) { - fc := &FailoverConfig{ - Regions: []string{"us-east"}, - } - require.False(t, fc.IsEmpty()) - }) - t.Run("regions", func(t *testing.T) { - fc := &FailoverConfig{ - SamenessGroup: "blah", - } - require.False(t, fc.IsEmpty()) - }) -} - -func TestFailoverPolicy_GetUnderlyingDestinations_AndRefs(t *testing.T) { - type testcase struct { - failover *FailoverPolicy - expectDests []*FailoverDestination - expectRefs []*pbresource.Reference - } - - run := func(t *testing.T, tc testcase) { - assertSliceEquals(t, tc.expectDests, tc.failover.GetUnderlyingDestinations()) - assertSliceEquals(t, tc.expectRefs, tc.failover.GetUnderlyingDestinationRefs()) - } - - cases := map[string]testcase{ - "nil": {}, - "kitchen sink dests": { - failover: &FailoverPolicy{ - Config: &FailoverConfig{ - Destinations: []*FailoverDestination{ - newFailoverDestination("foo"), - newFailoverDestination("bar"), - }, - }, - PortConfigs: map[string]*FailoverConfig{ - "admin": { - Destinations: []*FailoverDestination{ - newFailoverDestination("admin"), - }, - }, - "web": { - Destinations: []*FailoverDestination{ - newFailoverDestination("foo"), // duplicated - newFailoverDestination("www"), - }, - }, - }, - }, - expectDests: []*FailoverDestination{ - newFailoverDestination("foo"), - newFailoverDestination("bar"), - newFailoverDestination("admin"), - newFailoverDestination("foo"), // duplicated - newFailoverDestination("www"), - }, - expectRefs: []*pbresource.Reference{ - newFailoverRef("foo"), - newFailoverRef("bar"), - newFailoverRef("admin"), - newFailoverRef("foo"), // duplicated - newFailoverRef("www"), - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func assertSliceEquals[V proto.Message](t *testing.T, expect, got []V) { - t.Helper() - - require.Len(t, got, len(expect)) - - // O(N*M) scan - var expectedMissing []string - for _, expectVal := range expect { - found := false - for j, gotVal := range got { - if proto.Equal(expectVal, gotVal) { - found = true - got = append(got[:j], got[j+1:]...) // remove found item - break - } - } - - if !found { - expectedMissing = append(expectedMissing, protoToString(t, expectVal)) - } - } - - if len(expectedMissing) > 0 || len(got) > 0 { - var gotMissing []string - for _, gotVal := range got { - gotMissing = append(gotMissing, protoToString(t, gotVal)) - } - - t.Fatalf("assertion failed: unmatched values\n\texpected: %s\n\tactual: %s", - expectedMissing, - gotMissing, - ) - } -} - -func protoToString[V proto.Message](t *testing.T, pb V) string { - m := protojson.MarshalOptions{ - Indent: " ", - } - gotJSON, err := m.Marshal(pb) - require.NoError(t, err) - return string(gotJSON) -} - -func newFailoverRef(name string) *pbresource.Reference { - return &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "fake", - GroupVersion: "v1alpha1", - Kind: "fake", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "default", - Namespace: "default", - PeerName: "local", - }, - Name: name, - } -} - -func newFailoverDestination(name string) *FailoverDestination { - return &FailoverDestination{ - Ref: newFailoverRef(name), - } -} diff --git a/proto-public/pbcatalog/v2beta1/failover_policy_json.gen.go b/proto-public/pbcatalog/v2beta1/failover_policy_json.gen.go deleted file mode 100644 index 85998288a0314..0000000000000 --- a/proto-public/pbcatalog/v2beta1/failover_policy_json.gen.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for FailoverPolicy -func (this *FailoverPolicy) MarshalJSON() ([]byte, error) { - str, err := FailoverPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for FailoverPolicy -func (this *FailoverPolicy) UnmarshalJSON(b []byte) error { - return FailoverPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for FailoverConfig -func (this *FailoverConfig) MarshalJSON() ([]byte, error) { - str, err := FailoverPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for FailoverConfig -func (this *FailoverConfig) UnmarshalJSON(b []byte) error { - return FailoverPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for FailoverDestination -func (this *FailoverDestination) MarshalJSON() ([]byte, error) { - str, err := FailoverPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for FailoverDestination -func (this *FailoverDestination) UnmarshalJSON(b []byte) error { - return FailoverPolicyUnmarshaler.Unmarshal(b, this) -} - -var ( - FailoverPolicyMarshaler = &protojson.MarshalOptions{} - FailoverPolicyUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/health_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/health_deepcopy.gen.go deleted file mode 100644 index 677a1af1056d3..0000000000000 --- a/proto-public/pbcatalog/v2beta1/health_deepcopy.gen.go +++ /dev/null @@ -1,195 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using HealthStatus within kubernetes types, where deepcopy-gen is used. -func (in *HealthStatus) DeepCopyInto(out *HealthStatus) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthStatus. Required by controller-gen. -func (in *HealthStatus) DeepCopy() *HealthStatus { - if in == nil { - return nil - } - out := new(HealthStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HealthStatus. Required by controller-gen. -func (in *HealthStatus) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HealthChecks within kubernetes types, where deepcopy-gen is used. -func (in *HealthChecks) DeepCopyInto(out *HealthChecks) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthChecks. Required by controller-gen. -func (in *HealthChecks) DeepCopy() *HealthChecks { - if in == nil { - return nil - } - out := new(HealthChecks) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HealthChecks. Required by controller-gen. -func (in *HealthChecks) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HealthCheck within kubernetes types, where deepcopy-gen is used. -func (in *HealthCheck) DeepCopyInto(out *HealthCheck) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheck. Required by controller-gen. -func (in *HealthCheck) DeepCopy() *HealthCheck { - if in == nil { - return nil - } - out := new(HealthCheck) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheck. Required by controller-gen. -func (in *HealthCheck) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPCheck within kubernetes types, where deepcopy-gen is used. -func (in *HTTPCheck) DeepCopyInto(out *HTTPCheck) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPCheck. Required by controller-gen. -func (in *HTTPCheck) DeepCopy() *HTTPCheck { - if in == nil { - return nil - } - out := new(HTTPCheck) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPCheck. Required by controller-gen. -func (in *HTTPCheck) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TCPCheck within kubernetes types, where deepcopy-gen is used. -func (in *TCPCheck) DeepCopyInto(out *TCPCheck) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPCheck. Required by controller-gen. -func (in *TCPCheck) DeepCopy() *TCPCheck { - if in == nil { - return nil - } - out := new(TCPCheck) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TCPCheck. Required by controller-gen. -func (in *TCPCheck) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using UDPCheck within kubernetes types, where deepcopy-gen is used. -func (in *UDPCheck) DeepCopyInto(out *UDPCheck) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UDPCheck. Required by controller-gen. -func (in *UDPCheck) DeepCopy() *UDPCheck { - if in == nil { - return nil - } - out := new(UDPCheck) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new UDPCheck. Required by controller-gen. -func (in *UDPCheck) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GRPCCheck within kubernetes types, where deepcopy-gen is used. -func (in *GRPCCheck) DeepCopyInto(out *GRPCCheck) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCCheck. Required by controller-gen. -func (in *GRPCCheck) DeepCopy() *GRPCCheck { - if in == nil { - return nil - } - out := new(GRPCCheck) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GRPCCheck. Required by controller-gen. -func (in *GRPCCheck) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using OSServiceCheck within kubernetes types, where deepcopy-gen is used. -func (in *OSServiceCheck) DeepCopyInto(out *OSServiceCheck) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSServiceCheck. Required by controller-gen. -func (in *OSServiceCheck) DeepCopy() *OSServiceCheck { - if in == nil { - return nil - } - out := new(OSServiceCheck) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new OSServiceCheck. Required by controller-gen. -func (in *OSServiceCheck) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using CheckTLSConfig within kubernetes types, where deepcopy-gen is used. -func (in *CheckTLSConfig) DeepCopyInto(out *CheckTLSConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheckTLSConfig. Required by controller-gen. -func (in *CheckTLSConfig) DeepCopy() *CheckTLSConfig { - if in == nil { - return nil - } - out := new(CheckTLSConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new CheckTLSConfig. Required by controller-gen. -func (in *CheckTLSConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/health_json.gen.go b/proto-public/pbcatalog/v2beta1/health_json.gen.go deleted file mode 100644 index 7c0065d922b44..0000000000000 --- a/proto-public/pbcatalog/v2beta1/health_json.gen.go +++ /dev/null @@ -1,110 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for HealthStatus -func (this *HealthStatus) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HealthStatus -func (this *HealthStatus) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HealthChecks -func (this *HealthChecks) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HealthChecks -func (this *HealthChecks) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HealthCheck -func (this *HealthCheck) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HealthCheck -func (this *HealthCheck) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPCheck -func (this *HTTPCheck) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPCheck -func (this *HTTPCheck) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TCPCheck -func (this *TCPCheck) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TCPCheck -func (this *TCPCheck) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for UDPCheck -func (this *UDPCheck) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for UDPCheck -func (this *UDPCheck) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GRPCCheck -func (this *GRPCCheck) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GRPCCheck -func (this *GRPCCheck) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for OSServiceCheck -func (this *OSServiceCheck) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for OSServiceCheck -func (this *OSServiceCheck) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for CheckTLSConfig -func (this *CheckTLSConfig) MarshalJSON() ([]byte, error) { - str, err := HealthMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for CheckTLSConfig -func (this *CheckTLSConfig) UnmarshalJSON(b []byte) error { - return HealthUnmarshaler.Unmarshal(b, this) -} - -var ( - HealthMarshaler = &protojson.MarshalOptions{} - HealthUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/node.pb.go b/proto-public/pbcatalog/v2beta1/node.pb.go deleted file mode 100644 index fc6d57f7fc227..0000000000000 --- a/proto-public/pbcatalog/v2beta1/node.pb.go +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/node.proto - -package catalogv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Node struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Addresses []*NodeAddress `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` -} - -func (x *Node) Reset() { - *x = Node{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_node_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Node) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Node) ProtoMessage() {} - -func (x *Node) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_node_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Node.ProtoReflect.Descriptor instead. -func (*Node) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_node_proto_rawDescGZIP(), []int{0} -} - -func (x *Node) GetAddresses() []*NodeAddress { - if x != nil { - return x.Addresses - } - return nil -} - -type NodeAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // host can be an IP or DNS name.Í - Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` - // external indicates whether this address should be used for external communication - // (aka a WAN address). - External bool `protobuf:"varint,3,opt,name=external,proto3" json:"external,omitempty"` -} - -func (x *NodeAddress) Reset() { - *x = NodeAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_node_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NodeAddress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NodeAddress) ProtoMessage() {} - -func (x *NodeAddress) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_node_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NodeAddress.ProtoReflect.Descriptor instead. -func (*NodeAddress) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_node_proto_rawDescGZIP(), []int{1} -} - -func (x *NodeAddress) GetHost() string { - if x != nil { - return x.Host - } - return "" -} - -func (x *NodeAddress) GetExternal() bool { - if x != nil { - return x.External - } - return false -} - -var File_pbcatalog_v2beta1_node_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_node_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5b, - 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x4b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4e, 0x6f, 0x64, - 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x3d, 0x0a, 0x0b, 0x4e, - 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, - 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x42, 0x9f, 0x02, 0x0a, 0x24, 0x63, - 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, - 0x43, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_node_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_node_proto_rawDescData = file_pbcatalog_v2beta1_node_proto_rawDesc -) - -func file_pbcatalog_v2beta1_node_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_node_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_node_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_node_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_node_proto_rawDescData -} - -var file_pbcatalog_v2beta1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbcatalog_v2beta1_node_proto_goTypes = []interface{}{ - (*Node)(nil), // 0: hashicorp.consul.catalog.v2beta1.Node - (*NodeAddress)(nil), // 1: hashicorp.consul.catalog.v2beta1.NodeAddress -} -var file_pbcatalog_v2beta1_node_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.catalog.v2beta1.Node.addresses:type_name -> hashicorp.consul.catalog.v2beta1.NodeAddress - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_node_proto_init() } -func file_pbcatalog_v2beta1_node_proto_init() { - if File_pbcatalog_v2beta1_node_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_node_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Node); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_node_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NodeAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_node_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_node_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_node_proto_depIdxs, - MessageInfos: file_pbcatalog_v2beta1_node_proto_msgTypes, - }.Build() - File_pbcatalog_v2beta1_node_proto = out.File - file_pbcatalog_v2beta1_node_proto_rawDesc = nil - file_pbcatalog_v2beta1_node_proto_goTypes = nil - file_pbcatalog_v2beta1_node_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/node_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/node_deepcopy.gen.go deleted file mode 100644 index d864f7858fe62..0000000000000 --- a/proto-public/pbcatalog/v2beta1/node_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Node within kubernetes types, where deepcopy-gen is used. -func (in *Node) DeepCopyInto(out *Node) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Node. Required by controller-gen. -func (in *Node) DeepCopy() *Node { - if in == nil { - return nil - } - out := new(Node) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Node. Required by controller-gen. -func (in *Node) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using NodeAddress within kubernetes types, where deepcopy-gen is used. -func (in *NodeAddress) DeepCopyInto(out *NodeAddress) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAddress. Required by controller-gen. -func (in *NodeAddress) DeepCopy() *NodeAddress { - if in == nil { - return nil - } - out := new(NodeAddress) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new NodeAddress. Required by controller-gen. -func (in *NodeAddress) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/node_json.gen.go b/proto-public/pbcatalog/v2beta1/node_json.gen.go deleted file mode 100644 index f599ddb501645..0000000000000 --- a/proto-public/pbcatalog/v2beta1/node_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Node -func (this *Node) MarshalJSON() ([]byte, error) { - str, err := NodeMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Node -func (this *Node) UnmarshalJSON(b []byte) error { - return NodeUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for NodeAddress -func (this *NodeAddress) MarshalJSON() ([]byte, error) { - str, err := NodeMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for NodeAddress -func (this *NodeAddress) UnmarshalJSON(b []byte) error { - return NodeUnmarshaler.Unmarshal(b, this) -} - -var ( - NodeMarshaler = &protojson.MarshalOptions{} - NodeUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/protocol.pb.go b/proto-public/pbcatalog/v2beta1/protocol.pb.go deleted file mode 100644 index a1bdc899d92c9..0000000000000 --- a/proto-public/pbcatalog/v2beta1/protocol.pb.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/protocol.proto - -package catalogv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=PROTOCOL_UNSPECIFIED;PROTOCOL_TCP;PROTOCOL_HTTP;PROTOCOL_HTTP2;PROTOCOL_GRPC -// +kubebuilder:validation:Type=string -type Protocol int32 - -const ( - Protocol_PROTOCOL_UNSPECIFIED Protocol = 0 - Protocol_PROTOCOL_TCP Protocol = 1 - Protocol_PROTOCOL_HTTP Protocol = 2 - Protocol_PROTOCOL_HTTP2 Protocol = 3 - Protocol_PROTOCOL_GRPC Protocol = 4 - // Protocol Mesh indicates that this port can speak Consul's mTLS based mesh protocol. - Protocol_PROTOCOL_MESH Protocol = 5 -) - -// Enum value maps for Protocol. -var ( - Protocol_name = map[int32]string{ - 0: "PROTOCOL_UNSPECIFIED", - 1: "PROTOCOL_TCP", - 2: "PROTOCOL_HTTP", - 3: "PROTOCOL_HTTP2", - 4: "PROTOCOL_GRPC", - 5: "PROTOCOL_MESH", - } - Protocol_value = map[string]int32{ - "PROTOCOL_UNSPECIFIED": 0, - "PROTOCOL_TCP": 1, - "PROTOCOL_HTTP": 2, - "PROTOCOL_HTTP2": 3, - "PROTOCOL_GRPC": 4, - "PROTOCOL_MESH": 5, - } -) - -func (x Protocol) Enum() *Protocol { - p := new(Protocol) - *p = x - return p -} - -func (x Protocol) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Protocol) Descriptor() protoreflect.EnumDescriptor { - return file_pbcatalog_v2beta1_protocol_proto_enumTypes[0].Descriptor() -} - -func (Protocol) Type() protoreflect.EnumType { - return &file_pbcatalog_v2beta1_protocol_proto_enumTypes[0] -} - -func (x Protocol) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Protocol.Descriptor instead. -func (Protocol) EnumDescriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_protocol_proto_rawDescGZIP(), []int{0} -} - -var File_pbcatalog_v2beta1_protocol_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_protocol_proto_rawDesc = []byte{ - 0x0a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2a, 0x83, 0x01, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x12, 0x18, 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, - 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x43, 0x50, 0x10, 0x01, 0x12, 0x11, 0x0a, - 0x0d, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x02, - 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, - 0x50, 0x32, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, - 0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, 0x4f, - 0x43, 0x4f, 0x4c, 0x5f, 0x4d, 0x45, 0x53, 0x48, 0x10, 0x05, 0x42, 0xa3, 0x02, 0x0a, 0x24, 0x63, - 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, - 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, - 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, - 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, - 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_protocol_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_protocol_proto_rawDescData = file_pbcatalog_v2beta1_protocol_proto_rawDesc -) - -func file_pbcatalog_v2beta1_protocol_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_protocol_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_protocol_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_protocol_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_protocol_proto_rawDescData -} - -var file_pbcatalog_v2beta1_protocol_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbcatalog_v2beta1_protocol_proto_goTypes = []interface{}{ - (Protocol)(0), // 0: hashicorp.consul.catalog.v2beta1.Protocol -} -var file_pbcatalog_v2beta1_protocol_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_protocol_proto_init() } -func file_pbcatalog_v2beta1_protocol_proto_init() { - if File_pbcatalog_v2beta1_protocol_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_protocol_proto_rawDesc, - NumEnums: 1, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_protocol_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_protocol_proto_depIdxs, - EnumInfos: file_pbcatalog_v2beta1_protocol_proto_enumTypes, - }.Build() - File_pbcatalog_v2beta1_protocol_proto = out.File - file_pbcatalog_v2beta1_protocol_proto_rawDesc = nil - file_pbcatalog_v2beta1_protocol_proto_goTypes = nil - file_pbcatalog_v2beta1_protocol_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/protocol.proto b/proto-public/pbcatalog/v2beta1/protocol.proto deleted file mode 100644 index faebe9f0b0406..0000000000000 --- a/proto-public/pbcatalog/v2beta1/protocol.proto +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.catalog.v2beta1; - -// +kubebuilder:validation:Enum=PROTOCOL_UNSPECIFIED;PROTOCOL_TCP;PROTOCOL_HTTP;PROTOCOL_HTTP2;PROTOCOL_GRPC -// +kubebuilder:validation:Type=string -enum Protocol { - PROTOCOL_UNSPECIFIED = 0; - PROTOCOL_TCP = 1; - PROTOCOL_HTTP = 2; - PROTOCOL_HTTP2 = 3; - PROTOCOL_GRPC = 4; - - // Protocol Mesh indicates that this port can speak Consul's mTLS based mesh protocol. - PROTOCOL_MESH = 5; -} diff --git a/proto-public/pbcatalog/v2beta1/resource_types.gen.go b/proto-public/pbcatalog/v2beta1/resource_types.gen.go deleted file mode 100644 index c71a38ac70cda..0000000000000 --- a/proto-public/pbcatalog/v2beta1/resource_types.gen.go +++ /dev/null @@ -1,78 +0,0 @@ -// Code generated by protoc-gen-resource-types. DO NOT EDIT. - -package catalogv2beta1 - -import ( - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - GroupName = "catalog" - Version = "v2beta1" - - DNSPolicyKind = "DNSPolicy" - FailoverPolicyKind = "FailoverPolicy" - HealthChecksKind = "HealthChecks" - HealthStatusKind = "HealthStatus" - NodeKind = "Node" - ServiceKind = "Service" - ServiceEndpointsKind = "ServiceEndpoints" - VirtualIPsKind = "VirtualIPs" - WorkloadKind = "Workload" -) - -var ( - DNSPolicyType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: DNSPolicyKind, - } - - FailoverPolicyType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: FailoverPolicyKind, - } - - HealthChecksType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: HealthChecksKind, - } - - HealthStatusType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: HealthStatusKind, - } - - NodeType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: NodeKind, - } - - ServiceType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ServiceKind, - } - - ServiceEndpointsType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ServiceEndpointsKind, - } - - VirtualIPsType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: VirtualIPsKind, - } - - WorkloadType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: WorkloadKind, - } -) diff --git a/proto-public/pbcatalog/v2beta1/selector.pb.go b/proto-public/pbcatalog/v2beta1/selector.pb.go deleted file mode 100644 index be51858d72c6b..0000000000000 --- a/proto-public/pbcatalog/v2beta1/selector.pb.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/selector.proto - -package catalogv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// WorkloadSelector represents criteria for selecting a subset of workloads. -type WorkloadSelector struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Prefixes []string `protobuf:"bytes,1,rep,name=prefixes,proto3" json:"prefixes,omitempty"` - Names []string `protobuf:"bytes,2,rep,name=names,proto3" json:"names,omitempty"` - Filter string `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"` -} - -func (x *WorkloadSelector) Reset() { - *x = WorkloadSelector{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_selector_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *WorkloadSelector) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*WorkloadSelector) ProtoMessage() {} - -func (x *WorkloadSelector) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_selector_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use WorkloadSelector.ProtoReflect.Descriptor instead. -func (*WorkloadSelector) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_selector_proto_rawDescGZIP(), []int{0} -} - -func (x *WorkloadSelector) GetPrefixes() []string { - if x != nil { - return x.Prefixes - } - return nil -} - -func (x *WorkloadSelector) GetNames() []string { - if x != nil { - return x.Names - } - return nil -} - -func (x *WorkloadSelector) GetFilter() string { - if x != nil { - return x.Filter - } - return "" -} - -var File_pbcatalog_v2beta1_selector_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_selector_proto_rawDesc = []byte{ - 0x0a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x22, 0x5c, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x66, - 0x69, 0x78, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x65, 0x66, - 0x69, 0x78, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x42, 0xa3, 0x02, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0d, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x20, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, - 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_selector_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_selector_proto_rawDescData = file_pbcatalog_v2beta1_selector_proto_rawDesc -) - -func file_pbcatalog_v2beta1_selector_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_selector_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_selector_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_selector_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_selector_proto_rawDescData -} - -var file_pbcatalog_v2beta1_selector_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbcatalog_v2beta1_selector_proto_goTypes = []interface{}{ - (*WorkloadSelector)(nil), // 0: hashicorp.consul.catalog.v2beta1.WorkloadSelector -} -var file_pbcatalog_v2beta1_selector_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_selector_proto_init() } -func file_pbcatalog_v2beta1_selector_proto_init() { - if File_pbcatalog_v2beta1_selector_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_selector_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WorkloadSelector); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_selector_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_selector_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_selector_proto_depIdxs, - MessageInfos: file_pbcatalog_v2beta1_selector_proto_msgTypes, - }.Build() - File_pbcatalog_v2beta1_selector_proto = out.File - file_pbcatalog_v2beta1_selector_proto_rawDesc = nil - file_pbcatalog_v2beta1_selector_proto_goTypes = nil - file_pbcatalog_v2beta1_selector_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/selector_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/selector_deepcopy.gen.go deleted file mode 100644 index 7e59d55880819..0000000000000 --- a/proto-public/pbcatalog/v2beta1/selector_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using WorkloadSelector within kubernetes types, where deepcopy-gen is used. -func (in *WorkloadSelector) DeepCopyInto(out *WorkloadSelector) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadSelector. Required by controller-gen. -func (in *WorkloadSelector) DeepCopy() *WorkloadSelector { - if in == nil { - return nil - } - out := new(WorkloadSelector) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadSelector. Required by controller-gen. -func (in *WorkloadSelector) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/selector_json.gen.go b/proto-public/pbcatalog/v2beta1/selector_json.gen.go deleted file mode 100644 index 047e8d4c96dc3..0000000000000 --- a/proto-public/pbcatalog/v2beta1/selector_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for WorkloadSelector -func (this *WorkloadSelector) MarshalJSON() ([]byte, error) { - str, err := SelectorMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WorkloadSelector -func (this *WorkloadSelector) UnmarshalJSON(b []byte) error { - return SelectorUnmarshaler.Unmarshal(b, this) -} - -var ( - SelectorMarshaler = &protojson.MarshalOptions{} - SelectorUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/service.pb.go b/proto-public/pbcatalog/v2beta1/service.pb.go deleted file mode 100644 index 99d51a9783b55..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service.pb.go +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/service.proto - -package catalogv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Service struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // workloads is a selector for the workloads this service should represent. - Workloads *WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` - // ports is the list of mappings of workload ports that this service - // represents. - Ports []*ServicePort `protobuf:"bytes,2,rep,name=ports,proto3" json:"ports,omitempty"` - // virtual_ips is a list of virtual IPs for this service. This is useful when you need to set - // an IP from an external system (like Kubernetes). This can be an IPv4 or IPv6 string. - VirtualIps []string `protobuf:"bytes,3,rep,name=virtual_ips,json=virtualIps,proto3" json:"virtual_ips,omitempty"` -} - -func (x *Service) Reset() { - *x = Service{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_service_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Service) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Service) ProtoMessage() {} - -func (x *Service) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_service_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Service.ProtoReflect.Descriptor instead. -func (*Service) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_service_proto_rawDescGZIP(), []int{0} -} - -func (x *Service) GetWorkloads() *WorkloadSelector { - if x != nil { - return x.Workloads - } - return nil -} - -func (x *Service) GetPorts() []*ServicePort { - if x != nil { - return x.Ports - } - return nil -} - -func (x *Service) GetVirtualIps() []string { - if x != nil { - return x.VirtualIps - } - return nil -} - -type ServicePort struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // virtual_port is the port that could only be used when transparent - // proxy is used alongside a virtual IP or a virtual DNS address. - // This value is ignored in other cases. Whether or not using transparent - // proxy, this value is optional. - VirtualPort uint32 `protobuf:"varint,1,opt,name=virtual_port,json=virtualPort,proto3" json:"virtual_port,omitempty"` - // target_port is the name of the workload port. - TargetPort string `protobuf:"bytes,2,opt,name=target_port,json=targetPort,proto3" json:"target_port,omitempty"` - // protocol is the port's protocol. This should be set to "mesh" - // if the target port is the proxy's inbound port. - Protocol Protocol `protobuf:"varint,3,opt,name=protocol,proto3,enum=hashicorp.consul.catalog.v2beta1.Protocol" json:"protocol,omitempty"` -} - -func (x *ServicePort) Reset() { - *x = ServicePort{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_service_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServicePort) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServicePort) ProtoMessage() {} - -func (x *ServicePort) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_service_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServicePort.ProtoReflect.Descriptor instead. -func (*ServicePort) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_service_proto_rawDescGZIP(), []int{1} -} - -func (x *ServicePort) GetVirtualPort() uint32 { - if x != nil { - return x.VirtualPort - } - return 0 -} - -func (x *ServicePort) GetTargetPort() string { - if x != nil { - return x.TargetPort - } - return "" -} - -func (x *ServicePort) GetProtocol() Protocol { - if x != nil { - return x.Protocol - } - return Protocol_PROTOCOL_UNSPECIFIED -} - -var File_pbcatalog_v2beta1_service_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_service_proto_rawDesc = []byte{ - 0x0a, 0x1f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x1a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc9, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x50, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, - 0x61, 0x64, 0x73, 0x12, 0x43, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, - 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x69, 0x72, 0x74, - 0x75, 0x61, 0x6c, 0x5f, 0x69, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x76, - 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x49, 0x70, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, - 0x03, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, - 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x72, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, - 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, - 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x46, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x42, 0xa2, 0x02, - 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, - 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_service_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_service_proto_rawDescData = file_pbcatalog_v2beta1_service_proto_rawDesc -) - -func file_pbcatalog_v2beta1_service_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_service_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_service_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_service_proto_rawDescData -} - -var file_pbcatalog_v2beta1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbcatalog_v2beta1_service_proto_goTypes = []interface{}{ - (*Service)(nil), // 0: hashicorp.consul.catalog.v2beta1.Service - (*ServicePort)(nil), // 1: hashicorp.consul.catalog.v2beta1.ServicePort - (*WorkloadSelector)(nil), // 2: hashicorp.consul.catalog.v2beta1.WorkloadSelector - (Protocol)(0), // 3: hashicorp.consul.catalog.v2beta1.Protocol -} -var file_pbcatalog_v2beta1_service_proto_depIdxs = []int32{ - 2, // 0: hashicorp.consul.catalog.v2beta1.Service.workloads:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadSelector - 1, // 1: hashicorp.consul.catalog.v2beta1.Service.ports:type_name -> hashicorp.consul.catalog.v2beta1.ServicePort - 3, // 2: hashicorp.consul.catalog.v2beta1.ServicePort.protocol:type_name -> hashicorp.consul.catalog.v2beta1.Protocol - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_service_proto_init() } -func file_pbcatalog_v2beta1_service_proto_init() { - if File_pbcatalog_v2beta1_service_proto != nil { - return - } - file_pbcatalog_v2beta1_protocol_proto_init() - file_pbcatalog_v2beta1_selector_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Service); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServicePort); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_service_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_service_proto_depIdxs, - MessageInfos: file_pbcatalog_v2beta1_service_proto_msgTypes, - }.Build() - File_pbcatalog_v2beta1_service_proto = out.File - file_pbcatalog_v2beta1_service_proto_rawDesc = nil - file_pbcatalog_v2beta1_service_proto_goTypes = nil - file_pbcatalog_v2beta1_service_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/service_addon.go b/proto-public/pbcatalog/v2beta1/service_addon.go deleted file mode 100644 index 9f19296cc5f66..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_addon.go +++ /dev/null @@ -1,19 +0,0 @@ -package catalogv2beta1 - -func (s *Service) IsMeshEnabled() bool { - for _, port := range s.GetPorts() { - if port.Protocol == Protocol_PROTOCOL_MESH { - return true - } - } - return false -} - -func (s *Service) FindServicePort(name string) *ServicePort { - for _, port := range s.GetPorts() { - if port.TargetPort == name { - return port - } - } - return nil -} diff --git a/proto-public/pbcatalog/v2beta1/service_addon_test.go b/proto-public/pbcatalog/v2beta1/service_addon_test.go deleted file mode 100644 index 19c07a5901aac..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_addon_test.go +++ /dev/null @@ -1,120 +0,0 @@ -package catalogv2beta1 - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestServiceIsMeshEnabled(t *testing.T) { - cases := map[string]struct { - service *Service - exp bool - }{ - "nil": {service: nil, exp: false}, - "no ports": { - service: &Service{}, - exp: false, - }, - "no mesh ports": { - service: &Service{ - Ports: []*ServicePort{ - { - TargetPort: "foo", - Protocol: Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "bar", - Protocol: Protocol_PROTOCOL_TCP, - }, - }, - }, - exp: false, - }, - "with mesh ports": { - service: &Service{ - Ports: []*ServicePort{ - { - TargetPort: "foo", - Protocol: Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "bar", - Protocol: Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "baz", - Protocol: Protocol_PROTOCOL_MESH, - }, - }, - }, - exp: true, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - require.Equal(t, c.exp, c.service.IsMeshEnabled()) - }) - } -} - -func TestFindServicePort(t *testing.T) { - cases := map[string]struct { - service *Service - port string - exp *ServicePort - }{ - "nil": {service: nil, port: "foo", exp: nil}, - "no ports": { - service: &Service{}, - port: "foo", - exp: nil, - }, - "non-existing port": { - service: &Service{ - Ports: []*ServicePort{ - { - TargetPort: "foo", - Protocol: Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "bar", - Protocol: Protocol_PROTOCOL_TCP, - }, - }, - }, - port: "not-found", - exp: nil, - }, - "existing port": { - service: &Service{ - Ports: []*ServicePort{ - { - TargetPort: "foo", - Protocol: Protocol_PROTOCOL_HTTP, - }, - { - TargetPort: "bar", - Protocol: Protocol_PROTOCOL_TCP, - }, - { - TargetPort: "baz", - Protocol: Protocol_PROTOCOL_MESH, - }, - }, - }, - port: "bar", - exp: &ServicePort{ - TargetPort: "bar", - Protocol: Protocol_PROTOCOL_TCP, - }, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - require.Equal(t, c.exp, c.service.FindServicePort(c.port)) - }) - } -} diff --git a/proto-public/pbcatalog/v2beta1/service_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/service_deepcopy.gen.go deleted file mode 100644 index fa578cc344649..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Service within kubernetes types, where deepcopy-gen is used. -func (in *Service) DeepCopyInto(out *Service) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Service. Required by controller-gen. -func (in *Service) DeepCopy() *Service { - if in == nil { - return nil - } - out := new(Service) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Service. Required by controller-gen. -func (in *Service) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ServicePort within kubernetes types, where deepcopy-gen is used. -func (in *ServicePort) DeepCopyInto(out *ServicePort) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServicePort. Required by controller-gen. -func (in *ServicePort) DeepCopy() *ServicePort { - if in == nil { - return nil - } - out := new(ServicePort) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ServicePort. Required by controller-gen. -func (in *ServicePort) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/service_endpoints.pb.go b/proto-public/pbcatalog/v2beta1/service_endpoints.pb.go deleted file mode 100644 index fe98e95b2f27f..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_endpoints.pb.go +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/service_endpoints.proto - -package catalogv2beta1 - -import ( - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ServiceEndpoints struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Endpoints []*Endpoint `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"` -} - -func (x *ServiceEndpoints) Reset() { - *x = ServiceEndpoints{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_service_endpoints_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServiceEndpoints) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServiceEndpoints) ProtoMessage() {} - -func (x *ServiceEndpoints) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_service_endpoints_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServiceEndpoints.ProtoReflect.Descriptor instead. -func (*ServiceEndpoints) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_service_endpoints_proto_rawDescGZIP(), []int{0} -} - -func (x *ServiceEndpoints) GetEndpoints() []*Endpoint { - if x != nil { - return x.Endpoints - } - return nil -} - -type Endpoint struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // target_ref is the reference to the resource - // for this endpoint endpoint. This currently must be a workload. - TargetRef *pbresource.ID `protobuf:"bytes,1,opt,name=target_ref,json=targetRef,proto3" json:"target_ref,omitempty"` - // addresses is the list of addresses for this endpoint. - // This has the same structure as the workload addresses. - Addresses []*WorkloadAddress `protobuf:"bytes,2,rep,name=addresses,proto3" json:"addresses,omitempty"` - // ports is the map of ports for this endpoint. - // This has the same structure as the workload ports but - // will be filtered to just the ports selected by the service. - Ports map[string]*WorkloadPort `protobuf:"bytes,3,rep,name=ports,proto3" json:"ports,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // health_status is the aggregated health status of this endpoint. - HealthStatus Health `protobuf:"varint,4,opt,name=health_status,json=healthStatus,proto3,enum=hashicorp.consul.catalog.v2beta1.Health" json:"health_status,omitempty"` - // identity is the name of the workload identity for this endpoint. - Identity string `protobuf:"bytes,5,opt,name=identity,proto3" json:"identity,omitempty"` -} - -func (x *Endpoint) Reset() { - *x = Endpoint{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_service_endpoints_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Endpoint) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Endpoint) ProtoMessage() {} - -func (x *Endpoint) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_service_endpoints_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Endpoint.ProtoReflect.Descriptor instead. -func (*Endpoint) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_service_endpoints_proto_rawDescGZIP(), []int{1} -} - -func (x *Endpoint) GetTargetRef() *pbresource.ID { - if x != nil { - return x.TargetRef - } - return nil -} - -func (x *Endpoint) GetAddresses() []*WorkloadAddress { - if x != nil { - return x.Addresses - } - return nil -} - -func (x *Endpoint) GetPorts() map[string]*WorkloadPort { - if x != nil { - return x.Ports - } - return nil -} - -func (x *Endpoint) GetHealthStatus() Health { - if x != nil { - return x.HealthStatus - } - return Health_HEALTH_ANY -} - -func (x *Endpoint) GetIdentity() string { - if x != nil { - return x.Identity - } - return "" -} - -var File_pbcatalog_v2beta1_service_endpoints_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_service_endpoints_proto_rawDesc = []byte{ - 0x0a, 0x29, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, - 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1e, 0x70, - 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x70, - 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x70, - 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x64, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x48, 0x0a, 0x09, - 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, 0x65, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xbb, - 0x03, 0x0a, 0x08, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x49, 0x44, 0x52, 0x09, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x4f, 0x0a, 0x09, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, - 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x05, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x4d, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x1a, 0x68, 0x0a, 0x0a, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x72, - 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0xab, 0x02, 0x0a, - 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x15, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, - 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, - 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, - 0x67, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_service_endpoints_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_service_endpoints_proto_rawDescData = file_pbcatalog_v2beta1_service_endpoints_proto_rawDesc -) - -func file_pbcatalog_v2beta1_service_endpoints_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_service_endpoints_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_service_endpoints_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_service_endpoints_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_service_endpoints_proto_rawDescData -} - -var file_pbcatalog_v2beta1_service_endpoints_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_pbcatalog_v2beta1_service_endpoints_proto_goTypes = []interface{}{ - (*ServiceEndpoints)(nil), // 0: hashicorp.consul.catalog.v2beta1.ServiceEndpoints - (*Endpoint)(nil), // 1: hashicorp.consul.catalog.v2beta1.Endpoint - nil, // 2: hashicorp.consul.catalog.v2beta1.Endpoint.PortsEntry - (*pbresource.ID)(nil), // 3: hashicorp.consul.resource.ID - (*WorkloadAddress)(nil), // 4: hashicorp.consul.catalog.v2beta1.WorkloadAddress - (Health)(0), // 5: hashicorp.consul.catalog.v2beta1.Health - (*WorkloadPort)(nil), // 6: hashicorp.consul.catalog.v2beta1.WorkloadPort -} -var file_pbcatalog_v2beta1_service_endpoints_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.catalog.v2beta1.ServiceEndpoints.endpoints:type_name -> hashicorp.consul.catalog.v2beta1.Endpoint - 3, // 1: hashicorp.consul.catalog.v2beta1.Endpoint.target_ref:type_name -> hashicorp.consul.resource.ID - 4, // 2: hashicorp.consul.catalog.v2beta1.Endpoint.addresses:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadAddress - 2, // 3: hashicorp.consul.catalog.v2beta1.Endpoint.ports:type_name -> hashicorp.consul.catalog.v2beta1.Endpoint.PortsEntry - 5, // 4: hashicorp.consul.catalog.v2beta1.Endpoint.health_status:type_name -> hashicorp.consul.catalog.v2beta1.Health - 6, // 5: hashicorp.consul.catalog.v2beta1.Endpoint.PortsEntry.value:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadPort - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_service_endpoints_proto_init() } -func file_pbcatalog_v2beta1_service_endpoints_proto_init() { - if File_pbcatalog_v2beta1_service_endpoints_proto != nil { - return - } - file_pbcatalog_v2beta1_health_proto_init() - file_pbcatalog_v2beta1_workload_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_service_endpoints_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServiceEndpoints); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_service_endpoints_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Endpoint); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_service_endpoints_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_service_endpoints_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_service_endpoints_proto_depIdxs, - MessageInfos: file_pbcatalog_v2beta1_service_endpoints_proto_msgTypes, - }.Build() - File_pbcatalog_v2beta1_service_endpoints_proto = out.File - file_pbcatalog_v2beta1_service_endpoints_proto_rawDesc = nil - file_pbcatalog_v2beta1_service_endpoints_proto_goTypes = nil - file_pbcatalog_v2beta1_service_endpoints_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/service_endpoints_addon.go b/proto-public/pbcatalog/v2beta1/service_endpoints_addon.go deleted file mode 100644 index bd55db6c8236c..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_endpoints_addon.go +++ /dev/null @@ -1,26 +0,0 @@ -package catalogv2beta1 - -import ( - "golang.org/x/exp/maps" - "golang.org/x/exp/slices" -) - -// GetIdentities returns a list of unique identities that this service endpoints points to. -func (s *ServiceEndpoints) GetIdentities() []string { - uniqueIdentities := make(map[string]struct{}) - - for _, ep := range s.GetEndpoints() { - if ep.GetIdentity() != "" { - uniqueIdentities[ep.GetIdentity()] = struct{}{} - } - } - - if len(uniqueIdentities) == 0 { - return nil - } - - identities := maps.Keys(uniqueIdentities) - slices.Sort(identities) - - return identities -} diff --git a/proto-public/pbcatalog/v2beta1/service_endpoints_addon_test.go b/proto-public/pbcatalog/v2beta1/service_endpoints_addon_test.go deleted file mode 100644 index 5d3c54786ea90..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_endpoints_addon_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package catalogv2beta1 - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestServiceEndpoints_GetIdentities(t *testing.T) { - cases := map[string]struct { - endpoints []*Endpoint - expIdentities []string - }{ - "no endpoints": { - endpoints: nil, - expIdentities: nil, - }, - "no identities": { - endpoints: []*Endpoint{ - {}, - {}, - }, - expIdentities: nil, - }, - "single identity": { - endpoints: []*Endpoint{ - {Identity: "foo"}, - {Identity: "foo"}, - {Identity: "foo"}, - }, - expIdentities: []string{"foo"}, - }, - "multiple identities": { - endpoints: []*Endpoint{ - {Identity: "foo"}, - {Identity: "foo"}, - {Identity: "bar"}, - }, - expIdentities: []string{"bar", "foo"}, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - se := &ServiceEndpoints{Endpoints: c.endpoints} - require.Equal(t, c.expIdentities, se.GetIdentities()) - }) - } -} diff --git a/proto-public/pbcatalog/v2beta1/service_endpoints_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/service_endpoints_deepcopy.gen.go deleted file mode 100644 index f3634c091be75..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_endpoints_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ServiceEndpoints within kubernetes types, where deepcopy-gen is used. -func (in *ServiceEndpoints) DeepCopyInto(out *ServiceEndpoints) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceEndpoints. Required by controller-gen. -func (in *ServiceEndpoints) DeepCopy() *ServiceEndpoints { - if in == nil { - return nil - } - out := new(ServiceEndpoints) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ServiceEndpoints. Required by controller-gen. -func (in *ServiceEndpoints) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Endpoint within kubernetes types, where deepcopy-gen is used. -func (in *Endpoint) DeepCopyInto(out *Endpoint) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. Required by controller-gen. -func (in *Endpoint) DeepCopy() *Endpoint { - if in == nil { - return nil - } - out := new(Endpoint) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. Required by controller-gen. -func (in *Endpoint) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/service_endpoints_json.gen.go b/proto-public/pbcatalog/v2beta1/service_endpoints_json.gen.go deleted file mode 100644 index 2eef380ae6540..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_endpoints_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ServiceEndpoints -func (this *ServiceEndpoints) MarshalJSON() ([]byte, error) { - str, err := ServiceEndpointsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ServiceEndpoints -func (this *ServiceEndpoints) UnmarshalJSON(b []byte) error { - return ServiceEndpointsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Endpoint -func (this *Endpoint) MarshalJSON() ([]byte, error) { - str, err := ServiceEndpointsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Endpoint -func (this *Endpoint) UnmarshalJSON(b []byte) error { - return ServiceEndpointsUnmarshaler.Unmarshal(b, this) -} - -var ( - ServiceEndpointsMarshaler = &protojson.MarshalOptions{} - ServiceEndpointsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/service_json.gen.go b/proto-public/pbcatalog/v2beta1/service_json.gen.go deleted file mode 100644 index 6b9850f3a1f3f..0000000000000 --- a/proto-public/pbcatalog/v2beta1/service_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Service -func (this *Service) MarshalJSON() ([]byte, error) { - str, err := ServiceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Service -func (this *Service) UnmarshalJSON(b []byte) error { - return ServiceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ServicePort -func (this *ServicePort) MarshalJSON() ([]byte, error) { - str, err := ServiceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ServicePort -func (this *ServicePort) UnmarshalJSON(b []byte) error { - return ServiceUnmarshaler.Unmarshal(b, this) -} - -var ( - ServiceMarshaler = &protojson.MarshalOptions{} - ServiceUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/vip.pb.go b/proto-public/pbcatalog/v2beta1/vip.pb.go deleted file mode 100644 index f0774f08b3338..0000000000000 --- a/proto-public/pbcatalog/v2beta1/vip.pb.go +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/vip.proto - -package catalogv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type VirtualIPs struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ips []*IP `protobuf:"bytes,1,rep,name=ips,proto3" json:"ips,omitempty"` -} - -func (x *VirtualIPs) Reset() { - *x = VirtualIPs{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_vip_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *VirtualIPs) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*VirtualIPs) ProtoMessage() {} - -func (x *VirtualIPs) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_vip_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use VirtualIPs.ProtoReflect.Descriptor instead. -func (*VirtualIPs) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_vip_proto_rawDescGZIP(), []int{0} -} - -func (x *VirtualIPs) GetIps() []*IP { - if x != nil { - return x.Ips - } - return nil -} - -type IP struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // address is the string IPv4 address. - // This could also store IPv6 in the future. - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - // generated indicates whether Consul generated or it is user-provided - // (e.g. a ClusterIP of the Kubernetes service). - Generated bool `protobuf:"varint,2,opt,name=generated,proto3" json:"generated,omitempty"` -} - -func (x *IP) Reset() { - *x = IP{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_vip_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IP) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IP) ProtoMessage() {} - -func (x *IP) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_vip_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IP.ProtoReflect.Descriptor instead. -func (*IP) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_vip_proto_rawDescGZIP(), []int{1} -} - -func (x *IP) GetAddress() string { - if x != nil { - return x.Address - } - return "" -} - -func (x *IP) GetGenerated() bool { - if x != nil { - return x.Generated - } - return false -} - -var File_pbcatalog_v2beta1_vip_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_vip_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x76, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, - 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4c, 0x0a, - 0x0a, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x49, 0x50, 0x73, 0x12, 0x36, 0x0a, 0x03, 0x69, - 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x50, 0x52, 0x03, - 0x69, 0x70, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x3c, 0x0a, 0x02, 0x49, - 0x50, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, - 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x42, 0x9e, 0x02, 0x0a, 0x24, 0x63, 0x6f, - 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x42, 0x08, 0x56, 0x69, 0x70, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x43, 0xaa, - 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, 0x56, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, - 0x67, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_vip_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_vip_proto_rawDescData = file_pbcatalog_v2beta1_vip_proto_rawDesc -) - -func file_pbcatalog_v2beta1_vip_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_vip_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_vip_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_vip_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_vip_proto_rawDescData -} - -var file_pbcatalog_v2beta1_vip_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbcatalog_v2beta1_vip_proto_goTypes = []interface{}{ - (*VirtualIPs)(nil), // 0: hashicorp.consul.catalog.v2beta1.VirtualIPs - (*IP)(nil), // 1: hashicorp.consul.catalog.v2beta1.IP -} -var file_pbcatalog_v2beta1_vip_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.catalog.v2beta1.VirtualIPs.ips:type_name -> hashicorp.consul.catalog.v2beta1.IP - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_vip_proto_init() } -func file_pbcatalog_v2beta1_vip_proto_init() { - if File_pbcatalog_v2beta1_vip_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_vip_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VirtualIPs); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_vip_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IP); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_vip_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_vip_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_vip_proto_depIdxs, - MessageInfos: file_pbcatalog_v2beta1_vip_proto_msgTypes, - }.Build() - File_pbcatalog_v2beta1_vip_proto = out.File - file_pbcatalog_v2beta1_vip_proto_rawDesc = nil - file_pbcatalog_v2beta1_vip_proto_goTypes = nil - file_pbcatalog_v2beta1_vip_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/vip_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/vip_deepcopy.gen.go deleted file mode 100644 index 8308240c52b0f..0000000000000 --- a/proto-public/pbcatalog/v2beta1/vip_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using VirtualIPs within kubernetes types, where deepcopy-gen is used. -func (in *VirtualIPs) DeepCopyInto(out *VirtualIPs) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualIPs. Required by controller-gen. -func (in *VirtualIPs) DeepCopy() *VirtualIPs { - if in == nil { - return nil - } - out := new(VirtualIPs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new VirtualIPs. Required by controller-gen. -func (in *VirtualIPs) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using IP within kubernetes types, where deepcopy-gen is used. -func (in *IP) DeepCopyInto(out *IP) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IP. Required by controller-gen. -func (in *IP) DeepCopy() *IP { - if in == nil { - return nil - } - out := new(IP) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new IP. Required by controller-gen. -func (in *IP) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/vip_json.gen.go b/proto-public/pbcatalog/v2beta1/vip_json.gen.go deleted file mode 100644 index b464c310739b7..0000000000000 --- a/proto-public/pbcatalog/v2beta1/vip_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for VirtualIPs -func (this *VirtualIPs) MarshalJSON() ([]byte, error) { - str, err := VipMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for VirtualIPs -func (this *VirtualIPs) UnmarshalJSON(b []byte) error { - return VipUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for IP -func (this *IP) MarshalJSON() ([]byte, error) { - str, err := VipMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for IP -func (this *IP) UnmarshalJSON(b []byte) error { - return VipUnmarshaler.Unmarshal(b, this) -} - -var ( - VipMarshaler = &protojson.MarshalOptions{} - VipUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbcatalog/v2beta1/workload.pb.go b/proto-public/pbcatalog/v2beta1/workload.pb.go deleted file mode 100644 index fb2ffa773e46b..0000000000000 --- a/proto-public/pbcatalog/v2beta1/workload.pb.go +++ /dev/null @@ -1,523 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbcatalog/v2beta1/workload.proto - -package catalogv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Workload is the representation of a unit of addressable work. This could -// represent a process on a VM, a Kubernetes pod or something else entirely. -type Workload struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // addresses has a list of all workload addresses. This should include - // LAN and WAN addresses as well as any addresses a proxy would need - // to bind to (if different from the default address). - Addresses []*WorkloadAddress `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` - // ports is a map from port name to workload port’s number and protocol. - Ports map[string]*WorkloadPort `protobuf:"bytes,2,rep,name=ports,proto3" json:"ports,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // node_name is the name of the node this workload belongs to. - NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` - // identity is the name of the workload identity this workload is associated with. - Identity string `protobuf:"bytes,4,opt,name=identity,proto3" json:"identity,omitempty"` - // Locality specifies workload locality. - Locality *Locality `protobuf:"bytes,5,opt,name=locality,proto3" json:"locality,omitempty"` - // deprecated: tags correspond to service tags that you can add to a service for DNS resolution. - // - // Deprecated: Marked as deprecated in pbcatalog/v2beta1/workload.proto. - Tags []string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty"` - // deprecated: enable_tag_override indicates whether agents should be overriding tags during anti-entropy syncs. - // - // Deprecated: Marked as deprecated in pbcatalog/v2beta1/workload.proto. - EnableTagOverride bool `protobuf:"varint,7,opt,name=enable_tag_override,json=enableTagOverride,proto3" json:"enable_tag_override,omitempty"` - // deprecated: connect_native indicates whether this workload is connect native which will allow it to be - // part of MeshEndpoints without having the corresponding Proxy resource. - // - // Deprecated: Marked as deprecated in pbcatalog/v2beta1/workload.proto. - ConnectNative bool `protobuf:"varint,8,opt,name=connect_native,json=connectNative,proto3" json:"connect_native,omitempty"` -} - -func (x *Workload) Reset() { - *x = Workload{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_workload_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Workload) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Workload) ProtoMessage() {} - -func (x *Workload) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_workload_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Workload.ProtoReflect.Descriptor instead. -func (*Workload) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_workload_proto_rawDescGZIP(), []int{0} -} - -func (x *Workload) GetAddresses() []*WorkloadAddress { - if x != nil { - return x.Addresses - } - return nil -} - -func (x *Workload) GetPorts() map[string]*WorkloadPort { - if x != nil { - return x.Ports - } - return nil -} - -func (x *Workload) GetNodeName() string { - if x != nil { - return x.NodeName - } - return "" -} - -func (x *Workload) GetIdentity() string { - if x != nil { - return x.Identity - } - return "" -} - -func (x *Workload) GetLocality() *Locality { - if x != nil { - return x.Locality - } - return nil -} - -// Deprecated: Marked as deprecated in pbcatalog/v2beta1/workload.proto. -func (x *Workload) GetTags() []string { - if x != nil { - return x.Tags - } - return nil -} - -// Deprecated: Marked as deprecated in pbcatalog/v2beta1/workload.proto. -func (x *Workload) GetEnableTagOverride() bool { - if x != nil { - return x.EnableTagOverride - } - return false -} - -// Deprecated: Marked as deprecated in pbcatalog/v2beta1/workload.proto. -func (x *Workload) GetConnectNative() bool { - if x != nil { - return x.ConnectNative - } - return false -} - -type WorkloadAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // host can be an IP, DNS name or a unix socket. - // If it's a unix socket, only one port can be provided. - Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` - // ports is a list of names of ports that this host binds to. - // If no ports are provided, we will assume all ports from the ports map. - Ports []string `protobuf:"bytes,2,rep,name=ports,proto3" json:"ports,omitempty"` - // external indicates whether this address should be used for external communication - // (aka a WAN address). - External bool `protobuf:"varint,3,opt,name=external,proto3" json:"external,omitempty"` -} - -func (x *WorkloadAddress) Reset() { - *x = WorkloadAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_workload_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *WorkloadAddress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*WorkloadAddress) ProtoMessage() {} - -func (x *WorkloadAddress) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_workload_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use WorkloadAddress.ProtoReflect.Descriptor instead. -func (*WorkloadAddress) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_workload_proto_rawDescGZIP(), []int{1} -} - -func (x *WorkloadAddress) GetHost() string { - if x != nil { - return x.Host - } - return "" -} - -func (x *WorkloadAddress) GetPorts() []string { - if x != nil { - return x.Ports - } - return nil -} - -func (x *WorkloadAddress) GetExternal() bool { - if x != nil { - return x.External - } - return false -} - -type WorkloadPort struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Port uint32 `protobuf:"varint,1,opt,name=port,proto3" json:"port,omitempty"` - Protocol Protocol `protobuf:"varint,2,opt,name=protocol,proto3,enum=hashicorp.consul.catalog.v2beta1.Protocol" json:"protocol,omitempty"` -} - -func (x *WorkloadPort) Reset() { - *x = WorkloadPort{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_workload_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *WorkloadPort) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*WorkloadPort) ProtoMessage() {} - -func (x *WorkloadPort) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_workload_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use WorkloadPort.ProtoReflect.Descriptor instead. -func (*WorkloadPort) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_workload_proto_rawDescGZIP(), []int{2} -} - -func (x *WorkloadPort) GetPort() uint32 { - if x != nil { - return x.Port - } - return 0 -} - -func (x *WorkloadPort) GetProtocol() Protocol { - if x != nil { - return x.Protocol - } - return Protocol_PROTOCOL_UNSPECIFIED -} - -type Locality struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Region is region the zone belongs to. - Region string `protobuf:"bytes,1,opt,name=region,proto3" json:"region,omitempty"` - // Zone is the zone the entity is running in. - Zone string `protobuf:"bytes,2,opt,name=zone,proto3" json:"zone,omitempty"` -} - -func (x *Locality) Reset() { - *x = Locality{} - if protoimpl.UnsafeEnabled { - mi := &file_pbcatalog_v2beta1_workload_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Locality) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Locality) ProtoMessage() {} - -func (x *Locality) ProtoReflect() protoreflect.Message { - mi := &file_pbcatalog_v2beta1_workload_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Locality.ProtoReflect.Descriptor instead. -func (*Locality) Descriptor() ([]byte, []int) { - return file_pbcatalog_v2beta1_workload_proto_rawDescGZIP(), []int{3} -} - -func (x *Locality) GetRegion() string { - if x != nil { - return x.Region - } - return "" -} - -func (x *Locality) GetZone() string { - if x != nil { - return x.Zone - } - return "" -} - -var File_pbcatalog_v2beta1_workload_proto protoreflect.FileDescriptor - -var file_pbcatalog_v2beta1_workload_proto_rawDesc = []byte{ - 0x0a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x1a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x04, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, - 0x64, 0x12, 0x4f, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x6f, - 0x72, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, - 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, - 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, - 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, - 0x12, 0x16, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x32, 0x0a, 0x13, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x11, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x54, 0x61, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x29, 0x0a, 0x0e, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x1a, 0x68, 0x0a, 0x0a, 0x50, 0x6f, 0x72, 0x74, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, - 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, - 0x61, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x57, 0x0a, 0x0f, 0x57, 0x6f, 0x72, - 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x22, 0x6a, 0x0a, 0x0c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, - 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x46, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x36, - 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, - 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, - 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x42, 0xa3, 0x02, 0x0a, 0x24, 0x63, 0x6f, 0x6d, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, - 0x0d, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x63, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x63, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, - 0x43, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5c, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x43, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x43, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbcatalog_v2beta1_workload_proto_rawDescOnce sync.Once - file_pbcatalog_v2beta1_workload_proto_rawDescData = file_pbcatalog_v2beta1_workload_proto_rawDesc -) - -func file_pbcatalog_v2beta1_workload_proto_rawDescGZIP() []byte { - file_pbcatalog_v2beta1_workload_proto_rawDescOnce.Do(func() { - file_pbcatalog_v2beta1_workload_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbcatalog_v2beta1_workload_proto_rawDescData) - }) - return file_pbcatalog_v2beta1_workload_proto_rawDescData -} - -var file_pbcatalog_v2beta1_workload_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_pbcatalog_v2beta1_workload_proto_goTypes = []interface{}{ - (*Workload)(nil), // 0: hashicorp.consul.catalog.v2beta1.Workload - (*WorkloadAddress)(nil), // 1: hashicorp.consul.catalog.v2beta1.WorkloadAddress - (*WorkloadPort)(nil), // 2: hashicorp.consul.catalog.v2beta1.WorkloadPort - (*Locality)(nil), // 3: hashicorp.consul.catalog.v2beta1.Locality - nil, // 4: hashicorp.consul.catalog.v2beta1.Workload.PortsEntry - (Protocol)(0), // 5: hashicorp.consul.catalog.v2beta1.Protocol -} -var file_pbcatalog_v2beta1_workload_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.catalog.v2beta1.Workload.addresses:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadAddress - 4, // 1: hashicorp.consul.catalog.v2beta1.Workload.ports:type_name -> hashicorp.consul.catalog.v2beta1.Workload.PortsEntry - 3, // 2: hashicorp.consul.catalog.v2beta1.Workload.locality:type_name -> hashicorp.consul.catalog.v2beta1.Locality - 5, // 3: hashicorp.consul.catalog.v2beta1.WorkloadPort.protocol:type_name -> hashicorp.consul.catalog.v2beta1.Protocol - 2, // 4: hashicorp.consul.catalog.v2beta1.Workload.PortsEntry.value:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadPort - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name -} - -func init() { file_pbcatalog_v2beta1_workload_proto_init() } -func file_pbcatalog_v2beta1_workload_proto_init() { - if File_pbcatalog_v2beta1_workload_proto != nil { - return - } - file_pbcatalog_v2beta1_protocol_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbcatalog_v2beta1_workload_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Workload); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_workload_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WorkloadAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_workload_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WorkloadPort); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbcatalog_v2beta1_workload_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Locality); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbcatalog_v2beta1_workload_proto_rawDesc, - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbcatalog_v2beta1_workload_proto_goTypes, - DependencyIndexes: file_pbcatalog_v2beta1_workload_proto_depIdxs, - MessageInfos: file_pbcatalog_v2beta1_workload_proto_msgTypes, - }.Build() - File_pbcatalog_v2beta1_workload_proto = out.File - file_pbcatalog_v2beta1_workload_proto_rawDesc = nil - file_pbcatalog_v2beta1_workload_proto_goTypes = nil - file_pbcatalog_v2beta1_workload_proto_depIdxs = nil -} diff --git a/proto-public/pbcatalog/v2beta1/workload_addon.go b/proto-public/pbcatalog/v2beta1/workload_addon.go deleted file mode 100644 index d09ef61454514..0000000000000 --- a/proto-public/pbcatalog/v2beta1/workload_addon.go +++ /dev/null @@ -1,77 +0,0 @@ -package catalogv2beta1 - -import "golang.org/x/exp/slices" - -func (w *Workload) GetMeshPortName() (string, bool) { - var meshPort string - - for portName, port := range w.GetPorts() { - if port.Protocol == Protocol_PROTOCOL_MESH { - meshPort = portName - return meshPort, true - } - } - - return "", false -} - -func (w *Workload) IsMeshEnabled() bool { - _, ok := w.GetMeshPortName() - return ok -} - -func (w *Workload) GetNonExternalAddressesForPort(portName string) []*WorkloadAddress { - var addresses []*WorkloadAddress - - // If this port doesn't exist on a workload, return nil. - if _, ok := w.GetPorts()[portName]; !ok { - return nil - } - - for _, address := range w.GetAddresses() { - if address.GetExternal() { - // Skip external addresses. - continue - } - - // If there are no ports, that means this port is selected. - // Otherwise, check if the port is explicitly selected by this address - if len(address.Ports) == 0 || slices.Contains(address.GetPorts(), portName) { - addresses = append(addresses, address) - } - } - - return addresses -} - -func (w *Workload) GetFirstNonExternalMeshAddress() *WorkloadAddress { - // Find mesh port. - meshPort, ok := w.GetMeshPortName() - if !ok { - return nil - } - - // Check if the workload has a specific address for the mesh port. - meshAddresses := w.GetNonExternalAddressesForPort(meshPort) - - // If there are no mesh addresses, return. This should be impossible. - if len(meshAddresses) == 0 { - return nil - } - - // If there are more than one mesh address, use the first one in the list. - return meshAddresses[0] -} - -func (w *Workload) GetPortsByProtocol() map[Protocol][]string { - if w == nil { - return nil - } - - out := make(map[Protocol][]string, len(w.GetPorts())) - for name, port := range w.GetPorts() { - out[port.GetProtocol()] = append(out[port.GetProtocol()], name) - } - - return out -} diff --git a/proto-public/pbcatalog/v2beta1/workload_addon_test.go b/proto-public/pbcatalog/v2beta1/workload_addon_test.go deleted file mode 100644 index 0a40f77d1eaad..0000000000000 --- a/proto-public/pbcatalog/v2beta1/workload_addon_test.go +++ /dev/null @@ -1,259 +0,0 @@ -package catalogv2beta1 - -import ( - "sort" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestGetMeshPort(t *testing.T) { - cases := map[string]struct { - ports map[string]*WorkloadPort - exp string - }{ - "nil ports": { - ports: nil, - exp: "", - }, - "empty ports": { - ports: make(map[string]*WorkloadPort), - exp: "", - }, - "no mesh ports": { - ports: map[string]*WorkloadPort{ - "p1": {Port: 1000, Protocol: Protocol_PROTOCOL_HTTP}, - "p2": {Port: 2000, Protocol: Protocol_PROTOCOL_TCP}, - }, - exp: "", - }, - "one mesh port": { - ports: map[string]*WorkloadPort{ - "p1": {Port: 1000, Protocol: Protocol_PROTOCOL_HTTP}, - "p2": {Port: 2000, Protocol: Protocol_PROTOCOL_TCP}, - "p3": {Port: 3000, Protocol: Protocol_PROTOCOL_MESH}, - }, - exp: "p3", - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - workload := Workload{ - Ports: c.ports, - } - meshPort, ok := workload.GetMeshPortName() - if c.exp != "" { - require.True(t, ok) - require.Equal(t, c.exp, meshPort) - } - }) - } -} - -func TestWorkloadIsMeshEnabled(t *testing.T) { - cases := map[string]struct { - ports map[string]*WorkloadPort - exp bool - }{ - "no ports": { - ports: nil, - exp: false, - }, - "no mesh": { - ports: map[string]*WorkloadPort{ - "p1": {Port: 8080}, - "p2": {Port: 8081}, - }, - exp: false, - }, - "with mesh": { - ports: map[string]*WorkloadPort{ - "p1": {Port: 8080}, - "p2": {Port: 8081, Protocol: Protocol_PROTOCOL_MESH}, - }, - exp: false, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - w := &Workload{ - Ports: c.ports, - } - require.Equal(t, c.exp, w.IsMeshEnabled()) - }) - } -} - -func TestGetAddressesForPort(t *testing.T) { - cases := map[string]struct { - addresses []*WorkloadAddress - ports map[string]*WorkloadPort - portName string - expAddresses []*WorkloadAddress - }{ - "empty addresses": { - addresses: nil, - ports: nil, - portName: "doesn't matter", - expAddresses: nil, - }, - "addresses without selected port": { - addresses: []*WorkloadAddress{{Host: "1.1.1.1"}}, - ports: nil, - portName: "not-found", - expAddresses: nil, - }, - "single selected address": { - addresses: []*WorkloadAddress{ - {Host: "1.1.1.1", Ports: []string{"p1", "p2"}}, - {Host: "2.2.2.2", Ports: []string{"p3", "p4"}}, - }, - ports: map[string]*WorkloadPort{ - "p1": {Port: 8080}, - "p2": {Port: 8081}, - "p3": {Port: 8082}, - "p4": {Port: 8083}, - }, - portName: "p1", - expAddresses: []*WorkloadAddress{ - {Host: "1.1.1.1", Ports: []string{"p1", "p2"}}, - }, - }, - "multiple selected addresses": { - addresses: []*WorkloadAddress{ - {Host: "1.1.1.1", Ports: []string{"p1", "p2"}}, - {Host: "2.2.2.2", Ports: []string{"p3", "p4"}}, - {Host: "3.3.3.3"}, - {Host: "3.3.3.3", Ports: []string{"p1"}, External: true}, - }, - ports: map[string]*WorkloadPort{ - "p1": {Port: 8080}, - "p2": {Port: 8081}, - "p3": {Port: 8082}, - "p4": {Port: 8083}, - }, - portName: "p1", - expAddresses: []*WorkloadAddress{ - {Host: "1.1.1.1", Ports: []string{"p1", "p2"}}, - {Host: "3.3.3.3"}, - }, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - workload := Workload{ - Addresses: c.addresses, - Ports: c.ports, - } - - actualAddresses := workload.GetNonExternalAddressesForPort(c.portName) - require.Equal(t, c.expAddresses, actualAddresses) - }) - } -} - -func TestGetFirstNonExternalMeshAddress(t *testing.T) { - cases := map[string]struct { - workload *Workload - expAddress *WorkloadAddress - }{ - "empty addresses": { - workload: &Workload{}, - expAddress: nil, - }, - "no mesh port": { - workload: &Workload{ - Addresses: []*WorkloadAddress{{Host: "1.1.1.1"}}, - Ports: map[string]*WorkloadPort{ - "tcp": {Port: 8080}, - }, - }, - expAddress: nil, - }, - "only external mesh ports": { - workload: &Workload{ - Addresses: []*WorkloadAddress{{Host: "1.1.1.1", External: true}}, - Ports: map[string]*WorkloadPort{ - "mesh": {Port: 8080, Protocol: Protocol_PROTOCOL_MESH}, - }, - }, - expAddress: nil, - }, - "only external and internal mesh ports": { - workload: &Workload{ - Addresses: []*WorkloadAddress{ - {Host: "1.1.1.1"}, - {Host: "2.2.2.2", External: true}, - }, - Ports: map[string]*WorkloadPort{ - "mesh": {Port: 8080, Protocol: Protocol_PROTOCOL_MESH}, - }, - }, - expAddress: &WorkloadAddress{Host: "1.1.1.1"}, - }, - "multiple internal addresses for mesh port": { - workload: &Workload{ - Addresses: []*WorkloadAddress{ - {Host: "1.1.1.1"}, - {Host: "2.2.2.2", External: true}, - {Host: "3.3.3.3"}, - }, - Ports: map[string]*WorkloadPort{ - "mesh": {Port: 8080, Protocol: Protocol_PROTOCOL_MESH}, - }, - }, - expAddress: &WorkloadAddress{Host: "1.1.1.1"}, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - actualAddress := c.workload.GetFirstNonExternalMeshAddress() - require.Equal(t, actualAddress, c.expAddress) - }) - } -} - -func TestGetPortsByProtocol(t *testing.T) { - cases := map[string]struct { - w *Workload - exp map[Protocol][]string - }{ - "nil": { - w: nil, - exp: nil, - }, - "ports with protocols": { - w: &Workload{ - Ports: map[string]*WorkloadPort{ - "p1": {Port: 8080, Protocol: Protocol_PROTOCOL_TCP}, - "p2": {Port: 8081, Protocol: Protocol_PROTOCOL_HTTP}, - "p3": {Port: 8082, Protocol: Protocol_PROTOCOL_HTTP2}, - "p4": {Port: 8083, Protocol: Protocol_PROTOCOL_TCP}, - "p5": {Port: 8084, Protocol: Protocol_PROTOCOL_MESH}, - "p6": {Port: 8085, Protocol: Protocol_PROTOCOL_MESH}, - }, - }, - exp: map[Protocol][]string{ - Protocol_PROTOCOL_TCP: {"p1", "p4"}, - Protocol_PROTOCOL_HTTP: {"p2"}, - Protocol_PROTOCOL_HTTP2: {"p3"}, - Protocol_PROTOCOL_MESH: {"p5", "p6"}, - }, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - portsByProtocol := c.w.GetPortsByProtocol() - for protocol, ports := range portsByProtocol { - sort.Strings(ports) - portsByProtocol[protocol] = ports - } - require.Equal(t, c.exp, portsByProtocol) - }) - } -} diff --git a/proto-public/pbcatalog/v2beta1/workload_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/workload_deepcopy.gen.go deleted file mode 100644 index 10d71872bf6da..0000000000000 --- a/proto-public/pbcatalog/v2beta1/workload_deepcopy.gen.go +++ /dev/null @@ -1,90 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package catalogv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Workload within kubernetes types, where deepcopy-gen is used. -func (in *Workload) DeepCopyInto(out *Workload) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Workload. Required by controller-gen. -func (in *Workload) DeepCopy() *Workload { - if in == nil { - return nil - } - out := new(Workload) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Workload. Required by controller-gen. -func (in *Workload) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WorkloadAddress within kubernetes types, where deepcopy-gen is used. -func (in *WorkloadAddress) DeepCopyInto(out *WorkloadAddress) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadAddress. Required by controller-gen. -func (in *WorkloadAddress) DeepCopy() *WorkloadAddress { - if in == nil { - return nil - } - out := new(WorkloadAddress) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadAddress. Required by controller-gen. -func (in *WorkloadAddress) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WorkloadPort within kubernetes types, where deepcopy-gen is used. -func (in *WorkloadPort) DeepCopyInto(out *WorkloadPort) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadPort. Required by controller-gen. -func (in *WorkloadPort) DeepCopy() *WorkloadPort { - if in == nil { - return nil - } - out := new(WorkloadPort) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadPort. Required by controller-gen. -func (in *WorkloadPort) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Locality within kubernetes types, where deepcopy-gen is used. -func (in *Locality) DeepCopyInto(out *Locality) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Locality. Required by controller-gen. -func (in *Locality) DeepCopy() *Locality { - if in == nil { - return nil - } - out := new(Locality) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Locality. Required by controller-gen. -func (in *Locality) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbcatalog/v2beta1/workload_json.gen.go b/proto-public/pbcatalog/v2beta1/workload_json.gen.go deleted file mode 100644 index 98592bbd45e9d..0000000000000 --- a/proto-public/pbcatalog/v2beta1/workload_json.gen.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package catalogv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Workload -func (this *Workload) MarshalJSON() ([]byte, error) { - str, err := WorkloadMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Workload -func (this *Workload) UnmarshalJSON(b []byte) error { - return WorkloadUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WorkloadAddress -func (this *WorkloadAddress) MarshalJSON() ([]byte, error) { - str, err := WorkloadMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WorkloadAddress -func (this *WorkloadAddress) UnmarshalJSON(b []byte) error { - return WorkloadUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WorkloadPort -func (this *WorkloadPort) MarshalJSON() ([]byte, error) { - str, err := WorkloadMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WorkloadPort -func (this *WorkloadPort) UnmarshalJSON(b []byte) error { - return WorkloadUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Locality -func (this *Locality) MarshalJSON() ([]byte, error) { - str, err := WorkloadMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Locality -func (this *Locality) UnmarshalJSON(b []byte) error { - return WorkloadUnmarshaler.Unmarshal(b, this) -} - -var ( - WorkloadMarshaler = &protojson.MarshalOptions{} - WorkloadUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbconnectca/ca_deepcopy.gen.go b/proto-public/pbconnectca/ca_deepcopy.gen.go deleted file mode 100644 index 8ac221b224c5e..0000000000000 --- a/proto-public/pbconnectca/ca_deepcopy.gen.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbconnectca - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using WatchRootsRequest within kubernetes types, where deepcopy-gen is used. -func (in *WatchRootsRequest) DeepCopyInto(out *WatchRootsRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRootsRequest. Required by controller-gen. -func (in *WatchRootsRequest) DeepCopy() *WatchRootsRequest { - if in == nil { - return nil - } - out := new(WatchRootsRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WatchRootsRequest. Required by controller-gen. -func (in *WatchRootsRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WatchRootsResponse within kubernetes types, where deepcopy-gen is used. -func (in *WatchRootsResponse) DeepCopyInto(out *WatchRootsResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRootsResponse. Required by controller-gen. -func (in *WatchRootsResponse) DeepCopy() *WatchRootsResponse { - if in == nil { - return nil - } - out := new(WatchRootsResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WatchRootsResponse. Required by controller-gen. -func (in *WatchRootsResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using CARoot within kubernetes types, where deepcopy-gen is used. -func (in *CARoot) DeepCopyInto(out *CARoot) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CARoot. Required by controller-gen. -func (in *CARoot) DeepCopy() *CARoot { - if in == nil { - return nil - } - out := new(CARoot) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new CARoot. Required by controller-gen. -func (in *CARoot) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using SignRequest within kubernetes types, where deepcopy-gen is used. -func (in *SignRequest) DeepCopyInto(out *SignRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignRequest. Required by controller-gen. -func (in *SignRequest) DeepCopy() *SignRequest { - if in == nil { - return nil - } - out := new(SignRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new SignRequest. Required by controller-gen. -func (in *SignRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using SignResponse within kubernetes types, where deepcopy-gen is used. -func (in *SignResponse) DeepCopyInto(out *SignResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignResponse. Required by controller-gen. -func (in *SignResponse) DeepCopy() *SignResponse { - if in == nil { - return nil - } - out := new(SignResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new SignResponse. Required by controller-gen. -func (in *SignResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbconnectca/ca_json.gen.go b/proto-public/pbconnectca/ca_json.gen.go deleted file mode 100644 index 92ee77db53b2d..0000000000000 --- a/proto-public/pbconnectca/ca_json.gen.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbconnectca - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for WatchRootsRequest -func (this *WatchRootsRequest) MarshalJSON() ([]byte, error) { - str, err := CaMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WatchRootsRequest -func (this *WatchRootsRequest) UnmarshalJSON(b []byte) error { - return CaUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WatchRootsResponse -func (this *WatchRootsResponse) MarshalJSON() ([]byte, error) { - str, err := CaMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WatchRootsResponse -func (this *WatchRootsResponse) UnmarshalJSON(b []byte) error { - return CaUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for CARoot -func (this *CARoot) MarshalJSON() ([]byte, error) { - str, err := CaMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for CARoot -func (this *CARoot) UnmarshalJSON(b []byte) error { - return CaUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for SignRequest -func (this *SignRequest) MarshalJSON() ([]byte, error) { - str, err := CaMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for SignRequest -func (this *SignRequest) UnmarshalJSON(b []byte) error { - return CaUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for SignResponse -func (this *SignResponse) MarshalJSON() ([]byte, error) { - str, err := CaMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for SignResponse -func (this *SignResponse) UnmarshalJSON(b []byte) error { - return CaUnmarshaler.Unmarshal(b, this) -} - -var ( - CaMarshaler = &protojson.MarshalOptions{} - CaUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbdataplane/dataplane.pb.go b/proto-public/pbdataplane/dataplane.pb.go index faa826994768a..eeecbc2bd02b2 100644 --- a/proto-public/pbdataplane/dataplane.pb.go +++ b/proto-public/pbdataplane/dataplane.pb.go @@ -13,7 +13,6 @@ package pbdataplane import ( _ "github.com/hashicorp/consul/proto-public/annotations/ratelimit" - v2beta1 "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" structpb "google.golang.org/protobuf/types/known/structpb" @@ -314,10 +313,7 @@ type GetEnvoyBootstrapParamsRequest struct { // *GetEnvoyBootstrapParamsRequest_NodeName NodeSpec isGetEnvoyBootstrapParamsRequest_NodeSpec `protobuf_oneof:"node_spec"` // The proxy service ID - // - // Deprecated: Marked as deprecated in pbdataplane/dataplane.proto. ServiceId string `protobuf:"bytes,3,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"` - ProxyId string `protobuf:"bytes,6,opt,name=proxy_id,json=proxyId,proto3" json:"proxy_id,omitempty"` Partition string `protobuf:"bytes,4,opt,name=partition,proto3" json:"partition,omitempty"` Namespace string `protobuf:"bytes,5,opt,name=namespace,proto3" json:"namespace,omitempty"` } @@ -375,7 +371,6 @@ func (x *GetEnvoyBootstrapParamsRequest) GetNodeName() string { return "" } -// Deprecated: Marked as deprecated in pbdataplane/dataplane.proto. func (x *GetEnvoyBootstrapParamsRequest) GetServiceId() string { if x != nil { return x.ServiceId @@ -383,13 +378,6 @@ func (x *GetEnvoyBootstrapParamsRequest) GetServiceId() string { return "" } -func (x *GetEnvoyBootstrapParamsRequest) GetProxyId() string { - if x != nil { - return x.ProxyId - } - return "" -} - func (x *GetEnvoyBootstrapParamsRequest) GetPartition() string { if x != nil { return x.Partition @@ -425,28 +413,19 @@ type GetEnvoyBootstrapParamsResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // deprecated: use identity instead. - // service is used to identify the service (as the local cluster name and + ServiceKind ServiceKind `protobuf:"varint,1,opt,name=service_kind,json=serviceKind,proto3,enum=hashicorp.consul.dataplane.ServiceKind" json:"service_kind,omitempty"` + // service is be used to identify the service (as the local cluster name and // in metric tags). If the service is a connect proxy it will be the name of // the proxy's destination service, for gateways it will be the gateway // service's name. - // - // Deprecated: Marked as deprecated in pbdataplane/dataplane.proto. - Service string `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"` - // identity is used to identify this proxy (as the local cluster name and - // in metric tags). For v1, this should be the service name. - // If the service is a connect proxy it will be the name of - // the proxy's destination service, for gateways it will be the gateway - // service's name. - // For v2, this should be the workload identity name. - Identity string `protobuf:"bytes,10,opt,name=identity,proto3" json:"identity,omitempty"` - Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` - Partition string `protobuf:"bytes,4,opt,name=partition,proto3" json:"partition,omitempty"` - Datacenter string `protobuf:"bytes,5,opt,name=datacenter,proto3" json:"datacenter,omitempty"` - Config *structpb.Struct `protobuf:"bytes,6,opt,name=config,proto3" json:"config,omitempty"` - BootstrapConfig *v2beta1.BootstrapConfig `protobuf:"bytes,11,opt,name=bootstrap_config,json=bootstrapConfig,proto3" json:"bootstrap_config,omitempty"` - NodeName string `protobuf:"bytes,8,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` - AccessLogs []string `protobuf:"bytes,9,rep,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` + Service string `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"` + Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` + Partition string `protobuf:"bytes,4,opt,name=partition,proto3" json:"partition,omitempty"` + Datacenter string `protobuf:"bytes,5,opt,name=datacenter,proto3" json:"datacenter,omitempty"` + Config *structpb.Struct `protobuf:"bytes,6,opt,name=config,proto3" json:"config,omitempty"` + NodeId string `protobuf:"bytes,7,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` + NodeName string `protobuf:"bytes,8,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` + AccessLogs []string `protobuf:"bytes,9,rep,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` } func (x *GetEnvoyBootstrapParamsResponse) Reset() { @@ -481,17 +460,16 @@ func (*GetEnvoyBootstrapParamsResponse) Descriptor() ([]byte, []int) { return file_pbdataplane_dataplane_proto_rawDescGZIP(), []int{4} } -// Deprecated: Marked as deprecated in pbdataplane/dataplane.proto. -func (x *GetEnvoyBootstrapParamsResponse) GetService() string { +func (x *GetEnvoyBootstrapParamsResponse) GetServiceKind() ServiceKind { if x != nil { - return x.Service + return x.ServiceKind } - return "" + return ServiceKind_SERVICE_KIND_UNSPECIFIED } -func (x *GetEnvoyBootstrapParamsResponse) GetIdentity() string { +func (x *GetEnvoyBootstrapParamsResponse) GetService() string { if x != nil { - return x.Identity + return x.Service } return "" } @@ -524,11 +502,11 @@ func (x *GetEnvoyBootstrapParamsResponse) GetConfig() *structpb.Struct { return nil } -func (x *GetEnvoyBootstrapParamsResponse) GetBootstrapConfig() *v2beta1.BootstrapConfig { +func (x *GetEnvoyBootstrapParamsResponse) GetNodeId() string { if x != nil { - return x.BootstrapConfig + return x.NodeId } - return nil + return "" } func (x *GetEnvoyBootstrapParamsResponse) GetNodeName() string { @@ -555,138 +533,131 @@ var file_pbdataplane_dataplane_proto_rawDesc = []byte{ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2f, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, - 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x26, 0x0a, 0x24, 0x47, 0x65, 0x74, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x89, 0x01, 0x0a, 0x17, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x50, 0x0a, 0x0c, - 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x26, + 0x0a, 0x24, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, + 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x44, 0x61, 0x74, 0x61, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x50, 0x0a, 0x0c, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x0b, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x22, 0x9e, 0x01, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x1c, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, + 0x61, 0x6e, 0x65, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x1a, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x22, 0xc2, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x6f, 0x79, + 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, + 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x22, 0xeb, 0x02, 0x0a, 0x1f, 0x47, 0x65, 0x74, + 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0c, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0b, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, + 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x2f, + 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x2a, 0xe4, 0x01, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x1e, + 0x44, 0x41, 0x54, 0x41, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, + 0x45, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x24, 0x0a, 0x20, 0x44, 0x41, 0x54, 0x41, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x5f, 0x46, 0x45, + 0x41, 0x54, 0x55, 0x52, 0x45, 0x53, 0x5f, 0x57, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x53, 0x10, 0x01, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x50, 0x4c, + 0x41, 0x4e, 0x45, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x53, 0x5f, 0x45, 0x44, 0x47, + 0x45, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x41, + 0x4e, 0x41, 0x47, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x41, + 0x54, 0x41, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x53, + 0x5f, 0x45, 0x4e, 0x56, 0x4f, 0x59, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, + 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, + 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x41, 0x54, 0x41, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x5f, 0x46, 0x45, + 0x41, 0x54, 0x55, 0x52, 0x45, 0x53, 0x5f, 0x46, 0x49, 0x50, 0x53, 0x10, 0x04, 0x2a, 0xea, 0x01, + 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, + 0x18, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x53, + 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x49, + 0x43, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x5f, 0x50, 0x52, + 0x4f, 0x58, 0x59, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, + 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, + 0x41, 0x59, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, + 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x49, 0x4e, 0x47, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x10, 0x04, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, + 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x47, 0x52, 0x45, + 0x53, 0x53, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, + 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x49, + 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x10, 0x06, 0x32, 0xe2, 0x02, 0x0a, 0x10, 0x44, + 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0xae, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x52, 0x0b, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x22, 0x9e, 0x01, 0x0a, - 0x25, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, + 0x73, 0x12, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x47, + 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, + 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x1c, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x5f, 0x66, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xe2, 0x86, 0x04, 0x04, 0x08, 0x02, 0x10, 0x07, + 0x12, 0x9c, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x42, 0x6f, 0x6f, + 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x1a, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0xe1, 0x01, - 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, - 0x72, 0x61, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x19, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x09, 0x6e, - 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, - 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0a, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, - 0x18, 0x01, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x19, 0x0a, - 0x08, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x73, 0x70, 0x65, - 0x63, 0x22, 0x8d, 0x03, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x42, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, + 0x6f, 0x79, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, - 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x64, - 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, 0x0a, 0x10, - 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, - 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, - 0x6f, 0x67, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x07, 0x10, - 0x08, 0x2a, 0xe4, 0x01, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x1e, 0x44, 0x41, 0x54, 0x41, 0x50, - 0x4c, 0x41, 0x4e, 0x45, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x53, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x44, - 0x41, 0x54, 0x41, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, - 0x53, 0x5f, 0x57, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x53, 0x10, - 0x01, 0x12, 0x32, 0x0a, 0x2e, 0x44, 0x41, 0x54, 0x41, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x5f, 0x46, - 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x5f, 0x43, 0x45, 0x52, - 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x4d, - 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x34, 0x0a, 0x30, 0x44, 0x41, 0x54, 0x41, 0x50, 0x4c, 0x41, - 0x4e, 0x45, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x53, 0x5f, 0x45, 0x4e, 0x56, 0x4f, - 0x59, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x5f, 0x43, 0x4f, 0x4e, 0x46, - 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x44, - 0x41, 0x54, 0x41, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x5f, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, - 0x53, 0x5f, 0x46, 0x49, 0x50, 0x53, 0x10, 0x04, 0x2a, 0xea, 0x01, 0x0a, 0x0b, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x45, 0x52, 0x56, - 0x49, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, - 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x01, - 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x10, 0x02, - 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, - 0x5f, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x10, 0x03, 0x12, - 0x24, 0x0a, 0x20, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, - 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x47, 0x41, 0x54, 0x45, - 0x57, 0x41, 0x59, 0x10, 0x04, 0x12, 0x20, 0x0a, 0x1c, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, - 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x47, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x47, 0x41, - 0x54, 0x45, 0x57, 0x41, 0x59, 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x45, 0x52, 0x56, 0x49, - 0x43, 0x45, 0x5f, 0x4b, 0x49, 0x4e, 0x44, 0x5f, 0x41, 0x50, 0x49, 0x5f, 0x47, 0x41, 0x54, 0x45, - 0x57, 0x41, 0x59, 0x10, 0x06, 0x32, 0xe2, 0x02, 0x0a, 0x10, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, - 0x61, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xae, 0x01, 0x0a, 0x1d, 0x47, - 0x65, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x40, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x46, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x08, 0xe2, 0x86, 0x04, 0x04, 0x08, 0x02, 0x10, 0x07, 0x12, 0x9c, 0x01, 0x0a, 0x17, - 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, - 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, - 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x42, 0x6f, 0x6f, - 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, - 0x61, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x08, 0xe2, 0x86, 0x04, 0x04, 0x08, 0x02, 0x10, 0x07, 0x42, 0xf0, 0x01, 0x0a, 0x1e, 0x63, - 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x42, 0x0e, 0x44, - 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x64, 0x61, 0x74, 0x61, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x44, 0xaa, 0x02, 0x1a, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0xca, 0x02, 0x1a, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x44, 0x61, 0x74, 0x61, - 0x70, 0x6c, 0x61, 0x6e, 0x65, 0xe2, 0x02, 0x26, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x1c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x3a, 0x3a, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x08, 0xe2, 0x86, 0x04, 0x04, 0x08, 0x02, 0x10, 0x07, 0x42, + 0xf0, 0x01, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x42, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, + 0x62, 0x64, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x44, + 0xaa, 0x02, 0x1a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0xca, 0x02, 0x1a, + 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x5c, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0xe2, 0x02, 0x26, 0x48, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x44, 0x61, + 0x74, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x1c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, + 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x44, 0x61, 0x74, 0x61, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -712,13 +683,12 @@ var file_pbdataplane_dataplane_proto_goTypes = []interface{}{ (*GetEnvoyBootstrapParamsRequest)(nil), // 5: hashicorp.consul.dataplane.GetEnvoyBootstrapParamsRequest (*GetEnvoyBootstrapParamsResponse)(nil), // 6: hashicorp.consul.dataplane.GetEnvoyBootstrapParamsResponse (*structpb.Struct)(nil), // 7: google.protobuf.Struct - (*v2beta1.BootstrapConfig)(nil), // 8: hashicorp.consul.mesh.v2beta1.BootstrapConfig } var file_pbdataplane_dataplane_proto_depIdxs = []int32{ 0, // 0: hashicorp.consul.dataplane.DataplaneFeatureSupport.feature_name:type_name -> hashicorp.consul.dataplane.DataplaneFeatures 3, // 1: hashicorp.consul.dataplane.GetSupportedDataplaneFeaturesResponse.supported_dataplane_features:type_name -> hashicorp.consul.dataplane.DataplaneFeatureSupport - 7, // 2: hashicorp.consul.dataplane.GetEnvoyBootstrapParamsResponse.config:type_name -> google.protobuf.Struct - 8, // 3: hashicorp.consul.dataplane.GetEnvoyBootstrapParamsResponse.bootstrap_config:type_name -> hashicorp.consul.mesh.v2beta1.BootstrapConfig + 1, // 2: hashicorp.consul.dataplane.GetEnvoyBootstrapParamsResponse.service_kind:type_name -> hashicorp.consul.dataplane.ServiceKind + 7, // 3: hashicorp.consul.dataplane.GetEnvoyBootstrapParamsResponse.config:type_name -> google.protobuf.Struct 2, // 4: hashicorp.consul.dataplane.DataplaneService.GetSupportedDataplaneFeatures:input_type -> hashicorp.consul.dataplane.GetSupportedDataplaneFeaturesRequest 5, // 5: hashicorp.consul.dataplane.DataplaneService.GetEnvoyBootstrapParams:input_type -> hashicorp.consul.dataplane.GetEnvoyBootstrapParamsRequest 4, // 6: hashicorp.consul.dataplane.DataplaneService.GetSupportedDataplaneFeatures:output_type -> hashicorp.consul.dataplane.GetSupportedDataplaneFeaturesResponse diff --git a/proto-public/pbdataplane/dataplane.proto b/proto-public/pbdataplane/dataplane.proto index 8faad919726e1..98a0a750fbfa3 100644 --- a/proto-public/pbdataplane/dataplane.proto +++ b/proto-public/pbdataplane/dataplane.proto @@ -9,7 +9,6 @@ package hashicorp.consul.dataplane; import "annotations/ratelimit/ratelimit.proto"; import "google/protobuf/struct.proto"; -import "pbmesh/v2beta1/proxy_configuration.proto"; message GetSupportedDataplaneFeaturesRequest {} @@ -36,8 +35,7 @@ message GetEnvoyBootstrapParamsRequest { string node_name = 2; } // The proxy service ID - string service_id = 3 [deprecated = true]; - string proxy_id = 6; + string service_id = 3; string partition = 4; string namespace = 5; } @@ -78,30 +76,17 @@ enum ServiceKind { } message GetEnvoyBootstrapParamsResponse { - reserved 1; - - // deprecated: use identity instead. - // service is used to identify the service (as the local cluster name and + ServiceKind service_kind = 1; + // service is be used to identify the service (as the local cluster name and // in metric tags). If the service is a connect proxy it will be the name of // the proxy's destination service, for gateways it will be the gateway // service's name. - string service = 2 [deprecated = true]; - - // identity is used to identify this proxy (as the local cluster name and - // in metric tags). For v1, this should be the service name. - // If the service is a connect proxy it will be the name of - // the proxy's destination service, for gateways it will be the gateway - // service's name. - // For v2, this should be the workload identity name. - string identity = 10; + string service = 2; string namespace = 3; string partition = 4; string datacenter = 5; google.protobuf.Struct config = 6; - hashicorp.consul.mesh.v2beta1.BootstrapConfig bootstrap_config = 11; - - reserved 7; - + string node_id = 7; string node_name = 8; repeated string access_logs = 9; } diff --git a/proto-public/pbdataplane/dataplane_deepcopy.gen.go b/proto-public/pbdataplane/dataplane_deepcopy.gen.go deleted file mode 100644 index e1daf2b699fbf..0000000000000 --- a/proto-public/pbdataplane/dataplane_deepcopy.gen.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbdataplane - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using GetSupportedDataplaneFeaturesRequest within kubernetes types, where deepcopy-gen is used. -func (in *GetSupportedDataplaneFeaturesRequest) DeepCopyInto(out *GetSupportedDataplaneFeaturesRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetSupportedDataplaneFeaturesRequest. Required by controller-gen. -func (in *GetSupportedDataplaneFeaturesRequest) DeepCopy() *GetSupportedDataplaneFeaturesRequest { - if in == nil { - return nil - } - out := new(GetSupportedDataplaneFeaturesRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GetSupportedDataplaneFeaturesRequest. Required by controller-gen. -func (in *GetSupportedDataplaneFeaturesRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DataplaneFeatureSupport within kubernetes types, where deepcopy-gen is used. -func (in *DataplaneFeatureSupport) DeepCopyInto(out *DataplaneFeatureSupport) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataplaneFeatureSupport. Required by controller-gen. -func (in *DataplaneFeatureSupport) DeepCopy() *DataplaneFeatureSupport { - if in == nil { - return nil - } - out := new(DataplaneFeatureSupport) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DataplaneFeatureSupport. Required by controller-gen. -func (in *DataplaneFeatureSupport) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GetSupportedDataplaneFeaturesResponse within kubernetes types, where deepcopy-gen is used. -func (in *GetSupportedDataplaneFeaturesResponse) DeepCopyInto(out *GetSupportedDataplaneFeaturesResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetSupportedDataplaneFeaturesResponse. Required by controller-gen. -func (in *GetSupportedDataplaneFeaturesResponse) DeepCopy() *GetSupportedDataplaneFeaturesResponse { - if in == nil { - return nil - } - out := new(GetSupportedDataplaneFeaturesResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GetSupportedDataplaneFeaturesResponse. Required by controller-gen. -func (in *GetSupportedDataplaneFeaturesResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GetEnvoyBootstrapParamsRequest within kubernetes types, where deepcopy-gen is used. -func (in *GetEnvoyBootstrapParamsRequest) DeepCopyInto(out *GetEnvoyBootstrapParamsRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetEnvoyBootstrapParamsRequest. Required by controller-gen. -func (in *GetEnvoyBootstrapParamsRequest) DeepCopy() *GetEnvoyBootstrapParamsRequest { - if in == nil { - return nil - } - out := new(GetEnvoyBootstrapParamsRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GetEnvoyBootstrapParamsRequest. Required by controller-gen. -func (in *GetEnvoyBootstrapParamsRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GetEnvoyBootstrapParamsResponse within kubernetes types, where deepcopy-gen is used. -func (in *GetEnvoyBootstrapParamsResponse) DeepCopyInto(out *GetEnvoyBootstrapParamsResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetEnvoyBootstrapParamsResponse. Required by controller-gen. -func (in *GetEnvoyBootstrapParamsResponse) DeepCopy() *GetEnvoyBootstrapParamsResponse { - if in == nil { - return nil - } - out := new(GetEnvoyBootstrapParamsResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GetEnvoyBootstrapParamsResponse. Required by controller-gen. -func (in *GetEnvoyBootstrapParamsResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbdataplane/dataplane_json.gen.go b/proto-public/pbdataplane/dataplane_json.gen.go deleted file mode 100644 index 55c54e7771668..0000000000000 --- a/proto-public/pbdataplane/dataplane_json.gen.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbdataplane - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for GetSupportedDataplaneFeaturesRequest -func (this *GetSupportedDataplaneFeaturesRequest) MarshalJSON() ([]byte, error) { - str, err := DataplaneMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GetSupportedDataplaneFeaturesRequest -func (this *GetSupportedDataplaneFeaturesRequest) UnmarshalJSON(b []byte) error { - return DataplaneUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DataplaneFeatureSupport -func (this *DataplaneFeatureSupport) MarshalJSON() ([]byte, error) { - str, err := DataplaneMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DataplaneFeatureSupport -func (this *DataplaneFeatureSupport) UnmarshalJSON(b []byte) error { - return DataplaneUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GetSupportedDataplaneFeaturesResponse -func (this *GetSupportedDataplaneFeaturesResponse) MarshalJSON() ([]byte, error) { - str, err := DataplaneMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GetSupportedDataplaneFeaturesResponse -func (this *GetSupportedDataplaneFeaturesResponse) UnmarshalJSON(b []byte) error { - return DataplaneUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GetEnvoyBootstrapParamsRequest -func (this *GetEnvoyBootstrapParamsRequest) MarshalJSON() ([]byte, error) { - str, err := DataplaneMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GetEnvoyBootstrapParamsRequest -func (this *GetEnvoyBootstrapParamsRequest) UnmarshalJSON(b []byte) error { - return DataplaneUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GetEnvoyBootstrapParamsResponse -func (this *GetEnvoyBootstrapParamsResponse) MarshalJSON() ([]byte, error) { - str, err := DataplaneMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GetEnvoyBootstrapParamsResponse -func (this *GetEnvoyBootstrapParamsResponse) UnmarshalJSON(b []byte) error { - return DataplaneUnmarshaler.Unmarshal(b, this) -} - -var ( - DataplaneMarshaler = &protojson.MarshalOptions{} - DataplaneUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbdns/dns_deepcopy.gen.go b/proto-public/pbdns/dns_deepcopy.gen.go deleted file mode 100644 index 339ab448e1d1c..0000000000000 --- a/proto-public/pbdns/dns_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbdns - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using QueryRequest within kubernetes types, where deepcopy-gen is used. -func (in *QueryRequest) DeepCopyInto(out *QueryRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryRequest. Required by controller-gen. -func (in *QueryRequest) DeepCopy() *QueryRequest { - if in == nil { - return nil - } - out := new(QueryRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new QueryRequest. Required by controller-gen. -func (in *QueryRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using QueryResponse within kubernetes types, where deepcopy-gen is used. -func (in *QueryResponse) DeepCopyInto(out *QueryResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryResponse. Required by controller-gen. -func (in *QueryResponse) DeepCopy() *QueryResponse { - if in == nil { - return nil - } - out := new(QueryResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new QueryResponse. Required by controller-gen. -func (in *QueryResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbdns/dns_json.gen.go b/proto-public/pbdns/dns_json.gen.go deleted file mode 100644 index ac9789a7cb883..0000000000000 --- a/proto-public/pbdns/dns_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbdns - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for QueryRequest -func (this *QueryRequest) MarshalJSON() ([]byte, error) { - str, err := DnsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for QueryRequest -func (this *QueryRequest) UnmarshalJSON(b []byte) error { - return DnsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for QueryResponse -func (this *QueryResponse) MarshalJSON() ([]byte, error) { - str, err := DnsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for QueryResponse -func (this *QueryResponse) UnmarshalJSON(b []byte) error { - return DnsUnmarshaler.Unmarshal(b, this) -} - -var ( - DnsMarshaler = &protojson.MarshalOptions{} - DnsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/connection.pb.binary.go b/proto-public/pbmesh/v1alpha1/connection.pb.binary.go similarity index 91% rename from proto-public/pbmesh/v2beta1/connection.pb.binary.go rename to proto-public/pbmesh/v1alpha1/connection.pb.binary.go index 4ea017a273fb4..778f7ac4f7410 100644 --- a/proto-public/pbmesh/v2beta1/connection.pb.binary.go +++ b/proto-public/pbmesh/v1alpha1/connection.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/connection.proto +// source: pbmesh/v1alpha1/connection.proto -package meshv2beta1 +package meshv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbmesh/v1alpha1/connection.pb.go b/proto-public/pbmesh/v1alpha1/connection.pb.go new file mode 100644 index 0000000000000..5edc0ee76d1d7 --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/connection.pb.go @@ -0,0 +1,316 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbmesh/v1alpha1/connection.proto + +package meshv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type BalanceInboundConnections int32 + +const ( + // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX + BalanceInboundConnections_BALANCE_INBOUND_CONNECTIONS_DEFAULT BalanceInboundConnections = 0 + BalanceInboundConnections_BALANCE_INBOUND_CONNECTIONS_EXACT BalanceInboundConnections = 1 +) + +// Enum value maps for BalanceInboundConnections. +var ( + BalanceInboundConnections_name = map[int32]string{ + 0: "BALANCE_INBOUND_CONNECTIONS_DEFAULT", + 1: "BALANCE_INBOUND_CONNECTIONS_EXACT", + } + BalanceInboundConnections_value = map[string]int32{ + "BALANCE_INBOUND_CONNECTIONS_DEFAULT": 0, + "BALANCE_INBOUND_CONNECTIONS_EXACT": 1, + } +) + +func (x BalanceInboundConnections) Enum() *BalanceInboundConnections { + p := new(BalanceInboundConnections) + *p = x + return p +} + +func (x BalanceInboundConnections) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (BalanceInboundConnections) Descriptor() protoreflect.EnumDescriptor { + return file_pbmesh_v1alpha1_connection_proto_enumTypes[0].Descriptor() +} + +func (BalanceInboundConnections) Type() protoreflect.EnumType { + return &file_pbmesh_v1alpha1_connection_proto_enumTypes[0] +} + +func (x BalanceInboundConnections) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use BalanceInboundConnections.Descriptor instead. +func (BalanceInboundConnections) EnumDescriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_connection_proto_rawDescGZIP(), []int{0} +} + +type ConnectionConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ConnectTimeoutMs uint64 `protobuf:"varint,2,opt,name=connect_timeout_ms,json=connectTimeoutMs,proto3" json:"connect_timeout_ms,omitempty"` + RequestTimeoutMs uint64 `protobuf:"varint,3,opt,name=request_timeout_ms,json=requestTimeoutMs,proto3" json:"request_timeout_ms,omitempty"` +} + +func (x *ConnectionConfig) Reset() { + *x = ConnectionConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_connection_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConnectionConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnectionConfig) ProtoMessage() {} + +func (x *ConnectionConfig) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_connection_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnectionConfig.ProtoReflect.Descriptor instead. +func (*ConnectionConfig) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_connection_proto_rawDescGZIP(), []int{0} +} + +func (x *ConnectionConfig) GetConnectTimeoutMs() uint64 { + if x != nil { + return x.ConnectTimeoutMs + } + return 0 +} + +func (x *ConnectionConfig) GetRequestTimeoutMs() uint64 { + if x != nil { + return x.RequestTimeoutMs + } + return 0 +} + +type InboundConnectionsConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MaxInboundConnections uint64 `protobuf:"varint,12,opt,name=max_inbound_connections,json=maxInboundConnections,proto3" json:"max_inbound_connections,omitempty"` + BalanceInboundConnections BalanceInboundConnections `protobuf:"varint,13,opt,name=balance_inbound_connections,json=balanceInboundConnections,proto3,enum=hashicorp.consul.mesh.v1alpha1.BalanceInboundConnections" json:"balance_inbound_connections,omitempty"` +} + +func (x *InboundConnectionsConfig) Reset() { + *x = InboundConnectionsConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_connection_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InboundConnectionsConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InboundConnectionsConfig) ProtoMessage() {} + +func (x *InboundConnectionsConfig) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_connection_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InboundConnectionsConfig.ProtoReflect.Descriptor instead. +func (*InboundConnectionsConfig) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_connection_proto_rawDescGZIP(), []int{1} +} + +func (x *InboundConnectionsConfig) GetMaxInboundConnections() uint64 { + if x != nil { + return x.MaxInboundConnections + } + return 0 +} + +func (x *InboundConnectionsConfig) GetBalanceInboundConnections() BalanceInboundConnections { + if x != nil { + return x.BalanceInboundConnections + } + return BalanceInboundConnections_BALANCE_INBOUND_CONNECTIONS_DEFAULT +} + +var File_pbmesh_v1alpha1_connection_proto protoreflect.FileDescriptor + +var file_pbmesh_v1alpha1_connection_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x1e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x22, 0x6e, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x4d, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x4d, 0x73, 0x22, 0xcd, 0x01, 0x0a, 0x18, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x36, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x15, 0x6d, 0x61, 0x78, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x79, 0x0a, 0x1b, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2a, 0x6b, 0x0a, 0x19, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x62, + 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x27, 0x0a, 0x23, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x49, 0x4e, 0x42, 0x4f, 0x55, + 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x44, + 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x42, 0x41, 0x4c, 0x41, + 0x4e, 0x43, 0x45, 0x5f, 0x49, 0x4e, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, + 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x45, 0x58, 0x41, 0x43, 0x54, 0x10, 0x01, 0x42, + 0x97, 0x02, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0f, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x1e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, + 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, + 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, + 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_pbmesh_v1alpha1_connection_proto_rawDescOnce sync.Once + file_pbmesh_v1alpha1_connection_proto_rawDescData = file_pbmesh_v1alpha1_connection_proto_rawDesc +) + +func file_pbmesh_v1alpha1_connection_proto_rawDescGZIP() []byte { + file_pbmesh_v1alpha1_connection_proto_rawDescOnce.Do(func() { + file_pbmesh_v1alpha1_connection_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v1alpha1_connection_proto_rawDescData) + }) + return file_pbmesh_v1alpha1_connection_proto_rawDescData +} + +var file_pbmesh_v1alpha1_connection_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_pbmesh_v1alpha1_connection_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pbmesh_v1alpha1_connection_proto_goTypes = []interface{}{ + (BalanceInboundConnections)(0), // 0: hashicorp.consul.mesh.v1alpha1.BalanceInboundConnections + (*ConnectionConfig)(nil), // 1: hashicorp.consul.mesh.v1alpha1.ConnectionConfig + (*InboundConnectionsConfig)(nil), // 2: hashicorp.consul.mesh.v1alpha1.InboundConnectionsConfig +} +var file_pbmesh_v1alpha1_connection_proto_depIdxs = []int32{ + 0, // 0: hashicorp.consul.mesh.v1alpha1.InboundConnectionsConfig.balance_inbound_connections:type_name -> hashicorp.consul.mesh.v1alpha1.BalanceInboundConnections + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_pbmesh_v1alpha1_connection_proto_init() } +func file_pbmesh_v1alpha1_connection_proto_init() { + if File_pbmesh_v1alpha1_connection_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pbmesh_v1alpha1_connection_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnectionConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_connection_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InboundConnectionsConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbmesh_v1alpha1_connection_proto_rawDesc, + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbmesh_v1alpha1_connection_proto_goTypes, + DependencyIndexes: file_pbmesh_v1alpha1_connection_proto_depIdxs, + EnumInfos: file_pbmesh_v1alpha1_connection_proto_enumTypes, + MessageInfos: file_pbmesh_v1alpha1_connection_proto_msgTypes, + }.Build() + File_pbmesh_v1alpha1_connection_proto = out.File + file_pbmesh_v1alpha1_connection_proto_rawDesc = nil + file_pbmesh_v1alpha1_connection_proto_goTypes = nil + file_pbmesh_v1alpha1_connection_proto_depIdxs = nil +} diff --git a/proto-public/pbmesh/v1alpha1/connection.proto b/proto-public/pbmesh/v1alpha1/connection.proto new file mode 100644 index 0000000000000..8a1f4f0e7c575 --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/connection.proto @@ -0,0 +1,22 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +syntax = "proto3"; + +package hashicorp.consul.mesh.v1alpha1; + +message ConnectionConfig { + uint64 connect_timeout_ms = 2; + uint64 request_timeout_ms = 3; +} + +message InboundConnectionsConfig { + uint64 max_inbound_connections = 12; + BalanceInboundConnections balance_inbound_connections = 13; +} + +enum BalanceInboundConnections { + // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX + BALANCE_INBOUND_CONNECTIONS_DEFAULT = 0; + BALANCE_INBOUND_CONNECTIONS_EXACT = 1; +} diff --git a/proto-public/pbmesh/v2beta1/expose.pb.binary.go b/proto-public/pbmesh/v1alpha1/expose.pb.binary.go similarity index 91% rename from proto-public/pbmesh/v2beta1/expose.pb.binary.go rename to proto-public/pbmesh/v1alpha1/expose.pb.binary.go index 69154fab8fb2c..f849d03db5a07 100644 --- a/proto-public/pbmesh/v2beta1/expose.pb.binary.go +++ b/proto-public/pbmesh/v1alpha1/expose.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/expose.proto +// source: pbmesh/v1alpha1/expose.proto -package meshv2beta1 +package meshv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbmesh/v1alpha1/expose.pb.go b/proto-public/pbmesh/v1alpha1/expose.pb.go new file mode 100644 index 0000000000000..c5e13ecf00200 --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/expose.pb.go @@ -0,0 +1,269 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbmesh/v1alpha1/expose.proto + +package meshv1alpha1 + +import ( + v1alpha1 "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ExposeConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExposePaths []*ExposePath `protobuf:"bytes,1,rep,name=expose_paths,json=exposePaths,proto3" json:"expose_paths,omitempty"` +} + +func (x *ExposeConfig) Reset() { + *x = ExposeConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_expose_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExposeConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExposeConfig) ProtoMessage() {} + +func (x *ExposeConfig) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_expose_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExposeConfig.ProtoReflect.Descriptor instead. +func (*ExposeConfig) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_expose_proto_rawDescGZIP(), []int{0} +} + +func (x *ExposeConfig) GetExposePaths() []*ExposePath { + if x != nil { + return x.ExposePaths + } + return nil +} + +type ExposePath struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ListenerPort uint32 `protobuf:"varint,1,opt,name=listener_port,json=listenerPort,proto3" json:"listener_port,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + LocalPathPort uint32 `protobuf:"varint,3,opt,name=local_path_port,json=localPathPort,proto3" json:"local_path_port,omitempty"` + Protocol v1alpha1.Protocol `protobuf:"varint,4,opt,name=protocol,proto3,enum=hashicorp.consul.catalog.v1alpha1.Protocol" json:"protocol,omitempty"` +} + +func (x *ExposePath) Reset() { + *x = ExposePath{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_expose_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExposePath) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExposePath) ProtoMessage() {} + +func (x *ExposePath) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_expose_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExposePath.ProtoReflect.Descriptor instead. +func (*ExposePath) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_expose_proto_rawDescGZIP(), []int{1} +} + +func (x *ExposePath) GetListenerPort() uint32 { + if x != nil { + return x.ListenerPort + } + return 0 +} + +func (x *ExposePath) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *ExposePath) GetLocalPathPort() uint32 { + if x != nil { + return x.LocalPathPort + } + return 0 +} + +func (x *ExposePath) GetProtocol() v1alpha1.Protocol { + if x != nil { + return x.Protocol + } + return v1alpha1.Protocol(0) +} + +var File_pbmesh_v1alpha1_expose_proto protoreflect.FileDescriptor + +var file_pbmesh_v1alpha1_expose_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x21, + 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x22, 0x5d, 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x4d, 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, + 0x61, 0x74, 0x68, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, + 0x22, 0xb6, 0x01, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x23, 0x0a, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x72, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x50, 0x6f, 0x72, 0x74, + 0x12, 0x47, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, + 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x42, 0x93, 0x02, 0x0a, 0x22, 0x63, 0x6f, + 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x42, 0x0b, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1e, 0x48, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x1e, + 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, + 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x21, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, + 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbmesh_v1alpha1_expose_proto_rawDescOnce sync.Once + file_pbmesh_v1alpha1_expose_proto_rawDescData = file_pbmesh_v1alpha1_expose_proto_rawDesc +) + +func file_pbmesh_v1alpha1_expose_proto_rawDescGZIP() []byte { + file_pbmesh_v1alpha1_expose_proto_rawDescOnce.Do(func() { + file_pbmesh_v1alpha1_expose_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v1alpha1_expose_proto_rawDescData) + }) + return file_pbmesh_v1alpha1_expose_proto_rawDescData +} + +var file_pbmesh_v1alpha1_expose_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_pbmesh_v1alpha1_expose_proto_goTypes = []interface{}{ + (*ExposeConfig)(nil), // 0: hashicorp.consul.mesh.v1alpha1.ExposeConfig + (*ExposePath)(nil), // 1: hashicorp.consul.mesh.v1alpha1.ExposePath + (v1alpha1.Protocol)(0), // 2: hashicorp.consul.catalog.v1alpha1.Protocol +} +var file_pbmesh_v1alpha1_expose_proto_depIdxs = []int32{ + 1, // 0: hashicorp.consul.mesh.v1alpha1.ExposeConfig.expose_paths:type_name -> hashicorp.consul.mesh.v1alpha1.ExposePath + 2, // 1: hashicorp.consul.mesh.v1alpha1.ExposePath.protocol:type_name -> hashicorp.consul.catalog.v1alpha1.Protocol + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_pbmesh_v1alpha1_expose_proto_init() } +func file_pbmesh_v1alpha1_expose_proto_init() { + if File_pbmesh_v1alpha1_expose_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pbmesh_v1alpha1_expose_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExposeConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_expose_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExposePath); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbmesh_v1alpha1_expose_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbmesh_v1alpha1_expose_proto_goTypes, + DependencyIndexes: file_pbmesh_v1alpha1_expose_proto_depIdxs, + MessageInfos: file_pbmesh_v1alpha1_expose_proto_msgTypes, + }.Build() + File_pbmesh_v1alpha1_expose_proto = out.File + file_pbmesh_v1alpha1_expose_proto_rawDesc = nil + file_pbmesh_v1alpha1_expose_proto_goTypes = nil + file_pbmesh_v1alpha1_expose_proto_depIdxs = nil +} diff --git a/proto-public/pbmesh/v1alpha1/expose.proto b/proto-public/pbmesh/v1alpha1/expose.proto new file mode 100644 index 0000000000000..bf8591f20d74b --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/expose.proto @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +syntax = "proto3"; + +package hashicorp.consul.mesh.v1alpha1; + +import "pbcatalog/v1alpha1/protocol.proto"; + +message ExposeConfig { + repeated ExposePath expose_paths = 1; +} + +message ExposePath { + uint32 listener_port = 1; + string path = 2; + uint32 local_path_port = 3; + hashicorp.consul.catalog.v1alpha1.Protocol protocol = 4; +} diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration.pb.binary.go b/proto-public/pbmesh/v1alpha1/proxy.pb.binary.go similarity index 66% rename from proto-public/pbmesh/v2beta1/proxy_configuration.pb.binary.go rename to proto-public/pbmesh/v1alpha1/proxy.pb.binary.go index cb786967202d5..f39ae6afec843 100644 --- a/proto-public/pbmesh/v2beta1/proxy_configuration.pb.binary.go +++ b/proto-public/pbmesh/v1alpha1/proxy.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/proxy_configuration.proto +// source: pbmesh/v1alpha1/proxy.proto -package meshv2beta1 +package meshv1alpha1 import ( "google.golang.org/protobuf/proto" @@ -46,23 +46,3 @@ func (msg *BootstrapConfig) MarshalBinary() ([]byte, error) { func (msg *BootstrapConfig) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *AccessLogsConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *AccessLogsConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *EnvoyExtension) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *EnvoyExtension) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v1alpha1/proxy.pb.go b/proto-public/pbmesh/v1alpha1/proxy.pb.go new file mode 100644 index 0000000000000..b6ef2edf873bd --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/proxy.pb.go @@ -0,0 +1,816 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbmesh/v1alpha1/proxy.proto + +package meshv1alpha1 + +import ( + v1alpha1 "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ProxyMode int32 + +const ( + // ProxyModeDefault represents no specific mode and should + // be used to indicate that a different layer of the configuration + // chain should take precedence + // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX + ProxyMode_PROXY_MODE_DEFAULT ProxyMode = 0 + // ProxyModeTransparent represents that inbound and outbound application + // traffic is being captured and redirected through the proxy. + ProxyMode_PROXY_MODE_TRANSPARENT ProxyMode = 1 + // ProxyModeDirect represents that the proxy's listeners must be dialed directly + // by the local application and other proxies. + ProxyMode_PROXY_MODE_DIRECT ProxyMode = 2 +) + +// Enum value maps for ProxyMode. +var ( + ProxyMode_name = map[int32]string{ + 0: "PROXY_MODE_DEFAULT", + 1: "PROXY_MODE_TRANSPARENT", + 2: "PROXY_MODE_DIRECT", + } + ProxyMode_value = map[string]int32{ + "PROXY_MODE_DEFAULT": 0, + "PROXY_MODE_TRANSPARENT": 1, + "PROXY_MODE_DIRECT": 2, + } +) + +func (x ProxyMode) Enum() *ProxyMode { + p := new(ProxyMode) + *p = x + return p +} + +func (x ProxyMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProxyMode) Descriptor() protoreflect.EnumDescriptor { + return file_pbmesh_v1alpha1_proxy_proto_enumTypes[0].Descriptor() +} + +func (ProxyMode) Type() protoreflect.EnumType { + return &file_pbmesh_v1alpha1_proxy_proto_enumTypes[0] +} + +func (x ProxyMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ProxyMode.Descriptor instead. +func (ProxyMode) EnumDescriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_proxy_proto_rawDescGZIP(), []int{0} +} + +type ProxyConfiguration struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Selection of workloads this proxy configuration should apply to. + // These can be prefixes or specific workload names. + Workloads *v1alpha1.WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` + // dynamic_config is the configuration that could be changed + // dynamically (i.e. without needing restart). + DynamicConfig *DynamicConfig `protobuf:"bytes,2,opt,name=dynamic_config,json=dynamicConfig,proto3" json:"dynamic_config,omitempty"` + // bootstrap_config is the configuration that requires proxies + // to be restarted to be applied. + BootstrapConfig *BootstrapConfig `protobuf:"bytes,3,opt,name=bootstrap_config,json=bootstrapConfig,proto3" json:"bootstrap_config,omitempty"` + // deprecated: prevent usage when using v2 APIs directly. + // needed for backwards compatibility + // + // Deprecated: Marked as deprecated in pbmesh/v1alpha1/proxy.proto. + OpaqueConfig *structpb.Struct `protobuf:"bytes,4,opt,name=opaque_config,json=opaqueConfig,proto3" json:"opaque_config,omitempty"` +} + +func (x *ProxyConfiguration) Reset() { + *x = ProxyConfiguration{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_proxy_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProxyConfiguration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProxyConfiguration) ProtoMessage() {} + +func (x *ProxyConfiguration) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_proxy_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProxyConfiguration.ProtoReflect.Descriptor instead. +func (*ProxyConfiguration) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_proxy_proto_rawDescGZIP(), []int{0} +} + +func (x *ProxyConfiguration) GetWorkloads() *v1alpha1.WorkloadSelector { + if x != nil { + return x.Workloads + } + return nil +} + +func (x *ProxyConfiguration) GetDynamicConfig() *DynamicConfig { + if x != nil { + return x.DynamicConfig + } + return nil +} + +func (x *ProxyConfiguration) GetBootstrapConfig() *BootstrapConfig { + if x != nil { + return x.BootstrapConfig + } + return nil +} + +// Deprecated: Marked as deprecated in pbmesh/v1alpha1/proxy.proto. +func (x *ProxyConfiguration) GetOpaqueConfig() *structpb.Struct { + if x != nil { + return x.OpaqueConfig + } + return nil +} + +type DynamicConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // mode indicates the proxy's mode. This will default to 'transparent'. + Mode ProxyMode `protobuf:"varint,1,opt,name=mode,proto3,enum=hashicorp.consul.mesh.v1alpha1.ProxyMode" json:"mode,omitempty"` + TransparentProxy *TransparentProxy `protobuf:"bytes,2,opt,name=transparent_proxy,json=transparentProxy,proto3" json:"transparent_proxy,omitempty"` + // local_connection is the configuration that should be used + // to connect to the local application provided per-port. + // The map keys should correspond to port names on the workload. + LocalConnection map[string]*ConnectionConfig `protobuf:"bytes,3,rep,name=local_connection,json=localConnection,proto3" json:"local_connection,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // inbound_connections configures inbound connections to the proxy. + InboundConnections *InboundConnectionsConfig `protobuf:"bytes,4,opt,name=inbound_connections,json=inboundConnections,proto3" json:"inbound_connections,omitempty"` + MeshGatewayMode MeshGatewayMode `protobuf:"varint,5,opt,name=mesh_gateway_mode,json=meshGatewayMode,proto3,enum=hashicorp.consul.mesh.v1alpha1.MeshGatewayMode" json:"mesh_gateway_mode,omitempty"` + ExposeConfig *ExposeConfig `protobuf:"bytes,6,opt,name=expose_config,json=exposeConfig,proto3" json:"expose_config,omitempty"` + PublicListenerJson string `protobuf:"bytes,7,opt,name=public_listener_json,json=publicListenerJson,proto3" json:"public_listener_json,omitempty"` + ListenerTracingJson string `protobuf:"bytes,8,opt,name=listener_tracing_json,json=listenerTracingJson,proto3" json:"listener_tracing_json,omitempty"` + LocalClusterJson string `protobuf:"bytes,9,opt,name=local_cluster_json,json=localClusterJson,proto3" json:"local_cluster_json,omitempty"` + // deprecated: + // local_workload_address, local_workload_port, and local_workload_socket_path + // are deprecated and are only needed for migration of existing resources. + // + // Deprecated: Marked as deprecated in pbmesh/v1alpha1/proxy.proto. + LocalWorkloadAddress string `protobuf:"bytes,10,opt,name=local_workload_address,json=localWorkloadAddress,proto3" json:"local_workload_address,omitempty"` + // Deprecated: Marked as deprecated in pbmesh/v1alpha1/proxy.proto. + LocalWorkloadPort uint32 `protobuf:"varint,11,opt,name=local_workload_port,json=localWorkloadPort,proto3" json:"local_workload_port,omitempty"` + // Deprecated: Marked as deprecated in pbmesh/v1alpha1/proxy.proto. + LocalWorkloadSocketPath string `protobuf:"bytes,12,opt,name=local_workload_socket_path,json=localWorkloadSocketPath,proto3" json:"local_workload_socket_path,omitempty"` +} + +func (x *DynamicConfig) Reset() { + *x = DynamicConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_proxy_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DynamicConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DynamicConfig) ProtoMessage() {} + +func (x *DynamicConfig) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_proxy_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DynamicConfig.ProtoReflect.Descriptor instead. +func (*DynamicConfig) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_proxy_proto_rawDescGZIP(), []int{1} +} + +func (x *DynamicConfig) GetMode() ProxyMode { + if x != nil { + return x.Mode + } + return ProxyMode_PROXY_MODE_DEFAULT +} + +func (x *DynamicConfig) GetTransparentProxy() *TransparentProxy { + if x != nil { + return x.TransparentProxy + } + return nil +} + +func (x *DynamicConfig) GetLocalConnection() map[string]*ConnectionConfig { + if x != nil { + return x.LocalConnection + } + return nil +} + +func (x *DynamicConfig) GetInboundConnections() *InboundConnectionsConfig { + if x != nil { + return x.InboundConnections + } + return nil +} + +func (x *DynamicConfig) GetMeshGatewayMode() MeshGatewayMode { + if x != nil { + return x.MeshGatewayMode + } + return MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED +} + +func (x *DynamicConfig) GetExposeConfig() *ExposeConfig { + if x != nil { + return x.ExposeConfig + } + return nil +} + +func (x *DynamicConfig) GetPublicListenerJson() string { + if x != nil { + return x.PublicListenerJson + } + return "" +} + +func (x *DynamicConfig) GetListenerTracingJson() string { + if x != nil { + return x.ListenerTracingJson + } + return "" +} + +func (x *DynamicConfig) GetLocalClusterJson() string { + if x != nil { + return x.LocalClusterJson + } + return "" +} + +// Deprecated: Marked as deprecated in pbmesh/v1alpha1/proxy.proto. +func (x *DynamicConfig) GetLocalWorkloadAddress() string { + if x != nil { + return x.LocalWorkloadAddress + } + return "" +} + +// Deprecated: Marked as deprecated in pbmesh/v1alpha1/proxy.proto. +func (x *DynamicConfig) GetLocalWorkloadPort() uint32 { + if x != nil { + return x.LocalWorkloadPort + } + return 0 +} + +// Deprecated: Marked as deprecated in pbmesh/v1alpha1/proxy.proto. +func (x *DynamicConfig) GetLocalWorkloadSocketPath() string { + if x != nil { + return x.LocalWorkloadSocketPath + } + return "" +} + +type TransparentProxy struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // outbound_listener_port is the port for the proxy's outbound listener. + // This defaults to 15001. + OutboundListenerPort uint32 `protobuf:"varint,1,opt,name=outbound_listener_port,json=outboundListenerPort,proto3" json:"outbound_listener_port,omitempty"` + // dialed_directly indicates whether this proxy should be dialed using original destination IP + // in the connection rather than load balance between all endpoints. + DialedDirectly bool `protobuf:"varint,2,opt,name=dialed_directly,json=dialedDirectly,proto3" json:"dialed_directly,omitempty"` +} + +func (x *TransparentProxy) Reset() { + *x = TransparentProxy{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_proxy_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TransparentProxy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransparentProxy) ProtoMessage() {} + +func (x *TransparentProxy) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_proxy_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransparentProxy.ProtoReflect.Descriptor instead. +func (*TransparentProxy) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_proxy_proto_rawDescGZIP(), []int{2} +} + +func (x *TransparentProxy) GetOutboundListenerPort() uint32 { + if x != nil { + return x.OutboundListenerPort + } + return 0 +} + +func (x *TransparentProxy) GetDialedDirectly() bool { + if x != nil { + return x.DialedDirectly + } + return false +} + +// BootstrapConfig is equivalent to configuration defined +// in our docs. +type BootstrapConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StatsdUrl string `protobuf:"bytes,1,opt,name=statsd_url,json=statsdUrl,proto3" json:"statsd_url,omitempty"` + DogstatsdUrl string `protobuf:"bytes,2,opt,name=dogstatsd_url,json=dogstatsdUrl,proto3" json:"dogstatsd_url,omitempty"` + StatsTags []string `protobuf:"bytes,3,rep,name=stats_tags,json=statsTags,proto3" json:"stats_tags,omitempty"` + PrometheusBindAddr string `protobuf:"bytes,4,opt,name=prometheus_bind_addr,json=prometheusBindAddr,proto3" json:"prometheus_bind_addr,omitempty"` + StatsBindAddr string `protobuf:"bytes,5,opt,name=stats_bind_addr,json=statsBindAddr,proto3" json:"stats_bind_addr,omitempty"` + ReadyBindAddr string `protobuf:"bytes,6,opt,name=ready_bind_addr,json=readyBindAddr,proto3" json:"ready_bind_addr,omitempty"` + OverrideJsonTpl string `protobuf:"bytes,7,opt,name=override_json_tpl,json=overrideJsonTpl,proto3" json:"override_json_tpl,omitempty"` + StaticClustersJson string `protobuf:"bytes,8,opt,name=static_clusters_json,json=staticClustersJson,proto3" json:"static_clusters_json,omitempty"` + StaticListenersJson string `protobuf:"bytes,9,opt,name=static_listeners_json,json=staticListenersJson,proto3" json:"static_listeners_json,omitempty"` + StatsSinksJson string `protobuf:"bytes,10,opt,name=stats_sinks_json,json=statsSinksJson,proto3" json:"stats_sinks_json,omitempty"` + StatsConfigJson string `protobuf:"bytes,11,opt,name=stats_config_json,json=statsConfigJson,proto3" json:"stats_config_json,omitempty"` + StatsFlushInterval string `protobuf:"bytes,12,opt,name=stats_flush_interval,json=statsFlushInterval,proto3" json:"stats_flush_interval,omitempty"` + TracingConfigJson string `protobuf:"bytes,13,opt,name=tracing_config_json,json=tracingConfigJson,proto3" json:"tracing_config_json,omitempty"` +} + +func (x *BootstrapConfig) Reset() { + *x = BootstrapConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_proxy_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BootstrapConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BootstrapConfig) ProtoMessage() {} + +func (x *BootstrapConfig) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_proxy_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BootstrapConfig.ProtoReflect.Descriptor instead. +func (*BootstrapConfig) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_proxy_proto_rawDescGZIP(), []int{3} +} + +func (x *BootstrapConfig) GetStatsdUrl() string { + if x != nil { + return x.StatsdUrl + } + return "" +} + +func (x *BootstrapConfig) GetDogstatsdUrl() string { + if x != nil { + return x.DogstatsdUrl + } + return "" +} + +func (x *BootstrapConfig) GetStatsTags() []string { + if x != nil { + return x.StatsTags + } + return nil +} + +func (x *BootstrapConfig) GetPrometheusBindAddr() string { + if x != nil { + return x.PrometheusBindAddr + } + return "" +} + +func (x *BootstrapConfig) GetStatsBindAddr() string { + if x != nil { + return x.StatsBindAddr + } + return "" +} + +func (x *BootstrapConfig) GetReadyBindAddr() string { + if x != nil { + return x.ReadyBindAddr + } + return "" +} + +func (x *BootstrapConfig) GetOverrideJsonTpl() string { + if x != nil { + return x.OverrideJsonTpl + } + return "" +} + +func (x *BootstrapConfig) GetStaticClustersJson() string { + if x != nil { + return x.StaticClustersJson + } + return "" +} + +func (x *BootstrapConfig) GetStaticListenersJson() string { + if x != nil { + return x.StaticListenersJson + } + return "" +} + +func (x *BootstrapConfig) GetStatsSinksJson() string { + if x != nil { + return x.StatsSinksJson + } + return "" +} + +func (x *BootstrapConfig) GetStatsConfigJson() string { + if x != nil { + return x.StatsConfigJson + } + return "" +} + +func (x *BootstrapConfig) GetStatsFlushInterval() string { + if x != nil { + return x.StatsFlushInterval + } + return "" +} + +func (x *BootstrapConfig) GetTracingConfigJson() string { + if x != nil { + return x.TracingConfigJson + } + return "" +} + +var File_pbmesh_v1alpha1_proxy_proto protoreflect.FileDescriptor + +var file_pbmesh_v1alpha1_proxy_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1c, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21, 0x70, 0x62, 0x63, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, + 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, + 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, + 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdb, 0x02, + 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x54, 0x0a, 0x0e, 0x64, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, + 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5a, 0x0a, + 0x10, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, + 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, + 0x72, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x40, 0x0a, 0x0d, 0x6f, 0x70, 0x61, + 0x71, 0x75, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x6f, + 0x70, 0x61, 0x71, 0x75, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xf0, 0x07, 0x0a, 0x0d, + 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, + 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x5d, 0x0a, 0x11, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x6d, 0x0a, 0x10, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x69, 0x0a, 0x13, 0x69, 0x6e, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x12, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5b, 0x0a, 0x11, 0x6d, 0x65, 0x73, 0x68, 0x5f, 0x67, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, + 0x65, 0x52, 0x0f, 0x6d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, + 0x64, 0x65, 0x12, 0x51, 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, + 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6c, + 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x16, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x14, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x13, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, + 0x42, 0x02, 0x18, 0x01, 0x52, 0x11, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x3f, 0x0a, 0x1a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, + 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, + 0x17, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x1a, 0x74, 0x0a, 0x14, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x71, + 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x14, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x61, 0x6c, + 0x65, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0e, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, + 0x79, 0x22, 0xc0, 0x04, 0x0a, 0x0f, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x5f, + 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x64, 0x55, 0x72, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x6f, 0x67, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, + 0x74, 0x73, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x54, 0x61, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x6d, + 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, + 0x75, 0x73, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, + 0x64, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x62, 0x69, 0x6e, 0x64, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x61, + 0x64, 0x79, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x74, 0x70, 0x6c, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x4a, + 0x73, 0x6f, 0x6e, 0x54, 0x70, 0x6c, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x5f, 0x6a, 0x73, 0x6f, + 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x6b, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x53, 0x69, 0x6e, + 0x6b, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, + 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6c, 0x75, 0x73, + 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, 0x73, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x11, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x4a, 0x73, 0x6f, 0x6e, 0x2a, 0x56, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, + 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, + 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x4f, + 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x50, 0x41, 0x52, + 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x4d, + 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x10, 0x02, 0x42, 0x92, 0x02, 0x0a, + 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x42, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, + 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, + 0x1e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, + 0x02, 0x1e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0xe2, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x21, + 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbmesh_v1alpha1_proxy_proto_rawDescOnce sync.Once + file_pbmesh_v1alpha1_proxy_proto_rawDescData = file_pbmesh_v1alpha1_proxy_proto_rawDesc +) + +func file_pbmesh_v1alpha1_proxy_proto_rawDescGZIP() []byte { + file_pbmesh_v1alpha1_proxy_proto_rawDescOnce.Do(func() { + file_pbmesh_v1alpha1_proxy_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v1alpha1_proxy_proto_rawDescData) + }) + return file_pbmesh_v1alpha1_proxy_proto_rawDescData +} + +var file_pbmesh_v1alpha1_proxy_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_pbmesh_v1alpha1_proxy_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_pbmesh_v1alpha1_proxy_proto_goTypes = []interface{}{ + (ProxyMode)(0), // 0: hashicorp.consul.mesh.v1alpha1.ProxyMode + (*ProxyConfiguration)(nil), // 1: hashicorp.consul.mesh.v1alpha1.ProxyConfiguration + (*DynamicConfig)(nil), // 2: hashicorp.consul.mesh.v1alpha1.DynamicConfig + (*TransparentProxy)(nil), // 3: hashicorp.consul.mesh.v1alpha1.TransparentProxy + (*BootstrapConfig)(nil), // 4: hashicorp.consul.mesh.v1alpha1.BootstrapConfig + nil, // 5: hashicorp.consul.mesh.v1alpha1.DynamicConfig.LocalConnectionEntry + (*v1alpha1.WorkloadSelector)(nil), // 6: hashicorp.consul.catalog.v1alpha1.WorkloadSelector + (*structpb.Struct)(nil), // 7: google.protobuf.Struct + (*InboundConnectionsConfig)(nil), // 8: hashicorp.consul.mesh.v1alpha1.InboundConnectionsConfig + (MeshGatewayMode)(0), // 9: hashicorp.consul.mesh.v1alpha1.MeshGatewayMode + (*ExposeConfig)(nil), // 10: hashicorp.consul.mesh.v1alpha1.ExposeConfig + (*ConnectionConfig)(nil), // 11: hashicorp.consul.mesh.v1alpha1.ConnectionConfig +} +var file_pbmesh_v1alpha1_proxy_proto_depIdxs = []int32{ + 6, // 0: hashicorp.consul.mesh.v1alpha1.ProxyConfiguration.workloads:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadSelector + 2, // 1: hashicorp.consul.mesh.v1alpha1.ProxyConfiguration.dynamic_config:type_name -> hashicorp.consul.mesh.v1alpha1.DynamicConfig + 4, // 2: hashicorp.consul.mesh.v1alpha1.ProxyConfiguration.bootstrap_config:type_name -> hashicorp.consul.mesh.v1alpha1.BootstrapConfig + 7, // 3: hashicorp.consul.mesh.v1alpha1.ProxyConfiguration.opaque_config:type_name -> google.protobuf.Struct + 0, // 4: hashicorp.consul.mesh.v1alpha1.DynamicConfig.mode:type_name -> hashicorp.consul.mesh.v1alpha1.ProxyMode + 3, // 5: hashicorp.consul.mesh.v1alpha1.DynamicConfig.transparent_proxy:type_name -> hashicorp.consul.mesh.v1alpha1.TransparentProxy + 5, // 6: hashicorp.consul.mesh.v1alpha1.DynamicConfig.local_connection:type_name -> hashicorp.consul.mesh.v1alpha1.DynamicConfig.LocalConnectionEntry + 8, // 7: hashicorp.consul.mesh.v1alpha1.DynamicConfig.inbound_connections:type_name -> hashicorp.consul.mesh.v1alpha1.InboundConnectionsConfig + 9, // 8: hashicorp.consul.mesh.v1alpha1.DynamicConfig.mesh_gateway_mode:type_name -> hashicorp.consul.mesh.v1alpha1.MeshGatewayMode + 10, // 9: hashicorp.consul.mesh.v1alpha1.DynamicConfig.expose_config:type_name -> hashicorp.consul.mesh.v1alpha1.ExposeConfig + 11, // 10: hashicorp.consul.mesh.v1alpha1.DynamicConfig.LocalConnectionEntry.value:type_name -> hashicorp.consul.mesh.v1alpha1.ConnectionConfig + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name +} + +func init() { file_pbmesh_v1alpha1_proxy_proto_init() } +func file_pbmesh_v1alpha1_proxy_proto_init() { + if File_pbmesh_v1alpha1_proxy_proto != nil { + return + } + file_pbmesh_v1alpha1_connection_proto_init() + file_pbmesh_v1alpha1_expose_proto_init() + file_pbmesh_v1alpha1_routing_proto_init() + if !protoimpl.UnsafeEnabled { + file_pbmesh_v1alpha1_proxy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProxyConfiguration); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_proxy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DynamicConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_proxy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TransparentProxy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_proxy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BootstrapConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbmesh_v1alpha1_proxy_proto_rawDesc, + NumEnums: 1, + NumMessages: 5, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbmesh_v1alpha1_proxy_proto_goTypes, + DependencyIndexes: file_pbmesh_v1alpha1_proxy_proto_depIdxs, + EnumInfos: file_pbmesh_v1alpha1_proxy_proto_enumTypes, + MessageInfos: file_pbmesh_v1alpha1_proxy_proto_msgTypes, + }.Build() + File_pbmesh_v1alpha1_proxy_proto = out.File + file_pbmesh_v1alpha1_proxy_proto_rawDesc = nil + file_pbmesh_v1alpha1_proxy_proto_goTypes = nil + file_pbmesh_v1alpha1_proxy_proto_depIdxs = nil +} diff --git a/proto-public/pbmesh/v1alpha1/proxy.proto b/proto-public/pbmesh/v1alpha1/proxy.proto new file mode 100644 index 0000000000000..06ebecbf4abac --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/proxy.proto @@ -0,0 +1,104 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +syntax = "proto3"; + +package hashicorp.consul.mesh.v1alpha1; + +import "google/protobuf/struct.proto"; +import "pbcatalog/v1alpha1/selector.proto"; +import "pbmesh/v1alpha1/connection.proto"; +import "pbmesh/v1alpha1/expose.proto"; +import "pbmesh/v1alpha1/routing.proto"; + +message ProxyConfiguration { + // Selection of workloads this proxy configuration should apply to. + // These can be prefixes or specific workload names. + hashicorp.consul.catalog.v1alpha1.WorkloadSelector workloads = 1; + + // dynamic_config is the configuration that could be changed + // dynamically (i.e. without needing restart). + DynamicConfig dynamic_config = 2; + + // bootstrap_config is the configuration that requires proxies + // to be restarted to be applied. + BootstrapConfig bootstrap_config = 3; + + // deprecated: prevent usage when using v2 APIs directly. + // needed for backwards compatibility + google.protobuf.Struct opaque_config = 4 [deprecated = true]; +} + +message DynamicConfig { + // mode indicates the proxy's mode. This will default to 'transparent'. + ProxyMode mode = 1; + + TransparentProxy transparent_proxy = 2; + + // local_connection is the configuration that should be used + // to connect to the local application provided per-port. + // The map keys should correspond to port names on the workload. + map local_connection = 3; + + // inbound_connections configures inbound connections to the proxy. + InboundConnectionsConfig inbound_connections = 4; + + MeshGatewayMode mesh_gateway_mode = 5; + + ExposeConfig expose_config = 6; + + string public_listener_json = 7; + string listener_tracing_json = 8; + string local_cluster_json = 9; + + // deprecated: + // local_workload_address, local_workload_port, and local_workload_socket_path + // are deprecated and are only needed for migration of existing resources. + string local_workload_address = 10 [deprecated = true]; + uint32 local_workload_port = 11 [deprecated = true]; + string local_workload_socket_path = 12 [deprecated = true]; +} + +message TransparentProxy { + // outbound_listener_port is the port for the proxy's outbound listener. + // This defaults to 15001. + uint32 outbound_listener_port = 1; + + // dialed_directly indicates whether this proxy should be dialed using original destination IP + // in the connection rather than load balance between all endpoints. + bool dialed_directly = 2; +} + +// BootstrapConfig is equivalent to configuration defined +// in our docs. +message BootstrapConfig { + string statsd_url = 1; + string dogstatsd_url = 2; + repeated string stats_tags = 3; + string prometheus_bind_addr = 4; + string stats_bind_addr = 5; + string ready_bind_addr = 6; + string override_json_tpl = 7; + string static_clusters_json = 8; + string static_listeners_json = 9; + string stats_sinks_json = 10; + string stats_config_json = 11; + string stats_flush_interval = 12; + string tracing_config_json = 13; +} + +enum ProxyMode { + // ProxyModeDefault represents no specific mode and should + // be used to indicate that a different layer of the configuration + // chain should take precedence + // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX + PROXY_MODE_DEFAULT = 0; + + // ProxyModeTransparent represents that inbound and outbound application + // traffic is being captured and redirected through the proxy. + PROXY_MODE_TRANSPARENT = 1; + + // ProxyModeDirect represents that the proxy's listeners must be dialed directly + // by the local application and other proxies. + PROXY_MODE_DIRECT = 2; +} diff --git a/proto-public/pbmesh/v1alpha1/routing.pb.go b/proto-public/pbmesh/v1alpha1/routing.pb.go new file mode 100644 index 0000000000000..19f6a7d1c1b39 --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/routing.pb.go @@ -0,0 +1,181 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbmesh/v1alpha1/routing.proto + +package meshv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type MeshGatewayMode int32 + +const ( + // MESH_GATEWAY_MODE_UNSPECIFIED represents no specific mode and should be + // used to indicate that a the decision on the mode will be made by other + // configuration or default settings. + MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED MeshGatewayMode = 0 + // MESH_GATEWAY_MODE_NONE is the mode to use when traffic should not be + // routed through any gateway but instead be routed directly to the + // destination. + MeshGatewayMode_MESH_GATEWAY_MODE_NONE MeshGatewayMode = 1 + // MESH_GATEWAY_MODE_LOCAL is the mode to use when traffic should be routed + // to the local gateway. The local gateway will then ensure that the + // connection is proxied correctly to its final destination. This mode will + // most often be needed for workloads that are prevented from making outbound + // requests outside of their local network/environment. In this case a + // gateway will sit at the edge of sit at the edge of the network and will + // proxy outbound connections potentially to other gateways in remote + // environments. + MeshGatewayMode_MESH_GATEWAY_MODE_LOCAL MeshGatewayMode = 2 + // MESH_GATEWAY_MODE_REMOTE is the mode to use when traffic should be routed + // to a remote mesh gateway. This mode will most often be used when workloads + // can make outbound requests destined for a remote network/environment but + // where the remote network/environment will not allow direct addressing. The + // mesh gateway in the remote environment will sit at the edge and proxy + // requests into that environment. + MeshGatewayMode_MESH_GATEWAY_MODE_REMOTE MeshGatewayMode = 3 +) + +// Enum value maps for MeshGatewayMode. +var ( + MeshGatewayMode_name = map[int32]string{ + 0: "MESH_GATEWAY_MODE_UNSPECIFIED", + 1: "MESH_GATEWAY_MODE_NONE", + 2: "MESH_GATEWAY_MODE_LOCAL", + 3: "MESH_GATEWAY_MODE_REMOTE", + } + MeshGatewayMode_value = map[string]int32{ + "MESH_GATEWAY_MODE_UNSPECIFIED": 0, + "MESH_GATEWAY_MODE_NONE": 1, + "MESH_GATEWAY_MODE_LOCAL": 2, + "MESH_GATEWAY_MODE_REMOTE": 3, + } +) + +func (x MeshGatewayMode) Enum() *MeshGatewayMode { + p := new(MeshGatewayMode) + *p = x + return p +} + +func (x MeshGatewayMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MeshGatewayMode) Descriptor() protoreflect.EnumDescriptor { + return file_pbmesh_v1alpha1_routing_proto_enumTypes[0].Descriptor() +} + +func (MeshGatewayMode) Type() protoreflect.EnumType { + return &file_pbmesh_v1alpha1_routing_proto_enumTypes[0] +} + +func (x MeshGatewayMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MeshGatewayMode.Descriptor instead. +func (MeshGatewayMode) EnumDescriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_routing_proto_rawDescGZIP(), []int{0} +} + +var File_pbmesh_v1alpha1_routing_proto protoreflect.FileDescriptor + +var file_pbmesh_v1alpha1_routing_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x1e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2a, + 0x8b, 0x01, 0x0a, 0x0f, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, + 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, 0x45, + 0x57, 0x41, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, + 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, + 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, + 0x41, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x02, 0x12, + 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, + 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x10, 0x03, 0x42, 0x94, 0x02, + 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x42, 0x0c, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, + 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x6d, + 0x65, 0x73, 0x68, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, + 0x4d, 0xaa, 0x02, 0x1e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0xca, 0x02, 0x1e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbmesh_v1alpha1_routing_proto_rawDescOnce sync.Once + file_pbmesh_v1alpha1_routing_proto_rawDescData = file_pbmesh_v1alpha1_routing_proto_rawDesc +) + +func file_pbmesh_v1alpha1_routing_proto_rawDescGZIP() []byte { + file_pbmesh_v1alpha1_routing_proto_rawDescOnce.Do(func() { + file_pbmesh_v1alpha1_routing_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v1alpha1_routing_proto_rawDescData) + }) + return file_pbmesh_v1alpha1_routing_proto_rawDescData +} + +var file_pbmesh_v1alpha1_routing_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_pbmesh_v1alpha1_routing_proto_goTypes = []interface{}{ + (MeshGatewayMode)(0), // 0: hashicorp.consul.mesh.v1alpha1.MeshGatewayMode +} +var file_pbmesh_v1alpha1_routing_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_pbmesh_v1alpha1_routing_proto_init() } +func file_pbmesh_v1alpha1_routing_proto_init() { + if File_pbmesh_v1alpha1_routing_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbmesh_v1alpha1_routing_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbmesh_v1alpha1_routing_proto_goTypes, + DependencyIndexes: file_pbmesh_v1alpha1_routing_proto_depIdxs, + EnumInfos: file_pbmesh_v1alpha1_routing_proto_enumTypes, + }.Build() + File_pbmesh_v1alpha1_routing_proto = out.File + file_pbmesh_v1alpha1_routing_proto_rawDesc = nil + file_pbmesh_v1alpha1_routing_proto_goTypes = nil + file_pbmesh_v1alpha1_routing_proto_depIdxs = nil +} diff --git a/proto-public/pbmesh/v2beta1/routing.proto b/proto-public/pbmesh/v1alpha1/routing.proto similarity index 84% rename from proto-public/pbmesh/v2beta1/routing.proto rename to proto-public/pbmesh/v1alpha1/routing.proto index b09d28a6458ab..d2b1cdd8b0958 100644 --- a/proto-public/pbmesh/v2beta1/routing.proto +++ b/proto-public/pbmesh/v1alpha1/routing.proto @@ -3,13 +3,11 @@ syntax = "proto3"; -package hashicorp.consul.mesh.v2beta1; +package hashicorp.consul.mesh.v1alpha1; -// +kubebuilder:validation:Enum=MESH_GATEWAY_MODE_UNSPECIFIED;MESH_GATEWAY_MODE_NONE;MESH_GATEWAY_MODE_LOCAL;MESH_GATEWAY_MODE_REMOTE -// +kubebuilder:validation:Type=string enum MeshGatewayMode { // MESH_GATEWAY_MODE_UNSPECIFIED represents no specific mode and should be - // used to indicate that the decision on the mode will be made by other + // used to indicate that a the decision on the mode will be made by other // configuration or default settings. MESH_GATEWAY_MODE_UNSPECIFIED = 0; diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/listener.pb.binary.go b/proto-public/pbmesh/v1alpha1/upstreams.pb.binary.go similarity index 59% rename from proto-public/pbmesh/v2beta1/pbproxystate/listener.pb.binary.go rename to proto-public/pbmesh/v1alpha1/upstreams.pb.binary.go index f463b8049c3d8..cc8214e75a687 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/listener.pb.binary.go +++ b/proto-public/pbmesh/v1alpha1/upstreams.pb.binary.go @@ -1,88 +1,88 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/listener.proto +// source: pbmesh/v1alpha1/upstreams.proto -package pbproxystate +package meshv1alpha1 import ( "google.golang.org/protobuf/proto" ) // MarshalBinary implements encoding.BinaryMarshaler -func (msg *Listener) MarshalBinary() ([]byte, error) { +func (msg *Upstreams) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Listener) UnmarshalBinary(b []byte) error { +func (msg *Upstreams) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } // MarshalBinary implements encoding.BinaryMarshaler -func (msg *Router) MarshalBinary() ([]byte, error) { +func (msg *Upstream) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Router) UnmarshalBinary(b []byte) error { +func (msg *Upstream) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } // MarshalBinary implements encoding.BinaryMarshaler -func (msg *Match) MarshalBinary() ([]byte, error) { +func (msg *TCPAddress) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Match) UnmarshalBinary(b []byte) error { +func (msg *TCPAddress) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } // MarshalBinary implements encoding.BinaryMarshaler -func (msg *CidrRange) MarshalBinary() ([]byte, error) { +func (msg *UnixSocketAddress) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *CidrRange) UnmarshalBinary(b []byte) error { +func (msg *UnixSocketAddress) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } // MarshalBinary implements encoding.BinaryMarshaler -func (msg *L4Destination) MarshalBinary() ([]byte, error) { +func (msg *PreparedQueryUpstream) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *L4Destination) UnmarshalBinary(b []byte) error { +func (msg *PreparedQueryUpstream) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } // MarshalBinary implements encoding.BinaryMarshaler -func (msg *L7DestinationRoute) MarshalBinary() ([]byte, error) { +func (msg *UpstreamConfig) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *L7DestinationRoute) UnmarshalBinary(b []byte) error { +func (msg *UpstreamConfig) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } // MarshalBinary implements encoding.BinaryMarshaler -func (msg *L7Destination) MarshalBinary() ([]byte, error) { +func (msg *UpstreamLimits) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *L7Destination) UnmarshalBinary(b []byte) error { +func (msg *UpstreamLimits) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } // MarshalBinary implements encoding.BinaryMarshaler -func (msg *SNIDestination) MarshalBinary() ([]byte, error) { +func (msg *PassiveHealthCheck) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) } // UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *SNIDestination) UnmarshalBinary(b []byte) error { +func (msg *PassiveHealthCheck) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } diff --git a/proto-public/pbmesh/v1alpha1/upstreams.pb.go b/proto-public/pbmesh/v1alpha1/upstreams.pb.go new file mode 100644 index 0000000000000..575fe43006e46 --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/upstreams.pb.go @@ -0,0 +1,997 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbmesh/v1alpha1/upstreams.proto + +package meshv1alpha1 + +import ( + v1alpha1 "github.com/hashicorp/consul/proto-public/pbcatalog/v1alpha1" + pbresource "github.com/hashicorp/consul/proto-public/pbresource" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Upstreams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Selection of workloads these upstreams should apply to. + // These can be prefixes or specific workload names. + Workloads *v1alpha1.WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` + Upstreams []*Upstream `protobuf:"bytes,2,rep,name=upstreams,proto3" json:"upstreams,omitempty"` + PqUpstreams []*PreparedQueryUpstream `protobuf:"bytes,3,rep,name=pq_upstreams,json=pqUpstreams,proto3" json:"pq_upstreams,omitempty"` + UpstreamConfig *UpstreamConfig `protobuf:"bytes,4,opt,name=upstream_config,json=upstreamConfig,proto3" json:"upstream_config,omitempty"` +} + +func (x *Upstreams) Reset() { + *x = Upstreams{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Upstreams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upstreams) ProtoMessage() {} + +func (x *Upstreams) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upstreams.ProtoReflect.Descriptor instead. +func (*Upstreams) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP(), []int{0} +} + +func (x *Upstreams) GetWorkloads() *v1alpha1.WorkloadSelector { + if x != nil { + return x.Workloads + } + return nil +} + +func (x *Upstreams) GetUpstreams() []*Upstream { + if x != nil { + return x.Upstreams + } + return nil +} + +func (x *Upstreams) GetPqUpstreams() []*PreparedQueryUpstream { + if x != nil { + return x.PqUpstreams + } + return nil +} + +func (x *Upstreams) GetUpstreamConfig() *UpstreamConfig { + if x != nil { + return x.UpstreamConfig + } + return nil +} + +type Upstream struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DestinationRef *pbresource.ID `protobuf:"bytes,1,opt,name=destination_ref,json=destinationRef,proto3" json:"destination_ref,omitempty"` + DestinationPort string `protobuf:"bytes,2,opt,name=destination_port,json=destinationPort,proto3" json:"destination_port,omitempty"` + Datacenter string `protobuf:"bytes,3,opt,name=datacenter,proto3" json:"datacenter,omitempty"` + // Types that are assignable to ListenAddr: + // + // *Upstream_Tcp + // *Upstream_Unix + ListenAddr isUpstream_ListenAddr `protobuf_oneof:"listen_addr"` + UpstreamConfig *UpstreamConfig `protobuf:"bytes,7,opt,name=upstream_config,json=upstreamConfig,proto3" json:"upstream_config,omitempty"` +} + +func (x *Upstream) Reset() { + *x = Upstream{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Upstream) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upstream) ProtoMessage() {} + +func (x *Upstream) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upstream.ProtoReflect.Descriptor instead. +func (*Upstream) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP(), []int{1} +} + +func (x *Upstream) GetDestinationRef() *pbresource.ID { + if x != nil { + return x.DestinationRef + } + return nil +} + +func (x *Upstream) GetDestinationPort() string { + if x != nil { + return x.DestinationPort + } + return "" +} + +func (x *Upstream) GetDatacenter() string { + if x != nil { + return x.Datacenter + } + return "" +} + +func (m *Upstream) GetListenAddr() isUpstream_ListenAddr { + if m != nil { + return m.ListenAddr + } + return nil +} + +func (x *Upstream) GetTcp() *TCPAddress { + if x, ok := x.GetListenAddr().(*Upstream_Tcp); ok { + return x.Tcp + } + return nil +} + +func (x *Upstream) GetUnix() *UnixSocketAddress { + if x, ok := x.GetListenAddr().(*Upstream_Unix); ok { + return x.Unix + } + return nil +} + +func (x *Upstream) GetUpstreamConfig() *UpstreamConfig { + if x != nil { + return x.UpstreamConfig + } + return nil +} + +type isUpstream_ListenAddr interface { + isUpstream_ListenAddr() +} + +type Upstream_Tcp struct { + Tcp *TCPAddress `protobuf:"bytes,4,opt,name=tcp,proto3,oneof"` +} + +type Upstream_Unix struct { + Unix *UnixSocketAddress `protobuf:"bytes,5,opt,name=unix,proto3,oneof"` +} + +func (*Upstream_Tcp) isUpstream_ListenAddr() {} + +func (*Upstream_Unix) isUpstream_ListenAddr() {} + +type TCPAddress struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` + Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` +} + +func (x *TCPAddress) Reset() { + *x = TCPAddress{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TCPAddress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TCPAddress) ProtoMessage() {} + +func (x *TCPAddress) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TCPAddress.ProtoReflect.Descriptor instead. +func (*TCPAddress) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP(), []int{2} +} + +func (x *TCPAddress) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *TCPAddress) GetPort() uint32 { + if x != nil { + return x.Port + } + return 0 +} + +type UnixSocketAddress struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + Mode string `protobuf:"bytes,2,opt,name=mode,proto3" json:"mode,omitempty"` +} + +func (x *UnixSocketAddress) Reset() { + *x = UnixSocketAddress{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnixSocketAddress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnixSocketAddress) ProtoMessage() {} + +func (x *UnixSocketAddress) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnixSocketAddress.ProtoReflect.Descriptor instead. +func (*UnixSocketAddress) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP(), []int{3} +} + +func (x *UnixSocketAddress) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *UnixSocketAddress) GetMode() string { + if x != nil { + return x.Mode + } + return "" +} + +type PreparedQueryUpstream struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Datacenter string `protobuf:"bytes,2,opt,name=datacenter,proto3" json:"datacenter,omitempty"` + // Types that are assignable to ListenAddr: + // + // *PreparedQueryUpstream_Tcp + // *PreparedQueryUpstream_Unix + ListenAddr isPreparedQueryUpstream_ListenAddr `protobuf_oneof:"listen_addr"` + UpstreamConfig *UpstreamConfig `protobuf:"bytes,6,opt,name=upstream_config,json=upstreamConfig,proto3" json:"upstream_config,omitempty"` +} + +func (x *PreparedQueryUpstream) Reset() { + *x = PreparedQueryUpstream{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PreparedQueryUpstream) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreparedQueryUpstream) ProtoMessage() {} + +func (x *PreparedQueryUpstream) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PreparedQueryUpstream.ProtoReflect.Descriptor instead. +func (*PreparedQueryUpstream) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP(), []int{4} +} + +func (x *PreparedQueryUpstream) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PreparedQueryUpstream) GetDatacenter() string { + if x != nil { + return x.Datacenter + } + return "" +} + +func (m *PreparedQueryUpstream) GetListenAddr() isPreparedQueryUpstream_ListenAddr { + if m != nil { + return m.ListenAddr + } + return nil +} + +func (x *PreparedQueryUpstream) GetTcp() *TCPAddress { + if x, ok := x.GetListenAddr().(*PreparedQueryUpstream_Tcp); ok { + return x.Tcp + } + return nil +} + +func (x *PreparedQueryUpstream) GetUnix() *UnixSocketAddress { + if x, ok := x.GetListenAddr().(*PreparedQueryUpstream_Unix); ok { + return x.Unix + } + return nil +} + +func (x *PreparedQueryUpstream) GetUpstreamConfig() *UpstreamConfig { + if x != nil { + return x.UpstreamConfig + } + return nil +} + +type isPreparedQueryUpstream_ListenAddr interface { + isPreparedQueryUpstream_ListenAddr() +} + +type PreparedQueryUpstream_Tcp struct { + Tcp *TCPAddress `protobuf:"bytes,4,opt,name=tcp,proto3,oneof"` +} + +type PreparedQueryUpstream_Unix struct { + Unix *UnixSocketAddress `protobuf:"bytes,5,opt,name=unix,proto3,oneof"` +} + +func (*PreparedQueryUpstream_Tcp) isPreparedQueryUpstream_ListenAddr() {} + +func (*PreparedQueryUpstream_Unix) isPreparedQueryUpstream_ListenAddr() {} + +type UpstreamConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ConnectTimeoutMs uint64 `protobuf:"varint,2,opt,name=connect_timeout_ms,json=connectTimeoutMs,proto3" json:"connect_timeout_ms,omitempty"` + Limits *UpstreamLimits `protobuf:"bytes,3,opt,name=limits,proto3" json:"limits,omitempty"` + PassiveHealthCheck *PassiveHealthCheck `protobuf:"bytes,4,opt,name=passive_health_check,json=passiveHealthCheck,proto3" json:"passive_health_check,omitempty"` + BalanceInboundConnections BalanceInboundConnections `protobuf:"varint,5,opt,name=balance_inbound_connections,json=balanceInboundConnections,proto3,enum=hashicorp.consul.mesh.v1alpha1.BalanceInboundConnections" json:"balance_inbound_connections,omitempty"` + MeshGatewayMode MeshGatewayMode `protobuf:"varint,6,opt,name=mesh_gateway_mode,json=meshGatewayMode,proto3,enum=hashicorp.consul.mesh.v1alpha1.MeshGatewayMode" json:"mesh_gateway_mode,omitempty"` +} + +func (x *UpstreamConfig) Reset() { + *x = UpstreamConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamConfig) ProtoMessage() {} + +func (x *UpstreamConfig) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamConfig.ProtoReflect.Descriptor instead. +func (*UpstreamConfig) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP(), []int{5} +} + +func (x *UpstreamConfig) GetConnectTimeoutMs() uint64 { + if x != nil { + return x.ConnectTimeoutMs + } + return 0 +} + +func (x *UpstreamConfig) GetLimits() *UpstreamLimits { + if x != nil { + return x.Limits + } + return nil +} + +func (x *UpstreamConfig) GetPassiveHealthCheck() *PassiveHealthCheck { + if x != nil { + return x.PassiveHealthCheck + } + return nil +} + +func (x *UpstreamConfig) GetBalanceInboundConnections() BalanceInboundConnections { + if x != nil { + return x.BalanceInboundConnections + } + return BalanceInboundConnections_BALANCE_INBOUND_CONNECTIONS_DEFAULT +} + +func (x *UpstreamConfig) GetMeshGatewayMode() MeshGatewayMode { + if x != nil { + return x.MeshGatewayMode + } + return MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED +} + +// UpstreamLimits describes the limits that are associated with a specific +// upstream of a service instance. +type UpstreamLimits struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // MaxConnections is the maximum number of connections the local proxy can + // make to the upstream service. + MaxConnections int32 `protobuf:"varint,1,opt,name=max_connections,json=maxConnections,proto3" json:"max_connections,omitempty"` + // MaxPendingRequests is the maximum number of requests that will be queued + // waiting for an available connection. This is mostly applicable to HTTP/1.1 + // clusters since all HTTP/2 requests are streamed over a single + // connection. + MaxPendingRequests int32 `protobuf:"varint,2,opt,name=max_pending_requests,json=maxPendingRequests,proto3" json:"max_pending_requests,omitempty"` + // MaxConcurrentRequests is the maximum number of in-flight requests that will be allowed + // to the upstream cluster at a point in time. This is mostly applicable to HTTP/2 + // clusters since all HTTP/1.1 requests are limited by MaxConnections. + MaxConcurrentRequests int32 `protobuf:"varint,3,opt,name=max_concurrent_requests,json=maxConcurrentRequests,proto3" json:"max_concurrent_requests,omitempty"` +} + +func (x *UpstreamLimits) Reset() { + *x = UpstreamLimits{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpstreamLimits) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpstreamLimits) ProtoMessage() {} + +func (x *UpstreamLimits) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpstreamLimits.ProtoReflect.Descriptor instead. +func (*UpstreamLimits) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP(), []int{6} +} + +func (x *UpstreamLimits) GetMaxConnections() int32 { + if x != nil { + return x.MaxConnections + } + return 0 +} + +func (x *UpstreamLimits) GetMaxPendingRequests() int32 { + if x != nil { + return x.MaxPendingRequests + } + return 0 +} + +func (x *UpstreamLimits) GetMaxConcurrentRequests() int32 { + if x != nil { + return x.MaxConcurrentRequests + } + return 0 +} + +type PassiveHealthCheck struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Interval between health check analysis sweeps. Each sweep may remove + // hosts or return hosts to the pool. + Interval *durationpb.Duration `protobuf:"bytes,1,opt,name=interval,proto3" json:"interval,omitempty"` + // MaxFailures is the count of consecutive failures that results in a host + // being removed from the pool. + MaxFailures uint32 `protobuf:"varint,2,opt,name=max_failures,json=maxFailures,proto3" json:"max_failures,omitempty"` + // EnforcingConsecutive5xx is the % chance that a host will be actually ejected + // when an outlier status is detected through consecutive 5xx. + // This setting can be used to disable ejection or to ramp it up slowly. Defaults to 100. + EnforcingConsecutive_5Xx uint32 `protobuf:"varint,3,opt,name=enforcing_consecutive_5xx,json=enforcingConsecutive5xx,proto3" json:"enforcing_consecutive_5xx,omitempty"` +} + +func (x *PassiveHealthCheck) Reset() { + *x = PassiveHealthCheck{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PassiveHealthCheck) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PassiveHealthCheck) ProtoMessage() {} + +func (x *PassiveHealthCheck) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v1alpha1_upstreams_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PassiveHealthCheck.ProtoReflect.Descriptor instead. +func (*PassiveHealthCheck) Descriptor() ([]byte, []int) { + return file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP(), []int{7} +} + +func (x *PassiveHealthCheck) GetInterval() *durationpb.Duration { + if x != nil { + return x.Interval + } + return nil +} + +func (x *PassiveHealthCheck) GetMaxFailures() uint32 { + if x != nil { + return x.MaxFailures + } + return 0 +} + +func (x *PassiveHealthCheck) GetEnforcingConsecutive_5Xx() uint32 { + if x != nil { + return x.EnforcingConsecutive_5Xx + } + return 0 +} + +var File_pbmesh_v1alpha1_upstreams_proto protoreflect.FileDescriptor + +var file_pbmesh_v1alpha1_upstreams_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2f, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x1e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x21, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xd9, 0x02, 0x0a, 0x09, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x51, + 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, + 0x73, 0x12, 0x46, 0x0a, 0x09, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x09, + 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x58, 0x0a, 0x0c, 0x70, 0x71, 0x5f, + 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x0b, 0x70, 0x71, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x73, 0x12, 0x57, 0x0a, 0x0f, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x75, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x8e, 0x03, 0x0a, + 0x08, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x46, 0x0a, 0x0f, 0x64, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x49, + 0x44, 0x52, 0x0e, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x66, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, + 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x03, + 0x74, 0x63, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x43, 0x50, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x47, 0x0a, 0x04, + 0x75, 0x6e, 0x69, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, + 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x69, 0x78, + 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, + 0x04, 0x75, 0x6e, 0x69, 0x78, 0x12, 0x57, 0x0a, 0x0f, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, + 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x0d, + 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x22, 0x30, 0x0a, + 0x0a, 0x54, 0x43, 0x50, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, + 0x3b, 0x0a, 0x11, 0x55, 0x6e, 0x69, 0x78, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xbc, 0x02, 0x0a, + 0x15, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, + 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x03, 0x74, 0x63, + 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x54, 0x43, 0x50, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x47, 0x0a, 0x04, 0x75, 0x6e, + 0x69, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x69, 0x78, 0x53, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x04, 0x75, + 0x6e, 0x69, 0x78, 0x12, 0x57, 0x0a, 0x0f, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x75, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x0d, 0x0a, 0x0b, + 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x22, 0xc4, 0x03, 0x0a, 0x0e, + 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2c, + 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x46, 0x0a, 0x06, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x06, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x73, 0x12, 0x64, 0x0a, 0x14, 0x70, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x5f, + 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x12, 0x70, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x79, 0x0a, 0x1b, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5b, 0x0a, 0x11, 0x6d, 0x65, 0x73, 0x68, 0x5f, 0x67, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, + 0x65, 0x52, 0x0f, 0x6d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, + 0x64, 0x65, 0x22, 0xa3, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, + 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, + 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x6d, 0x61, + 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, + 0x12, 0x36, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0xaa, 0x01, 0x0a, 0x12, 0x50, 0x61, 0x73, + 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, + 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x61, + 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x61, + 0x78, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x65, 0x6e, 0x66, + 0x6f, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x35, 0x78, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x65, 0x6e, + 0x66, 0x6f, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x76, 0x65, 0x35, 0x78, 0x78, 0x42, 0x96, 0x02, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0e, 0x55, 0x70, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1e, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, + 0x65, 0x73, 0x68, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x1e, 0x48, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, + 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2a, + 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x21, 0x48, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, + 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbmesh_v1alpha1_upstreams_proto_rawDescOnce sync.Once + file_pbmesh_v1alpha1_upstreams_proto_rawDescData = file_pbmesh_v1alpha1_upstreams_proto_rawDesc +) + +func file_pbmesh_v1alpha1_upstreams_proto_rawDescGZIP() []byte { + file_pbmesh_v1alpha1_upstreams_proto_rawDescOnce.Do(func() { + file_pbmesh_v1alpha1_upstreams_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v1alpha1_upstreams_proto_rawDescData) + }) + return file_pbmesh_v1alpha1_upstreams_proto_rawDescData +} + +var file_pbmesh_v1alpha1_upstreams_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_pbmesh_v1alpha1_upstreams_proto_goTypes = []interface{}{ + (*Upstreams)(nil), // 0: hashicorp.consul.mesh.v1alpha1.Upstreams + (*Upstream)(nil), // 1: hashicorp.consul.mesh.v1alpha1.Upstream + (*TCPAddress)(nil), // 2: hashicorp.consul.mesh.v1alpha1.TCPAddress + (*UnixSocketAddress)(nil), // 3: hashicorp.consul.mesh.v1alpha1.UnixSocketAddress + (*PreparedQueryUpstream)(nil), // 4: hashicorp.consul.mesh.v1alpha1.PreparedQueryUpstream + (*UpstreamConfig)(nil), // 5: hashicorp.consul.mesh.v1alpha1.UpstreamConfig + (*UpstreamLimits)(nil), // 6: hashicorp.consul.mesh.v1alpha1.UpstreamLimits + (*PassiveHealthCheck)(nil), // 7: hashicorp.consul.mesh.v1alpha1.PassiveHealthCheck + (*v1alpha1.WorkloadSelector)(nil), // 8: hashicorp.consul.catalog.v1alpha1.WorkloadSelector + (*pbresource.ID)(nil), // 9: hashicorp.consul.resource.ID + (BalanceInboundConnections)(0), // 10: hashicorp.consul.mesh.v1alpha1.BalanceInboundConnections + (MeshGatewayMode)(0), // 11: hashicorp.consul.mesh.v1alpha1.MeshGatewayMode + (*durationpb.Duration)(nil), // 12: google.protobuf.Duration +} +var file_pbmesh_v1alpha1_upstreams_proto_depIdxs = []int32{ + 8, // 0: hashicorp.consul.mesh.v1alpha1.Upstreams.workloads:type_name -> hashicorp.consul.catalog.v1alpha1.WorkloadSelector + 1, // 1: hashicorp.consul.mesh.v1alpha1.Upstreams.upstreams:type_name -> hashicorp.consul.mesh.v1alpha1.Upstream + 4, // 2: hashicorp.consul.mesh.v1alpha1.Upstreams.pq_upstreams:type_name -> hashicorp.consul.mesh.v1alpha1.PreparedQueryUpstream + 5, // 3: hashicorp.consul.mesh.v1alpha1.Upstreams.upstream_config:type_name -> hashicorp.consul.mesh.v1alpha1.UpstreamConfig + 9, // 4: hashicorp.consul.mesh.v1alpha1.Upstream.destination_ref:type_name -> hashicorp.consul.resource.ID + 2, // 5: hashicorp.consul.mesh.v1alpha1.Upstream.tcp:type_name -> hashicorp.consul.mesh.v1alpha1.TCPAddress + 3, // 6: hashicorp.consul.mesh.v1alpha1.Upstream.unix:type_name -> hashicorp.consul.mesh.v1alpha1.UnixSocketAddress + 5, // 7: hashicorp.consul.mesh.v1alpha1.Upstream.upstream_config:type_name -> hashicorp.consul.mesh.v1alpha1.UpstreamConfig + 2, // 8: hashicorp.consul.mesh.v1alpha1.PreparedQueryUpstream.tcp:type_name -> hashicorp.consul.mesh.v1alpha1.TCPAddress + 3, // 9: hashicorp.consul.mesh.v1alpha1.PreparedQueryUpstream.unix:type_name -> hashicorp.consul.mesh.v1alpha1.UnixSocketAddress + 5, // 10: hashicorp.consul.mesh.v1alpha1.PreparedQueryUpstream.upstream_config:type_name -> hashicorp.consul.mesh.v1alpha1.UpstreamConfig + 6, // 11: hashicorp.consul.mesh.v1alpha1.UpstreamConfig.limits:type_name -> hashicorp.consul.mesh.v1alpha1.UpstreamLimits + 7, // 12: hashicorp.consul.mesh.v1alpha1.UpstreamConfig.passive_health_check:type_name -> hashicorp.consul.mesh.v1alpha1.PassiveHealthCheck + 10, // 13: hashicorp.consul.mesh.v1alpha1.UpstreamConfig.balance_inbound_connections:type_name -> hashicorp.consul.mesh.v1alpha1.BalanceInboundConnections + 11, // 14: hashicorp.consul.mesh.v1alpha1.UpstreamConfig.mesh_gateway_mode:type_name -> hashicorp.consul.mesh.v1alpha1.MeshGatewayMode + 12, // 15: hashicorp.consul.mesh.v1alpha1.PassiveHealthCheck.interval:type_name -> google.protobuf.Duration + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name +} + +func init() { file_pbmesh_v1alpha1_upstreams_proto_init() } +func file_pbmesh_v1alpha1_upstreams_proto_init() { + if File_pbmesh_v1alpha1_upstreams_proto != nil { + return + } + file_pbmesh_v1alpha1_connection_proto_init() + file_pbmesh_v1alpha1_routing_proto_init() + if !protoimpl.UnsafeEnabled { + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Upstreams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Upstream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TCPAddress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnixSocketAddress); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PreparedQueryUpstream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpstreamLimits); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PassiveHealthCheck); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*Upstream_Tcp)(nil), + (*Upstream_Unix)(nil), + } + file_pbmesh_v1alpha1_upstreams_proto_msgTypes[4].OneofWrappers = []interface{}{ + (*PreparedQueryUpstream_Tcp)(nil), + (*PreparedQueryUpstream_Unix)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbmesh_v1alpha1_upstreams_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbmesh_v1alpha1_upstreams_proto_goTypes, + DependencyIndexes: file_pbmesh_v1alpha1_upstreams_proto_depIdxs, + MessageInfos: file_pbmesh_v1alpha1_upstreams_proto_msgTypes, + }.Build() + File_pbmesh_v1alpha1_upstreams_proto = out.File + file_pbmesh_v1alpha1_upstreams_proto_rawDesc = nil + file_pbmesh_v1alpha1_upstreams_proto_goTypes = nil + file_pbmesh_v1alpha1_upstreams_proto_depIdxs = nil +} diff --git a/proto-public/pbmesh/v1alpha1/upstreams.proto b/proto-public/pbmesh/v1alpha1/upstreams.proto new file mode 100644 index 0000000000000..9239bac774b8e --- /dev/null +++ b/proto-public/pbmesh/v1alpha1/upstreams.proto @@ -0,0 +1,100 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +syntax = "proto3"; + +package hashicorp.consul.mesh.v1alpha1; + +import "google/protobuf/duration.proto"; +import "pbcatalog/v1alpha1/selector.proto"; +import "pbmesh/v1alpha1/connection.proto"; +import "pbmesh/v1alpha1/routing.proto"; +import "pbresource/resource.proto"; + +message Upstreams { + // Selection of workloads these upstreams should apply to. + // These can be prefixes or specific workload names. + hashicorp.consul.catalog.v1alpha1.WorkloadSelector workloads = 1; + + repeated Upstream upstreams = 2; + repeated PreparedQueryUpstream pq_upstreams = 3; + + UpstreamConfig upstream_config = 4; +} + +message Upstream { + hashicorp.consul.resource.ID destination_ref = 1; + string destination_port = 2; + string datacenter = 3; + + oneof listen_addr { + TCPAddress tcp = 4; + UnixSocketAddress unix = 5; + } + + UpstreamConfig upstream_config = 7; +} + +message TCPAddress { + string ip = 1; + uint32 port = 2; +} + +message UnixSocketAddress { + string path = 1; + string mode = 2; +} + +message PreparedQueryUpstream { + string name = 1; + string datacenter = 2; + + oneof listen_addr { + TCPAddress tcp = 4; + UnixSocketAddress unix = 5; + } + + UpstreamConfig upstream_config = 6; +} + +message UpstreamConfig { + uint64 connect_timeout_ms = 2; + UpstreamLimits limits = 3; + PassiveHealthCheck passive_health_check = 4; + BalanceInboundConnections balance_inbound_connections = 5; + MeshGatewayMode mesh_gateway_mode = 6; +} + +// UpstreamLimits describes the limits that are associated with a specific +// upstream of a service instance. +message UpstreamLimits { + // MaxConnections is the maximum number of connections the local proxy can + // make to the upstream service. + int32 max_connections = 1; + + // MaxPendingRequests is the maximum number of requests that will be queued + // waiting for an available connection. This is mostly applicable to HTTP/1.1 + // clusters since all HTTP/2 requests are streamed over a single + // connection. + int32 max_pending_requests = 2; + + // MaxConcurrentRequests is the maximum number of in-flight requests that will be allowed + // to the upstream cluster at a point in time. This is mostly applicable to HTTP/2 + // clusters since all HTTP/1.1 requests are limited by MaxConnections. + int32 max_concurrent_requests = 3; +} + +message PassiveHealthCheck { + // Interval between health check analysis sweeps. Each sweep may remove + // hosts or return hosts to the pool. + google.protobuf.Duration interval = 1; + + // MaxFailures is the count of consecutive failures that results in a host + // being removed from the pool. + uint32 max_failures = 2; + + // EnforcingConsecutive5xx is the % chance that a host will be actually ejected + // when an outlier status is detected through consecutive 5xx. + // This setting can be used to disable ejection or to ramp it up slowly. Defaults to 100. + uint32 enforcing_consecutive_5xx = 3; +} diff --git a/proto-public/pbmesh/v2beta1/common.pb.binary.go b/proto-public/pbmesh/v2beta1/common.pb.binary.go deleted file mode 100644 index eb62aa3358e3b..0000000000000 --- a/proto-public/pbmesh/v2beta1/common.pb.binary.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/common.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ParentReference) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ParentReference) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *BackendReference) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *BackendReference) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/common.pb.go b/proto-public/pbmesh/v2beta1/common.pb.go deleted file mode 100644 index c960d7c923884..0000000000000 --- a/proto-public/pbmesh/v2beta1/common.pb.go +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/common.proto - -package meshv2beta1 - -import ( - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// NOTE: roughly equivalent to structs.ResourceReference -type ParentReference struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // For east/west configuration, this should point to a Service. - // For north/south it should point to a Gateway. - Ref *pbresource.Reference `protobuf:"bytes,1,opt,name=ref,proto3" json:"ref,omitempty"` - // For east/west this is the name of the Consul Service port to direct traffic to - // or empty to imply all. - // For north/south this is TBD. - Port string `protobuf:"bytes,2,opt,name=port,proto3" json:"port,omitempty"` -} - -func (x *ParentReference) Reset() { - *x = ParentReference{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_common_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ParentReference) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ParentReference) ProtoMessage() {} - -func (x *ParentReference) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_common_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ParentReference.ProtoReflect.Descriptor instead. -func (*ParentReference) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_common_proto_rawDescGZIP(), []int{0} -} - -func (x *ParentReference) GetRef() *pbresource.Reference { - if x != nil { - return x.Ref - } - return nil -} - -func (x *ParentReference) GetPort() string { - if x != nil { - return x.Port - } - return "" -} - -type BackendReference struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // For east/west configuration, this should point to a Service. - Ref *pbresource.Reference `protobuf:"bytes,1,opt,name=ref,proto3" json:"ref,omitempty"` - // For east/west this is the name of the Consul Service port to direct traffic to - // or empty to imply using the same value as the parent ref. - // - // For north/south this is TBD. - Port string `protobuf:"bytes,2,opt,name=port,proto3" json:"port,omitempty"` - Datacenter string `protobuf:"bytes,3,opt,name=datacenter,proto3" json:"datacenter,omitempty"` -} - -func (x *BackendReference) Reset() { - *x = BackendReference{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_common_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BackendReference) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BackendReference) ProtoMessage() {} - -func (x *BackendReference) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_common_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use BackendReference.ProtoReflect.Descriptor instead. -func (*BackendReference) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_common_proto_rawDescGZIP(), []int{1} -} - -func (x *BackendReference) GetRef() *pbresource.Reference { - if x != nil { - return x.Ref - } - return nil -} - -func (x *BackendReference) GetPort() string { - if x != nil { - return x.Port - } - return "" -} - -func (x *BackendReference) GetDatacenter() string { - if x != nil { - return x.Datacenter - } - return "" -} - -var File_pbmesh_v2beta1_common_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_common_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x19, 0x70, 0x62, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x03, 0x72, 0x65, - 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x03, 0x72, - 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x7e, 0x0a, 0x10, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, - 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x03, 0x72, 0x65, - 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x03, 0x72, - 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, - 0x6e, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, - 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x42, 0x8c, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0b, 0x43, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_common_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_common_proto_rawDescData = file_pbmesh_v2beta1_common_proto_rawDesc -) - -func file_pbmesh_v2beta1_common_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_common_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_common_proto_rawDescData) - }) - return file_pbmesh_v2beta1_common_proto_rawDescData -} - -var file_pbmesh_v2beta1_common_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbmesh_v2beta1_common_proto_goTypes = []interface{}{ - (*ParentReference)(nil), // 0: hashicorp.consul.mesh.v2beta1.ParentReference - (*BackendReference)(nil), // 1: hashicorp.consul.mesh.v2beta1.BackendReference - (*pbresource.Reference)(nil), // 2: hashicorp.consul.resource.Reference -} -var file_pbmesh_v2beta1_common_proto_depIdxs = []int32{ - 2, // 0: hashicorp.consul.mesh.v2beta1.ParentReference.ref:type_name -> hashicorp.consul.resource.Reference - 2, // 1: hashicorp.consul.mesh.v2beta1.BackendReference.ref:type_name -> hashicorp.consul.resource.Reference - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_common_proto_init() } -func file_pbmesh_v2beta1_common_proto_init() { - if File_pbmesh_v2beta1_common_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParentReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BackendReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_common_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_common_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_common_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_common_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_common_proto = out.File - file_pbmesh_v2beta1_common_proto_rawDesc = nil - file_pbmesh_v2beta1_common_proto_goTypes = nil - file_pbmesh_v2beta1_common_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/common.proto b/proto-public/pbmesh/v2beta1/common.proto deleted file mode 100644 index 02ab5de3400d8..0000000000000 --- a/proto-public/pbmesh/v2beta1/common.proto +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbresource/resource.proto"; - -// NOTE: roughly equivalent to structs.ResourceReference -message ParentReference { - // For east/west configuration, this should point to a Service. - // For north/south it should point to a Gateway. - hashicorp.consul.resource.Reference ref = 1; - - // For east/west this is the name of the Consul Service port to direct traffic to - // or empty to imply all. - // For north/south this is TBD. - string port = 2; -} - -message BackendReference { - // For east/west configuration, this should point to a Service. - hashicorp.consul.resource.Reference ref = 1; - - // For east/west this is the name of the Consul Service port to direct traffic to - // or empty to imply using the same value as the parent ref. - // - // For north/south this is TBD. - string port = 2; - string datacenter = 3; -} diff --git a/proto-public/pbmesh/v2beta1/common_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/common_deepcopy.gen.go deleted file mode 100644 index f9aa662c4182b..0000000000000 --- a/proto-public/pbmesh/v2beta1/common_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ParentReference within kubernetes types, where deepcopy-gen is used. -func (in *ParentReference) DeepCopyInto(out *ParentReference) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentReference. Required by controller-gen. -func (in *ParentReference) DeepCopy() *ParentReference { - if in == nil { - return nil - } - out := new(ParentReference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ParentReference. Required by controller-gen. -func (in *ParentReference) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using BackendReference within kubernetes types, where deepcopy-gen is used. -func (in *BackendReference) DeepCopyInto(out *BackendReference) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendReference. Required by controller-gen. -func (in *BackendReference) DeepCopy() *BackendReference { - if in == nil { - return nil - } - out := new(BackendReference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new BackendReference. Required by controller-gen. -func (in *BackendReference) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/common_json.gen.go b/proto-public/pbmesh/v2beta1/common_json.gen.go deleted file mode 100644 index f5bc4a9627031..0000000000000 --- a/proto-public/pbmesh/v2beta1/common_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ParentReference -func (this *ParentReference) MarshalJSON() ([]byte, error) { - str, err := CommonMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ParentReference -func (this *ParentReference) UnmarshalJSON(b []byte) error { - return CommonUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for BackendReference -func (this *BackendReference) MarshalJSON() ([]byte, error) { - str, err := CommonMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for BackendReference -func (this *BackendReference) UnmarshalJSON(b []byte) error { - return CommonUnmarshaler.Unmarshal(b, this) -} - -var ( - CommonMarshaler = &protojson.MarshalOptions{} - CommonUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/computed_explicit_destinations.pb.binary.go b/proto-public/pbmesh/v2beta1/computed_explicit_destinations.pb.binary.go deleted file mode 100644 index d9aab9ad37338..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_explicit_destinations.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/computed_explicit_destinations.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedExplicitDestinations) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedExplicitDestinations) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/computed_explicit_destinations.pb.go b/proto-public/pbmesh/v2beta1/computed_explicit_destinations.pb.go deleted file mode 100644 index 407fd7d31d41c..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_explicit_destinations.pb.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/computed_explicit_destinations.proto - -package meshv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ComputedExplicitDestinations struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // destinations is the list of explicit destinations to define for the selected workloads. - Destinations []*Destination `protobuf:"bytes,1,rep,name=destinations,proto3" json:"destinations,omitempty"` -} - -func (x *ComputedExplicitDestinations) Reset() { - *x = ComputedExplicitDestinations{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_explicit_destinations_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedExplicitDestinations) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedExplicitDestinations) ProtoMessage() {} - -func (x *ComputedExplicitDestinations) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_explicit_destinations_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedExplicitDestinations.ProtoReflect.Descriptor instead. -func (*ComputedExplicitDestinations) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDescGZIP(), []int{0} -} - -func (x *ComputedExplicitDestinations) GetDestinations() []*Destination { - if x != nil { - return x.Destinations - } - return nil -} - -var File_pbmesh_v2beta1_computed_explicit_destinations_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDesc = []byte{ - 0x0a, 0x33, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, - 0x69, 0x74, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x1a, 0x21, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x76, 0x0a, 0x1c, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x64, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4e, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x42, 0xa2, 0x02, - 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x21, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, - 0x6c, 0x69, 0x63, 0x69, 0x74, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, - 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDescData = file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDesc -) - -func file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDescData) - }) - return file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDescData -} - -var file_pbmesh_v2beta1_computed_explicit_destinations_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmesh_v2beta1_computed_explicit_destinations_proto_goTypes = []interface{}{ - (*ComputedExplicitDestinations)(nil), // 0: hashicorp.consul.mesh.v2beta1.ComputedExplicitDestinations - (*Destination)(nil), // 1: hashicorp.consul.mesh.v2beta1.Destination -} -var file_pbmesh_v2beta1_computed_explicit_destinations_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.mesh.v2beta1.ComputedExplicitDestinations.destinations:type_name -> hashicorp.consul.mesh.v2beta1.Destination - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_computed_explicit_destinations_proto_init() } -func file_pbmesh_v2beta1_computed_explicit_destinations_proto_init() { - if File_pbmesh_v2beta1_computed_explicit_destinations_proto != nil { - return - } - file_pbmesh_v2beta1_destinations_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_computed_explicit_destinations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedExplicitDestinations); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_computed_explicit_destinations_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_computed_explicit_destinations_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_computed_explicit_destinations_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_computed_explicit_destinations_proto = out.File - file_pbmesh_v2beta1_computed_explicit_destinations_proto_rawDesc = nil - file_pbmesh_v2beta1_computed_explicit_destinations_proto_goTypes = nil - file_pbmesh_v2beta1_computed_explicit_destinations_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/computed_explicit_destinations.proto b/proto-public/pbmesh/v2beta1/computed_explicit_destinations.proto deleted file mode 100644 index f3e84c4848989..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_explicit_destinations.proto +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbmesh/v2beta1/destinations.proto"; -import "pbresource/annotations.proto"; - -message ComputedExplicitDestinations { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // destinations is the list of explicit destinations to define for the selected workloads. - repeated Destination destinations = 1; -} diff --git a/proto-public/pbmesh/v2beta1/computed_explicit_destinations_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/computed_explicit_destinations_deepcopy.gen.go deleted file mode 100644 index 7a14e57454f2d..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_explicit_destinations_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ComputedExplicitDestinations within kubernetes types, where deepcopy-gen is used. -func (in *ComputedExplicitDestinations) DeepCopyInto(out *ComputedExplicitDestinations) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExplicitDestinations. Required by controller-gen. -func (in *ComputedExplicitDestinations) DeepCopy() *ComputedExplicitDestinations { - if in == nil { - return nil - } - out := new(ComputedExplicitDestinations) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExplicitDestinations. Required by controller-gen. -func (in *ComputedExplicitDestinations) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/computed_explicit_destinations_json.gen.go b/proto-public/pbmesh/v2beta1/computed_explicit_destinations_json.gen.go deleted file mode 100644 index d483944a11da3..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_explicit_destinations_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ComputedExplicitDestinations -func (this *ComputedExplicitDestinations) MarshalJSON() ([]byte, error) { - str, err := ComputedExplicitDestinationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedExplicitDestinations -func (this *ComputedExplicitDestinations) UnmarshalJSON(b []byte) error { - return ComputedExplicitDestinationsUnmarshaler.Unmarshal(b, this) -} - -var ( - ComputedExplicitDestinationsMarshaler = &protojson.MarshalOptions{} - ComputedExplicitDestinationsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/computed_proxy_configuration.pb.binary.go b/proto-public/pbmesh/v2beta1/computed_proxy_configuration.pb.binary.go deleted file mode 100644 index 25fe0e577bc4e..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_proxy_configuration.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/computed_proxy_configuration.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedProxyConfiguration) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedProxyConfiguration) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/computed_proxy_configuration.pb.go b/proto-public/pbmesh/v2beta1/computed_proxy_configuration.pb.go deleted file mode 100644 index a35764664e3c3..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_proxy_configuration.pb.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/computed_proxy_configuration.proto - -package meshv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ComputedProxyConfiguration struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // dynamic_config is the configuration that could be changed - // dynamically (i.e. without needing restart). - DynamicConfig *DynamicConfig `protobuf:"bytes,2,opt,name=dynamic_config,json=dynamicConfig,proto3" json:"dynamic_config,omitempty"` - // bootstrap_config is the configuration that requires proxies - // to be restarted to be applied. - BootstrapConfig *BootstrapConfig `protobuf:"bytes,3,opt,name=bootstrap_config,json=bootstrapConfig,proto3" json:"bootstrap_config,omitempty"` -} - -func (x *ComputedProxyConfiguration) Reset() { - *x = ComputedProxyConfiguration{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_proxy_configuration_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedProxyConfiguration) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedProxyConfiguration) ProtoMessage() {} - -func (x *ComputedProxyConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_proxy_configuration_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedProxyConfiguration.ProtoReflect.Descriptor instead. -func (*ComputedProxyConfiguration) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDescGZIP(), []int{0} -} - -func (x *ComputedProxyConfiguration) GetDynamicConfig() *DynamicConfig { - if x != nil { - return x.DynamicConfig - } - return nil -} - -func (x *ComputedProxyConfiguration) GetBootstrapConfig() *BootstrapConfig { - if x != nil { - return x.BootstrapConfig - } - return nil -} - -var File_pbmesh_v2beta1_computed_proxy_configuration_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDesc = []byte{ - 0x0a, 0x31, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x1a, 0x28, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd4, 0x01, 0x0a, 0x1a, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x0e, 0x64, 0x79, 0x6e, - 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x0d, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x59, - 0x0a, 0x10, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, - 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, - 0x72, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, - 0x03, 0x42, 0xa0, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x1f, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x64, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, - 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDescData = file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDesc -) - -func file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDescData) - }) - return file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDescData -} - -var file_pbmesh_v2beta1_computed_proxy_configuration_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmesh_v2beta1_computed_proxy_configuration_proto_goTypes = []interface{}{ - (*ComputedProxyConfiguration)(nil), // 0: hashicorp.consul.mesh.v2beta1.ComputedProxyConfiguration - (*DynamicConfig)(nil), // 1: hashicorp.consul.mesh.v2beta1.DynamicConfig - (*BootstrapConfig)(nil), // 2: hashicorp.consul.mesh.v2beta1.BootstrapConfig -} -var file_pbmesh_v2beta1_computed_proxy_configuration_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.mesh.v2beta1.ComputedProxyConfiguration.dynamic_config:type_name -> hashicorp.consul.mesh.v2beta1.DynamicConfig - 2, // 1: hashicorp.consul.mesh.v2beta1.ComputedProxyConfiguration.bootstrap_config:type_name -> hashicorp.consul.mesh.v2beta1.BootstrapConfig - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_computed_proxy_configuration_proto_init() } -func file_pbmesh_v2beta1_computed_proxy_configuration_proto_init() { - if File_pbmesh_v2beta1_computed_proxy_configuration_proto != nil { - return - } - file_pbmesh_v2beta1_proxy_configuration_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_computed_proxy_configuration_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedProxyConfiguration); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_computed_proxy_configuration_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_computed_proxy_configuration_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_computed_proxy_configuration_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_computed_proxy_configuration_proto = out.File - file_pbmesh_v2beta1_computed_proxy_configuration_proto_rawDesc = nil - file_pbmesh_v2beta1_computed_proxy_configuration_proto_goTypes = nil - file_pbmesh_v2beta1_computed_proxy_configuration_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/computed_proxy_configuration.proto b/proto-public/pbmesh/v2beta1/computed_proxy_configuration.proto deleted file mode 100644 index 52ce0c6ad562c..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_proxy_configuration.proto +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbmesh/v2beta1/proxy_configuration.proto"; -import "pbresource/annotations.proto"; - -message ComputedProxyConfiguration { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // dynamic_config is the configuration that could be changed - // dynamically (i.e. without needing restart). - DynamicConfig dynamic_config = 2; - - // bootstrap_config is the configuration that requires proxies - // to be restarted to be applied. - BootstrapConfig bootstrap_config = 3; -} diff --git a/proto-public/pbmesh/v2beta1/computed_proxy_configuration_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/computed_proxy_configuration_deepcopy.gen.go deleted file mode 100644 index d6eb5723030be..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_proxy_configuration_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ComputedProxyConfiguration within kubernetes types, where deepcopy-gen is used. -func (in *ComputedProxyConfiguration) DeepCopyInto(out *ComputedProxyConfiguration) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedProxyConfiguration. Required by controller-gen. -func (in *ComputedProxyConfiguration) DeepCopy() *ComputedProxyConfiguration { - if in == nil { - return nil - } - out := new(ComputedProxyConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedProxyConfiguration. Required by controller-gen. -func (in *ComputedProxyConfiguration) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/computed_proxy_configuration_json.gen.go b/proto-public/pbmesh/v2beta1/computed_proxy_configuration_json.gen.go deleted file mode 100644 index 614a75c365779..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_proxy_configuration_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ComputedProxyConfiguration -func (this *ComputedProxyConfiguration) MarshalJSON() ([]byte, error) { - str, err := ComputedProxyConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedProxyConfiguration -func (this *ComputedProxyConfiguration) UnmarshalJSON(b []byte) error { - return ComputedProxyConfigurationUnmarshaler.Unmarshal(b, this) -} - -var ( - ComputedProxyConfigurationMarshaler = &protojson.MarshalOptions{} - ComputedProxyConfigurationUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/computed_routes.pb.binary.go b/proto-public/pbmesh/v2beta1/computed_routes.pb.binary.go deleted file mode 100644 index f0f24154692ed..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_routes.pb.binary.go +++ /dev/null @@ -1,148 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/computed_routes.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedRoutes) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedRoutes) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedPortRoutes) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedPortRoutes) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedHTTPRoute) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedHTTPRoute) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedHTTPRouteRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedHTTPRouteRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedHTTPBackendRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedHTTPBackendRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedGRPCRoute) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedGRPCRoute) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedGRPCRouteRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedGRPCRouteRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedGRPCBackendRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedGRPCBackendRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedTCPRoute) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedTCPRoute) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedTCPRouteRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedTCPRouteRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedTCPBackendRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedTCPBackendRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *BackendTargetDetails) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *BackendTargetDetails) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedFailoverConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedFailoverConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedFailoverDestination) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedFailoverDestination) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/computed_routes.pb.go b/proto-public/pbmesh/v2beta1/computed_routes.pb.go deleted file mode 100644 index 612da01c249b3..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_routes.pb.go +++ /dev/null @@ -1,1635 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/computed_routes.proto - -package meshv2beta1 - -import ( - v2beta1 "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=BACKEND_TARGET_DETAILS_TYPE_UNSPECIFIED;BACKEND_TARGET_DETAILS_TYPE_DIRECT;BACKEND_TARGET_DETAILS_TYPE_INDIRECT -// +kubebuilder:validation:Type=string -type BackendTargetDetailsType int32 - -const ( - BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_UNSPECIFIED BackendTargetDetailsType = 0 - // Direct means that the target is directly routable from a route. This does - // not mean that the target is not also indirect though. - BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT BackendTargetDetailsType = 1 - // Indirect means that the target is not directly routable from a route. - // - // One example would be for a FailoverPolicy destination. - BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_INDIRECT BackendTargetDetailsType = 2 -) - -// Enum value maps for BackendTargetDetailsType. -var ( - BackendTargetDetailsType_name = map[int32]string{ - 0: "BACKEND_TARGET_DETAILS_TYPE_UNSPECIFIED", - 1: "BACKEND_TARGET_DETAILS_TYPE_DIRECT", - 2: "BACKEND_TARGET_DETAILS_TYPE_INDIRECT", - } - BackendTargetDetailsType_value = map[string]int32{ - "BACKEND_TARGET_DETAILS_TYPE_UNSPECIFIED": 0, - "BACKEND_TARGET_DETAILS_TYPE_DIRECT": 1, - "BACKEND_TARGET_DETAILS_TYPE_INDIRECT": 2, - } -) - -func (x BackendTargetDetailsType) Enum() *BackendTargetDetailsType { - p := new(BackendTargetDetailsType) - *p = x - return p -} - -func (x BackendTargetDetailsType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (BackendTargetDetailsType) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_computed_routes_proto_enumTypes[0].Descriptor() -} - -func (BackendTargetDetailsType) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_computed_routes_proto_enumTypes[0] -} - -func (x BackendTargetDetailsType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use BackendTargetDetailsType.Descriptor instead. -func (BackendTargetDetailsType) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{0} -} - -// This is a Resource type. -type ComputedRoutes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PortedConfigs map[string]*ComputedPortRoutes `protobuf:"bytes,1,rep,name=ported_configs,json=portedConfigs,proto3" json:"ported_configs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // BoundReferences is a slice of mixed type references of resources that were - // involved in the formulation of this resource. - BoundReferences []*pbresource.Reference `protobuf:"bytes,2,rep,name=bound_references,json=boundReferences,proto3" json:"bound_references,omitempty"` -} - -func (x *ComputedRoutes) Reset() { - *x = ComputedRoutes{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedRoutes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedRoutes) ProtoMessage() {} - -func (x *ComputedRoutes) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedRoutes.ProtoReflect.Descriptor instead. -func (*ComputedRoutes) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{0} -} - -func (x *ComputedRoutes) GetPortedConfigs() map[string]*ComputedPortRoutes { - if x != nil { - return x.PortedConfigs - } - return nil -} - -func (x *ComputedRoutes) GetBoundReferences() []*pbresource.Reference { - if x != nil { - return x.BoundReferences - } - return nil -} - -type ComputedPortRoutes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Config: - // - // *ComputedPortRoutes_Http - // *ComputedPortRoutes_Grpc - // *ComputedPortRoutes_Tcp - Config isComputedPortRoutes_Config `protobuf_oneof:"config"` - UsingDefaultConfig bool `protobuf:"varint,4,opt,name=using_default_config,json=usingDefaultConfig,proto3" json:"using_default_config,omitempty"` // TODO - ParentRef *ParentReference `protobuf:"bytes,5,opt,name=parent_ref,json=parentRef,proto3" json:"parent_ref,omitempty"` - // Protocol is the ParentRef.Port's protocol. It is based on the value in the - // Service object, but may differ depending upon which xRoutes are actually - // in use. - Protocol v2beta1.Protocol `protobuf:"varint,6,opt,name=protocol,proto3,enum=hashicorp.consul.catalog.v2beta1.Protocol" json:"protocol,omitempty"` - // map key is an opaque string; like disco chain target name - Targets map[string]*BackendTargetDetails `protobuf:"bytes,7,rep,name=targets,proto3" json:"targets,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *ComputedPortRoutes) Reset() { - *x = ComputedPortRoutes{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedPortRoutes) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedPortRoutes) ProtoMessage() {} - -func (x *ComputedPortRoutes) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedPortRoutes.ProtoReflect.Descriptor instead. -func (*ComputedPortRoutes) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{1} -} - -func (m *ComputedPortRoutes) GetConfig() isComputedPortRoutes_Config { - if m != nil { - return m.Config - } - return nil -} - -func (x *ComputedPortRoutes) GetHttp() *ComputedHTTPRoute { - if x, ok := x.GetConfig().(*ComputedPortRoutes_Http); ok { - return x.Http - } - return nil -} - -func (x *ComputedPortRoutes) GetGrpc() *ComputedGRPCRoute { - if x, ok := x.GetConfig().(*ComputedPortRoutes_Grpc); ok { - return x.Grpc - } - return nil -} - -func (x *ComputedPortRoutes) GetTcp() *ComputedTCPRoute { - if x, ok := x.GetConfig().(*ComputedPortRoutes_Tcp); ok { - return x.Tcp - } - return nil -} - -func (x *ComputedPortRoutes) GetUsingDefaultConfig() bool { - if x != nil { - return x.UsingDefaultConfig - } - return false -} - -func (x *ComputedPortRoutes) GetParentRef() *ParentReference { - if x != nil { - return x.ParentRef - } - return nil -} - -func (x *ComputedPortRoutes) GetProtocol() v2beta1.Protocol { - if x != nil { - return x.Protocol - } - return v2beta1.Protocol(0) -} - -func (x *ComputedPortRoutes) GetTargets() map[string]*BackendTargetDetails { - if x != nil { - return x.Targets - } - return nil -} - -type isComputedPortRoutes_Config interface { - isComputedPortRoutes_Config() -} - -type ComputedPortRoutes_Http struct { - Http *ComputedHTTPRoute `protobuf:"bytes,1,opt,name=http,proto3,oneof"` -} - -type ComputedPortRoutes_Grpc struct { - Grpc *ComputedGRPCRoute `protobuf:"bytes,2,opt,name=grpc,proto3,oneof"` -} - -type ComputedPortRoutes_Tcp struct { - Tcp *ComputedTCPRoute `protobuf:"bytes,3,opt,name=tcp,proto3,oneof"` -} - -func (*ComputedPortRoutes_Http) isComputedPortRoutes_Config() {} - -func (*ComputedPortRoutes_Grpc) isComputedPortRoutes_Config() {} - -func (*ComputedPortRoutes_Tcp) isComputedPortRoutes_Config() {} - -type ComputedHTTPRoute struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Rules []*ComputedHTTPRouteRule `protobuf:"bytes,2,rep,name=rules,proto3" json:"rules,omitempty"` -} - -func (x *ComputedHTTPRoute) Reset() { - *x = ComputedHTTPRoute{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedHTTPRoute) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedHTTPRoute) ProtoMessage() {} - -func (x *ComputedHTTPRoute) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedHTTPRoute.ProtoReflect.Descriptor instead. -func (*ComputedHTTPRoute) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{2} -} - -func (x *ComputedHTTPRoute) GetRules() []*ComputedHTTPRouteRule { - if x != nil { - return x.Rules - } - return nil -} - -type ComputedHTTPRouteRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Matches []*HTTPRouteMatch `protobuf:"bytes,1,rep,name=matches,proto3" json:"matches,omitempty"` - Filters []*HTTPRouteFilter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` - BackendRefs []*ComputedHTTPBackendRef `protobuf:"bytes,3,rep,name=backend_refs,json=backendRefs,proto3" json:"backend_refs,omitempty"` - Timeouts *HTTPRouteTimeouts `protobuf:"bytes,4,opt,name=timeouts,proto3" json:"timeouts,omitempty"` - Retries *HTTPRouteRetries `protobuf:"bytes,5,opt,name=retries,proto3" json:"retries,omitempty"` -} - -func (x *ComputedHTTPRouteRule) Reset() { - *x = ComputedHTTPRouteRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedHTTPRouteRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedHTTPRouteRule) ProtoMessage() {} - -func (x *ComputedHTTPRouteRule) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedHTTPRouteRule.ProtoReflect.Descriptor instead. -func (*ComputedHTTPRouteRule) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{3} -} - -func (x *ComputedHTTPRouteRule) GetMatches() []*HTTPRouteMatch { - if x != nil { - return x.Matches - } - return nil -} - -func (x *ComputedHTTPRouteRule) GetFilters() []*HTTPRouteFilter { - if x != nil { - return x.Filters - } - return nil -} - -func (x *ComputedHTTPRouteRule) GetBackendRefs() []*ComputedHTTPBackendRef { - if x != nil { - return x.BackendRefs - } - return nil -} - -func (x *ComputedHTTPRouteRule) GetTimeouts() *HTTPRouteTimeouts { - if x != nil { - return x.Timeouts - } - return nil -} - -func (x *ComputedHTTPRouteRule) GetRetries() *HTTPRouteRetries { - if x != nil { - return x.Retries - } - return nil -} - -type ComputedHTTPBackendRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // BackendTarget indicates which key in the targets map provides - // the rest of the configuration. - // - // If this field is set to the empty string, or is the sentinel value - // "NULL-ROUTE" is an indication that all of the traffic destined for this - // backend reference should be null routed in a format appropriate for the - // protocol (i.e. for HTTP use 5xx). - BackendTarget string `protobuf:"bytes,1,opt,name=backend_target,json=backendTarget,proto3" json:"backend_target,omitempty"` - Weight uint32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` - Filters []*HTTPRouteFilter `protobuf:"bytes,3,rep,name=filters,proto3" json:"filters,omitempty"` -} - -func (x *ComputedHTTPBackendRef) Reset() { - *x = ComputedHTTPBackendRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedHTTPBackendRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedHTTPBackendRef) ProtoMessage() {} - -func (x *ComputedHTTPBackendRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedHTTPBackendRef.ProtoReflect.Descriptor instead. -func (*ComputedHTTPBackendRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{4} -} - -func (x *ComputedHTTPBackendRef) GetBackendTarget() string { - if x != nil { - return x.BackendTarget - } - return "" -} - -func (x *ComputedHTTPBackendRef) GetWeight() uint32 { - if x != nil { - return x.Weight - } - return 0 -} - -func (x *ComputedHTTPBackendRef) GetFilters() []*HTTPRouteFilter { - if x != nil { - return x.Filters - } - return nil -} - -type ComputedGRPCRoute struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Rules []*ComputedGRPCRouteRule `protobuf:"bytes,2,rep,name=rules,proto3" json:"rules,omitempty"` -} - -func (x *ComputedGRPCRoute) Reset() { - *x = ComputedGRPCRoute{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedGRPCRoute) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedGRPCRoute) ProtoMessage() {} - -func (x *ComputedGRPCRoute) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedGRPCRoute.ProtoReflect.Descriptor instead. -func (*ComputedGRPCRoute) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{5} -} - -func (x *ComputedGRPCRoute) GetRules() []*ComputedGRPCRouteRule { - if x != nil { - return x.Rules - } - return nil -} - -type ComputedGRPCRouteRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Matches []*GRPCRouteMatch `protobuf:"bytes,1,rep,name=matches,proto3" json:"matches,omitempty"` - Filters []*GRPCRouteFilter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` - BackendRefs []*ComputedGRPCBackendRef `protobuf:"bytes,3,rep,name=backend_refs,json=backendRefs,proto3" json:"backend_refs,omitempty"` - Timeouts *HTTPRouteTimeouts `protobuf:"bytes,4,opt,name=timeouts,proto3" json:"timeouts,omitempty"` - Retries *HTTPRouteRetries `protobuf:"bytes,5,opt,name=retries,proto3" json:"retries,omitempty"` -} - -func (x *ComputedGRPCRouteRule) Reset() { - *x = ComputedGRPCRouteRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedGRPCRouteRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedGRPCRouteRule) ProtoMessage() {} - -func (x *ComputedGRPCRouteRule) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedGRPCRouteRule.ProtoReflect.Descriptor instead. -func (*ComputedGRPCRouteRule) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{6} -} - -func (x *ComputedGRPCRouteRule) GetMatches() []*GRPCRouteMatch { - if x != nil { - return x.Matches - } - return nil -} - -func (x *ComputedGRPCRouteRule) GetFilters() []*GRPCRouteFilter { - if x != nil { - return x.Filters - } - return nil -} - -func (x *ComputedGRPCRouteRule) GetBackendRefs() []*ComputedGRPCBackendRef { - if x != nil { - return x.BackendRefs - } - return nil -} - -func (x *ComputedGRPCRouteRule) GetTimeouts() *HTTPRouteTimeouts { - if x != nil { - return x.Timeouts - } - return nil -} - -func (x *ComputedGRPCRouteRule) GetRetries() *HTTPRouteRetries { - if x != nil { - return x.Retries - } - return nil -} - -type ComputedGRPCBackendRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // BackendTarget indicates which key in the targets map provides - // the rest of the configuration. - // - // If this field is set to the empty string, or is the sentinel value - // "NULL-ROUTE" is an indication that all of the traffic destined for this - // backend reference should be null routed in a format appropriate for the - // protocol (i.e. for HTTP use 5xx). - BackendTarget string `protobuf:"bytes,1,opt,name=backend_target,json=backendTarget,proto3" json:"backend_target,omitempty"` - Weight uint32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` - Filters []*GRPCRouteFilter `protobuf:"bytes,3,rep,name=filters,proto3" json:"filters,omitempty"` -} - -func (x *ComputedGRPCBackendRef) Reset() { - *x = ComputedGRPCBackendRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedGRPCBackendRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedGRPCBackendRef) ProtoMessage() {} - -func (x *ComputedGRPCBackendRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedGRPCBackendRef.ProtoReflect.Descriptor instead. -func (*ComputedGRPCBackendRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{7} -} - -func (x *ComputedGRPCBackendRef) GetBackendTarget() string { - if x != nil { - return x.BackendTarget - } - return "" -} - -func (x *ComputedGRPCBackendRef) GetWeight() uint32 { - if x != nil { - return x.Weight - } - return 0 -} - -func (x *ComputedGRPCBackendRef) GetFilters() []*GRPCRouteFilter { - if x != nil { - return x.Filters - } - return nil -} - -type ComputedTCPRoute struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Rules []*ComputedTCPRouteRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` -} - -func (x *ComputedTCPRoute) Reset() { - *x = ComputedTCPRoute{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedTCPRoute) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedTCPRoute) ProtoMessage() {} - -func (x *ComputedTCPRoute) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedTCPRoute.ProtoReflect.Descriptor instead. -func (*ComputedTCPRoute) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{8} -} - -func (x *ComputedTCPRoute) GetRules() []*ComputedTCPRouteRule { - if x != nil { - return x.Rules - } - return nil -} - -type ComputedTCPRouteRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - BackendRefs []*ComputedTCPBackendRef `protobuf:"bytes,1,rep,name=backend_refs,json=backendRefs,proto3" json:"backend_refs,omitempty"` -} - -func (x *ComputedTCPRouteRule) Reset() { - *x = ComputedTCPRouteRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedTCPRouteRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedTCPRouteRule) ProtoMessage() {} - -func (x *ComputedTCPRouteRule) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedTCPRouteRule.ProtoReflect.Descriptor instead. -func (*ComputedTCPRouteRule) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{9} -} - -func (x *ComputedTCPRouteRule) GetBackendRefs() []*ComputedTCPBackendRef { - if x != nil { - return x.BackendRefs - } - return nil -} - -// TODO: look into smuggling the target through a different typeURL, or just skip in favor of letting the caller do their own lookups? -type ComputedTCPBackendRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // BackendTarget indicates which key in the targets map provides - // the rest of the configuration. - // - // If this field is set to the empty string, or is the sentinel value - // "NULL-ROUTE" is an indication that all of the traffic destined for this - // backend reference should be null routed in a format appropriate for the - // protocol (i.e. for HTTP use 5xx). - BackendTarget string `protobuf:"bytes,1,opt,name=backend_target,json=backendTarget,proto3" json:"backend_target,omitempty"` - Weight uint32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` -} - -func (x *ComputedTCPBackendRef) Reset() { - *x = ComputedTCPBackendRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedTCPBackendRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedTCPBackendRef) ProtoMessage() {} - -func (x *ComputedTCPBackendRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedTCPBackendRef.ProtoReflect.Descriptor instead. -func (*ComputedTCPBackendRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{10} -} - -func (x *ComputedTCPBackendRef) GetBackendTarget() string { - if x != nil { - return x.BackendTarget - } - return "" -} - -func (x *ComputedTCPBackendRef) GetWeight() uint32 { - if x != nil { - return x.Weight - } - return 0 -} - -type BackendTargetDetails struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type BackendTargetDetailsType `protobuf:"varint,1,opt,name=type,proto3,enum=hashicorp.consul.mesh.v2beta1.BackendTargetDetailsType" json:"type,omitempty"` - BackendRef *BackendReference `protobuf:"bytes,2,opt,name=backend_ref,json=backendRef,proto3" json:"backend_ref,omitempty"` - MeshPort string `protobuf:"bytes,3,opt,name=mesh_port,json=meshPort,proto3" json:"mesh_port,omitempty"` - FailoverConfig *ComputedFailoverConfig `protobuf:"bytes,4,opt,name=failover_config,json=failoverConfig,proto3" json:"failover_config,omitempty"` - DestinationConfig *DestinationConfig `protobuf:"bytes,5,opt,name=destination_config,json=destinationConfig,proto3" json:"destination_config,omitempty"` - // ServiceEndpointsID is not populated naturally and the field exists only for - // downstream consumers. - ServiceEndpointsId *pbresource.ID `protobuf:"bytes,21,opt,name=service_endpoints_id,json=serviceEndpointsId,proto3" json:"service_endpoints_id,omitempty"` - // ServiceEndpoints is not populated naturally and the field exists only for - // downstream consumers. - ServiceEndpoints *v2beta1.ServiceEndpoints `protobuf:"bytes,22,opt,name=service_endpoints,json=serviceEndpoints,proto3" json:"service_endpoints,omitempty"` - // IdentityRefs are not populated naturally and the field exists only for - // downstream consumers. - IdentityRefs []*pbresource.Reference `protobuf:"bytes,23,rep,name=identity_refs,json=identityRefs,proto3" json:"identity_refs,omitempty"` -} - -func (x *BackendTargetDetails) Reset() { - *x = BackendTargetDetails{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BackendTargetDetails) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BackendTargetDetails) ProtoMessage() {} - -func (x *BackendTargetDetails) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use BackendTargetDetails.ProtoReflect.Descriptor instead. -func (*BackendTargetDetails) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{11} -} - -func (x *BackendTargetDetails) GetType() BackendTargetDetailsType { - if x != nil { - return x.Type - } - return BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_UNSPECIFIED -} - -func (x *BackendTargetDetails) GetBackendRef() *BackendReference { - if x != nil { - return x.BackendRef - } - return nil -} - -func (x *BackendTargetDetails) GetMeshPort() string { - if x != nil { - return x.MeshPort - } - return "" -} - -func (x *BackendTargetDetails) GetFailoverConfig() *ComputedFailoverConfig { - if x != nil { - return x.FailoverConfig - } - return nil -} - -func (x *BackendTargetDetails) GetDestinationConfig() *DestinationConfig { - if x != nil { - return x.DestinationConfig - } - return nil -} - -func (x *BackendTargetDetails) GetServiceEndpointsId() *pbresource.ID { - if x != nil { - return x.ServiceEndpointsId - } - return nil -} - -func (x *BackendTargetDetails) GetServiceEndpoints() *v2beta1.ServiceEndpoints { - if x != nil { - return x.ServiceEndpoints - } - return nil -} - -func (x *BackendTargetDetails) GetIdentityRefs() []*pbresource.Reference { - if x != nil { - return x.IdentityRefs - } - return nil -} - -type ComputedFailoverConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Destinations []*ComputedFailoverDestination `protobuf:"bytes,1,rep,name=destinations,proto3" json:"destinations,omitempty"` - Mode v2beta1.FailoverMode `protobuf:"varint,2,opt,name=mode,proto3,enum=hashicorp.consul.catalog.v2beta1.FailoverMode" json:"mode,omitempty"` - Regions []string `protobuf:"bytes,3,rep,name=regions,proto3" json:"regions,omitempty"` - // SamenessGroup specifies the sameness group to failover to. - SamenessGroup string `protobuf:"bytes,4,opt,name=sameness_group,json=samenessGroup,proto3" json:"sameness_group,omitempty"` -} - -func (x *ComputedFailoverConfig) Reset() { - *x = ComputedFailoverConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedFailoverConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedFailoverConfig) ProtoMessage() {} - -func (x *ComputedFailoverConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedFailoverConfig.ProtoReflect.Descriptor instead. -func (*ComputedFailoverConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{12} -} - -func (x *ComputedFailoverConfig) GetDestinations() []*ComputedFailoverDestination { - if x != nil { - return x.Destinations - } - return nil -} - -func (x *ComputedFailoverConfig) GetMode() v2beta1.FailoverMode { - if x != nil { - return x.Mode - } - return v2beta1.FailoverMode(0) -} - -func (x *ComputedFailoverConfig) GetRegions() []string { - if x != nil { - return x.Regions - } - return nil -} - -func (x *ComputedFailoverConfig) GetSamenessGroup() string { - if x != nil { - return x.SamenessGroup - } - return "" -} - -type ComputedFailoverDestination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // BackendTarget must be a Service. - BackendTarget string `protobuf:"bytes,1,opt,name=backend_target,json=backendTarget,proto3" json:"backend_target,omitempty"` -} - -func (x *ComputedFailoverDestination) Reset() { - *x = ComputedFailoverDestination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedFailoverDestination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedFailoverDestination) ProtoMessage() {} - -func (x *ComputedFailoverDestination) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_computed_routes_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedFailoverDestination.ProtoReflect.Descriptor instead. -func (*ComputedFailoverDestination) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP(), []int{13} -} - -func (x *ComputedFailoverDestination) GetBackendTarget() string { - if x != nil { - return x.BackendTarget - } - return "" -} - -var File_pbmesh_v2beta1_computed_routes_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_computed_routes_proto_rawDesc = []byte{ - 0x0a, 0x24, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x27, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, - 0x72, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, - 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x29, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x70, 0x62, 0x6d, - 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x72, - 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, 0x70, 0x62, - 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, - 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xc7, 0x02, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x73, 0x12, 0x67, 0x0a, 0x0e, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, - 0x74, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x4f, 0x0a, 0x10, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0f, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x1a, 0x73, 0x0a, 0x12, - 0x50, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x87, 0x05, 0x0a, 0x12, 0x43, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, - 0x12, 0x46, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x48, 0x00, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x46, 0x0a, 0x04, 0x67, 0x72, 0x70, 0x63, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47, - 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x00, 0x52, 0x04, 0x67, 0x72, 0x70, 0x63, - 0x12, 0x43, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x48, 0x00, - 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x30, 0x0a, 0x14, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x12, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4d, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x09, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x12, 0x46, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x58, - 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x73, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x1a, 0x6f, 0x0a, 0x0c, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x49, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, - 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x22, 0x65, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, - 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4a, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, - 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, - 0x75, 0x6c, 0x65, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x9d, 0x03, 0x0a, 0x15, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x52, 0x75, 0x6c, 0x65, 0x12, 0x47, 0x0a, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x48, 0x0a, - 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, - 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x58, 0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, - 0x64, 0x52, 0x65, 0x66, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, - 0x73, 0x12, 0x4c, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x73, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x12, - 0x49, 0x0a, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x16, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x48, 0x54, 0x54, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, - 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, - 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x65, - 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x12, 0x4a, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x4a, - 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x9d, 0x03, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, - 0x47, 0x0a, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, - 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x73, 0x12, 0x58, 0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, - 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x64, 0x47, 0x52, 0x50, 0x43, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x52, - 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x12, 0x4c, 0x0a, 0x08, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, - 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, - 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x07, 0x72, 0x65, - 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x07, 0x72, 0x65, - 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x65, 0x64, 0x47, 0x52, 0x50, 0x43, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, - 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, - 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x5d, 0x0a, 0x10, 0x43, 0x6f, 0x6d, - 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x49, 0x0a, - 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, - 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, - 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x6f, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x70, - 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, - 0x12, 0x57, 0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, - 0x43, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x52, 0x0b, 0x62, 0x61, - 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x22, 0x56, 0x0a, 0x15, 0x43, 0x6f, 0x6d, - 0x70, 0x75, 0x74, 0x65, 0x64, 0x54, 0x43, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, - 0x65, 0x66, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, - 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x22, 0x96, 0x05, 0x0a, 0x14, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x4b, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, - 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x62, - 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x73, - 0x68, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, - 0x73, 0x68, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x5e, 0x0a, 0x0f, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, - 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5f, 0x0a, 0x12, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, 0x14, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x5f, 0x69, 0x64, 0x18, - 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x49, 0x44, 0x52, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x49, 0x64, 0x12, 0x5f, 0x0a, 0x11, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x16, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, - 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x10, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x52, 0x65, 0x66, 0x73, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x15, 0x22, 0xfd, 0x01, 0x0a, 0x16, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5e, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, - 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x42, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x4d, - 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x67, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x67, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x61, 0x6d, - 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x44, 0x0a, 0x1b, 0x43, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x61, 0x63, - 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x2a, 0x99, 0x01, 0x0a, 0x18, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, - 0x27, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, - 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x26, 0x0a, 0x22, 0x42, 0x41, - 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x44, 0x45, 0x54, - 0x41, 0x49, 0x4c, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, - 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24, 0x42, 0x41, 0x43, 0x4b, 0x45, 0x4e, 0x44, 0x5f, 0x54, 0x41, - 0x52, 0x47, 0x45, 0x54, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x49, 0x4e, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x10, 0x02, 0x42, 0x94, 0x02, 0x0a, - 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x42, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, - 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_computed_routes_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_computed_routes_proto_rawDescData = file_pbmesh_v2beta1_computed_routes_proto_rawDesc -) - -func file_pbmesh_v2beta1_computed_routes_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_computed_routes_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_computed_routes_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_computed_routes_proto_rawDescData) - }) - return file_pbmesh_v2beta1_computed_routes_proto_rawDescData -} - -var file_pbmesh_v2beta1_computed_routes_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_computed_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 16) -var file_pbmesh_v2beta1_computed_routes_proto_goTypes = []interface{}{ - (BackendTargetDetailsType)(0), // 0: hashicorp.consul.mesh.v2beta1.BackendTargetDetailsType - (*ComputedRoutes)(nil), // 1: hashicorp.consul.mesh.v2beta1.ComputedRoutes - (*ComputedPortRoutes)(nil), // 2: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes - (*ComputedHTTPRoute)(nil), // 3: hashicorp.consul.mesh.v2beta1.ComputedHTTPRoute - (*ComputedHTTPRouteRule)(nil), // 4: hashicorp.consul.mesh.v2beta1.ComputedHTTPRouteRule - (*ComputedHTTPBackendRef)(nil), // 5: hashicorp.consul.mesh.v2beta1.ComputedHTTPBackendRef - (*ComputedGRPCRoute)(nil), // 6: hashicorp.consul.mesh.v2beta1.ComputedGRPCRoute - (*ComputedGRPCRouteRule)(nil), // 7: hashicorp.consul.mesh.v2beta1.ComputedGRPCRouteRule - (*ComputedGRPCBackendRef)(nil), // 8: hashicorp.consul.mesh.v2beta1.ComputedGRPCBackendRef - (*ComputedTCPRoute)(nil), // 9: hashicorp.consul.mesh.v2beta1.ComputedTCPRoute - (*ComputedTCPRouteRule)(nil), // 10: hashicorp.consul.mesh.v2beta1.ComputedTCPRouteRule - (*ComputedTCPBackendRef)(nil), // 11: hashicorp.consul.mesh.v2beta1.ComputedTCPBackendRef - (*BackendTargetDetails)(nil), // 12: hashicorp.consul.mesh.v2beta1.BackendTargetDetails - (*ComputedFailoverConfig)(nil), // 13: hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig - (*ComputedFailoverDestination)(nil), // 14: hashicorp.consul.mesh.v2beta1.ComputedFailoverDestination - nil, // 15: hashicorp.consul.mesh.v2beta1.ComputedRoutes.PortedConfigsEntry - nil, // 16: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.TargetsEntry - (*pbresource.Reference)(nil), // 17: hashicorp.consul.resource.Reference - (*ParentReference)(nil), // 18: hashicorp.consul.mesh.v2beta1.ParentReference - (v2beta1.Protocol)(0), // 19: hashicorp.consul.catalog.v2beta1.Protocol - (*HTTPRouteMatch)(nil), // 20: hashicorp.consul.mesh.v2beta1.HTTPRouteMatch - (*HTTPRouteFilter)(nil), // 21: hashicorp.consul.mesh.v2beta1.HTTPRouteFilter - (*HTTPRouteTimeouts)(nil), // 22: hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts - (*HTTPRouteRetries)(nil), // 23: hashicorp.consul.mesh.v2beta1.HTTPRouteRetries - (*GRPCRouteMatch)(nil), // 24: hashicorp.consul.mesh.v2beta1.GRPCRouteMatch - (*GRPCRouteFilter)(nil), // 25: hashicorp.consul.mesh.v2beta1.GRPCRouteFilter - (*BackendReference)(nil), // 26: hashicorp.consul.mesh.v2beta1.BackendReference - (*DestinationConfig)(nil), // 27: hashicorp.consul.mesh.v2beta1.DestinationConfig - (*pbresource.ID)(nil), // 28: hashicorp.consul.resource.ID - (*v2beta1.ServiceEndpoints)(nil), // 29: hashicorp.consul.catalog.v2beta1.ServiceEndpoints - (v2beta1.FailoverMode)(0), // 30: hashicorp.consul.catalog.v2beta1.FailoverMode -} -var file_pbmesh_v2beta1_computed_routes_proto_depIdxs = []int32{ - 15, // 0: hashicorp.consul.mesh.v2beta1.ComputedRoutes.ported_configs:type_name -> hashicorp.consul.mesh.v2beta1.ComputedRoutes.PortedConfigsEntry - 17, // 1: hashicorp.consul.mesh.v2beta1.ComputedRoutes.bound_references:type_name -> hashicorp.consul.resource.Reference - 3, // 2: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.http:type_name -> hashicorp.consul.mesh.v2beta1.ComputedHTTPRoute - 6, // 3: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.grpc:type_name -> hashicorp.consul.mesh.v2beta1.ComputedGRPCRoute - 9, // 4: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.tcp:type_name -> hashicorp.consul.mesh.v2beta1.ComputedTCPRoute - 18, // 5: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.parent_ref:type_name -> hashicorp.consul.mesh.v2beta1.ParentReference - 19, // 6: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.protocol:type_name -> hashicorp.consul.catalog.v2beta1.Protocol - 16, // 7: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.targets:type_name -> hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.TargetsEntry - 4, // 8: hashicorp.consul.mesh.v2beta1.ComputedHTTPRoute.rules:type_name -> hashicorp.consul.mesh.v2beta1.ComputedHTTPRouteRule - 20, // 9: hashicorp.consul.mesh.v2beta1.ComputedHTTPRouteRule.matches:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteMatch - 21, // 10: hashicorp.consul.mesh.v2beta1.ComputedHTTPRouteRule.filters:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteFilter - 5, // 11: hashicorp.consul.mesh.v2beta1.ComputedHTTPRouteRule.backend_refs:type_name -> hashicorp.consul.mesh.v2beta1.ComputedHTTPBackendRef - 22, // 12: hashicorp.consul.mesh.v2beta1.ComputedHTTPRouteRule.timeouts:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts - 23, // 13: hashicorp.consul.mesh.v2beta1.ComputedHTTPRouteRule.retries:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteRetries - 21, // 14: hashicorp.consul.mesh.v2beta1.ComputedHTTPBackendRef.filters:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteFilter - 7, // 15: hashicorp.consul.mesh.v2beta1.ComputedGRPCRoute.rules:type_name -> hashicorp.consul.mesh.v2beta1.ComputedGRPCRouteRule - 24, // 16: hashicorp.consul.mesh.v2beta1.ComputedGRPCRouteRule.matches:type_name -> hashicorp.consul.mesh.v2beta1.GRPCRouteMatch - 25, // 17: hashicorp.consul.mesh.v2beta1.ComputedGRPCRouteRule.filters:type_name -> hashicorp.consul.mesh.v2beta1.GRPCRouteFilter - 8, // 18: hashicorp.consul.mesh.v2beta1.ComputedGRPCRouteRule.backend_refs:type_name -> hashicorp.consul.mesh.v2beta1.ComputedGRPCBackendRef - 22, // 19: hashicorp.consul.mesh.v2beta1.ComputedGRPCRouteRule.timeouts:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts - 23, // 20: hashicorp.consul.mesh.v2beta1.ComputedGRPCRouteRule.retries:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteRetries - 25, // 21: hashicorp.consul.mesh.v2beta1.ComputedGRPCBackendRef.filters:type_name -> hashicorp.consul.mesh.v2beta1.GRPCRouteFilter - 10, // 22: hashicorp.consul.mesh.v2beta1.ComputedTCPRoute.rules:type_name -> hashicorp.consul.mesh.v2beta1.ComputedTCPRouteRule - 11, // 23: hashicorp.consul.mesh.v2beta1.ComputedTCPRouteRule.backend_refs:type_name -> hashicorp.consul.mesh.v2beta1.ComputedTCPBackendRef - 0, // 24: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.type:type_name -> hashicorp.consul.mesh.v2beta1.BackendTargetDetailsType - 26, // 25: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.backend_ref:type_name -> hashicorp.consul.mesh.v2beta1.BackendReference - 13, // 26: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.failover_config:type_name -> hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig - 27, // 27: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.destination_config:type_name -> hashicorp.consul.mesh.v2beta1.DestinationConfig - 28, // 28: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.service_endpoints_id:type_name -> hashicorp.consul.resource.ID - 29, // 29: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.service_endpoints:type_name -> hashicorp.consul.catalog.v2beta1.ServiceEndpoints - 17, // 30: hashicorp.consul.mesh.v2beta1.BackendTargetDetails.identity_refs:type_name -> hashicorp.consul.resource.Reference - 14, // 31: hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig.destinations:type_name -> hashicorp.consul.mesh.v2beta1.ComputedFailoverDestination - 30, // 32: hashicorp.consul.mesh.v2beta1.ComputedFailoverConfig.mode:type_name -> hashicorp.consul.catalog.v2beta1.FailoverMode - 2, // 33: hashicorp.consul.mesh.v2beta1.ComputedRoutes.PortedConfigsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.ComputedPortRoutes - 12, // 34: hashicorp.consul.mesh.v2beta1.ComputedPortRoutes.TargetsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.BackendTargetDetails - 35, // [35:35] is the sub-list for method output_type - 35, // [35:35] is the sub-list for method input_type - 35, // [35:35] is the sub-list for extension type_name - 35, // [35:35] is the sub-list for extension extendee - 0, // [0:35] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_computed_routes_proto_init() } -func file_pbmesh_v2beta1_computed_routes_proto_init() { - if File_pbmesh_v2beta1_computed_routes_proto != nil { - return - } - file_pbmesh_v2beta1_common_proto_init() - file_pbmesh_v2beta1_destination_policy_proto_init() - file_pbmesh_v2beta1_grpc_route_proto_init() - file_pbmesh_v2beta1_http_route_proto_init() - file_pbmesh_v2beta1_http_route_retries_proto_init() - file_pbmesh_v2beta1_http_route_timeouts_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedRoutes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedPortRoutes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedHTTPRoute); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedHTTPRouteRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedHTTPBackendRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedGRPCRoute); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedGRPCRouteRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedGRPCBackendRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedTCPRoute); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedTCPRouteRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedTCPBackendRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BackendTargetDetails); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedFailoverConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedFailoverDestination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_computed_routes_proto_msgTypes[1].OneofWrappers = []interface{}{ - (*ComputedPortRoutes_Http)(nil), - (*ComputedPortRoutes_Grpc)(nil), - (*ComputedPortRoutes_Tcp)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_computed_routes_proto_rawDesc, - NumEnums: 1, - NumMessages: 16, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_computed_routes_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_computed_routes_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_computed_routes_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_computed_routes_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_computed_routes_proto = out.File - file_pbmesh_v2beta1_computed_routes_proto_rawDesc = nil - file_pbmesh_v2beta1_computed_routes_proto_goTypes = nil - file_pbmesh_v2beta1_computed_routes_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/computed_routes.proto b/proto-public/pbmesh/v2beta1/computed_routes.proto deleted file mode 100644 index f9243bff4bc12..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_routes.proto +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbcatalog/v2beta1/failover_policy.proto"; -import "pbcatalog/v2beta1/protocol.proto"; -import "pbcatalog/v2beta1/service_endpoints.proto"; -import "pbmesh/v2beta1/common.proto"; -import "pbmesh/v2beta1/destination_policy.proto"; -import "pbmesh/v2beta1/grpc_route.proto"; -import "pbmesh/v2beta1/http_route.proto"; -import "pbmesh/v2beta1/http_route_retries.proto"; -import "pbmesh/v2beta1/http_route_timeouts.proto"; -import "pbresource/annotations.proto"; -import "pbresource/resource.proto"; - -// This is a Resource type. -message ComputedRoutes { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - map ported_configs = 1; - - // BoundReferences is a slice of mixed type references of resources that were - // involved in the formulation of this resource. - repeated hashicorp.consul.resource.Reference bound_references = 2; -} - -message ComputedPortRoutes { - oneof config { - ComputedHTTPRoute http = 1; - ComputedGRPCRoute grpc = 2; - ComputedTCPRoute tcp = 3; - } - bool using_default_config = 4; // TODO - - ParentReference parent_ref = 5; - // Protocol is the ParentRef.Port's protocol. It is based on the value in the - // Service object, but may differ depending upon which xRoutes are actually - // in use. - hashicorp.consul.catalog.v2beta1.Protocol protocol = 6; - - // map key is an opaque string; like disco chain target name - map targets = 7; -} - -message ComputedHTTPRoute { - reserved 1; // hostnames - repeated ComputedHTTPRouteRule rules = 2; -} - -message ComputedHTTPRouteRule { - repeated HTTPRouteMatch matches = 1; - repeated HTTPRouteFilter filters = 2; - repeated ComputedHTTPBackendRef backend_refs = 3; - HTTPRouteTimeouts timeouts = 4; - HTTPRouteRetries retries = 5; -} - -message ComputedHTTPBackendRef { - // BackendTarget indicates which key in the targets map provides - // the rest of the configuration. - // - // If this field is set to the empty string, or is the sentinel value - // "NULL-ROUTE" is an indication that all of the traffic destined for this - // backend reference should be null routed in a format appropriate for the - // protocol (i.e. for HTTP use 5xx). - string backend_target = 1; - uint32 weight = 2; - repeated HTTPRouteFilter filters = 3; -} - -message ComputedGRPCRoute { - reserved 1; // hostnames - repeated ComputedGRPCRouteRule rules = 2; -} - -message ComputedGRPCRouteRule { - repeated GRPCRouteMatch matches = 1; - repeated GRPCRouteFilter filters = 2; - repeated ComputedGRPCBackendRef backend_refs = 3; - HTTPRouteTimeouts timeouts = 4; - HTTPRouteRetries retries = 5; -} - -message ComputedGRPCBackendRef { - // BackendTarget indicates which key in the targets map provides - // the rest of the configuration. - // - // If this field is set to the empty string, or is the sentinel value - // "NULL-ROUTE" is an indication that all of the traffic destined for this - // backend reference should be null routed in a format appropriate for the - // protocol (i.e. for HTTP use 5xx). - string backend_target = 1; - uint32 weight = 2; - repeated GRPCRouteFilter filters = 3; -} - -message ComputedTCPRoute { - repeated ComputedTCPRouteRule rules = 1; -} - -message ComputedTCPRouteRule { - repeated ComputedTCPBackendRef backend_refs = 1; -} - -// TODO: look into smuggling the target through a different typeURL, or just skip in favor of letting the caller do their own lookups? -message ComputedTCPBackendRef { - // BackendTarget indicates which key in the targets map provides - // the rest of the configuration. - // - // If this field is set to the empty string, or is the sentinel value - // "NULL-ROUTE" is an indication that all of the traffic destined for this - // backend reference should be null routed in a format appropriate for the - // protocol (i.e. for HTTP use 5xx). - string backend_target = 1; - uint32 weight = 2; -} - -message BackendTargetDetails { - BackendTargetDetailsType type = 1; - BackendReference backend_ref = 2; - - string mesh_port = 3; - ComputedFailoverConfig failover_config = 4; - DestinationConfig destination_config = 5; - - reserved 6 to 20; // leaving a gap between computed and retroactively added fields. - - // ServiceEndpointsID is not populated naturally and the field exists only for - // downstream consumers. - hashicorp.consul.resource.ID service_endpoints_id = 21; - - // ServiceEndpoints is not populated naturally and the field exists only for - // downstream consumers. - hashicorp.consul.catalog.v2beta1.ServiceEndpoints service_endpoints = 22; - - // IdentityRefs are not populated naturally and the field exists only for - // downstream consumers. - repeated hashicorp.consul.resource.Reference identity_refs = 23; -} - -// +kubebuilder:validation:Enum=BACKEND_TARGET_DETAILS_TYPE_UNSPECIFIED;BACKEND_TARGET_DETAILS_TYPE_DIRECT;BACKEND_TARGET_DETAILS_TYPE_INDIRECT -// +kubebuilder:validation:Type=string -enum BackendTargetDetailsType { - BACKEND_TARGET_DETAILS_TYPE_UNSPECIFIED = 0; - - // Direct means that the target is directly routable from a route. This does - // not mean that the target is not also indirect though. - BACKEND_TARGET_DETAILS_TYPE_DIRECT = 1; - - // Indirect means that the target is not directly routable from a route. - // - // One example would be for a FailoverPolicy destination. - BACKEND_TARGET_DETAILS_TYPE_INDIRECT = 2; -} - -message ComputedFailoverConfig { - repeated ComputedFailoverDestination destinations = 1; - hashicorp.consul.catalog.v2beta1.FailoverMode mode = 2; - repeated string regions = 3; - - // SamenessGroup specifies the sameness group to failover to. - string sameness_group = 4; -} - -message ComputedFailoverDestination { - // BackendTarget must be a Service. - string backend_target = 1; -} diff --git a/proto-public/pbmesh/v2beta1/computed_routes_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/computed_routes_deepcopy.gen.go deleted file mode 100644 index d633584558924..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_routes_deepcopy.gen.go +++ /dev/null @@ -1,300 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ComputedRoutes within kubernetes types, where deepcopy-gen is used. -func (in *ComputedRoutes) DeepCopyInto(out *ComputedRoutes) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedRoutes. Required by controller-gen. -func (in *ComputedRoutes) DeepCopy() *ComputedRoutes { - if in == nil { - return nil - } - out := new(ComputedRoutes) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedRoutes. Required by controller-gen. -func (in *ComputedRoutes) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedPortRoutes within kubernetes types, where deepcopy-gen is used. -func (in *ComputedPortRoutes) DeepCopyInto(out *ComputedPortRoutes) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedPortRoutes. Required by controller-gen. -func (in *ComputedPortRoutes) DeepCopy() *ComputedPortRoutes { - if in == nil { - return nil - } - out := new(ComputedPortRoutes) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedPortRoutes. Required by controller-gen. -func (in *ComputedPortRoutes) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedHTTPRoute within kubernetes types, where deepcopy-gen is used. -func (in *ComputedHTTPRoute) DeepCopyInto(out *ComputedHTTPRoute) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPRoute. Required by controller-gen. -func (in *ComputedHTTPRoute) DeepCopy() *ComputedHTTPRoute { - if in == nil { - return nil - } - out := new(ComputedHTTPRoute) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPRoute. Required by controller-gen. -func (in *ComputedHTTPRoute) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedHTTPRouteRule within kubernetes types, where deepcopy-gen is used. -func (in *ComputedHTTPRouteRule) DeepCopyInto(out *ComputedHTTPRouteRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPRouteRule. Required by controller-gen. -func (in *ComputedHTTPRouteRule) DeepCopy() *ComputedHTTPRouteRule { - if in == nil { - return nil - } - out := new(ComputedHTTPRouteRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPRouteRule. Required by controller-gen. -func (in *ComputedHTTPRouteRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedHTTPBackendRef within kubernetes types, where deepcopy-gen is used. -func (in *ComputedHTTPBackendRef) DeepCopyInto(out *ComputedHTTPBackendRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPBackendRef. Required by controller-gen. -func (in *ComputedHTTPBackendRef) DeepCopy() *ComputedHTTPBackendRef { - if in == nil { - return nil - } - out := new(ComputedHTTPBackendRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPBackendRef. Required by controller-gen. -func (in *ComputedHTTPBackendRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedGRPCRoute within kubernetes types, where deepcopy-gen is used. -func (in *ComputedGRPCRoute) DeepCopyInto(out *ComputedGRPCRoute) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCRoute. Required by controller-gen. -func (in *ComputedGRPCRoute) DeepCopy() *ComputedGRPCRoute { - if in == nil { - return nil - } - out := new(ComputedGRPCRoute) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCRoute. Required by controller-gen. -func (in *ComputedGRPCRoute) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedGRPCRouteRule within kubernetes types, where deepcopy-gen is used. -func (in *ComputedGRPCRouteRule) DeepCopyInto(out *ComputedGRPCRouteRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCRouteRule. Required by controller-gen. -func (in *ComputedGRPCRouteRule) DeepCopy() *ComputedGRPCRouteRule { - if in == nil { - return nil - } - out := new(ComputedGRPCRouteRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCRouteRule. Required by controller-gen. -func (in *ComputedGRPCRouteRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedGRPCBackendRef within kubernetes types, where deepcopy-gen is used. -func (in *ComputedGRPCBackendRef) DeepCopyInto(out *ComputedGRPCBackendRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCBackendRef. Required by controller-gen. -func (in *ComputedGRPCBackendRef) DeepCopy() *ComputedGRPCBackendRef { - if in == nil { - return nil - } - out := new(ComputedGRPCBackendRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCBackendRef. Required by controller-gen. -func (in *ComputedGRPCBackendRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedTCPRoute within kubernetes types, where deepcopy-gen is used. -func (in *ComputedTCPRoute) DeepCopyInto(out *ComputedTCPRoute) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPRoute. Required by controller-gen. -func (in *ComputedTCPRoute) DeepCopy() *ComputedTCPRoute { - if in == nil { - return nil - } - out := new(ComputedTCPRoute) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPRoute. Required by controller-gen. -func (in *ComputedTCPRoute) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedTCPRouteRule within kubernetes types, where deepcopy-gen is used. -func (in *ComputedTCPRouteRule) DeepCopyInto(out *ComputedTCPRouteRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPRouteRule. Required by controller-gen. -func (in *ComputedTCPRouteRule) DeepCopy() *ComputedTCPRouteRule { - if in == nil { - return nil - } - out := new(ComputedTCPRouteRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPRouteRule. Required by controller-gen. -func (in *ComputedTCPRouteRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedTCPBackendRef within kubernetes types, where deepcopy-gen is used. -func (in *ComputedTCPBackendRef) DeepCopyInto(out *ComputedTCPBackendRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPBackendRef. Required by controller-gen. -func (in *ComputedTCPBackendRef) DeepCopy() *ComputedTCPBackendRef { - if in == nil { - return nil - } - out := new(ComputedTCPBackendRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPBackendRef. Required by controller-gen. -func (in *ComputedTCPBackendRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using BackendTargetDetails within kubernetes types, where deepcopy-gen is used. -func (in *BackendTargetDetails) DeepCopyInto(out *BackendTargetDetails) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTargetDetails. Required by controller-gen. -func (in *BackendTargetDetails) DeepCopy() *BackendTargetDetails { - if in == nil { - return nil - } - out := new(BackendTargetDetails) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new BackendTargetDetails. Required by controller-gen. -func (in *BackendTargetDetails) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedFailoverConfig within kubernetes types, where deepcopy-gen is used. -func (in *ComputedFailoverConfig) DeepCopyInto(out *ComputedFailoverConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedFailoverConfig. Required by controller-gen. -func (in *ComputedFailoverConfig) DeepCopy() *ComputedFailoverConfig { - if in == nil { - return nil - } - out := new(ComputedFailoverConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedFailoverConfig. Required by controller-gen. -func (in *ComputedFailoverConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedFailoverDestination within kubernetes types, where deepcopy-gen is used. -func (in *ComputedFailoverDestination) DeepCopyInto(out *ComputedFailoverDestination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedFailoverDestination. Required by controller-gen. -func (in *ComputedFailoverDestination) DeepCopy() *ComputedFailoverDestination { - if in == nil { - return nil - } - out := new(ComputedFailoverDestination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedFailoverDestination. Required by controller-gen. -func (in *ComputedFailoverDestination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/computed_routes_json.gen.go b/proto-public/pbmesh/v2beta1/computed_routes_json.gen.go deleted file mode 100644 index e1a60cf422810..0000000000000 --- a/proto-public/pbmesh/v2beta1/computed_routes_json.gen.go +++ /dev/null @@ -1,165 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ComputedRoutes -func (this *ComputedRoutes) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedRoutes -func (this *ComputedRoutes) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedPortRoutes -func (this *ComputedPortRoutes) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedPortRoutes -func (this *ComputedPortRoutes) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedHTTPRoute -func (this *ComputedHTTPRoute) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedHTTPRoute -func (this *ComputedHTTPRoute) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedHTTPRouteRule -func (this *ComputedHTTPRouteRule) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedHTTPRouteRule -func (this *ComputedHTTPRouteRule) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedHTTPBackendRef -func (this *ComputedHTTPBackendRef) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedHTTPBackendRef -func (this *ComputedHTTPBackendRef) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedGRPCRoute -func (this *ComputedGRPCRoute) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedGRPCRoute -func (this *ComputedGRPCRoute) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedGRPCRouteRule -func (this *ComputedGRPCRouteRule) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedGRPCRouteRule -func (this *ComputedGRPCRouteRule) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedGRPCBackendRef -func (this *ComputedGRPCBackendRef) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedGRPCBackendRef -func (this *ComputedGRPCBackendRef) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedTCPRoute -func (this *ComputedTCPRoute) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedTCPRoute -func (this *ComputedTCPRoute) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedTCPRouteRule -func (this *ComputedTCPRouteRule) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedTCPRouteRule -func (this *ComputedTCPRouteRule) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedTCPBackendRef -func (this *ComputedTCPBackendRef) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedTCPBackendRef -func (this *ComputedTCPBackendRef) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for BackendTargetDetails -func (this *BackendTargetDetails) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for BackendTargetDetails -func (this *BackendTargetDetails) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedFailoverConfig -func (this *ComputedFailoverConfig) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedFailoverConfig -func (this *ComputedFailoverConfig) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedFailoverDestination -func (this *ComputedFailoverDestination) MarshalJSON() ([]byte, error) { - str, err := ComputedRoutesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedFailoverDestination -func (this *ComputedFailoverDestination) UnmarshalJSON(b []byte) error { - return ComputedRoutesUnmarshaler.Unmarshal(b, this) -} - -var ( - ComputedRoutesMarshaler = &protojson.MarshalOptions{} - ComputedRoutesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/connection.pb.go b/proto-public/pbmesh/v2beta1/connection.pb.go deleted file mode 100644 index 591df222fc93e..0000000000000 --- a/proto-public/pbmesh/v2beta1/connection.pb.go +++ /dev/null @@ -1,328 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/connection.proto - -package meshv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=BALANCE_CONNECTIONS_DEFAULT;BALANCE_CONNECTIONS_EXACT -// +kubebuilder:validation:Type=string -type BalanceConnections int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - BalanceConnections_BALANCE_CONNECTIONS_DEFAULT BalanceConnections = 0 - BalanceConnections_BALANCE_CONNECTIONS_EXACT BalanceConnections = 1 -) - -// Enum value maps for BalanceConnections. -var ( - BalanceConnections_name = map[int32]string{ - 0: "BALANCE_CONNECTIONS_DEFAULT", - 1: "BALANCE_CONNECTIONS_EXACT", - } - BalanceConnections_value = map[string]int32{ - "BALANCE_CONNECTIONS_DEFAULT": 0, - "BALANCE_CONNECTIONS_EXACT": 1, - } -) - -func (x BalanceConnections) Enum() *BalanceConnections { - p := new(BalanceConnections) - *p = x - return p -} - -func (x BalanceConnections) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (BalanceConnections) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_connection_proto_enumTypes[0].Descriptor() -} - -func (BalanceConnections) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_connection_proto_enumTypes[0] -} - -func (x BalanceConnections) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use BalanceConnections.Descriptor instead. -func (BalanceConnections) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_connection_proto_rawDescGZIP(), []int{0} -} - -// Referenced by ProxyConfiguration -type ConnectionConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // +kubebuilder:validation:Format=duration - ConnectTimeout *durationpb.Duration `protobuf:"bytes,1,opt,name=connect_timeout,json=connectTimeout,proto3" json:"connect_timeout,omitempty"` - // +kubebuilder:validation:Format=duration - RequestTimeout *durationpb.Duration `protobuf:"bytes,2,opt,name=request_timeout,json=requestTimeout,proto3" json:"request_timeout,omitempty"` -} - -func (x *ConnectionConfig) Reset() { - *x = ConnectionConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_connection_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ConnectionConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConnectionConfig) ProtoMessage() {} - -func (x *ConnectionConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_connection_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConnectionConfig.ProtoReflect.Descriptor instead. -func (*ConnectionConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_connection_proto_rawDescGZIP(), []int{0} -} - -func (x *ConnectionConfig) GetConnectTimeout() *durationpb.Duration { - if x != nil { - return x.ConnectTimeout - } - return nil -} - -func (x *ConnectionConfig) GetRequestTimeout() *durationpb.Duration { - if x != nil { - return x.RequestTimeout - } - return nil -} - -// Referenced by ProxyConfiguration -type InboundConnectionsConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MaxInboundConnections uint32 `protobuf:"varint,1,opt,name=max_inbound_connections,json=maxInboundConnections,proto3" json:"max_inbound_connections,omitempty"` - BalanceInboundConnections BalanceConnections `protobuf:"varint,2,opt,name=balance_inbound_connections,json=balanceInboundConnections,proto3,enum=hashicorp.consul.mesh.v2beta1.BalanceConnections" json:"balance_inbound_connections,omitempty"` -} - -func (x *InboundConnectionsConfig) Reset() { - *x = InboundConnectionsConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_connection_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InboundConnectionsConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InboundConnectionsConfig) ProtoMessage() {} - -func (x *InboundConnectionsConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_connection_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InboundConnectionsConfig.ProtoReflect.Descriptor instead. -func (*InboundConnectionsConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_connection_proto_rawDescGZIP(), []int{1} -} - -func (x *InboundConnectionsConfig) GetMaxInboundConnections() uint32 { - if x != nil { - return x.MaxInboundConnections - } - return 0 -} - -func (x *InboundConnectionsConfig) GetBalanceInboundConnections() BalanceConnections { - if x != nil { - return x.BalanceInboundConnections - } - return BalanceConnections_BALANCE_CONNECTIONS_DEFAULT -} - -var File_pbmesh_v2beta1_connection_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_connection_proto_rawDesc = []byte{ - 0x0a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x9a, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x42, 0x0a, 0x0f, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xc5, 0x01, - 0x0a, 0x18, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x6d, 0x61, - 0x78, 0x5f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x6d, 0x61, 0x78, - 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x71, 0x0a, 0x1b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, 0x62, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2a, 0x54, 0x0a, 0x12, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x42, - 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x53, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, - 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, - 0x4f, 0x4e, 0x53, 0x5f, 0x45, 0x58, 0x41, 0x43, 0x54, 0x10, 0x01, 0x42, 0x90, 0x02, 0x0a, 0x21, - 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x42, 0x0f, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, - 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, - 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, - 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, - 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, - 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, - 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_connection_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_connection_proto_rawDescData = file_pbmesh_v2beta1_connection_proto_rawDesc -) - -func file_pbmesh_v2beta1_connection_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_connection_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_connection_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_connection_proto_rawDescData) - }) - return file_pbmesh_v2beta1_connection_proto_rawDescData -} - -var file_pbmesh_v2beta1_connection_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_connection_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbmesh_v2beta1_connection_proto_goTypes = []interface{}{ - (BalanceConnections)(0), // 0: hashicorp.consul.mesh.v2beta1.BalanceConnections - (*ConnectionConfig)(nil), // 1: hashicorp.consul.mesh.v2beta1.ConnectionConfig - (*InboundConnectionsConfig)(nil), // 2: hashicorp.consul.mesh.v2beta1.InboundConnectionsConfig - (*durationpb.Duration)(nil), // 3: google.protobuf.Duration -} -var file_pbmesh_v2beta1_connection_proto_depIdxs = []int32{ - 3, // 0: hashicorp.consul.mesh.v2beta1.ConnectionConfig.connect_timeout:type_name -> google.protobuf.Duration - 3, // 1: hashicorp.consul.mesh.v2beta1.ConnectionConfig.request_timeout:type_name -> google.protobuf.Duration - 0, // 2: hashicorp.consul.mesh.v2beta1.InboundConnectionsConfig.balance_inbound_connections:type_name -> hashicorp.consul.mesh.v2beta1.BalanceConnections - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_connection_proto_init() } -func file_pbmesh_v2beta1_connection_proto_init() { - if File_pbmesh_v2beta1_connection_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_connection_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ConnectionConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_connection_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InboundConnectionsConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_connection_proto_rawDesc, - NumEnums: 1, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_connection_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_connection_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_connection_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_connection_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_connection_proto = out.File - file_pbmesh_v2beta1_connection_proto_rawDesc = nil - file_pbmesh_v2beta1_connection_proto_goTypes = nil - file_pbmesh_v2beta1_connection_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/connection.proto b/proto-public/pbmesh/v2beta1/connection.proto deleted file mode 100644 index 65cb21e586dd2..0000000000000 --- a/proto-public/pbmesh/v2beta1/connection.proto +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "google/protobuf/duration.proto"; - -// Referenced by ProxyConfiguration -message ConnectionConfig { - // +kubebuilder:validation:Format=duration - google.protobuf.Duration connect_timeout = 1; - // +kubebuilder:validation:Format=duration - google.protobuf.Duration request_timeout = 2; -} - -// Referenced by ProxyConfiguration -message InboundConnectionsConfig { - uint32 max_inbound_connections = 1; - BalanceConnections balance_inbound_connections = 2; -} - -// +kubebuilder:validation:Enum=BALANCE_CONNECTIONS_DEFAULT;BALANCE_CONNECTIONS_EXACT -// +kubebuilder:validation:Type=string -enum BalanceConnections { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - BALANCE_CONNECTIONS_DEFAULT = 0; - BALANCE_CONNECTIONS_EXACT = 1; -} diff --git a/proto-public/pbmesh/v2beta1/connection_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/connection_deepcopy.gen.go deleted file mode 100644 index a0cfa77757567..0000000000000 --- a/proto-public/pbmesh/v2beta1/connection_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ConnectionConfig within kubernetes types, where deepcopy-gen is used. -func (in *ConnectionConfig) DeepCopyInto(out *ConnectionConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionConfig. Required by controller-gen. -func (in *ConnectionConfig) DeepCopy() *ConnectionConfig { - if in == nil { - return nil - } - out := new(ConnectionConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionConfig. Required by controller-gen. -func (in *ConnectionConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using InboundConnectionsConfig within kubernetes types, where deepcopy-gen is used. -func (in *InboundConnectionsConfig) DeepCopyInto(out *InboundConnectionsConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InboundConnectionsConfig. Required by controller-gen. -func (in *InboundConnectionsConfig) DeepCopy() *InboundConnectionsConfig { - if in == nil { - return nil - } - out := new(InboundConnectionsConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new InboundConnectionsConfig. Required by controller-gen. -func (in *InboundConnectionsConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/connection_json.gen.go b/proto-public/pbmesh/v2beta1/connection_json.gen.go deleted file mode 100644 index 15649a3f25420..0000000000000 --- a/proto-public/pbmesh/v2beta1/connection_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ConnectionConfig -func (this *ConnectionConfig) MarshalJSON() ([]byte, error) { - str, err := ConnectionMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ConnectionConfig -func (this *ConnectionConfig) UnmarshalJSON(b []byte) error { - return ConnectionUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for InboundConnectionsConfig -func (this *InboundConnectionsConfig) MarshalJSON() ([]byte, error) { - str, err := ConnectionMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for InboundConnectionsConfig -func (this *InboundConnectionsConfig) UnmarshalJSON(b []byte) error { - return ConnectionUnmarshaler.Unmarshal(b, this) -} - -var ( - ConnectionMarshaler = &protojson.MarshalOptions{} - ConnectionUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/destination_policy.pb.binary.go b/proto-public/pbmesh/v2beta1/destination_policy.pb.binary.go deleted file mode 100644 index 777d8a8cc03b4..0000000000000 --- a/proto-public/pbmesh/v2beta1/destination_policy.pb.binary.go +++ /dev/null @@ -1,88 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/destination_policy.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LocalityPrioritization) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LocalityPrioritization) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LoadBalancer) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LoadBalancer) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RingHashConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RingHashConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LeastRequestConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LeastRequestConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HashPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HashPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *CookieConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *CookieConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/destination_policy.pb.go b/proto-public/pbmesh/v2beta1/destination_policy.pb.go deleted file mode 100644 index 99d7c7eaeaeeb..0000000000000 --- a/proto-public/pbmesh/v2beta1/destination_policy.pb.go +++ /dev/null @@ -1,1102 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/destination_policy.proto - -package meshv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED;LOCALITY_PRIORITIZATION_MODE_NONE;LOCALITY_PRIORITIZATION_MODE_FAILOVER -// +kubebuilder:validation:Type=string -type LocalityPrioritizationMode int32 - -const ( - LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED LocalityPrioritizationMode = 0 - LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_NONE LocalityPrioritizationMode = 1 - LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_FAILOVER LocalityPrioritizationMode = 2 -) - -// Enum value maps for LocalityPrioritizationMode. -var ( - LocalityPrioritizationMode_name = map[int32]string{ - 0: "LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED", - 1: "LOCALITY_PRIORITIZATION_MODE_NONE", - 2: "LOCALITY_PRIORITIZATION_MODE_FAILOVER", - } - LocalityPrioritizationMode_value = map[string]int32{ - "LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED": 0, - "LOCALITY_PRIORITIZATION_MODE_NONE": 1, - "LOCALITY_PRIORITIZATION_MODE_FAILOVER": 2, - } -) - -func (x LocalityPrioritizationMode) Enum() *LocalityPrioritizationMode { - p := new(LocalityPrioritizationMode) - *p = x - return p -} - -func (x LocalityPrioritizationMode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (LocalityPrioritizationMode) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_destination_policy_proto_enumTypes[0].Descriptor() -} - -func (LocalityPrioritizationMode) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_destination_policy_proto_enumTypes[0] -} - -func (x LocalityPrioritizationMode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use LocalityPrioritizationMode.Descriptor instead. -func (LocalityPrioritizationMode) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{0} -} - -// +kubebuilder:validation:Enum=LOAD_BALANCER_POLICY_UNSPECIFIED;LOAD_BALANCER_POLICY_RANDOM;LOAD_BALANCER_POLICY_ROUND_ROBIN;LOAD_BALANCER_POLICY_LEAST_REQUEST;LOAD_BALANCER_POLICY_MAGLEV;LOAD_BALANCER_POLICY_RING_HASH -// +kubebuilder:validation:Type=string -type LoadBalancerPolicy int32 - -const ( - LoadBalancerPolicy_LOAD_BALANCER_POLICY_UNSPECIFIED LoadBalancerPolicy = 0 - LoadBalancerPolicy_LOAD_BALANCER_POLICY_RANDOM LoadBalancerPolicy = 1 - LoadBalancerPolicy_LOAD_BALANCER_POLICY_ROUND_ROBIN LoadBalancerPolicy = 2 - LoadBalancerPolicy_LOAD_BALANCER_POLICY_LEAST_REQUEST LoadBalancerPolicy = 3 - LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV LoadBalancerPolicy = 4 - LoadBalancerPolicy_LOAD_BALANCER_POLICY_RING_HASH LoadBalancerPolicy = 5 -) - -// Enum value maps for LoadBalancerPolicy. -var ( - LoadBalancerPolicy_name = map[int32]string{ - 0: "LOAD_BALANCER_POLICY_UNSPECIFIED", - 1: "LOAD_BALANCER_POLICY_RANDOM", - 2: "LOAD_BALANCER_POLICY_ROUND_ROBIN", - 3: "LOAD_BALANCER_POLICY_LEAST_REQUEST", - 4: "LOAD_BALANCER_POLICY_MAGLEV", - 5: "LOAD_BALANCER_POLICY_RING_HASH", - } - LoadBalancerPolicy_value = map[string]int32{ - "LOAD_BALANCER_POLICY_UNSPECIFIED": 0, - "LOAD_BALANCER_POLICY_RANDOM": 1, - "LOAD_BALANCER_POLICY_ROUND_ROBIN": 2, - "LOAD_BALANCER_POLICY_LEAST_REQUEST": 3, - "LOAD_BALANCER_POLICY_MAGLEV": 4, - "LOAD_BALANCER_POLICY_RING_HASH": 5, - } -) - -func (x LoadBalancerPolicy) Enum() *LoadBalancerPolicy { - p := new(LoadBalancerPolicy) - *p = x - return p -} - -func (x LoadBalancerPolicy) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (LoadBalancerPolicy) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_destination_policy_proto_enumTypes[1].Descriptor() -} - -func (LoadBalancerPolicy) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_destination_policy_proto_enumTypes[1] -} - -func (x LoadBalancerPolicy) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use LoadBalancerPolicy.Descriptor instead. -func (LoadBalancerPolicy) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{1} -} - -// +kubebuilder:validation:Enum=HASH_POLICY_FIELD_UNSPECIFIED;HASH_POLICY_FIELD_HEADER;HASH_POLICY_FIELD_COOKIE;HASH_POLICY_FIELD_QUERY_PARAMETER -// +kubebuilder:validation:Type=string -type HashPolicyField int32 - -const ( - HashPolicyField_HASH_POLICY_FIELD_UNSPECIFIED HashPolicyField = 0 - HashPolicyField_HASH_POLICY_FIELD_HEADER HashPolicyField = 1 - HashPolicyField_HASH_POLICY_FIELD_COOKIE HashPolicyField = 2 - HashPolicyField_HASH_POLICY_FIELD_QUERY_PARAMETER HashPolicyField = 3 -) - -// Enum value maps for HashPolicyField. -var ( - HashPolicyField_name = map[int32]string{ - 0: "HASH_POLICY_FIELD_UNSPECIFIED", - 1: "HASH_POLICY_FIELD_HEADER", - 2: "HASH_POLICY_FIELD_COOKIE", - 3: "HASH_POLICY_FIELD_QUERY_PARAMETER", - } - HashPolicyField_value = map[string]int32{ - "HASH_POLICY_FIELD_UNSPECIFIED": 0, - "HASH_POLICY_FIELD_HEADER": 1, - "HASH_POLICY_FIELD_COOKIE": 2, - "HASH_POLICY_FIELD_QUERY_PARAMETER": 3, - } -) - -func (x HashPolicyField) Enum() *HashPolicyField { - p := new(HashPolicyField) - *p = x - return p -} - -func (x HashPolicyField) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (HashPolicyField) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_destination_policy_proto_enumTypes[2].Descriptor() -} - -func (HashPolicyField) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_destination_policy_proto_enumTypes[2] -} - -func (x HashPolicyField) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use HashPolicyField.Descriptor instead. -func (HashPolicyField) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{2} -} - -// DestinationPolicy is the destination-controlled set of defaults that -// are used when similar controls defined in an UpstreamConfig are left -// unspecified. -// -// Users may wish to share commonly configured settings for communicating with -// a service in one place, but yet retain the ability to tweak those on a -// client-by-client basis, which is why there are separate resources to control -// the definition of these values from either end of the connection. -// -// This is a Resource type. -type DestinationPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PortConfigs map[string]*DestinationConfig `protobuf:"bytes,1,rep,name=port_configs,json=portConfigs,proto3" json:"port_configs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *DestinationPolicy) Reset() { - *x = DestinationPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationPolicy) ProtoMessage() {} - -func (x *DestinationPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationPolicy.ProtoReflect.Descriptor instead. -func (*DestinationPolicy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{0} -} - -func (x *DestinationPolicy) GetPortConfigs() map[string]*DestinationConfig { - if x != nil { - return x.PortConfigs - } - return nil -} - -type DestinationConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ConnectTimeout is the timeout for establishing new network connections - // to this service. - // +kubebuilder:validation:Format=duration - ConnectTimeout *durationpb.Duration `protobuf:"bytes,1,opt,name=connect_timeout,json=connectTimeout,proto3" json:"connect_timeout,omitempty"` - // RequestTimeout is the timeout for an HTTP request to complete before the - // connection is automatically terminated. If unspecified, defaults to 15 - // seconds. - // +kubebuilder:validation:Format=duration - RequestTimeout *durationpb.Duration `protobuf:"bytes,2,opt,name=request_timeout,json=requestTimeout,proto3" json:"request_timeout,omitempty"` - // LoadBalancer determines the load balancing policy and configuration for - // services issuing requests to this upstream service. - LoadBalancer *LoadBalancer `protobuf:"bytes,3,opt,name=load_balancer,json=loadBalancer,proto3" json:"load_balancer,omitempty"` - // LocalityPrioritization controls whether the locality of services within the - // local partition will be used to prioritize connectivity. - LocalityPrioritization *LocalityPrioritization `protobuf:"bytes,4,opt,name=locality_prioritization,json=localityPrioritization,proto3" json:"locality_prioritization,omitempty"` -} - -func (x *DestinationConfig) Reset() { - *x = DestinationConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationConfig) ProtoMessage() {} - -func (x *DestinationConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationConfig.ProtoReflect.Descriptor instead. -func (*DestinationConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{1} -} - -func (x *DestinationConfig) GetConnectTimeout() *durationpb.Duration { - if x != nil { - return x.ConnectTimeout - } - return nil -} - -func (x *DestinationConfig) GetRequestTimeout() *durationpb.Duration { - if x != nil { - return x.RequestTimeout - } - return nil -} - -func (x *DestinationConfig) GetLoadBalancer() *LoadBalancer { - if x != nil { - return x.LoadBalancer - } - return nil -} - -func (x *DestinationConfig) GetLocalityPrioritization() *LocalityPrioritization { - if x != nil { - return x.LocalityPrioritization - } - return nil -} - -type LocalityPrioritization struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // 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 LocalityPrioritizationMode `protobuf:"varint,1,opt,name=mode,proto3,enum=hashicorp.consul.mesh.v2beta1.LocalityPrioritizationMode" json:"mode,omitempty"` -} - -func (x *LocalityPrioritization) Reset() { - *x = LocalityPrioritization{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LocalityPrioritization) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LocalityPrioritization) ProtoMessage() {} - -func (x *LocalityPrioritization) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LocalityPrioritization.ProtoReflect.Descriptor instead. -func (*LocalityPrioritization) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{2} -} - -func (x *LocalityPrioritization) GetMode() LocalityPrioritizationMode { - if x != nil { - return x.Mode - } - return LocalityPrioritizationMode_LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED -} - -// LoadBalancer determines the load balancing policy and configuration -// for services issuing requests to this upstream service. -type LoadBalancer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Policy is the load balancing policy used to select a host - Policy LoadBalancerPolicy `protobuf:"varint,1,opt,name=policy,proto3,enum=hashicorp.consul.mesh.v2beta1.LoadBalancerPolicy" json:"policy,omitempty"` - // HashPolicies is a list of hash policies to use for hashing load balancing - // algorithms. Hash policies are evaluated individually and combined such - // that identical lists result in the same hash. - // - // If no hash policies are present, or none are successfully evaluated, - // then a random backend host will be selected. - HashPolicies []*HashPolicy `protobuf:"bytes,2,rep,name=hash_policies,json=hashPolicies,proto3" json:"hash_policies,omitempty"` - // Types that are assignable to Config: - // - // *LoadBalancer_RingHashConfig - // *LoadBalancer_LeastRequestConfig - Config isLoadBalancer_Config `protobuf_oneof:"config"` -} - -func (x *LoadBalancer) Reset() { - *x = LoadBalancer{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LoadBalancer) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LoadBalancer) ProtoMessage() {} - -func (x *LoadBalancer) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LoadBalancer.ProtoReflect.Descriptor instead. -func (*LoadBalancer) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{3} -} - -func (x *LoadBalancer) GetPolicy() LoadBalancerPolicy { - if x != nil { - return x.Policy - } - return LoadBalancerPolicy_LOAD_BALANCER_POLICY_UNSPECIFIED -} - -func (x *LoadBalancer) GetHashPolicies() []*HashPolicy { - if x != nil { - return x.HashPolicies - } - return nil -} - -func (m *LoadBalancer) GetConfig() isLoadBalancer_Config { - if m != nil { - return m.Config - } - return nil -} - -func (x *LoadBalancer) GetRingHashConfig() *RingHashConfig { - if x, ok := x.GetConfig().(*LoadBalancer_RingHashConfig); ok { - return x.RingHashConfig - } - return nil -} - -func (x *LoadBalancer) GetLeastRequestConfig() *LeastRequestConfig { - if x, ok := x.GetConfig().(*LoadBalancer_LeastRequestConfig); ok { - return x.LeastRequestConfig - } - return nil -} - -type isLoadBalancer_Config interface { - isLoadBalancer_Config() -} - -type LoadBalancer_RingHashConfig struct { - // RingHashConfig contains configuration for the "ring_hash" policy type - RingHashConfig *RingHashConfig `protobuf:"bytes,3,opt,name=ring_hash_config,json=ringHashConfig,proto3,oneof"` -} - -type LoadBalancer_LeastRequestConfig struct { - // LeastRequestConfig contains configuration for the "least_request" policy type - LeastRequestConfig *LeastRequestConfig `protobuf:"bytes,4,opt,name=least_request_config,json=leastRequestConfig,proto3,oneof"` -} - -func (*LoadBalancer_RingHashConfig) isLoadBalancer_Config() {} - -func (*LoadBalancer_LeastRequestConfig) isLoadBalancer_Config() {} - -// RingHashConfig contains configuration for the "ring_hash" policy type -type RingHashConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // MinimumRingSize determines the minimum number of entries in the hash ring - MinimumRingSize uint64 `protobuf:"varint,1,opt,name=minimum_ring_size,json=minimumRingSize,proto3" json:"minimum_ring_size,omitempty"` - // MaximumRingSize determines the maximum number of entries in the hash ring - MaximumRingSize uint64 `protobuf:"varint,2,opt,name=maximum_ring_size,json=maximumRingSize,proto3" json:"maximum_ring_size,omitempty"` -} - -func (x *RingHashConfig) Reset() { - *x = RingHashConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RingHashConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RingHashConfig) ProtoMessage() {} - -func (x *RingHashConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RingHashConfig.ProtoReflect.Descriptor instead. -func (*RingHashConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{4} -} - -func (x *RingHashConfig) GetMinimumRingSize() uint64 { - if x != nil { - return x.MinimumRingSize - } - return 0 -} - -func (x *RingHashConfig) GetMaximumRingSize() uint64 { - if x != nil { - return x.MaximumRingSize - } - return 0 -} - -// LeastRequestConfig contains configuration for the "least_request" policy type -type LeastRequestConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests. - ChoiceCount uint32 `protobuf:"varint,1,opt,name=choice_count,json=choiceCount,proto3" json:"choice_count,omitempty"` -} - -func (x *LeastRequestConfig) Reset() { - *x = LeastRequestConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LeastRequestConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LeastRequestConfig) ProtoMessage() {} - -func (x *LeastRequestConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LeastRequestConfig.ProtoReflect.Descriptor instead. -func (*LeastRequestConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{5} -} - -func (x *LeastRequestConfig) GetChoiceCount() uint32 { - if x != nil { - return x.ChoiceCount - } - return 0 -} - -// HashPolicy defines which attributes will be hashed by hash-based LB algorithms -type HashPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Field is the attribute type to hash on. - // Must be one of "header","cookie", or "query_parameter". - // Cannot be specified along with SourceIP. - Field HashPolicyField `protobuf:"varint,1,opt,name=field,proto3,enum=hashicorp.consul.mesh.v2beta1.HashPolicyField" json:"field,omitempty"` - // FieldValue is the value to hash. - // ie. header name, cookie name, URL query parameter name - // Cannot be specified along with SourceIP. - FieldValue string `protobuf:"bytes,2,opt,name=field_value,json=fieldValue,proto3" json:"field_value,omitempty"` - // CookieConfig contains configuration for the "cookie" hash policy type. - CookieConfig *CookieConfig `protobuf:"bytes,3,opt,name=cookie_config,json=cookieConfig,proto3" json:"cookie_config,omitempty"` - // SourceIP determines whether the hash should be of the source IP rather than of a field and field value. - // Cannot be specified along with Field or FieldValue. - SourceIp bool `protobuf:"varint,4,opt,name=source_ip,json=sourceIp,proto3" json:"source_ip,omitempty"` - // Terminal will short circuit the computation of the hash when multiple hash policies are present. - // If a hash is computed when a Terminal policy is evaluated, - // then that hash will be used and subsequent hash policies will be ignored. - Terminal bool `protobuf:"varint,5,opt,name=terminal,proto3" json:"terminal,omitempty"` -} - -func (x *HashPolicy) Reset() { - *x = HashPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HashPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HashPolicy) ProtoMessage() {} - -func (x *HashPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HashPolicy.ProtoReflect.Descriptor instead. -func (*HashPolicy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{6} -} - -func (x *HashPolicy) GetField() HashPolicyField { - if x != nil { - return x.Field - } - return HashPolicyField_HASH_POLICY_FIELD_UNSPECIFIED -} - -func (x *HashPolicy) GetFieldValue() string { - if x != nil { - return x.FieldValue - } - return "" -} - -func (x *HashPolicy) GetCookieConfig() *CookieConfig { - if x != nil { - return x.CookieConfig - } - return nil -} - -func (x *HashPolicy) GetSourceIp() bool { - if x != nil { - return x.SourceIp - } - return false -} - -func (x *HashPolicy) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -// CookieConfig contains configuration for the "cookie" hash policy type. -// This is specified to have Envoy generate a cookie for a client on its first request. -type CookieConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Generates a session cookie with no expiration. - Session bool `protobuf:"varint,1,opt,name=session,proto3" json:"session,omitempty"` - // TTL for generated cookies. Cannot be specified for session cookies. - // +kubebuilder:validation:Format=duration - Ttl *durationpb.Duration `protobuf:"bytes,2,opt,name=ttl,proto3" json:"ttl,omitempty"` - // The path to set for the cookie - Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` -} - -func (x *CookieConfig) Reset() { - *x = CookieConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CookieConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CookieConfig) ProtoMessage() {} - -func (x *CookieConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destination_policy_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CookieConfig.ProtoReflect.Descriptor instead. -func (*CookieConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP(), []int{7} -} - -func (x *CookieConfig) GetSession() bool { - if x != nil { - return x.Session - } - return false -} - -func (x *CookieConfig) GetTtl() *durationpb.Duration { - if x != nil { - return x.Ttl - } - return nil -} - -func (x *CookieConfig) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -var File_pbmesh_v2beta1_destination_policy_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_destination_policy_proto_rawDesc = []byte{ - 0x0a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf3, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x64, 0x0a, 0x0c, - 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x73, 0x1a, 0x70, 0x0a, 0x10, 0x50, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xdd, 0x02, 0x0a, - 0x11, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x42, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x50, 0x0a, 0x0d, 0x6c, 0x6f, - 0x61, 0x64, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x52, 0x0c, - 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x6e, 0x0a, 0x17, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, - 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, - 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x67, 0x0a, 0x16, - 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x69, - 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, - 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xf5, 0x02, 0x0a, 0x0c, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x12, 0x49, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x12, 0x4e, 0x0a, 0x0d, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x52, 0x0c, 0x68, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, - 0x73, 0x12, 0x59, 0x0a, 0x10, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x69, 0x6e, 0x67, - 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0e, 0x72, 0x69, - 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x65, 0x0a, 0x14, - 0x6c, 0x65, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, - 0x12, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x68, 0x0a, - 0x0e, 0x52, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x2a, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x69, - 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x6d, - 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x52, - 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x37, 0x0a, 0x12, 0x4c, 0x65, 0x61, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x22, 0xfe, 0x01, 0x0a, 0x0a, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, - 0x44, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, - 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x50, 0x0a, 0x0d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, - 0x6f, 0x6b, 0x69, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x63, 0x6f, 0x6f, 0x6b, - 0x69, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x49, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, - 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, - 0x6c, 0x22, 0x69, 0x0a, 0x0c, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x03, 0x74, - 0x74, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x2a, 0x9c, 0x01, 0x0a, - 0x1a, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x2c, 0x0a, 0x28, 0x4c, - 0x4f, 0x43, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x52, 0x49, 0x4f, 0x52, 0x49, 0x54, 0x49, - 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, 0x4c, 0x4f, 0x43, - 0x41, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x52, 0x49, 0x4f, 0x52, 0x49, 0x54, 0x49, 0x5a, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, - 0x12, 0x29, 0x0a, 0x25, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x52, 0x49, - 0x4f, 0x52, 0x49, 0x54, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x45, - 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x4f, 0x56, 0x45, 0x52, 0x10, 0x02, 0x2a, 0xee, 0x01, 0x0a, 0x12, - 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x12, 0x24, 0x0a, 0x20, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, - 0x43, 0x45, 0x52, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1f, 0x0a, 0x1b, 0x4c, 0x4f, 0x41, 0x44, - 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x52, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, - 0x5f, 0x52, 0x41, 0x4e, 0x44, 0x4f, 0x4d, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x4c, 0x4f, 0x41, - 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x52, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, - 0x59, 0x5f, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x52, 0x4f, 0x42, 0x49, 0x4e, 0x10, 0x02, 0x12, - 0x26, 0x0a, 0x22, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x52, - 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x4c, 0x45, 0x41, 0x53, 0x54, 0x5f, 0x52, 0x45, - 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x4c, 0x4f, 0x41, 0x44, 0x5f, - 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x52, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, - 0x4d, 0x41, 0x47, 0x4c, 0x45, 0x56, 0x10, 0x04, 0x12, 0x22, 0x0a, 0x1e, 0x4c, 0x4f, 0x41, 0x44, - 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x52, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, - 0x5f, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x05, 0x2a, 0x97, 0x01, 0x0a, - 0x0f, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x12, 0x21, 0x0a, 0x1d, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, - 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x50, 0x4f, 0x4c, 0x49, - 0x43, 0x59, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x10, - 0x01, 0x12, 0x1c, 0x0a, 0x18, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, - 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x43, 0x4f, 0x4f, 0x4b, 0x49, 0x45, 0x10, 0x02, 0x12, - 0x25, 0x0a, 0x21, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x46, - 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, - 0x45, 0x54, 0x45, 0x52, 0x10, 0x03, 0x42, 0x97, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x16, 0x44, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, - 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, - 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_destination_policy_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_destination_policy_proto_rawDescData = file_pbmesh_v2beta1_destination_policy_proto_rawDesc -) - -func file_pbmesh_v2beta1_destination_policy_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_destination_policy_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_destination_policy_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_destination_policy_proto_rawDescData) - }) - return file_pbmesh_v2beta1_destination_policy_proto_rawDescData -} - -var file_pbmesh_v2beta1_destination_policy_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_pbmesh_v2beta1_destination_policy_proto_msgTypes = make([]protoimpl.MessageInfo, 9) -var file_pbmesh_v2beta1_destination_policy_proto_goTypes = []interface{}{ - (LocalityPrioritizationMode)(0), // 0: hashicorp.consul.mesh.v2beta1.LocalityPrioritizationMode - (LoadBalancerPolicy)(0), // 1: hashicorp.consul.mesh.v2beta1.LoadBalancerPolicy - (HashPolicyField)(0), // 2: hashicorp.consul.mesh.v2beta1.HashPolicyField - (*DestinationPolicy)(nil), // 3: hashicorp.consul.mesh.v2beta1.DestinationPolicy - (*DestinationConfig)(nil), // 4: hashicorp.consul.mesh.v2beta1.DestinationConfig - (*LocalityPrioritization)(nil), // 5: hashicorp.consul.mesh.v2beta1.LocalityPrioritization - (*LoadBalancer)(nil), // 6: hashicorp.consul.mesh.v2beta1.LoadBalancer - (*RingHashConfig)(nil), // 7: hashicorp.consul.mesh.v2beta1.RingHashConfig - (*LeastRequestConfig)(nil), // 8: hashicorp.consul.mesh.v2beta1.LeastRequestConfig - (*HashPolicy)(nil), // 9: hashicorp.consul.mesh.v2beta1.HashPolicy - (*CookieConfig)(nil), // 10: hashicorp.consul.mesh.v2beta1.CookieConfig - nil, // 11: hashicorp.consul.mesh.v2beta1.DestinationPolicy.PortConfigsEntry - (*durationpb.Duration)(nil), // 12: google.protobuf.Duration -} -var file_pbmesh_v2beta1_destination_policy_proto_depIdxs = []int32{ - 11, // 0: hashicorp.consul.mesh.v2beta1.DestinationPolicy.port_configs:type_name -> hashicorp.consul.mesh.v2beta1.DestinationPolicy.PortConfigsEntry - 12, // 1: hashicorp.consul.mesh.v2beta1.DestinationConfig.connect_timeout:type_name -> google.protobuf.Duration - 12, // 2: hashicorp.consul.mesh.v2beta1.DestinationConfig.request_timeout:type_name -> google.protobuf.Duration - 6, // 3: hashicorp.consul.mesh.v2beta1.DestinationConfig.load_balancer:type_name -> hashicorp.consul.mesh.v2beta1.LoadBalancer - 5, // 4: hashicorp.consul.mesh.v2beta1.DestinationConfig.locality_prioritization:type_name -> hashicorp.consul.mesh.v2beta1.LocalityPrioritization - 0, // 5: hashicorp.consul.mesh.v2beta1.LocalityPrioritization.mode:type_name -> hashicorp.consul.mesh.v2beta1.LocalityPrioritizationMode - 1, // 6: hashicorp.consul.mesh.v2beta1.LoadBalancer.policy:type_name -> hashicorp.consul.mesh.v2beta1.LoadBalancerPolicy - 9, // 7: hashicorp.consul.mesh.v2beta1.LoadBalancer.hash_policies:type_name -> hashicorp.consul.mesh.v2beta1.HashPolicy - 7, // 8: hashicorp.consul.mesh.v2beta1.LoadBalancer.ring_hash_config:type_name -> hashicorp.consul.mesh.v2beta1.RingHashConfig - 8, // 9: hashicorp.consul.mesh.v2beta1.LoadBalancer.least_request_config:type_name -> hashicorp.consul.mesh.v2beta1.LeastRequestConfig - 2, // 10: hashicorp.consul.mesh.v2beta1.HashPolicy.field:type_name -> hashicorp.consul.mesh.v2beta1.HashPolicyField - 10, // 11: hashicorp.consul.mesh.v2beta1.HashPolicy.cookie_config:type_name -> hashicorp.consul.mesh.v2beta1.CookieConfig - 12, // 12: hashicorp.consul.mesh.v2beta1.CookieConfig.ttl:type_name -> google.protobuf.Duration - 4, // 13: hashicorp.consul.mesh.v2beta1.DestinationPolicy.PortConfigsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.DestinationConfig - 14, // [14:14] is the sub-list for method output_type - 14, // [14:14] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_destination_policy_proto_init() } -func file_pbmesh_v2beta1_destination_policy_proto_init() { - if File_pbmesh_v2beta1_destination_policy_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LocalityPrioritization); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LoadBalancer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RingHashConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LeastRequestConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HashPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CookieConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_destination_policy_proto_msgTypes[3].OneofWrappers = []interface{}{ - (*LoadBalancer_RingHashConfig)(nil), - (*LoadBalancer_LeastRequestConfig)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_destination_policy_proto_rawDesc, - NumEnums: 3, - NumMessages: 9, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_destination_policy_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_destination_policy_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_destination_policy_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_destination_policy_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_destination_policy_proto = out.File - file_pbmesh_v2beta1_destination_policy_proto_rawDesc = nil - file_pbmesh_v2beta1_destination_policy_proto_goTypes = nil - file_pbmesh_v2beta1_destination_policy_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/destination_policy.proto b/proto-public/pbmesh/v2beta1/destination_policy.proto deleted file mode 100644 index 0a18fd8c49b6a..0000000000000 --- a/proto-public/pbmesh/v2beta1/destination_policy.proto +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "google/protobuf/duration.proto"; -import "pbresource/annotations.proto"; - -// DestinationPolicy is the destination-controlled set of defaults that -// are used when similar controls defined in an UpstreamConfig are left -// unspecified. -// -// Users may wish to share commonly configured settings for communicating with -// a service in one place, but yet retain the ability to tweak those on a -// client-by-client basis, which is why there are separate resources to control -// the definition of these values from either end of the connection. -// -// This is a Resource type. -message DestinationPolicy { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - map port_configs = 1; -} - -message DestinationConfig { - // ConnectTimeout is the timeout for establishing new network connections - // to this service. - // +kubebuilder:validation:Format=duration - google.protobuf.Duration connect_timeout = 1; - - // RequestTimeout is the timeout for an HTTP request to complete before the - // connection is automatically terminated. If unspecified, defaults to 15 - // seconds. - // +kubebuilder:validation:Format=duration - google.protobuf.Duration request_timeout = 2; - - // LoadBalancer determines the load balancing policy and configuration for - // services issuing requests to this upstream service. - LoadBalancer load_balancer = 3; - - // LocalityPrioritization controls whether the locality of services within the - // local partition will be used to prioritize connectivity. - LocalityPrioritization locality_prioritization = 4; -} - -message LocalityPrioritization { - // 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". - LocalityPrioritizationMode mode = 1; -} - -// +kubebuilder:validation:Enum=LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED;LOCALITY_PRIORITIZATION_MODE_NONE;LOCALITY_PRIORITIZATION_MODE_FAILOVER -// +kubebuilder:validation:Type=string -enum LocalityPrioritizationMode { - LOCALITY_PRIORITIZATION_MODE_UNSPECIFIED = 0; - LOCALITY_PRIORITIZATION_MODE_NONE = 1; - LOCALITY_PRIORITIZATION_MODE_FAILOVER = 2; -} - -// LoadBalancer determines the load balancing policy and configuration -// for services issuing requests to this upstream service. -// -message LoadBalancer { - // Policy is the load balancing policy used to select a host - LoadBalancerPolicy policy = 1; - - // HashPolicies is a list of hash policies to use for hashing load balancing - // algorithms. Hash policies are evaluated individually and combined such - // that identical lists result in the same hash. - // - // If no hash policies are present, or none are successfully evaluated, - // then a random backend host will be selected. - repeated HashPolicy hash_policies = 2; - - oneof config { - // RingHashConfig contains configuration for the "ring_hash" policy type - RingHashConfig ring_hash_config = 3; - - // LeastRequestConfig contains configuration for the "least_request" policy type - LeastRequestConfig least_request_config = 4; - } -} - -// +kubebuilder:validation:Enum=LOAD_BALANCER_POLICY_UNSPECIFIED;LOAD_BALANCER_POLICY_RANDOM;LOAD_BALANCER_POLICY_ROUND_ROBIN;LOAD_BALANCER_POLICY_LEAST_REQUEST;LOAD_BALANCER_POLICY_MAGLEV;LOAD_BALANCER_POLICY_RING_HASH -// +kubebuilder:validation:Type=string -enum LoadBalancerPolicy { - LOAD_BALANCER_POLICY_UNSPECIFIED = 0; - LOAD_BALANCER_POLICY_RANDOM = 1; - LOAD_BALANCER_POLICY_ROUND_ROBIN = 2; - LOAD_BALANCER_POLICY_LEAST_REQUEST = 3; - LOAD_BALANCER_POLICY_MAGLEV = 4; - LOAD_BALANCER_POLICY_RING_HASH = 5; -} - -// RingHashConfig contains configuration for the "ring_hash" policy type -message RingHashConfig { - // MinimumRingSize determines the minimum number of entries in the hash ring - uint64 minimum_ring_size = 1; - - // MaximumRingSize determines the maximum number of entries in the hash ring - uint64 maximum_ring_size = 2; -} - -// LeastRequestConfig contains configuration for the "least_request" policy type -message LeastRequestConfig { - // ChoiceCount determines the number of random healthy hosts from which to select the one with the least requests. - uint32 choice_count = 1; -} - -// HashPolicy defines which attributes will be hashed by hash-based LB algorithms -message HashPolicy { - // Field is the attribute type to hash on. - // Must be one of "header","cookie", or "query_parameter". - // Cannot be specified along with SourceIP. - HashPolicyField field = 1; - - // FieldValue is the value to hash. - // ie. header name, cookie name, URL query parameter name - // Cannot be specified along with SourceIP. - string field_value = 2; - - // CookieConfig contains configuration for the "cookie" hash policy type. - CookieConfig cookie_config = 3; - - // SourceIP determines whether the hash should be of the source IP rather than of a field and field value. - // Cannot be specified along with Field or FieldValue. - bool source_ip = 4; - - // Terminal will short circuit the computation of the hash when multiple hash policies are present. - // If a hash is computed when a Terminal policy is evaluated, - // then that hash will be used and subsequent hash policies will be ignored. - bool terminal = 5; -} - -// +kubebuilder:validation:Enum=HASH_POLICY_FIELD_UNSPECIFIED;HASH_POLICY_FIELD_HEADER;HASH_POLICY_FIELD_COOKIE;HASH_POLICY_FIELD_QUERY_PARAMETER -// +kubebuilder:validation:Type=string -enum HashPolicyField { - HASH_POLICY_FIELD_UNSPECIFIED = 0; - HASH_POLICY_FIELD_HEADER = 1; - HASH_POLICY_FIELD_COOKIE = 2; - HASH_POLICY_FIELD_QUERY_PARAMETER = 3; -} - -// CookieConfig contains configuration for the "cookie" hash policy type. -// This is specified to have Envoy generate a cookie for a client on its first request. -message CookieConfig { - // Generates a session cookie with no expiration. - bool session = 1; - - // TTL for generated cookies. Cannot be specified for session cookies. - // +kubebuilder:validation:Format=duration - google.protobuf.Duration ttl = 2; - - // The path to set for the cookie - string path = 3; -} diff --git a/proto-public/pbmesh/v2beta1/destination_policy_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/destination_policy_deepcopy.gen.go deleted file mode 100644 index 1935359729e59..0000000000000 --- a/proto-public/pbmesh/v2beta1/destination_policy_deepcopy.gen.go +++ /dev/null @@ -1,174 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using DestinationPolicy within kubernetes types, where deepcopy-gen is used. -func (in *DestinationPolicy) DeepCopyInto(out *DestinationPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationPolicy. Required by controller-gen. -func (in *DestinationPolicy) DeepCopy() *DestinationPolicy { - if in == nil { - return nil - } - out := new(DestinationPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationPolicy. Required by controller-gen. -func (in *DestinationPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DestinationConfig within kubernetes types, where deepcopy-gen is used. -func (in *DestinationConfig) DeepCopyInto(out *DestinationConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfig. Required by controller-gen. -func (in *DestinationConfig) DeepCopy() *DestinationConfig { - if in == nil { - return nil - } - out := new(DestinationConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfig. Required by controller-gen. -func (in *DestinationConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LocalityPrioritization within kubernetes types, where deepcopy-gen is used. -func (in *LocalityPrioritization) DeepCopyInto(out *LocalityPrioritization) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalityPrioritization. Required by controller-gen. -func (in *LocalityPrioritization) DeepCopy() *LocalityPrioritization { - if in == nil { - return nil - } - out := new(LocalityPrioritization) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LocalityPrioritization. Required by controller-gen. -func (in *LocalityPrioritization) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LoadBalancer within kubernetes types, where deepcopy-gen is used. -func (in *LoadBalancer) DeepCopyInto(out *LoadBalancer) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancer. Required by controller-gen. -func (in *LoadBalancer) DeepCopy() *LoadBalancer { - if in == nil { - return nil - } - out := new(LoadBalancer) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancer. Required by controller-gen. -func (in *LoadBalancer) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using RingHashConfig within kubernetes types, where deepcopy-gen is used. -func (in *RingHashConfig) DeepCopyInto(out *RingHashConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RingHashConfig. Required by controller-gen. -func (in *RingHashConfig) DeepCopy() *RingHashConfig { - if in == nil { - return nil - } - out := new(RingHashConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new RingHashConfig. Required by controller-gen. -func (in *RingHashConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LeastRequestConfig within kubernetes types, where deepcopy-gen is used. -func (in *LeastRequestConfig) DeepCopyInto(out *LeastRequestConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeastRequestConfig. Required by controller-gen. -func (in *LeastRequestConfig) DeepCopy() *LeastRequestConfig { - if in == nil { - return nil - } - out := new(LeastRequestConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LeastRequestConfig. Required by controller-gen. -func (in *LeastRequestConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HashPolicy within kubernetes types, where deepcopy-gen is used. -func (in *HashPolicy) DeepCopyInto(out *HashPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HashPolicy. Required by controller-gen. -func (in *HashPolicy) DeepCopy() *HashPolicy { - if in == nil { - return nil - } - out := new(HashPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HashPolicy. Required by controller-gen. -func (in *HashPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using CookieConfig within kubernetes types, where deepcopy-gen is used. -func (in *CookieConfig) DeepCopyInto(out *CookieConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookieConfig. Required by controller-gen. -func (in *CookieConfig) DeepCopy() *CookieConfig { - if in == nil { - return nil - } - out := new(CookieConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new CookieConfig. Required by controller-gen. -func (in *CookieConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/destination_policy_json.gen.go b/proto-public/pbmesh/v2beta1/destination_policy_json.gen.go deleted file mode 100644 index fc1c98b08d1e8..0000000000000 --- a/proto-public/pbmesh/v2beta1/destination_policy_json.gen.go +++ /dev/null @@ -1,99 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for DestinationPolicy -func (this *DestinationPolicy) MarshalJSON() ([]byte, error) { - str, err := DestinationPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationPolicy -func (this *DestinationPolicy) UnmarshalJSON(b []byte) error { - return DestinationPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DestinationConfig -func (this *DestinationConfig) MarshalJSON() ([]byte, error) { - str, err := DestinationPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationConfig -func (this *DestinationConfig) UnmarshalJSON(b []byte) error { - return DestinationPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LocalityPrioritization -func (this *LocalityPrioritization) MarshalJSON() ([]byte, error) { - str, err := DestinationPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LocalityPrioritization -func (this *LocalityPrioritization) UnmarshalJSON(b []byte) error { - return DestinationPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LoadBalancer -func (this *LoadBalancer) MarshalJSON() ([]byte, error) { - str, err := DestinationPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LoadBalancer -func (this *LoadBalancer) UnmarshalJSON(b []byte) error { - return DestinationPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for RingHashConfig -func (this *RingHashConfig) MarshalJSON() ([]byte, error) { - str, err := DestinationPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for RingHashConfig -func (this *RingHashConfig) UnmarshalJSON(b []byte) error { - return DestinationPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LeastRequestConfig -func (this *LeastRequestConfig) MarshalJSON() ([]byte, error) { - str, err := DestinationPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LeastRequestConfig -func (this *LeastRequestConfig) UnmarshalJSON(b []byte) error { - return DestinationPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HashPolicy -func (this *HashPolicy) MarshalJSON() ([]byte, error) { - str, err := DestinationPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HashPolicy -func (this *HashPolicy) UnmarshalJSON(b []byte) error { - return DestinationPolicyUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for CookieConfig -func (this *CookieConfig) MarshalJSON() ([]byte, error) { - str, err := DestinationPolicyMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for CookieConfig -func (this *CookieConfig) UnmarshalJSON(b []byte) error { - return DestinationPolicyUnmarshaler.Unmarshal(b, this) -} - -var ( - DestinationPolicyMarshaler = &protojson.MarshalOptions{} - DestinationPolicyUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/destinations.pb.binary.go b/proto-public/pbmesh/v2beta1/destinations.pb.binary.go deleted file mode 100644 index 6716785708c0b..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations.pb.binary.go +++ /dev/null @@ -1,58 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/destinations.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Destinations) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Destinations) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Destination) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Destination) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *IPPortAddress) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *IPPortAddress) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *UnixSocketAddress) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *UnixSocketAddress) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *PreparedQueryDestination) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PreparedQueryDestination) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/destinations.pb.go b/proto-public/pbmesh/v2beta1/destinations.pb.go deleted file mode 100644 index 623920c5145e1..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations.pb.go +++ /dev/null @@ -1,670 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/destinations.proto - -package meshv2beta1 - -import ( - v2beta1 "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Destinations struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Selection of workloads these destinations should apply to. - // These can be prefixes or specific workload names. - Workloads *v2beta1.WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` - // Destinations is the list of explicit destinations to define for the selected workloads. - Destinations []*Destination `protobuf:"bytes,2,rep,name=destinations,proto3" json:"destinations,omitempty"` - // PQDestinations is the list of prepared query destinations. This field is not supported directly in v2 - // and should only be used for migration reasons. - PqDestinations []*PreparedQueryDestination `protobuf:"bytes,3,rep,name=pq_destinations,json=pqDestinations,proto3" json:"pq_destinations,omitempty"` -} - -func (x *Destinations) Reset() { - *x = Destinations{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Destinations) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Destinations) ProtoMessage() {} - -func (x *Destinations) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Destinations.ProtoReflect.Descriptor instead. -func (*Destinations) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_proto_rawDescGZIP(), []int{0} -} - -func (x *Destinations) GetWorkloads() *v2beta1.WorkloadSelector { - if x != nil { - return x.Workloads - } - return nil -} - -func (x *Destinations) GetDestinations() []*Destination { - if x != nil { - return x.Destinations - } - return nil -} - -func (x *Destinations) GetPqDestinations() []*PreparedQueryDestination { - if x != nil { - return x.PqDestinations - } - return nil -} - -type Destination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // DestinationRef is the reference to an destination service. This has to be pbcatalog.Service type. - DestinationRef *pbresource.Reference `protobuf:"bytes,1,opt,name=destination_ref,json=destinationRef,proto3" json:"destination_ref,omitempty"` - // DestinationPort is the port name of the destination service. This should be the name - // of the service's target port. - DestinationPort string `protobuf:"bytes,2,opt,name=destination_port,json=destinationPort,proto3" json:"destination_port,omitempty"` - // Datacenter is the datacenter for where this destination service lives. - Datacenter string `protobuf:"bytes,3,opt,name=datacenter,proto3" json:"datacenter,omitempty"` - // ListenAddr is the address where Envoy will listen for requests to this destination. - // It can provided either as an ip:port or as a Unix domain socket. - // - // Types that are assignable to ListenAddr: - // - // *Destination_IpPort - // *Destination_Unix - ListenAddr isDestination_ListenAddr `protobuf_oneof:"listen_addr"` -} - -func (x *Destination) Reset() { - *x = Destination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Destination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Destination) ProtoMessage() {} - -func (x *Destination) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Destination.ProtoReflect.Descriptor instead. -func (*Destination) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_proto_rawDescGZIP(), []int{1} -} - -func (x *Destination) GetDestinationRef() *pbresource.Reference { - if x != nil { - return x.DestinationRef - } - return nil -} - -func (x *Destination) GetDestinationPort() string { - if x != nil { - return x.DestinationPort - } - return "" -} - -func (x *Destination) GetDatacenter() string { - if x != nil { - return x.Datacenter - } - return "" -} - -func (m *Destination) GetListenAddr() isDestination_ListenAddr { - if m != nil { - return m.ListenAddr - } - return nil -} - -func (x *Destination) GetIpPort() *IPPortAddress { - if x, ok := x.GetListenAddr().(*Destination_IpPort); ok { - return x.IpPort - } - return nil -} - -func (x *Destination) GetUnix() *UnixSocketAddress { - if x, ok := x.GetListenAddr().(*Destination_Unix); ok { - return x.Unix - } - return nil -} - -type isDestination_ListenAddr interface { - isDestination_ListenAddr() -} - -type Destination_IpPort struct { - IpPort *IPPortAddress `protobuf:"bytes,4,opt,name=ip_port,json=ipPort,proto3,oneof"` -} - -type Destination_Unix struct { - Unix *UnixSocketAddress `protobuf:"bytes,5,opt,name=unix,proto3,oneof"` -} - -func (*Destination_IpPort) isDestination_ListenAddr() {} - -func (*Destination_Unix) isDestination_ListenAddr() {} - -type IPPortAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ip is an IPv4 or an IPv6 address. - Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` - // port is the port number. - Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` -} - -func (x *IPPortAddress) Reset() { - *x = IPPortAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IPPortAddress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IPPortAddress) ProtoMessage() {} - -func (x *IPPortAddress) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IPPortAddress.ProtoReflect.Descriptor instead. -func (*IPPortAddress) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_proto_rawDescGZIP(), []int{2} -} - -func (x *IPPortAddress) GetIp() string { - if x != nil { - return x.Ip - } - return "" -} - -func (x *IPPortAddress) GetPort() uint32 { - if x != nil { - return x.Port - } - return 0 -} - -type UnixSocketAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Path is the file system path at which to bind a Unix domain socket listener. - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - // Mode is the Unix file mode for the socket file. It should be provided - // in the numeric notation, for example, "0600". - Mode string `protobuf:"bytes,2,opt,name=mode,proto3" json:"mode,omitempty"` -} - -func (x *UnixSocketAddress) Reset() { - *x = UnixSocketAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UnixSocketAddress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnixSocketAddress) ProtoMessage() {} - -func (x *UnixSocketAddress) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UnixSocketAddress.ProtoReflect.Descriptor instead. -func (*UnixSocketAddress) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_proto_rawDescGZIP(), []int{3} -} - -func (x *UnixSocketAddress) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -func (x *UnixSocketAddress) GetMode() string { - if x != nil { - return x.Mode - } - return "" -} - -type PreparedQueryDestination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Name is the name of the prepared query to use as an destination. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Datacenter is the datacenter for where this destination service lives. - Datacenter string `protobuf:"bytes,2,opt,name=datacenter,proto3" json:"datacenter,omitempty"` - // ListenAddr is the address where Envoy will listen for requests to this destination. - // It can provided either as an ip:port or as a Unix domain socket. - // - // Types that are assignable to ListenAddr: - // - // *PreparedQueryDestination_Tcp - // *PreparedQueryDestination_Unix - ListenAddr isPreparedQueryDestination_ListenAddr `protobuf_oneof:"listen_addr"` - DestinationConfig *DestinationConfiguration `protobuf:"bytes,6,opt,name=destination_config,json=destinationConfig,proto3" json:"destination_config,omitempty"` -} - -func (x *PreparedQueryDestination) Reset() { - *x = PreparedQueryDestination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PreparedQueryDestination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PreparedQueryDestination) ProtoMessage() {} - -func (x *PreparedQueryDestination) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PreparedQueryDestination.ProtoReflect.Descriptor instead. -func (*PreparedQueryDestination) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_proto_rawDescGZIP(), []int{4} -} - -func (x *PreparedQueryDestination) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *PreparedQueryDestination) GetDatacenter() string { - if x != nil { - return x.Datacenter - } - return "" -} - -func (m *PreparedQueryDestination) GetListenAddr() isPreparedQueryDestination_ListenAddr { - if m != nil { - return m.ListenAddr - } - return nil -} - -func (x *PreparedQueryDestination) GetTcp() *IPPortAddress { - if x, ok := x.GetListenAddr().(*PreparedQueryDestination_Tcp); ok { - return x.Tcp - } - return nil -} - -func (x *PreparedQueryDestination) GetUnix() *UnixSocketAddress { - if x, ok := x.GetListenAddr().(*PreparedQueryDestination_Unix); ok { - return x.Unix - } - return nil -} - -func (x *PreparedQueryDestination) GetDestinationConfig() *DestinationConfiguration { - if x != nil { - return x.DestinationConfig - } - return nil -} - -type isPreparedQueryDestination_ListenAddr interface { - isPreparedQueryDestination_ListenAddr() -} - -type PreparedQueryDestination_Tcp struct { - Tcp *IPPortAddress `protobuf:"bytes,4,opt,name=tcp,proto3,oneof"` -} - -type PreparedQueryDestination_Unix struct { - Unix *UnixSocketAddress `protobuf:"bytes,5,opt,name=unix,proto3,oneof"` -} - -func (*PreparedQueryDestination_Tcp) isPreparedQueryDestination_ListenAddr() {} - -func (*PreparedQueryDestination_Unix) isPreparedQueryDestination_ListenAddr() {} - -var File_pbmesh_v2beta1_destinations_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_destinations_proto_rawDesc = []byte{ - 0x0a, 0x21, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x1a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9a, - 0x02, 0x0a, 0x0c, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x50, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, - 0x73, 0x12, 0x4e, 0x0a, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x60, 0x0a, 0x0f, 0x70, 0x71, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x65, 0x70, 0x61, - 0x72, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x70, 0x71, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xc7, 0x02, 0x0a, 0x0b, - 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x0f, 0x64, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0e, 0x64, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, - 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, - 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x47, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x50, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x46, - 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x69, - 0x78, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, - 0x52, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x42, 0x0d, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x22, 0x33, 0x0a, 0x0d, 0x49, 0x50, 0x50, 0x6f, 0x72, 0x74, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x3b, 0x0a, 0x11, 0x55, 0x6e, - 0x69, 0x78, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0xcf, 0x02, 0x0a, 0x18, 0x50, 0x72, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, - 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, - 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x50, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x46, 0x0a, 0x04, 0x75, 0x6e, - 0x69, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x69, 0x78, 0x53, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x04, 0x75, 0x6e, - 0x69, 0x78, 0x12, 0x66, 0x0a, 0x12, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x0d, 0x0a, 0x0b, 0x6c, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x42, 0x92, 0x02, 0x0a, 0x21, 0x63, 0x6f, - 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, - 0x11, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, - 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, - 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, - 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, - 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, - 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, - 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_destinations_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_destinations_proto_rawDescData = file_pbmesh_v2beta1_destinations_proto_rawDesc -) - -func file_pbmesh_v2beta1_destinations_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_destinations_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_destinations_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_destinations_proto_rawDescData) - }) - return file_pbmesh_v2beta1_destinations_proto_rawDescData -} - -var file_pbmesh_v2beta1_destinations_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_pbmesh_v2beta1_destinations_proto_goTypes = []interface{}{ - (*Destinations)(nil), // 0: hashicorp.consul.mesh.v2beta1.Destinations - (*Destination)(nil), // 1: hashicorp.consul.mesh.v2beta1.Destination - (*IPPortAddress)(nil), // 2: hashicorp.consul.mesh.v2beta1.IPPortAddress - (*UnixSocketAddress)(nil), // 3: hashicorp.consul.mesh.v2beta1.UnixSocketAddress - (*PreparedQueryDestination)(nil), // 4: hashicorp.consul.mesh.v2beta1.PreparedQueryDestination - (*v2beta1.WorkloadSelector)(nil), // 5: hashicorp.consul.catalog.v2beta1.WorkloadSelector - (*pbresource.Reference)(nil), // 6: hashicorp.consul.resource.Reference - (*DestinationConfiguration)(nil), // 7: hashicorp.consul.mesh.v2beta1.DestinationConfiguration -} -var file_pbmesh_v2beta1_destinations_proto_depIdxs = []int32{ - 5, // 0: hashicorp.consul.mesh.v2beta1.Destinations.workloads:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadSelector - 1, // 1: hashicorp.consul.mesh.v2beta1.Destinations.destinations:type_name -> hashicorp.consul.mesh.v2beta1.Destination - 4, // 2: hashicorp.consul.mesh.v2beta1.Destinations.pq_destinations:type_name -> hashicorp.consul.mesh.v2beta1.PreparedQueryDestination - 6, // 3: hashicorp.consul.mesh.v2beta1.Destination.destination_ref:type_name -> hashicorp.consul.resource.Reference - 2, // 4: hashicorp.consul.mesh.v2beta1.Destination.ip_port:type_name -> hashicorp.consul.mesh.v2beta1.IPPortAddress - 3, // 5: hashicorp.consul.mesh.v2beta1.Destination.unix:type_name -> hashicorp.consul.mesh.v2beta1.UnixSocketAddress - 2, // 6: hashicorp.consul.mesh.v2beta1.PreparedQueryDestination.tcp:type_name -> hashicorp.consul.mesh.v2beta1.IPPortAddress - 3, // 7: hashicorp.consul.mesh.v2beta1.PreparedQueryDestination.unix:type_name -> hashicorp.consul.mesh.v2beta1.UnixSocketAddress - 7, // 8: hashicorp.consul.mesh.v2beta1.PreparedQueryDestination.destination_config:type_name -> hashicorp.consul.mesh.v2beta1.DestinationConfiguration - 9, // [9:9] is the sub-list for method output_type - 9, // [9:9] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_destinations_proto_init() } -func file_pbmesh_v2beta1_destinations_proto_init() { - if File_pbmesh_v2beta1_destinations_proto != nil { - return - } - file_pbmesh_v2beta1_destinations_configuration_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_destinations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Destinations); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destinations_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Destination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destinations_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IPPortAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destinations_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnixSocketAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destinations_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PreparedQueryDestination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_destinations_proto_msgTypes[1].OneofWrappers = []interface{}{ - (*Destination_IpPort)(nil), - (*Destination_Unix)(nil), - } - file_pbmesh_v2beta1_destinations_proto_msgTypes[4].OneofWrappers = []interface{}{ - (*PreparedQueryDestination_Tcp)(nil), - (*PreparedQueryDestination_Unix)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_destinations_proto_rawDesc, - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_destinations_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_destinations_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_destinations_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_destinations_proto = out.File - file_pbmesh_v2beta1_destinations_proto_rawDesc = nil - file_pbmesh_v2beta1_destinations_proto_goTypes = nil - file_pbmesh_v2beta1_destinations_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/destinations.proto b/proto-public/pbmesh/v2beta1/destinations.proto deleted file mode 100644 index 33c7ea9195975..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations.proto +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbcatalog/v2beta1/selector.proto"; -import "pbmesh/v2beta1/destinations_configuration.proto"; -import "pbresource/annotations.proto"; -import "pbresource/resource.proto"; - -message Destinations { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // Selection of workloads these destinations should apply to. - // These can be prefixes or specific workload names. - hashicorp.consul.catalog.v2beta1.WorkloadSelector workloads = 1; - - // Destinations is the list of explicit destinations to define for the selected workloads. - repeated Destination destinations = 2; - - // PQDestinations is the list of prepared query destinations. This field is not supported directly in v2 - // and should only be used for migration reasons. - repeated PreparedQueryDestination pq_destinations = 3; -} - -message Destination { - // DestinationRef is the reference to an destination service. This has to be pbcatalog.Service type. - hashicorp.consul.resource.Reference destination_ref = 1; - - // DestinationPort is the port name of the destination service. This should be the name - // of the service's target port. - string destination_port = 2; - - // Datacenter is the datacenter for where this destination service lives. - string datacenter = 3; - - // ListenAddr is the address where Envoy will listen for requests to this destination. - // It can provided either as an ip:port or as a Unix domain socket. - oneof listen_addr { - IPPortAddress ip_port = 4; - UnixSocketAddress unix = 5; - } -} - -message IPPortAddress { - // ip is an IPv4 or an IPv6 address. - string ip = 1; - - // port is the port number. - uint32 port = 2; -} - -message UnixSocketAddress { - // Path is the file system path at which to bind a Unix domain socket listener. - string path = 1; - - // Mode is the Unix file mode for the socket file. It should be provided - // in the numeric notation, for example, "0600". - string mode = 2; -} - -message PreparedQueryDestination { - // Name is the name of the prepared query to use as an destination. - string name = 1; - - // Datacenter is the datacenter for where this destination service lives. - string datacenter = 2; - - // ListenAddr is the address where Envoy will listen for requests to this destination. - // It can provided either as an ip:port or as a Unix domain socket. - oneof listen_addr { - IPPortAddress tcp = 4; - UnixSocketAddress unix = 5; - } - - DestinationConfiguration destination_config = 6; -} diff --git a/proto-public/pbmesh/v2beta1/destinations_configuration.pb.binary.go b/proto-public/pbmesh/v2beta1/destinations_configuration.pb.binary.go deleted file mode 100644 index 7aa00d90651d9..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations_configuration.pb.binary.go +++ /dev/null @@ -1,58 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/destinations_configuration.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationsConfiguration) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationsConfiguration) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationConfigOverrides) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationConfigOverrides) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationConfiguration) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationConfiguration) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationLimits) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationLimits) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *PassiveHealthCheck) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PassiveHealthCheck) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/destinations_configuration.pb.go b/proto-public/pbmesh/v2beta1/destinations_configuration.pb.go deleted file mode 100644 index 2e6a8f5e969d8..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations_configuration.pb.go +++ /dev/null @@ -1,701 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/destinations_configuration.proto - -package meshv2beta1 - -import ( - v2beta1 "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type DestinationsConfiguration struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Selection of workloads these destinations should apply to. - // These can be prefixes or specific workload names. - Workloads *v2beta1.WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` - // DefaultConfig applies to all destinations for the workloads selected by this resource. - DefaultConfig *DestinationConfiguration `protobuf:"bytes,2,opt,name=default_config,json=defaultConfig,proto3" json:"default_config,omitempty"` - // ConfigOverrides provides per-destination or per-destination-port config overrides. - ConfigOverrides []*DestinationConfigOverrides `protobuf:"bytes,3,rep,name=config_overrides,json=configOverrides,proto3" json:"config_overrides,omitempty"` -} - -func (x *DestinationsConfiguration) Reset() { - *x = DestinationsConfiguration{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationsConfiguration) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationsConfiguration) ProtoMessage() {} - -func (x *DestinationsConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationsConfiguration.ProtoReflect.Descriptor instead. -func (*DestinationsConfiguration) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_configuration_proto_rawDescGZIP(), []int{0} -} - -func (x *DestinationsConfiguration) GetWorkloads() *v2beta1.WorkloadSelector { - if x != nil { - return x.Workloads - } - return nil -} - -func (x *DestinationsConfiguration) GetDefaultConfig() *DestinationConfiguration { - if x != nil { - return x.DefaultConfig - } - return nil -} - -func (x *DestinationsConfiguration) GetConfigOverrides() []*DestinationConfigOverrides { - if x != nil { - return x.ConfigOverrides - } - return nil -} - -// UpstreamConfigOverrides allow to override destination configuration per destination_ref/port/datacenter. -// In that sense, those three fields (destination_ref, destination_port and datacenter) are treated -// sort of like map keys and config is a like a map value for that key. -type DestinationConfigOverrides struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // DestinationRef is the reference to an destination service that this configuration applies to. - // This has to be pbcatalog.Service type. - DestinationRef *pbresource.Reference `protobuf:"bytes,1,opt,name=destination_ref,json=destinationRef,proto3" json:"destination_ref,omitempty"` - // DestinationPort is the port name of the destination service. This should be the name - // of the service's target port. If not provided, this configuration will apply to all ports of an destination. - DestinationPort string `protobuf:"bytes,2,opt,name=destination_port,json=destinationPort,proto3" json:"destination_port,omitempty"` - // Datacenter is the datacenter for where this destination service lives. - Datacenter string `protobuf:"bytes,3,opt,name=datacenter,proto3" json:"datacenter,omitempty"` - // Config is the configuration that should apply to this destination. - Config *DestinationConfiguration `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` -} - -func (x *DestinationConfigOverrides) Reset() { - *x = DestinationConfigOverrides{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationConfigOverrides) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationConfigOverrides) ProtoMessage() {} - -func (x *DestinationConfigOverrides) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationConfigOverrides.ProtoReflect.Descriptor instead. -func (*DestinationConfigOverrides) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_configuration_proto_rawDescGZIP(), []int{1} -} - -func (x *DestinationConfigOverrides) GetDestinationRef() *pbresource.Reference { - if x != nil { - return x.DestinationRef - } - return nil -} - -func (x *DestinationConfigOverrides) GetDestinationPort() string { - if x != nil { - return x.DestinationPort - } - return "" -} - -func (x *DestinationConfigOverrides) GetDatacenter() string { - if x != nil { - return x.Datacenter - } - return "" -} - -func (x *DestinationConfigOverrides) GetConfig() *DestinationConfiguration { - if x != nil { - return x.Config - } - return nil -} - -type DestinationConfiguration struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Protocol overrides destination's port protocol. If no port for an destination is specified - // or if used in the default configuration, this protocol will be used for all ports - // or for all ports of all destinations respectively. - Protocol v2beta1.Protocol `protobuf:"varint,1,opt,name=protocol,proto3,enum=hashicorp.consul.catalog.v2beta1.Protocol" json:"protocol,omitempty"` - // ConnectTimeout is the timeout used when making a new - // connection to this destination. Defaults to 5 seconds if not set. - // +kubebuilder:validation:Format=duration - ConnectTimeout *durationpb.Duration `protobuf:"bytes,2,opt,name=connect_timeout,json=connectTimeout,proto3" json:"connect_timeout,omitempty"` - // Limits are the set of limits that are applied to the proxy for a specific destination. - Limits *DestinationLimits `protobuf:"bytes,3,opt,name=limits,proto3" json:"limits,omitempty"` - // PassiveHealthCheck configuration determines how destination proxy instances will - // be monitored for removal from the load balancing pool. - PassiveHealthCheck *PassiveHealthCheck `protobuf:"bytes,4,opt,name=passive_health_check,json=passiveHealthCheck,proto3" json:"passive_health_check,omitempty"` - // BalanceOutboundConnections indicates how the proxy should attempt to distribute - // connections across worker threads. - BalanceOutboundConnections BalanceConnections `protobuf:"varint,5,opt,name=balance_outbound_connections,json=balanceOutboundConnections,proto3,enum=hashicorp.consul.mesh.v2beta1.BalanceConnections" json:"balance_outbound_connections,omitempty"` - // MeshGatewayMode is the Mesh Gateway routing mode. - MeshGatewayMode MeshGatewayMode `protobuf:"varint,6,opt,name=mesh_gateway_mode,json=meshGatewayMode,proto3,enum=hashicorp.consul.mesh.v2beta1.MeshGatewayMode" json:"mesh_gateway_mode,omitempty"` -} - -func (x *DestinationConfiguration) Reset() { - *x = DestinationConfiguration{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationConfiguration) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationConfiguration) ProtoMessage() {} - -func (x *DestinationConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationConfiguration.ProtoReflect.Descriptor instead. -func (*DestinationConfiguration) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_configuration_proto_rawDescGZIP(), []int{2} -} - -func (x *DestinationConfiguration) GetProtocol() v2beta1.Protocol { - if x != nil { - return x.Protocol - } - return v2beta1.Protocol(0) -} - -func (x *DestinationConfiguration) GetConnectTimeout() *durationpb.Duration { - if x != nil { - return x.ConnectTimeout - } - return nil -} - -func (x *DestinationConfiguration) GetLimits() *DestinationLimits { - if x != nil { - return x.Limits - } - return nil -} - -func (x *DestinationConfiguration) GetPassiveHealthCheck() *PassiveHealthCheck { - if x != nil { - return x.PassiveHealthCheck - } - return nil -} - -func (x *DestinationConfiguration) GetBalanceOutboundConnections() BalanceConnections { - if x != nil { - return x.BalanceOutboundConnections - } - return BalanceConnections_BALANCE_CONNECTIONS_DEFAULT -} - -func (x *DestinationConfiguration) GetMeshGatewayMode() MeshGatewayMode { - if x != nil { - return x.MeshGatewayMode - } - return MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED -} - -// UpstreamLimits describes the limits that are associated with a specific -// destination of a service instance. -type DestinationLimits struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // MaxConnections is the maximum number of connections the local proxy can - // make to the destination service. - MaxConnections *wrapperspb.UInt32Value `protobuf:"bytes,1,opt,name=max_connections,json=maxConnections,proto3" json:"max_connections,omitempty"` - // MaxPendingRequests is the maximum number of requests that will be queued - // waiting for an available connection. This is mostly applicable to HTTP/1.1 - // clusters since all HTTP/2 requests are streamed over a single - // connection. - MaxPendingRequests *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=max_pending_requests,json=maxPendingRequests,proto3" json:"max_pending_requests,omitempty"` - // MaxConcurrentRequests is the maximum number of in-flight requests that will be allowed - // to the destination cluster at a point in time. This is mostly applicable to HTTP/2 - // clusters since all HTTP/1.1 requests are limited by MaxConnections. - MaxConcurrentRequests *wrapperspb.UInt32Value `protobuf:"bytes,3,opt,name=max_concurrent_requests,json=maxConcurrentRequests,proto3" json:"max_concurrent_requests,omitempty"` -} - -func (x *DestinationLimits) Reset() { - *x = DestinationLimits{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationLimits) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationLimits) ProtoMessage() {} - -func (x *DestinationLimits) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationLimits.ProtoReflect.Descriptor instead. -func (*DestinationLimits) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_configuration_proto_rawDescGZIP(), []int{3} -} - -func (x *DestinationLimits) GetMaxConnections() *wrapperspb.UInt32Value { - if x != nil { - return x.MaxConnections - } - return nil -} - -func (x *DestinationLimits) GetMaxPendingRequests() *wrapperspb.UInt32Value { - if x != nil { - return x.MaxPendingRequests - } - return nil -} - -func (x *DestinationLimits) GetMaxConcurrentRequests() *wrapperspb.UInt32Value { - if x != nil { - return x.MaxConcurrentRequests - } - return nil -} - -type PassiveHealthCheck struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Interval between health check analysis sweeps. Each sweep may remove - // hosts or return hosts to the pool. - // +kubebuilder:validation:Format=duration - Interval *durationpb.Duration `protobuf:"bytes,1,opt,name=interval,proto3" json:"interval,omitempty"` - // MaxFailures is the count of consecutive failures that results in a host - // being removed from the pool. - MaxFailures uint32 `protobuf:"varint,2,opt,name=max_failures,json=maxFailures,proto3" json:"max_failures,omitempty"` - // EnforcingConsecutive5XX is the % chance that a host will be actually ejected - // when an outlier status is detected through consecutive 5xx. - // This setting can be used to disable ejection or to ramp it up slowly. Defaults to 100. - EnforcingConsecutive_5Xx uint32 `protobuf:"varint,3,opt,name=enforcing_consecutive_5xx,json=enforcingConsecutive5xx,proto3" json:"enforcing_consecutive_5xx,omitempty"` -} - -func (x *PassiveHealthCheck) Reset() { - *x = PassiveHealthCheck{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PassiveHealthCheck) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PassiveHealthCheck) ProtoMessage() {} - -func (x *PassiveHealthCheck) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PassiveHealthCheck.ProtoReflect.Descriptor instead. -func (*PassiveHealthCheck) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_destinations_configuration_proto_rawDescGZIP(), []int{4} -} - -func (x *PassiveHealthCheck) GetInterval() *durationpb.Duration { - if x != nil { - return x.Interval - } - return nil -} - -func (x *PassiveHealthCheck) GetMaxFailures() uint32 { - if x != nil { - return x.MaxFailures - } - return 0 -} - -func (x *PassiveHealthCheck) GetEnforcingConsecutive_5Xx() uint32 { - if x != nil { - return x.EnforcingConsecutive_5Xx - } - return 0 -} - -var File_pbmesh_v2beta1_destinations_configuration_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_destinations_configuration_proto_rawDesc = []byte{ - 0x0a, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2f, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbb, 0x02, 0x0a, - 0x19, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x09, 0x77, 0x6f, - 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x5e, 0x0a, 0x0e, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x64, 0x0a, 0x10, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, - 0x73, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, - 0x65, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x87, 0x02, 0x0a, 0x1a, 0x44, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x0f, 0x64, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0e, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x66, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, - 0x74, 0x65, 0x72, 0x12, 0x4f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x22, 0xa6, 0x04, 0x0a, 0x18, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x46, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x42, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x48, 0x0a, - 0x06, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, - 0x06, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x63, 0x0a, 0x14, 0x70, 0x61, 0x73, 0x73, 0x69, - 0x76, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x12, 0x70, 0x61, 0x73, 0x73, 0x69, 0x76, - 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x73, 0x0a, 0x1c, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x1a, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x75, - 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x5a, 0x0a, 0x11, 0x6d, 0x65, 0x73, 0x68, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x65, 0x73, - 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0f, 0x6d, 0x65, - 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x80, 0x02, - 0x0a, 0x11, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x6d, - 0x69, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, - 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4e, 0x0a, 0x14, 0x6d, 0x61, - 0x78, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, - 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x54, 0x0a, 0x17, 0x6d, 0x61, - 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, - 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x43, 0x6f, - 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, - 0x22, 0xaa, 0x01, 0x0a, 0x12, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x21, - 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, - 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, - 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x35, 0x78, 0x78, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x69, 0x6e, 0x67, 0x43, - 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, 0x78, 0x78, 0x42, 0x9f, 0x02, - 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x1e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, - 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, - 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, - 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_destinations_configuration_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_destinations_configuration_proto_rawDescData = file_pbmesh_v2beta1_destinations_configuration_proto_rawDesc -) - -func file_pbmesh_v2beta1_destinations_configuration_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_destinations_configuration_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_destinations_configuration_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_destinations_configuration_proto_rawDescData) - }) - return file_pbmesh_v2beta1_destinations_configuration_proto_rawDescData -} - -var file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_pbmesh_v2beta1_destinations_configuration_proto_goTypes = []interface{}{ - (*DestinationsConfiguration)(nil), // 0: hashicorp.consul.mesh.v2beta1.DestinationsConfiguration - (*DestinationConfigOverrides)(nil), // 1: hashicorp.consul.mesh.v2beta1.DestinationConfigOverrides - (*DestinationConfiguration)(nil), // 2: hashicorp.consul.mesh.v2beta1.DestinationConfiguration - (*DestinationLimits)(nil), // 3: hashicorp.consul.mesh.v2beta1.DestinationLimits - (*PassiveHealthCheck)(nil), // 4: hashicorp.consul.mesh.v2beta1.PassiveHealthCheck - (*v2beta1.WorkloadSelector)(nil), // 5: hashicorp.consul.catalog.v2beta1.WorkloadSelector - (*pbresource.Reference)(nil), // 6: hashicorp.consul.resource.Reference - (v2beta1.Protocol)(0), // 7: hashicorp.consul.catalog.v2beta1.Protocol - (*durationpb.Duration)(nil), // 8: google.protobuf.Duration - (BalanceConnections)(0), // 9: hashicorp.consul.mesh.v2beta1.BalanceConnections - (MeshGatewayMode)(0), // 10: hashicorp.consul.mesh.v2beta1.MeshGatewayMode - (*wrapperspb.UInt32Value)(nil), // 11: google.protobuf.UInt32Value -} -var file_pbmesh_v2beta1_destinations_configuration_proto_depIdxs = []int32{ - 5, // 0: hashicorp.consul.mesh.v2beta1.DestinationsConfiguration.workloads:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadSelector - 2, // 1: hashicorp.consul.mesh.v2beta1.DestinationsConfiguration.default_config:type_name -> hashicorp.consul.mesh.v2beta1.DestinationConfiguration - 1, // 2: hashicorp.consul.mesh.v2beta1.DestinationsConfiguration.config_overrides:type_name -> hashicorp.consul.mesh.v2beta1.DestinationConfigOverrides - 6, // 3: hashicorp.consul.mesh.v2beta1.DestinationConfigOverrides.destination_ref:type_name -> hashicorp.consul.resource.Reference - 2, // 4: hashicorp.consul.mesh.v2beta1.DestinationConfigOverrides.config:type_name -> hashicorp.consul.mesh.v2beta1.DestinationConfiguration - 7, // 5: hashicorp.consul.mesh.v2beta1.DestinationConfiguration.protocol:type_name -> hashicorp.consul.catalog.v2beta1.Protocol - 8, // 6: hashicorp.consul.mesh.v2beta1.DestinationConfiguration.connect_timeout:type_name -> google.protobuf.Duration - 3, // 7: hashicorp.consul.mesh.v2beta1.DestinationConfiguration.limits:type_name -> hashicorp.consul.mesh.v2beta1.DestinationLimits - 4, // 8: hashicorp.consul.mesh.v2beta1.DestinationConfiguration.passive_health_check:type_name -> hashicorp.consul.mesh.v2beta1.PassiveHealthCheck - 9, // 9: hashicorp.consul.mesh.v2beta1.DestinationConfiguration.balance_outbound_connections:type_name -> hashicorp.consul.mesh.v2beta1.BalanceConnections - 10, // 10: hashicorp.consul.mesh.v2beta1.DestinationConfiguration.mesh_gateway_mode:type_name -> hashicorp.consul.mesh.v2beta1.MeshGatewayMode - 11, // 11: hashicorp.consul.mesh.v2beta1.DestinationLimits.max_connections:type_name -> google.protobuf.UInt32Value - 11, // 12: hashicorp.consul.mesh.v2beta1.DestinationLimits.max_pending_requests:type_name -> google.protobuf.UInt32Value - 11, // 13: hashicorp.consul.mesh.v2beta1.DestinationLimits.max_concurrent_requests:type_name -> google.protobuf.UInt32Value - 8, // 14: hashicorp.consul.mesh.v2beta1.PassiveHealthCheck.interval:type_name -> google.protobuf.Duration - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_destinations_configuration_proto_init() } -func file_pbmesh_v2beta1_destinations_configuration_proto_init() { - if File_pbmesh_v2beta1_destinations_configuration_proto != nil { - return - } - file_pbmesh_v2beta1_connection_proto_init() - file_pbmesh_v2beta1_routing_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationsConfiguration); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationConfigOverrides); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationConfiguration); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationLimits); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PassiveHealthCheck); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_destinations_configuration_proto_rawDesc, - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_destinations_configuration_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_destinations_configuration_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_destinations_configuration_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_destinations_configuration_proto = out.File - file_pbmesh_v2beta1_destinations_configuration_proto_rawDesc = nil - file_pbmesh_v2beta1_destinations_configuration_proto_goTypes = nil - file_pbmesh_v2beta1_destinations_configuration_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/destinations_configuration.proto b/proto-public/pbmesh/v2beta1/destinations_configuration.proto deleted file mode 100644 index facdde6e1f5a5..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations_configuration.proto +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "google/protobuf/duration.proto"; -import "google/protobuf/wrappers.proto"; -import "pbcatalog/v2beta1/protocol.proto"; -import "pbcatalog/v2beta1/selector.proto"; -import "pbmesh/v2beta1/connection.proto"; -import "pbmesh/v2beta1/routing.proto"; -import "pbresource/annotations.proto"; -import "pbresource/resource.proto"; - -message DestinationsConfiguration { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // Selection of workloads these destinations should apply to. - // These can be prefixes or specific workload names. - hashicorp.consul.catalog.v2beta1.WorkloadSelector workloads = 1; - - // DefaultConfig applies to all destinations for the workloads selected by this resource. - DestinationConfiguration default_config = 2; - - // ConfigOverrides provides per-destination or per-destination-port config overrides. - repeated DestinationConfigOverrides config_overrides = 3; -} - -// UpstreamConfigOverrides allow to override destination configuration per destination_ref/port/datacenter. -// In that sense, those three fields (destination_ref, destination_port and datacenter) are treated -// sort of like map keys and config is a like a map value for that key. -message DestinationConfigOverrides { - // DestinationRef is the reference to an destination service that this configuration applies to. - // This has to be pbcatalog.Service type. - hashicorp.consul.resource.Reference destination_ref = 1; - - // DestinationPort is the port name of the destination service. This should be the name - // of the service's target port. If not provided, this configuration will apply to all ports of an destination. - string destination_port = 2; - - // Datacenter is the datacenter for where this destination service lives. - string datacenter = 3; - - // Config is the configuration that should apply to this destination. - DestinationConfiguration config = 4; -} - -message DestinationConfiguration { - // Protocol overrides destination's port protocol. If no port for an destination is specified - // or if used in the default configuration, this protocol will be used for all ports - // or for all ports of all destinations respectively. - hashicorp.consul.catalog.v2beta1.Protocol protocol = 1; - - // ConnectTimeout is the timeout used when making a new - // connection to this destination. Defaults to 5 seconds if not set. - // +kubebuilder:validation:Format=duration - google.protobuf.Duration connect_timeout = 2; - - // Limits are the set of limits that are applied to the proxy for a specific destination. - DestinationLimits limits = 3; - - // PassiveHealthCheck configuration determines how destination proxy instances will - // be monitored for removal from the load balancing pool. - PassiveHealthCheck passive_health_check = 4; - - // BalanceOutboundConnections indicates how the proxy should attempt to distribute - // connections across worker threads. - BalanceConnections balance_outbound_connections = 5; - - // MeshGatewayMode is the Mesh Gateway routing mode. - MeshGatewayMode mesh_gateway_mode = 6; -} - -// UpstreamLimits describes the limits that are associated with a specific -// destination of a service instance. -message DestinationLimits { - // MaxConnections is the maximum number of connections the local proxy can - // make to the destination service. - google.protobuf.UInt32Value max_connections = 1; - - // MaxPendingRequests is the maximum number of requests that will be queued - // waiting for an available connection. This is mostly applicable to HTTP/1.1 - // clusters since all HTTP/2 requests are streamed over a single - // connection. - google.protobuf.UInt32Value max_pending_requests = 2; - - // MaxConcurrentRequests is the maximum number of in-flight requests that will be allowed - // to the destination cluster at a point in time. This is mostly applicable to HTTP/2 - // clusters since all HTTP/1.1 requests are limited by MaxConnections. - google.protobuf.UInt32Value max_concurrent_requests = 3; -} - -message PassiveHealthCheck { - // Interval between health check analysis sweeps. Each sweep may remove - // hosts or return hosts to the pool. - // +kubebuilder:validation:Format=duration - google.protobuf.Duration interval = 1; - - // MaxFailures is the count of consecutive failures that results in a host - // being removed from the pool. - uint32 max_failures = 2; - - // EnforcingConsecutive5XX is the % chance that a host will be actually ejected - // when an outlier status is detected through consecutive 5xx. - // This setting can be used to disable ejection or to ramp it up slowly. Defaults to 100. - uint32 enforcing_consecutive_5xx = 3; -} diff --git a/proto-public/pbmesh/v2beta1/destinations_configuration_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/destinations_configuration_deepcopy.gen.go deleted file mode 100644 index 1c7f04e7f23aa..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations_configuration_deepcopy.gen.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using DestinationsConfiguration within kubernetes types, where deepcopy-gen is used. -func (in *DestinationsConfiguration) DeepCopyInto(out *DestinationsConfiguration) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationsConfiguration. Required by controller-gen. -func (in *DestinationsConfiguration) DeepCopy() *DestinationsConfiguration { - if in == nil { - return nil - } - out := new(DestinationsConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationsConfiguration. Required by controller-gen. -func (in *DestinationsConfiguration) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DestinationConfigOverrides within kubernetes types, where deepcopy-gen is used. -func (in *DestinationConfigOverrides) DeepCopyInto(out *DestinationConfigOverrides) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfigOverrides. Required by controller-gen. -func (in *DestinationConfigOverrides) DeepCopy() *DestinationConfigOverrides { - if in == nil { - return nil - } - out := new(DestinationConfigOverrides) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfigOverrides. Required by controller-gen. -func (in *DestinationConfigOverrides) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DestinationConfiguration within kubernetes types, where deepcopy-gen is used. -func (in *DestinationConfiguration) DeepCopyInto(out *DestinationConfiguration) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfiguration. Required by controller-gen. -func (in *DestinationConfiguration) DeepCopy() *DestinationConfiguration { - if in == nil { - return nil - } - out := new(DestinationConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfiguration. Required by controller-gen. -func (in *DestinationConfiguration) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DestinationLimits within kubernetes types, where deepcopy-gen is used. -func (in *DestinationLimits) DeepCopyInto(out *DestinationLimits) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationLimits. Required by controller-gen. -func (in *DestinationLimits) DeepCopy() *DestinationLimits { - if in == nil { - return nil - } - out := new(DestinationLimits) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationLimits. Required by controller-gen. -func (in *DestinationLimits) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using PassiveHealthCheck within kubernetes types, where deepcopy-gen is used. -func (in *PassiveHealthCheck) DeepCopyInto(out *PassiveHealthCheck) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PassiveHealthCheck. Required by controller-gen. -func (in *PassiveHealthCheck) DeepCopy() *PassiveHealthCheck { - if in == nil { - return nil - } - out := new(PassiveHealthCheck) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new PassiveHealthCheck. Required by controller-gen. -func (in *PassiveHealthCheck) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/destinations_configuration_json.gen.go b/proto-public/pbmesh/v2beta1/destinations_configuration_json.gen.go deleted file mode 100644 index f8daafdbeb513..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations_configuration_json.gen.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for DestinationsConfiguration -func (this *DestinationsConfiguration) MarshalJSON() ([]byte, error) { - str, err := DestinationsConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationsConfiguration -func (this *DestinationsConfiguration) UnmarshalJSON(b []byte) error { - return DestinationsConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DestinationConfigOverrides -func (this *DestinationConfigOverrides) MarshalJSON() ([]byte, error) { - str, err := DestinationsConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationConfigOverrides -func (this *DestinationConfigOverrides) UnmarshalJSON(b []byte) error { - return DestinationsConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DestinationConfiguration -func (this *DestinationConfiguration) MarshalJSON() ([]byte, error) { - str, err := DestinationsConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationConfiguration -func (this *DestinationConfiguration) UnmarshalJSON(b []byte) error { - return DestinationsConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DestinationLimits -func (this *DestinationLimits) MarshalJSON() ([]byte, error) { - str, err := DestinationsConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationLimits -func (this *DestinationLimits) UnmarshalJSON(b []byte) error { - return DestinationsConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for PassiveHealthCheck -func (this *PassiveHealthCheck) MarshalJSON() ([]byte, error) { - str, err := DestinationsConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for PassiveHealthCheck -func (this *PassiveHealthCheck) UnmarshalJSON(b []byte) error { - return DestinationsConfigurationUnmarshaler.Unmarshal(b, this) -} - -var ( - DestinationsConfigurationMarshaler = &protojson.MarshalOptions{} - DestinationsConfigurationUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/destinations_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/destinations_deepcopy.gen.go deleted file mode 100644 index 3f513b7d861d0..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations_deepcopy.gen.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Destinations within kubernetes types, where deepcopy-gen is used. -func (in *Destinations) DeepCopyInto(out *Destinations) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Destinations. Required by controller-gen. -func (in *Destinations) DeepCopy() *Destinations { - if in == nil { - return nil - } - out := new(Destinations) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Destinations. Required by controller-gen. -func (in *Destinations) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Destination within kubernetes types, where deepcopy-gen is used. -func (in *Destination) DeepCopyInto(out *Destination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Destination. Required by controller-gen. -func (in *Destination) DeepCopy() *Destination { - if in == nil { - return nil - } - out := new(Destination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Destination. Required by controller-gen. -func (in *Destination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using IPPortAddress within kubernetes types, where deepcopy-gen is used. -func (in *IPPortAddress) DeepCopyInto(out *IPPortAddress) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPortAddress. Required by controller-gen. -func (in *IPPortAddress) DeepCopy() *IPPortAddress { - if in == nil { - return nil - } - out := new(IPPortAddress) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new IPPortAddress. Required by controller-gen. -func (in *IPPortAddress) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using UnixSocketAddress within kubernetes types, where deepcopy-gen is used. -func (in *UnixSocketAddress) DeepCopyInto(out *UnixSocketAddress) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnixSocketAddress. Required by controller-gen. -func (in *UnixSocketAddress) DeepCopy() *UnixSocketAddress { - if in == nil { - return nil - } - out := new(UnixSocketAddress) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new UnixSocketAddress. Required by controller-gen. -func (in *UnixSocketAddress) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using PreparedQueryDestination within kubernetes types, where deepcopy-gen is used. -func (in *PreparedQueryDestination) DeepCopyInto(out *PreparedQueryDestination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreparedQueryDestination. Required by controller-gen. -func (in *PreparedQueryDestination) DeepCopy() *PreparedQueryDestination { - if in == nil { - return nil - } - out := new(PreparedQueryDestination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new PreparedQueryDestination. Required by controller-gen. -func (in *PreparedQueryDestination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/destinations_json.gen.go b/proto-public/pbmesh/v2beta1/destinations_json.gen.go deleted file mode 100644 index 989540524ef03..0000000000000 --- a/proto-public/pbmesh/v2beta1/destinations_json.gen.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Destinations -func (this *Destinations) MarshalJSON() ([]byte, error) { - str, err := DestinationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Destinations -func (this *Destinations) UnmarshalJSON(b []byte) error { - return DestinationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Destination -func (this *Destination) MarshalJSON() ([]byte, error) { - str, err := DestinationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Destination -func (this *Destination) UnmarshalJSON(b []byte) error { - return DestinationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for IPPortAddress -func (this *IPPortAddress) MarshalJSON() ([]byte, error) { - str, err := DestinationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for IPPortAddress -func (this *IPPortAddress) UnmarshalJSON(b []byte) error { - return DestinationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for UnixSocketAddress -func (this *UnixSocketAddress) MarshalJSON() ([]byte, error) { - str, err := DestinationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for UnixSocketAddress -func (this *UnixSocketAddress) UnmarshalJSON(b []byte) error { - return DestinationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for PreparedQueryDestination -func (this *PreparedQueryDestination) MarshalJSON() ([]byte, error) { - str, err := DestinationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for PreparedQueryDestination -func (this *PreparedQueryDestination) UnmarshalJSON(b []byte) error { - return DestinationsUnmarshaler.Unmarshal(b, this) -} - -var ( - DestinationsMarshaler = &protojson.MarshalOptions{} - DestinationsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/expose.pb.go b/proto-public/pbmesh/v2beta1/expose.pb.go deleted file mode 100644 index 63958a4b4f213..0000000000000 --- a/proto-public/pbmesh/v2beta1/expose.pb.go +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/expose.proto - -package meshv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=EXPOSE_PATH_PROTOCOL_HTTP;EXPOSE_PATH_PROTOCOL_HTTP2 -// +kubebuilder:validation:Type=string -type ExposePathProtocol int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP ExposePathProtocol = 0 - ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2 ExposePathProtocol = 1 -) - -// Enum value maps for ExposePathProtocol. -var ( - ExposePathProtocol_name = map[int32]string{ - 0: "EXPOSE_PATH_PROTOCOL_HTTP", - 1: "EXPOSE_PATH_PROTOCOL_HTTP2", - } - ExposePathProtocol_value = map[string]int32{ - "EXPOSE_PATH_PROTOCOL_HTTP": 0, - "EXPOSE_PATH_PROTOCOL_HTTP2": 1, - } -) - -func (x ExposePathProtocol) Enum() *ExposePathProtocol { - p := new(ExposePathProtocol) - *p = x - return p -} - -func (x ExposePathProtocol) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (ExposePathProtocol) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_expose_proto_enumTypes[0].Descriptor() -} - -func (ExposePathProtocol) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_expose_proto_enumTypes[0] -} - -func (x ExposePathProtocol) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ExposePathProtocol.Descriptor instead. -func (ExposePathProtocol) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_expose_proto_rawDescGZIP(), []int{0} -} - -type ExposeConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ExposePaths []*ExposePath `protobuf:"bytes,1,rep,name=expose_paths,json=exposePaths,proto3" json:"expose_paths,omitempty"` -} - -func (x *ExposeConfig) Reset() { - *x = ExposeConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_expose_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExposeConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExposeConfig) ProtoMessage() {} - -func (x *ExposeConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_expose_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExposeConfig.ProtoReflect.Descriptor instead. -func (*ExposeConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_expose_proto_rawDescGZIP(), []int{0} -} - -func (x *ExposeConfig) GetExposePaths() []*ExposePath { - if x != nil { - return x.ExposePaths - } - return nil -} - -type ExposePath struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ListenerPort uint32 `protobuf:"varint,1,opt,name=listener_port,json=listenerPort,proto3" json:"listener_port,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` - LocalPathPort uint32 `protobuf:"varint,3,opt,name=local_path_port,json=localPathPort,proto3" json:"local_path_port,omitempty"` - Protocol ExposePathProtocol `protobuf:"varint,4,opt,name=protocol,proto3,enum=hashicorp.consul.mesh.v2beta1.ExposePathProtocol" json:"protocol,omitempty"` -} - -func (x *ExposePath) Reset() { - *x = ExposePath{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_expose_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExposePath) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExposePath) ProtoMessage() {} - -func (x *ExposePath) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_expose_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExposePath.ProtoReflect.Descriptor instead. -func (*ExposePath) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_expose_proto_rawDescGZIP(), []int{1} -} - -func (x *ExposePath) GetListenerPort() uint32 { - if x != nil { - return x.ListenerPort - } - return 0 -} - -func (x *ExposePath) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -func (x *ExposePath) GetLocalPathPort() uint32 { - if x != nil { - return x.LocalPathPort - } - return 0 -} - -func (x *ExposePath) GetProtocol() ExposePathProtocol { - if x != nil { - return x.Protocol - } - return ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP -} - -var File_pbmesh_v2beta1_expose_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_expose_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x22, 0x5c, 0x0a, 0x0c, - 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4c, 0x0a, 0x0c, - 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x0b, 0x65, - 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, 0xbc, 0x01, 0x0a, 0x0a, 0x45, - 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x4d, 0x0a, 0x08, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, - 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, - 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2a, 0x53, 0x0a, 0x12, 0x45, 0x78, 0x70, - 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, - 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x50, - 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x1e, - 0x0a, 0x1a, 0x45, 0x58, 0x50, 0x4f, 0x53, 0x45, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x50, 0x52, - 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x01, 0x42, 0x8c, - 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x0b, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, - 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, - 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, - 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, - 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, - 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, - 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_expose_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_expose_proto_rawDescData = file_pbmesh_v2beta1_expose_proto_rawDesc -) - -func file_pbmesh_v2beta1_expose_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_expose_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_expose_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_expose_proto_rawDescData) - }) - return file_pbmesh_v2beta1_expose_proto_rawDescData -} - -var file_pbmesh_v2beta1_expose_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_expose_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbmesh_v2beta1_expose_proto_goTypes = []interface{}{ - (ExposePathProtocol)(0), // 0: hashicorp.consul.mesh.v2beta1.ExposePathProtocol - (*ExposeConfig)(nil), // 1: hashicorp.consul.mesh.v2beta1.ExposeConfig - (*ExposePath)(nil), // 2: hashicorp.consul.mesh.v2beta1.ExposePath -} -var file_pbmesh_v2beta1_expose_proto_depIdxs = []int32{ - 2, // 0: hashicorp.consul.mesh.v2beta1.ExposeConfig.expose_paths:type_name -> hashicorp.consul.mesh.v2beta1.ExposePath - 0, // 1: hashicorp.consul.mesh.v2beta1.ExposePath.protocol:type_name -> hashicorp.consul.mesh.v2beta1.ExposePathProtocol - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_expose_proto_init() } -func file_pbmesh_v2beta1_expose_proto_init() { - if File_pbmesh_v2beta1_expose_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_expose_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExposeConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_expose_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExposePath); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_expose_proto_rawDesc, - NumEnums: 1, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_expose_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_expose_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_expose_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_expose_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_expose_proto = out.File - file_pbmesh_v2beta1_expose_proto_rawDesc = nil - file_pbmesh_v2beta1_expose_proto_goTypes = nil - file_pbmesh_v2beta1_expose_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/expose.proto b/proto-public/pbmesh/v2beta1/expose.proto deleted file mode 100644 index cf5c67d370152..0000000000000 --- a/proto-public/pbmesh/v2beta1/expose.proto +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -message ExposeConfig { - repeated ExposePath expose_paths = 1; -} - -message ExposePath { - uint32 listener_port = 1; - string path = 2; - uint32 local_path_port = 3; - ExposePathProtocol protocol = 4; -} - -// +kubebuilder:validation:Enum=EXPOSE_PATH_PROTOCOL_HTTP;EXPOSE_PATH_PROTOCOL_HTTP2 -// +kubebuilder:validation:Type=string -enum ExposePathProtocol { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - EXPOSE_PATH_PROTOCOL_HTTP = 0; - EXPOSE_PATH_PROTOCOL_HTTP2 = 1; -} diff --git a/proto-public/pbmesh/v2beta1/expose_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/expose_deepcopy.gen.go deleted file mode 100644 index 2b75adbbcd349..0000000000000 --- a/proto-public/pbmesh/v2beta1/expose_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ExposeConfig within kubernetes types, where deepcopy-gen is used. -func (in *ExposeConfig) DeepCopyInto(out *ExposeConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExposeConfig. Required by controller-gen. -func (in *ExposeConfig) DeepCopy() *ExposeConfig { - if in == nil { - return nil - } - out := new(ExposeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ExposeConfig. Required by controller-gen. -func (in *ExposeConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ExposePath within kubernetes types, where deepcopy-gen is used. -func (in *ExposePath) DeepCopyInto(out *ExposePath) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExposePath. Required by controller-gen. -func (in *ExposePath) DeepCopy() *ExposePath { - if in == nil { - return nil - } - out := new(ExposePath) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ExposePath. Required by controller-gen. -func (in *ExposePath) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/expose_json.gen.go b/proto-public/pbmesh/v2beta1/expose_json.gen.go deleted file mode 100644 index 14f04649c1f83..0000000000000 --- a/proto-public/pbmesh/v2beta1/expose_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ExposeConfig -func (this *ExposeConfig) MarshalJSON() ([]byte, error) { - str, err := ExposeMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ExposeConfig -func (this *ExposeConfig) UnmarshalJSON(b []byte) error { - return ExposeUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ExposePath -func (this *ExposePath) MarshalJSON() ([]byte, error) { - str, err := ExposeMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ExposePath -func (this *ExposePath) UnmarshalJSON(b []byte) error { - return ExposeUnmarshaler.Unmarshal(b, this) -} - -var ( - ExposeMarshaler = &protojson.MarshalOptions{} - ExposeUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/grpc_route.pb.binary.go b/proto-public/pbmesh/v2beta1/grpc_route.pb.binary.go deleted file mode 100644 index 3a5d3ac5a2cd2..0000000000000 --- a/proto-public/pbmesh/v2beta1/grpc_route.pb.binary.go +++ /dev/null @@ -1,78 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/grpc_route.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *GRPCRoute) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *GRPCRoute) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *GRPCRouteRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *GRPCRouteRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *GRPCRouteMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *GRPCRouteMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *GRPCMethodMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *GRPCMethodMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *GRPCHeaderMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *GRPCHeaderMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *GRPCRouteFilter) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *GRPCRouteFilter) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *GRPCBackendRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *GRPCBackendRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/grpc_route.pb.go b/proto-public/pbmesh/v2beta1/grpc_route.pb.go deleted file mode 100644 index e0b4f364810a9..0000000000000 --- a/proto-public/pbmesh/v2beta1/grpc_route.pb.go +++ /dev/null @@ -1,908 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/grpc_route.proto - -package meshv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=GRPC_METHOD_MATCH_TYPE_UNSPECIFIED;GRPC_METHOD_MATCH_TYPE_EXACT;GRPC_METHOD_MATCH_TYPE_REGEX -// +kubebuilder:validation:Type=string -type GRPCMethodMatchType int32 - -const ( - GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_UNSPECIFIED GRPCMethodMatchType = 0 - GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_EXACT GRPCMethodMatchType = 1 - GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_REGEX GRPCMethodMatchType = 2 -) - -// Enum value maps for GRPCMethodMatchType. -var ( - GRPCMethodMatchType_name = map[int32]string{ - 0: "GRPC_METHOD_MATCH_TYPE_UNSPECIFIED", - 1: "GRPC_METHOD_MATCH_TYPE_EXACT", - 2: "GRPC_METHOD_MATCH_TYPE_REGEX", - } - GRPCMethodMatchType_value = map[string]int32{ - "GRPC_METHOD_MATCH_TYPE_UNSPECIFIED": 0, - "GRPC_METHOD_MATCH_TYPE_EXACT": 1, - "GRPC_METHOD_MATCH_TYPE_REGEX": 2, - } -) - -func (x GRPCMethodMatchType) Enum() *GRPCMethodMatchType { - p := new(GRPCMethodMatchType) - *p = x - return p -} - -func (x GRPCMethodMatchType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (GRPCMethodMatchType) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_grpc_route_proto_enumTypes[0].Descriptor() -} - -func (GRPCMethodMatchType) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_grpc_route_proto_enumTypes[0] -} - -func (x GRPCMethodMatchType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use GRPCMethodMatchType.Descriptor instead. -func (GRPCMethodMatchType) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP(), []int{0} -} - -// NOTE: this should align to the GAMMA/gateway-api version, or at least be -// easily translatable. -// -// https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute -// -// This is a Resource type. -type GRPCRoute struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ParentRefs references the resources (usually Services) that a Route wants - // to be attached to. - // - // It is invalid to reference an identical parent more than once. It is valid - // to reference multiple distinct sections within the same parent resource. - ParentRefs []*ParentReference `protobuf:"bytes,1,rep,name=parent_refs,json=parentRefs,proto3" json:"parent_refs,omitempty"` - // Hostnames are the hostnames for which this GRPCRoute should respond to requests. - // - // This is only valid for north/south. - Hostnames []string `protobuf:"bytes,2,rep,name=hostnames,proto3" json:"hostnames,omitempty"` - // Rules are a list of GRPC matchers, filters and actions. - Rules []*GRPCRouteRule `protobuf:"bytes,3,rep,name=rules,proto3" json:"rules,omitempty"` -} - -func (x *GRPCRoute) Reset() { - *x = GRPCRoute{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GRPCRoute) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GRPCRoute) ProtoMessage() {} - -func (x *GRPCRoute) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GRPCRoute.ProtoReflect.Descriptor instead. -func (*GRPCRoute) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP(), []int{0} -} - -func (x *GRPCRoute) GetParentRefs() []*ParentReference { - if x != nil { - return x.ParentRefs - } - return nil -} - -func (x *GRPCRoute) GetHostnames() []string { - if x != nil { - return x.Hostnames - } - return nil -} - -func (x *GRPCRoute) GetRules() []*GRPCRouteRule { - if x != nil { - return x.Rules - } - return nil -} - -type GRPCRouteRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Matches []*GRPCRouteMatch `protobuf:"bytes,1,rep,name=matches,proto3" json:"matches,omitempty"` - Filters []*GRPCRouteFilter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` - // BackendRefs defines the backend(s) where matching requests should be sent. - // Failure behavior here depends on how many BackendRefs are specified and - // how many are invalid. - // - // If all entries in BackendRefs are invalid, and there are also no filters - // specified in this route rule, all traffic which matches this rule MUST - // receive a 500 status code. - // - // See the GRPCBackendRef definition for the rules about what makes a single - // GRPCBackendRef invalid. - // - // When a GRPCBackendRef is invalid, 500 status codes MUST be returned for - // requests that would have otherwise been routed to an invalid backend. If - // multiple backends are specified, and some are invalid, the proportion of - // requests that would otherwise have been routed to an invalid backend MUST - // receive a 500 status code. - // - // For example, if two backends are specified with equal weights, and one is - // invalid, 50 percent of traffic must receive a 500. Implementations may - // choose how that 50 percent is determined. - BackendRefs []*GRPCBackendRef `protobuf:"bytes,3,rep,name=backend_refs,json=backendRefs,proto3" json:"backend_refs,omitempty"` - Timeouts *HTTPRouteTimeouts `protobuf:"bytes,4,opt,name=timeouts,proto3" json:"timeouts,omitempty"` - Retries *HTTPRouteRetries `protobuf:"bytes,5,opt,name=retries,proto3" json:"retries,omitempty"` -} - -func (x *GRPCRouteRule) Reset() { - *x = GRPCRouteRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GRPCRouteRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GRPCRouteRule) ProtoMessage() {} - -func (x *GRPCRouteRule) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GRPCRouteRule.ProtoReflect.Descriptor instead. -func (*GRPCRouteRule) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP(), []int{1} -} - -func (x *GRPCRouteRule) GetMatches() []*GRPCRouteMatch { - if x != nil { - return x.Matches - } - return nil -} - -func (x *GRPCRouteRule) GetFilters() []*GRPCRouteFilter { - if x != nil { - return x.Filters - } - return nil -} - -func (x *GRPCRouteRule) GetBackendRefs() []*GRPCBackendRef { - if x != nil { - return x.BackendRefs - } - return nil -} - -func (x *GRPCRouteRule) GetTimeouts() *HTTPRouteTimeouts { - if x != nil { - return x.Timeouts - } - return nil -} - -func (x *GRPCRouteRule) GetRetries() *HTTPRouteRetries { - if x != nil { - return x.Retries - } - return nil -} - -type GRPCRouteMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Method specifies a gRPC request service/method matcher. If this field is - // not specified, all services and methods will match. - Method *GRPCMethodMatch `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` - // Headers specifies gRPC request header matchers. Multiple match values are - // ANDed together, meaning, a request MUST match all the specified headers to - // select the route. - Headers []*GRPCHeaderMatch `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty"` -} - -func (x *GRPCRouteMatch) Reset() { - *x = GRPCRouteMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GRPCRouteMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GRPCRouteMatch) ProtoMessage() {} - -func (x *GRPCRouteMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GRPCRouteMatch.ProtoReflect.Descriptor instead. -func (*GRPCRouteMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP(), []int{2} -} - -func (x *GRPCRouteMatch) GetMethod() *GRPCMethodMatch { - if x != nil { - return x.Method - } - return nil -} - -func (x *GRPCRouteMatch) GetHeaders() []*GRPCHeaderMatch { - if x != nil { - return x.Headers - } - return nil -} - -type GRPCMethodMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Type specifies how to match against the service and/or method. Support: - // Core (Exact with service and method specified) - Type GRPCMethodMatchType `protobuf:"varint,1,opt,name=type,proto3,enum=hashicorp.consul.mesh.v2beta1.GRPCMethodMatchType" json:"type,omitempty"` - // Value of the service to match against. If left empty or omitted, will - // match any service. - // - // At least one of Service and Method MUST be a non-empty string. - Service string `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"` - // Value of the method to match against. If left empty or omitted, will match - // all services. - // - // At least one of Service and Method MUST be a non-empty string.} - Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"` -} - -func (x *GRPCMethodMatch) Reset() { - *x = GRPCMethodMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GRPCMethodMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GRPCMethodMatch) ProtoMessage() {} - -func (x *GRPCMethodMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GRPCMethodMatch.ProtoReflect.Descriptor instead. -func (*GRPCMethodMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP(), []int{3} -} - -func (x *GRPCMethodMatch) GetType() GRPCMethodMatchType { - if x != nil { - return x.Type - } - return GRPCMethodMatchType_GRPC_METHOD_MATCH_TYPE_UNSPECIFIED -} - -func (x *GRPCMethodMatch) GetService() string { - if x != nil { - return x.Service - } - return "" -} - -func (x *GRPCMethodMatch) GetMethod() string { - if x != nil { - return x.Method - } - return "" -} - -type GRPCHeaderMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type HeaderMatchType `protobuf:"varint,1,opt,name=type,proto3,enum=hashicorp.consul.mesh.v2beta1.HeaderMatchType" json:"type,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *GRPCHeaderMatch) Reset() { - *x = GRPCHeaderMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GRPCHeaderMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GRPCHeaderMatch) ProtoMessage() {} - -func (x *GRPCHeaderMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GRPCHeaderMatch.ProtoReflect.Descriptor instead. -func (*GRPCHeaderMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP(), []int{4} -} - -func (x *GRPCHeaderMatch) GetType() HeaderMatchType { - if x != nil { - return x.Type - } - return HeaderMatchType_HEADER_MATCH_TYPE_UNSPECIFIED -} - -func (x *GRPCHeaderMatch) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *GRPCHeaderMatch) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -type GRPCRouteFilter struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // RequestHeaderModifier defines a schema for a filter that modifies request - // headers. - RequestHeaderModifier *HTTPHeaderFilter `protobuf:"bytes,1,opt,name=request_header_modifier,json=requestHeaderModifier,proto3" json:"request_header_modifier,omitempty"` - // ResponseHeaderModifier defines a schema for a filter that modifies - // response headers. - ResponseHeaderModifier *HTTPHeaderFilter `protobuf:"bytes,2,opt,name=response_header_modifier,json=responseHeaderModifier,proto3" json:"response_header_modifier,omitempty"` - // URLRewrite defines a schema for a filter that modifies a request during - // forwarding. - UrlRewrite *HTTPURLRewriteFilter `protobuf:"bytes,5,opt,name=url_rewrite,json=urlRewrite,proto3" json:"url_rewrite,omitempty"` -} - -func (x *GRPCRouteFilter) Reset() { - *x = GRPCRouteFilter{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GRPCRouteFilter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GRPCRouteFilter) ProtoMessage() {} - -func (x *GRPCRouteFilter) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GRPCRouteFilter.ProtoReflect.Descriptor instead. -func (*GRPCRouteFilter) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP(), []int{5} -} - -func (x *GRPCRouteFilter) GetRequestHeaderModifier() *HTTPHeaderFilter { - if x != nil { - return x.RequestHeaderModifier - } - return nil -} - -func (x *GRPCRouteFilter) GetResponseHeaderModifier() *HTTPHeaderFilter { - if x != nil { - return x.ResponseHeaderModifier - } - return nil -} - -func (x *GRPCRouteFilter) GetUrlRewrite() *HTTPURLRewriteFilter { - if x != nil { - return x.UrlRewrite - } - return nil -} - -type GRPCBackendRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - BackendRef *BackendReference `protobuf:"bytes,1,opt,name=backend_ref,json=backendRef,proto3" json:"backend_ref,omitempty"` - // Weight specifies the proportion of requests forwarded to the referenced - // backend. This is computed as weight/(sum of all weights in this - // BackendRefs list). For non-zero values, there may be some epsilon from the - // exact proportion defined here depending on the precision an implementation - // supports. Weight is not a percentage and the sum of weights does not need - // to equal 100. - // - // If only one backend is specified and it has a weight greater than 0, 100% - // of the traffic is forwarded to that backend. If weight is set to 0, no - // traffic should be forwarded for this entry. If unspecified, weight defaults - // to 1. - Weight uint32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` - // Filters defined at this level should be executed if and only if the - // request is being forwarded to the backend defined here. - Filters []*GRPCRouteFilter `protobuf:"bytes,3,rep,name=filters,proto3" json:"filters,omitempty"` -} - -func (x *GRPCBackendRef) Reset() { - *x = GRPCBackendRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GRPCBackendRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GRPCBackendRef) ProtoMessage() {} - -func (x *GRPCBackendRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_grpc_route_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GRPCBackendRef.ProtoReflect.Descriptor instead. -func (*GRPCBackendRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP(), []int{6} -} - -func (x *GRPCBackendRef) GetBackendRef() *BackendReference { - if x != nil { - return x.BackendRef - } - return nil -} - -func (x *GRPCBackendRef) GetWeight() uint32 { - if x != nil { - return x.Weight - } - return 0 -} - -func (x *GRPCBackendRef) GetFilters() []*GRPCRouteFilter { - if x != nil { - return x.Filters - } - return nil -} - -var File_pbmesh_v2beta1_grpc_route_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_grpc_route_proto_rawDesc = []byte{ - 0x0a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x1a, 0x1b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, - 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, - 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, - 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, - 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, - 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xc6, 0x01, 0x0a, 0x09, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4f, 0x0a, - 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x73, 0x12, 0x1c, - 0x0a, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x05, - 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, - 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x8d, 0x03, 0x0a, 0x0d, 0x47, 0x52, 0x50, - 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x47, 0x0a, 0x07, 0x6d, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x50, 0x0a, - 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, - 0x65, 0x66, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x12, - 0x4c, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x73, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x12, 0x49, 0x0a, - 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, - 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, - 0x07, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x0e, 0x47, 0x52, 0x50, - 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x46, 0x0a, 0x06, 0x6d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, - 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x06, 0x6d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x12, 0x48, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x22, 0x8b, 0x01, - 0x0a, 0x0f, 0x47, 0x52, 0x50, 0x43, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x12, 0x46, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x47, 0x52, 0x50, 0x43, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x7f, 0x0a, 0x0f, 0x47, - 0x52, 0x50, 0x43, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x42, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xbb, 0x02, 0x0a, - 0x0f, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x12, 0x67, 0x0a, 0x17, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x52, 0x15, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x69, 0x0a, 0x18, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x16, 0x72, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x0b, 0x75, 0x72, 0x6c, 0x5f, 0x72, 0x65, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x55, 0x52, - 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, - 0x75, 0x72, 0x6c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x0e, 0x47, - 0x52, 0x50, 0x43, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x50, 0x0a, - 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, - 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x73, 0x2a, 0x81, 0x01, 0x0a, 0x13, 0x47, 0x52, 0x50, 0x43, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x47, 0x52, 0x50, - 0x43, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, - 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x41, 0x43, - 0x54, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x4d, 0x45, 0x54, 0x48, - 0x4f, 0x44, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, - 0x47, 0x45, 0x58, 0x10, 0x02, 0x42, 0x8f, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0e, 0x47, 0x72, 0x70, - 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, - 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_grpc_route_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_grpc_route_proto_rawDescData = file_pbmesh_v2beta1_grpc_route_proto_rawDesc -) - -func file_pbmesh_v2beta1_grpc_route_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_grpc_route_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_grpc_route_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_grpc_route_proto_rawDescData) - }) - return file_pbmesh_v2beta1_grpc_route_proto_rawDescData -} - -var file_pbmesh_v2beta1_grpc_route_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_grpc_route_proto_msgTypes = make([]protoimpl.MessageInfo, 7) -var file_pbmesh_v2beta1_grpc_route_proto_goTypes = []interface{}{ - (GRPCMethodMatchType)(0), // 0: hashicorp.consul.mesh.v2beta1.GRPCMethodMatchType - (*GRPCRoute)(nil), // 1: hashicorp.consul.mesh.v2beta1.GRPCRoute - (*GRPCRouteRule)(nil), // 2: hashicorp.consul.mesh.v2beta1.GRPCRouteRule - (*GRPCRouteMatch)(nil), // 3: hashicorp.consul.mesh.v2beta1.GRPCRouteMatch - (*GRPCMethodMatch)(nil), // 4: hashicorp.consul.mesh.v2beta1.GRPCMethodMatch - (*GRPCHeaderMatch)(nil), // 5: hashicorp.consul.mesh.v2beta1.GRPCHeaderMatch - (*GRPCRouteFilter)(nil), // 6: hashicorp.consul.mesh.v2beta1.GRPCRouteFilter - (*GRPCBackendRef)(nil), // 7: hashicorp.consul.mesh.v2beta1.GRPCBackendRef - (*ParentReference)(nil), // 8: hashicorp.consul.mesh.v2beta1.ParentReference - (*HTTPRouteTimeouts)(nil), // 9: hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts - (*HTTPRouteRetries)(nil), // 10: hashicorp.consul.mesh.v2beta1.HTTPRouteRetries - (HeaderMatchType)(0), // 11: hashicorp.consul.mesh.v2beta1.HeaderMatchType - (*HTTPHeaderFilter)(nil), // 12: hashicorp.consul.mesh.v2beta1.HTTPHeaderFilter - (*HTTPURLRewriteFilter)(nil), // 13: hashicorp.consul.mesh.v2beta1.HTTPURLRewriteFilter - (*BackendReference)(nil), // 14: hashicorp.consul.mesh.v2beta1.BackendReference -} -var file_pbmesh_v2beta1_grpc_route_proto_depIdxs = []int32{ - 8, // 0: hashicorp.consul.mesh.v2beta1.GRPCRoute.parent_refs:type_name -> hashicorp.consul.mesh.v2beta1.ParentReference - 2, // 1: hashicorp.consul.mesh.v2beta1.GRPCRoute.rules:type_name -> hashicorp.consul.mesh.v2beta1.GRPCRouteRule - 3, // 2: hashicorp.consul.mesh.v2beta1.GRPCRouteRule.matches:type_name -> hashicorp.consul.mesh.v2beta1.GRPCRouteMatch - 6, // 3: hashicorp.consul.mesh.v2beta1.GRPCRouteRule.filters:type_name -> hashicorp.consul.mesh.v2beta1.GRPCRouteFilter - 7, // 4: hashicorp.consul.mesh.v2beta1.GRPCRouteRule.backend_refs:type_name -> hashicorp.consul.mesh.v2beta1.GRPCBackendRef - 9, // 5: hashicorp.consul.mesh.v2beta1.GRPCRouteRule.timeouts:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts - 10, // 6: hashicorp.consul.mesh.v2beta1.GRPCRouteRule.retries:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteRetries - 4, // 7: hashicorp.consul.mesh.v2beta1.GRPCRouteMatch.method:type_name -> hashicorp.consul.mesh.v2beta1.GRPCMethodMatch - 5, // 8: hashicorp.consul.mesh.v2beta1.GRPCRouteMatch.headers:type_name -> hashicorp.consul.mesh.v2beta1.GRPCHeaderMatch - 0, // 9: hashicorp.consul.mesh.v2beta1.GRPCMethodMatch.type:type_name -> hashicorp.consul.mesh.v2beta1.GRPCMethodMatchType - 11, // 10: hashicorp.consul.mesh.v2beta1.GRPCHeaderMatch.type:type_name -> hashicorp.consul.mesh.v2beta1.HeaderMatchType - 12, // 11: hashicorp.consul.mesh.v2beta1.GRPCRouteFilter.request_header_modifier:type_name -> hashicorp.consul.mesh.v2beta1.HTTPHeaderFilter - 12, // 12: hashicorp.consul.mesh.v2beta1.GRPCRouteFilter.response_header_modifier:type_name -> hashicorp.consul.mesh.v2beta1.HTTPHeaderFilter - 13, // 13: hashicorp.consul.mesh.v2beta1.GRPCRouteFilter.url_rewrite:type_name -> hashicorp.consul.mesh.v2beta1.HTTPURLRewriteFilter - 14, // 14: hashicorp.consul.mesh.v2beta1.GRPCBackendRef.backend_ref:type_name -> hashicorp.consul.mesh.v2beta1.BackendReference - 6, // 15: hashicorp.consul.mesh.v2beta1.GRPCBackendRef.filters:type_name -> hashicorp.consul.mesh.v2beta1.GRPCRouteFilter - 16, // [16:16] is the sub-list for method output_type - 16, // [16:16] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_grpc_route_proto_init() } -func file_pbmesh_v2beta1_grpc_route_proto_init() { - if File_pbmesh_v2beta1_grpc_route_proto != nil { - return - } - file_pbmesh_v2beta1_common_proto_init() - file_pbmesh_v2beta1_http_route_proto_init() - file_pbmesh_v2beta1_http_route_retries_proto_init() - file_pbmesh_v2beta1_http_route_timeouts_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_grpc_route_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GRPCRoute); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_grpc_route_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GRPCRouteRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_grpc_route_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GRPCRouteMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_grpc_route_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GRPCMethodMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_grpc_route_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GRPCHeaderMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_grpc_route_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GRPCRouteFilter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_grpc_route_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GRPCBackendRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_grpc_route_proto_rawDesc, - NumEnums: 1, - NumMessages: 7, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_grpc_route_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_grpc_route_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_grpc_route_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_grpc_route_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_grpc_route_proto = out.File - file_pbmesh_v2beta1_grpc_route_proto_rawDesc = nil - file_pbmesh_v2beta1_grpc_route_proto_goTypes = nil - file_pbmesh_v2beta1_grpc_route_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/grpc_route.proto b/proto-public/pbmesh/v2beta1/grpc_route.proto deleted file mode 100644 index a971bb0610993..0000000000000 --- a/proto-public/pbmesh/v2beta1/grpc_route.proto +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbmesh/v2beta1/common.proto"; -import "pbmesh/v2beta1/http_route.proto"; -import "pbmesh/v2beta1/http_route_retries.proto"; -import "pbmesh/v2beta1/http_route_timeouts.proto"; -import "pbresource/annotations.proto"; - -// NOTE: this should align to the GAMMA/gateway-api version, or at least be -// easily translatable. -// -// https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute -// -// This is a Resource type. -message GRPCRoute { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // ParentRefs references the resources (usually Services) that a Route wants - // to be attached to. - // - // It is invalid to reference an identical parent more than once. It is valid - // to reference multiple distinct sections within the same parent resource. - repeated ParentReference parent_refs = 1; - - // Hostnames are the hostnames for which this GRPCRoute should respond to requests. - // - // This is only valid for north/south. - repeated string hostnames = 2; - - // Rules are a list of GRPC matchers, filters and actions. - repeated GRPCRouteRule rules = 3; -} - -message GRPCRouteRule { - repeated GRPCRouteMatch matches = 1; - repeated GRPCRouteFilter filters = 2; - - // BackendRefs defines the backend(s) where matching requests should be sent. - // Failure behavior here depends on how many BackendRefs are specified and - // how many are invalid. - // - // If all entries in BackendRefs are invalid, and there are also no filters - // specified in this route rule, all traffic which matches this rule MUST - // receive a 500 status code. - // - // See the GRPCBackendRef definition for the rules about what makes a single - // GRPCBackendRef invalid. - // - // When a GRPCBackendRef is invalid, 500 status codes MUST be returned for - // requests that would have otherwise been routed to an invalid backend. If - // multiple backends are specified, and some are invalid, the proportion of - // requests that would otherwise have been routed to an invalid backend MUST - // receive a 500 status code. - // - // For example, if two backends are specified with equal weights, and one is - // invalid, 50 percent of traffic must receive a 500. Implementations may - // choose how that 50 percent is determined. - repeated GRPCBackendRef backend_refs = 3; - - HTTPRouteTimeouts timeouts = 4; - HTTPRouteRetries retries = 5; -} - -message GRPCRouteMatch { - // Method specifies a gRPC request service/method matcher. If this field is - // not specified, all services and methods will match. - GRPCMethodMatch method = 1; - - // Headers specifies gRPC request header matchers. Multiple match values are - // ANDed together, meaning, a request MUST match all the specified headers to - // select the route. - repeated GRPCHeaderMatch headers = 2; -} - -message GRPCMethodMatch { - // Type specifies how to match against the service and/or method. Support: - // Core (Exact with service and method specified) - GRPCMethodMatchType type = 1; - - // Value of the service to match against. If left empty or omitted, will - // match any service. - // - // At least one of Service and Method MUST be a non-empty string. - string service = 2; - - // Value of the method to match against. If left empty or omitted, will match - // all services. - // - // At least one of Service and Method MUST be a non-empty string.} - string method = 3; -} - -// +kubebuilder:validation:Enum=GRPC_METHOD_MATCH_TYPE_UNSPECIFIED;GRPC_METHOD_MATCH_TYPE_EXACT;GRPC_METHOD_MATCH_TYPE_REGEX -// +kubebuilder:validation:Type=string -enum GRPCMethodMatchType { - GRPC_METHOD_MATCH_TYPE_UNSPECIFIED = 0; - GRPC_METHOD_MATCH_TYPE_EXACT = 1; - GRPC_METHOD_MATCH_TYPE_REGEX = 2; -} - -message GRPCHeaderMatch { - HeaderMatchType type = 1; - string name = 2; - string value = 3; -} - -message GRPCRouteFilter { - // RequestHeaderModifier defines a schema for a filter that modifies request - // headers. - HTTPHeaderFilter request_header_modifier = 1; - - // ResponseHeaderModifier defines a schema for a filter that modifies - // response headers. - HTTPHeaderFilter response_header_modifier = 2; - - // URLRewrite defines a schema for a filter that modifies a request during - // forwarding. - HTTPURLRewriteFilter url_rewrite = 5; -} - -message GRPCBackendRef { - BackendReference backend_ref = 1; - - // Weight specifies the proportion of requests forwarded to the referenced - // backend. This is computed as weight/(sum of all weights in this - // BackendRefs list). For non-zero values, there may be some epsilon from the - // exact proportion defined here depending on the precision an implementation - // supports. Weight is not a percentage and the sum of weights does not need - // to equal 100. - // - //If only one backend is specified and it has a weight greater than 0, 100% - //of the traffic is forwarded to that backend. If weight is set to 0, no - //traffic should be forwarded for this entry. If unspecified, weight defaults - //to 1. - uint32 weight = 2; - - // Filters defined at this level should be executed if and only if the - // request is being forwarded to the backend defined here. - repeated GRPCRouteFilter filters = 3; -} diff --git a/proto-public/pbmesh/v2beta1/grpc_route_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/grpc_route_deepcopy.gen.go deleted file mode 100644 index ea7e1dc8ed26d..0000000000000 --- a/proto-public/pbmesh/v2beta1/grpc_route_deepcopy.gen.go +++ /dev/null @@ -1,153 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using GRPCRoute within kubernetes types, where deepcopy-gen is used. -func (in *GRPCRoute) DeepCopyInto(out *GRPCRoute) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRoute. Required by controller-gen. -func (in *GRPCRoute) DeepCopy() *GRPCRoute { - if in == nil { - return nil - } - out := new(GRPCRoute) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRoute. Required by controller-gen. -func (in *GRPCRoute) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GRPCRouteRule within kubernetes types, where deepcopy-gen is used. -func (in *GRPCRouteRule) DeepCopyInto(out *GRPCRouteRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteRule. Required by controller-gen. -func (in *GRPCRouteRule) DeepCopy() *GRPCRouteRule { - if in == nil { - return nil - } - out := new(GRPCRouteRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteRule. Required by controller-gen. -func (in *GRPCRouteRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GRPCRouteMatch within kubernetes types, where deepcopy-gen is used. -func (in *GRPCRouteMatch) DeepCopyInto(out *GRPCRouteMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteMatch. Required by controller-gen. -func (in *GRPCRouteMatch) DeepCopy() *GRPCRouteMatch { - if in == nil { - return nil - } - out := new(GRPCRouteMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteMatch. Required by controller-gen. -func (in *GRPCRouteMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GRPCMethodMatch within kubernetes types, where deepcopy-gen is used. -func (in *GRPCMethodMatch) DeepCopyInto(out *GRPCMethodMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCMethodMatch. Required by controller-gen. -func (in *GRPCMethodMatch) DeepCopy() *GRPCMethodMatch { - if in == nil { - return nil - } - out := new(GRPCMethodMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GRPCMethodMatch. Required by controller-gen. -func (in *GRPCMethodMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GRPCHeaderMatch within kubernetes types, where deepcopy-gen is used. -func (in *GRPCHeaderMatch) DeepCopyInto(out *GRPCHeaderMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCHeaderMatch. Required by controller-gen. -func (in *GRPCHeaderMatch) DeepCopy() *GRPCHeaderMatch { - if in == nil { - return nil - } - out := new(GRPCHeaderMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GRPCHeaderMatch. Required by controller-gen. -func (in *GRPCHeaderMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GRPCRouteFilter within kubernetes types, where deepcopy-gen is used. -func (in *GRPCRouteFilter) DeepCopyInto(out *GRPCRouteFilter) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteFilter. Required by controller-gen. -func (in *GRPCRouteFilter) DeepCopy() *GRPCRouteFilter { - if in == nil { - return nil - } - out := new(GRPCRouteFilter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteFilter. Required by controller-gen. -func (in *GRPCRouteFilter) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using GRPCBackendRef within kubernetes types, where deepcopy-gen is used. -func (in *GRPCBackendRef) DeepCopyInto(out *GRPCBackendRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCBackendRef. Required by controller-gen. -func (in *GRPCBackendRef) DeepCopy() *GRPCBackendRef { - if in == nil { - return nil - } - out := new(GRPCBackendRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new GRPCBackendRef. Required by controller-gen. -func (in *GRPCBackendRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/grpc_route_json.gen.go b/proto-public/pbmesh/v2beta1/grpc_route_json.gen.go deleted file mode 100644 index f995efcfa8498..0000000000000 --- a/proto-public/pbmesh/v2beta1/grpc_route_json.gen.go +++ /dev/null @@ -1,88 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for GRPCRoute -func (this *GRPCRoute) MarshalJSON() ([]byte, error) { - str, err := GrpcRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GRPCRoute -func (this *GRPCRoute) UnmarshalJSON(b []byte) error { - return GrpcRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GRPCRouteRule -func (this *GRPCRouteRule) MarshalJSON() ([]byte, error) { - str, err := GrpcRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GRPCRouteRule -func (this *GRPCRouteRule) UnmarshalJSON(b []byte) error { - return GrpcRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GRPCRouteMatch -func (this *GRPCRouteMatch) MarshalJSON() ([]byte, error) { - str, err := GrpcRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GRPCRouteMatch -func (this *GRPCRouteMatch) UnmarshalJSON(b []byte) error { - return GrpcRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GRPCMethodMatch -func (this *GRPCMethodMatch) MarshalJSON() ([]byte, error) { - str, err := GrpcRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GRPCMethodMatch -func (this *GRPCMethodMatch) UnmarshalJSON(b []byte) error { - return GrpcRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GRPCHeaderMatch -func (this *GRPCHeaderMatch) MarshalJSON() ([]byte, error) { - str, err := GrpcRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GRPCHeaderMatch -func (this *GRPCHeaderMatch) UnmarshalJSON(b []byte) error { - return GrpcRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GRPCRouteFilter -func (this *GRPCRouteFilter) MarshalJSON() ([]byte, error) { - str, err := GrpcRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GRPCRouteFilter -func (this *GRPCRouteFilter) UnmarshalJSON(b []byte) error { - return GrpcRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for GRPCBackendRef -func (this *GRPCBackendRef) MarshalJSON() ([]byte, error) { - str, err := GrpcRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for GRPCBackendRef -func (this *GRPCBackendRef) UnmarshalJSON(b []byte) error { - return GrpcRouteUnmarshaler.Unmarshal(b, this) -} - -var ( - GrpcRouteMarshaler = &protojson.MarshalOptions{} - GrpcRouteUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/http_route.pb.binary.go b/proto-public/pbmesh/v2beta1/http_route.pb.binary.go deleted file mode 100644 index b8b4b08a9cc3f..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route.pb.binary.go +++ /dev/null @@ -1,118 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/http_route.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPRoute) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPRoute) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPRouteRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPRouteRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPRouteMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPRouteMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPPathMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPPathMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPHeaderMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPHeaderMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPQueryParamMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPQueryParamMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPRouteFilter) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPRouteFilter) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPHeaderFilter) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPHeaderFilter) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPHeader) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPHeader) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPURLRewriteFilter) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPURLRewriteFilter) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPBackendRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPBackendRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/http_route.pb.go b/proto-public/pbmesh/v2beta1/http_route.pb.go deleted file mode 100644 index 383308f1ad000..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route.pb.go +++ /dev/null @@ -1,1445 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/http_route.proto - -package meshv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// PathMatchType specifies the semantics of how HTTP paths should be compared. -// Valid PathMatchType values, along with their support levels, are: -// -// PathPrefix and Exact paths must be syntactically valid: -// -// - Must begin with the / character -// - Must not contain consecutive / characters (e.g. /foo///, //). -// - Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. -// -// Unknown values here must result in the implementation setting the Accepted -// Condition for the Route to status: False, with a Reason of UnsupportedValue. -// -// +kubebuilder:validation:Enum=PATH_MATCH_TYPE_UNSPECIFIED;PATH_MATCH_TYPE_EXACT;PATH_MATCH_TYPE_PREFIX;PATH_MATCH_TYPE_REGEX -// +kubebuilder:validation:Type=string -type PathMatchType int32 - -const ( - PathMatchType_PATH_MATCH_TYPE_UNSPECIFIED PathMatchType = 0 - PathMatchType_PATH_MATCH_TYPE_EXACT PathMatchType = 1 - PathMatchType_PATH_MATCH_TYPE_PREFIX PathMatchType = 2 - PathMatchType_PATH_MATCH_TYPE_REGEX PathMatchType = 3 -) - -// Enum value maps for PathMatchType. -var ( - PathMatchType_name = map[int32]string{ - 0: "PATH_MATCH_TYPE_UNSPECIFIED", - 1: "PATH_MATCH_TYPE_EXACT", - 2: "PATH_MATCH_TYPE_PREFIX", - 3: "PATH_MATCH_TYPE_REGEX", - } - PathMatchType_value = map[string]int32{ - "PATH_MATCH_TYPE_UNSPECIFIED": 0, - "PATH_MATCH_TYPE_EXACT": 1, - "PATH_MATCH_TYPE_PREFIX": 2, - "PATH_MATCH_TYPE_REGEX": 3, - } -) - -func (x PathMatchType) Enum() *PathMatchType { - p := new(PathMatchType) - *p = x - return p -} - -func (x PathMatchType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (PathMatchType) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_http_route_proto_enumTypes[0].Descriptor() -} - -func (PathMatchType) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_http_route_proto_enumTypes[0] -} - -func (x PathMatchType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use PathMatchType.Descriptor instead. -func (PathMatchType) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{0} -} - -// HeaderMatchType specifies the semantics of how HTTP header values should be -// compared. Valid HeaderMatchType values, along with their conformance levels, -// are: -// -// Note that values may be added to this enum, implementations must ensure that -// unknown values will not cause a crash. -// -// Unknown values here must result in the implementation setting the Accepted -// Condition for the Route to status: False, with a Reason of UnsupportedValue. -// -// +kubebuilder:validation:Enum=HEADER_MATCH_TYPE_UNSPECIFIED;HEADER_MATCH_TYPE_EXACT;HEADER_MATCH_TYPE_REGEX;HEADER_MATCH_TYPE_PRESENT;HEADER_MATCH_TYPE_PREFIX;HEADER_MATCH_TYPE_SUFFIX -// +kubebuilder:validation:Type=string -type HeaderMatchType int32 - -const ( - HeaderMatchType_HEADER_MATCH_TYPE_UNSPECIFIED HeaderMatchType = 0 - HeaderMatchType_HEADER_MATCH_TYPE_EXACT HeaderMatchType = 1 - HeaderMatchType_HEADER_MATCH_TYPE_REGEX HeaderMatchType = 2 - // consul only after this point (service-router compat) - HeaderMatchType_HEADER_MATCH_TYPE_PRESENT HeaderMatchType = 3 - HeaderMatchType_HEADER_MATCH_TYPE_PREFIX HeaderMatchType = 4 - HeaderMatchType_HEADER_MATCH_TYPE_SUFFIX HeaderMatchType = 5 -) - -// Enum value maps for HeaderMatchType. -var ( - HeaderMatchType_name = map[int32]string{ - 0: "HEADER_MATCH_TYPE_UNSPECIFIED", - 1: "HEADER_MATCH_TYPE_EXACT", - 2: "HEADER_MATCH_TYPE_REGEX", - 3: "HEADER_MATCH_TYPE_PRESENT", - 4: "HEADER_MATCH_TYPE_PREFIX", - 5: "HEADER_MATCH_TYPE_SUFFIX", - } - HeaderMatchType_value = map[string]int32{ - "HEADER_MATCH_TYPE_UNSPECIFIED": 0, - "HEADER_MATCH_TYPE_EXACT": 1, - "HEADER_MATCH_TYPE_REGEX": 2, - "HEADER_MATCH_TYPE_PRESENT": 3, - "HEADER_MATCH_TYPE_PREFIX": 4, - "HEADER_MATCH_TYPE_SUFFIX": 5, - } -) - -func (x HeaderMatchType) Enum() *HeaderMatchType { - p := new(HeaderMatchType) - *p = x - return p -} - -func (x HeaderMatchType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (HeaderMatchType) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_http_route_proto_enumTypes[1].Descriptor() -} - -func (HeaderMatchType) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_http_route_proto_enumTypes[1] -} - -func (x HeaderMatchType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use HeaderMatchType.Descriptor instead. -func (HeaderMatchType) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{1} -} - -// +kubebuilder:validation:Enum=QUERY_PARAM_MATCH_TYPE_UNSPECIFIED;QUERY_PARAM_MATCH_TYPE_EXACT;QUERY_PARAM_MATCH_TYPE_REGEX;QUERY_PARAM_MATCH_TYPE_PRESENT -// +kubebuilder:validation:Type=string -type QueryParamMatchType int32 - -const ( - QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_UNSPECIFIED QueryParamMatchType = 0 - QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_EXACT QueryParamMatchType = 1 - QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_REGEX QueryParamMatchType = 2 - // consul only after this point (service-router compat) - QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_PRESENT QueryParamMatchType = 3 -) - -// Enum value maps for QueryParamMatchType. -var ( - QueryParamMatchType_name = map[int32]string{ - 0: "QUERY_PARAM_MATCH_TYPE_UNSPECIFIED", - 1: "QUERY_PARAM_MATCH_TYPE_EXACT", - 2: "QUERY_PARAM_MATCH_TYPE_REGEX", - 3: "QUERY_PARAM_MATCH_TYPE_PRESENT", - } - QueryParamMatchType_value = map[string]int32{ - "QUERY_PARAM_MATCH_TYPE_UNSPECIFIED": 0, - "QUERY_PARAM_MATCH_TYPE_EXACT": 1, - "QUERY_PARAM_MATCH_TYPE_REGEX": 2, - "QUERY_PARAM_MATCH_TYPE_PRESENT": 3, - } -) - -func (x QueryParamMatchType) Enum() *QueryParamMatchType { - p := new(QueryParamMatchType) - *p = x - return p -} - -func (x QueryParamMatchType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (QueryParamMatchType) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_http_route_proto_enumTypes[2].Descriptor() -} - -func (QueryParamMatchType) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_http_route_proto_enumTypes[2] -} - -func (x QueryParamMatchType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use QueryParamMatchType.Descriptor instead. -func (QueryParamMatchType) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{2} -} - -// NOTE: this should align to the GAMMA/gateway-api version, or at least be -// easily translatable. -// -// https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.HTTPRoute -// -// This is a Resource type. -type HTTPRoute struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ParentRefs references the resources (usually Services) that a Route wants - // to be attached to. - // - // It is invalid to reference an identical parent more than once. It is valid - // to reference multiple distinct sections within the same parent resource. - ParentRefs []*ParentReference `protobuf:"bytes,1,rep,name=parent_refs,json=parentRefs,proto3" json:"parent_refs,omitempty"` - // Hostnames are the hostnames for which this HTTPRoute should respond to requests. - // - // This is only valid for north/south. - Hostnames []string `protobuf:"bytes,2,rep,name=hostnames,proto3" json:"hostnames,omitempty"` - // Rules are a list of HTTP-based routing rules that this route should - // use for constructing a routing table. - Rules []*HTTPRouteRule `protobuf:"bytes,3,rep,name=rules,proto3" json:"rules,omitempty"` -} - -func (x *HTTPRoute) Reset() { - *x = HTTPRoute{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPRoute) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPRoute) ProtoMessage() {} - -func (x *HTTPRoute) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPRoute.ProtoReflect.Descriptor instead. -func (*HTTPRoute) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{0} -} - -func (x *HTTPRoute) GetParentRefs() []*ParentReference { - if x != nil { - return x.ParentRefs - } - return nil -} - -func (x *HTTPRoute) GetHostnames() []string { - if x != nil { - return x.Hostnames - } - return nil -} - -func (x *HTTPRoute) GetRules() []*HTTPRouteRule { - if x != nil { - return x.Rules - } - return nil -} - -// HTTPRouteRule specifies the routing rules used to determine what upstream -// service an HTTP request is routed to. -type HTTPRouteRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Matches []*HTTPRouteMatch `protobuf:"bytes,1,rep,name=matches,proto3" json:"matches,omitempty"` - Filters []*HTTPRouteFilter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` - // BackendRefs defines the backend(s) where matching requests should be sent. - // - // Failure behavior here depends on how many BackendRefs are specified and - // how many are invalid. - // - // If all entries in BackendRefs are invalid, and there are also no filters - // specified in this route rule, all traffic which matches this rule MUST - // receive a 500 status code. - // - // See the HTTPBackendRef definition for the rules about what makes a single - // HTTPBackendRef invalid. - // - // When a HTTPBackendRef is invalid, 500 status codes MUST be returned for - // requests that would have otherwise been routed to an invalid backend. If - // multiple backends are specified, and some are invalid, the proportion of - // requests that would otherwise have been routed to an invalid backend MUST - // receive a 500 status code. - // - // For example, if two backends are specified with equal weights, and one is - // invalid, 50 percent of traffic must receive a 500. Implementations may - // choose how that 50 percent is determined. - BackendRefs []*HTTPBackendRef `protobuf:"bytes,3,rep,name=backend_refs,json=backendRefs,proto3" json:"backend_refs,omitempty"` - Timeouts *HTTPRouteTimeouts `protobuf:"bytes,4,opt,name=timeouts,proto3" json:"timeouts,omitempty"` - Retries *HTTPRouteRetries `protobuf:"bytes,5,opt,name=retries,proto3" json:"retries,omitempty"` -} - -func (x *HTTPRouteRule) Reset() { - *x = HTTPRouteRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPRouteRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPRouteRule) ProtoMessage() {} - -func (x *HTTPRouteRule) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPRouteRule.ProtoReflect.Descriptor instead. -func (*HTTPRouteRule) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{1} -} - -func (x *HTTPRouteRule) GetMatches() []*HTTPRouteMatch { - if x != nil { - return x.Matches - } - return nil -} - -func (x *HTTPRouteRule) GetFilters() []*HTTPRouteFilter { - if x != nil { - return x.Filters - } - return nil -} - -func (x *HTTPRouteRule) GetBackendRefs() []*HTTPBackendRef { - if x != nil { - return x.BackendRefs - } - return nil -} - -func (x *HTTPRouteRule) GetTimeouts() *HTTPRouteTimeouts { - if x != nil { - return x.Timeouts - } - return nil -} - -func (x *HTTPRouteRule) GetRetries() *HTTPRouteRetries { - if x != nil { - return x.Retries - } - return nil -} - -type HTTPRouteMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Path specifies a HTTP request path matcher. If this field is not - // specified, a default prefix match on the “/” path is provided. - Path *HTTPPathMatch `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - // Headers specifies HTTP request header matchers. Multiple match values are - // ANDed together, meaning, a request must match all the specified headers to - // select the route. - Headers []*HTTPHeaderMatch `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty"` - // QueryParams specifies HTTP query parameter matchers. Multiple match values - // are ANDed together, meaning, a request must match all the specified query - // parameters to select the route. - QueryParams []*HTTPQueryParamMatch `protobuf:"bytes,3,rep,name=query_params,json=queryParams,proto3" json:"query_params,omitempty"` - // Method specifies HTTP method matcher. When specified, this route will be - // matched only if the request has the specified method. - Method string `protobuf:"bytes,4,opt,name=method,proto3" json:"method,omitempty"` -} - -func (x *HTTPRouteMatch) Reset() { - *x = HTTPRouteMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPRouteMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPRouteMatch) ProtoMessage() {} - -func (x *HTTPRouteMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPRouteMatch.ProtoReflect.Descriptor instead. -func (*HTTPRouteMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{2} -} - -func (x *HTTPRouteMatch) GetPath() *HTTPPathMatch { - if x != nil { - return x.Path - } - return nil -} - -func (x *HTTPRouteMatch) GetHeaders() []*HTTPHeaderMatch { - if x != nil { - return x.Headers - } - return nil -} - -func (x *HTTPRouteMatch) GetQueryParams() []*HTTPQueryParamMatch { - if x != nil { - return x.QueryParams - } - return nil -} - -func (x *HTTPRouteMatch) GetMethod() string { - if x != nil { - return x.Method - } - return "" -} - -type HTTPPathMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Type specifies how to match against the path Value. - Type PathMatchType `protobuf:"varint,1,opt,name=type,proto3,enum=hashicorp.consul.mesh.v2beta1.PathMatchType" json:"type,omitempty"` - // Value of the HTTP path to match against. - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *HTTPPathMatch) Reset() { - *x = HTTPPathMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPPathMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPPathMatch) ProtoMessage() {} - -func (x *HTTPPathMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPPathMatch.ProtoReflect.Descriptor instead. -func (*HTTPPathMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{3} -} - -func (x *HTTPPathMatch) GetType() PathMatchType { - if x != nil { - return x.Type - } - return PathMatchType_PATH_MATCH_TYPE_UNSPECIFIED -} - -func (x *HTTPPathMatch) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -type HTTPHeaderMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Type specifies how to match against the value of the header. - Type HeaderMatchType `protobuf:"varint,1,opt,name=type,proto3,enum=hashicorp.consul.mesh.v2beta1.HeaderMatchType" json:"type,omitempty"` - // Name is the name of the HTTP Header to be matched. Name matching MUST be - // case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). - // - // If multiple entries specify equivalent header names, only the first entry - // with an equivalent name MUST be considered for a match. Subsequent entries - // with an equivalent header name MUST be ignored. Due to the - // case-insensitivity of header names, “foo” and “Foo” are considered - // equivalent. - // - // When a header is repeated in an HTTP request, it is - // implementation-specific behavior as to how this is represented. Generally, - // proxies should follow the guidance from the RFC: - // https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding - // processing a repeated header, with special handling for “Set-Cookie”. - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - // Value is the value of HTTP Header to be matched. - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` - // NOTE: not in gamma; service-router compat - Invert bool `protobuf:"varint,4,opt,name=invert,proto3" json:"invert,omitempty"` -} - -func (x *HTTPHeaderMatch) Reset() { - *x = HTTPHeaderMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPHeaderMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPHeaderMatch) ProtoMessage() {} - -func (x *HTTPHeaderMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPHeaderMatch.ProtoReflect.Descriptor instead. -func (*HTTPHeaderMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{4} -} - -func (x *HTTPHeaderMatch) GetType() HeaderMatchType { - if x != nil { - return x.Type - } - return HeaderMatchType_HEADER_MATCH_TYPE_UNSPECIFIED -} - -func (x *HTTPHeaderMatch) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *HTTPHeaderMatch) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -func (x *HTTPHeaderMatch) GetInvert() bool { - if x != nil { - return x.Invert - } - return false -} - -type HTTPQueryParamMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Type specifies how to match against the value of the query parameter. - Type QueryParamMatchType `protobuf:"varint,1,opt,name=type,proto3,enum=hashicorp.consul.mesh.v2beta1.QueryParamMatchType" json:"type,omitempty"` - // Name is the name of the HTTP query param to be matched. This must be an - // exact string match. (See - // https://tools.ietf.org/html/rfc7230#section-2.7.3). - // - // If multiple entries specify equivalent query param names, only the first - // entry with an equivalent name MUST be considered for a match. Subsequent - // entries with an equivalent query param name MUST be ignored. - // - // If a query param is repeated in an HTTP request, the behavior is purposely - // left undefined, since different data planes have different capabilities. - // However, it is recommended that implementations should match against the - // first value of the param if the data plane supports it, as this behavior - // is expected in other load balancing contexts outside of the Gateway API. - // - // Users SHOULD NOT route traffic based on repeated query params to guard - // themselves against potential differences in the implementations. - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - // Value is the value of HTTP query param to be matched. - Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *HTTPQueryParamMatch) Reset() { - *x = HTTPQueryParamMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPQueryParamMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPQueryParamMatch) ProtoMessage() {} - -func (x *HTTPQueryParamMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPQueryParamMatch.ProtoReflect.Descriptor instead. -func (*HTTPQueryParamMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{5} -} - -func (x *HTTPQueryParamMatch) GetType() QueryParamMatchType { - if x != nil { - return x.Type - } - return QueryParamMatchType_QUERY_PARAM_MATCH_TYPE_UNSPECIFIED -} - -func (x *HTTPQueryParamMatch) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *HTTPQueryParamMatch) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -type HTTPRouteFilter struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // RequestHeaderModifier defines a schema for a filter that modifies request - // headers. - RequestHeaderModifier *HTTPHeaderFilter `protobuf:"bytes,1,opt,name=request_header_modifier,json=requestHeaderModifier,proto3" json:"request_header_modifier,omitempty"` - // ResponseHeaderModifier defines a schema for a filter that modifies - // response headers. - ResponseHeaderModifier *HTTPHeaderFilter `protobuf:"bytes,2,opt,name=response_header_modifier,json=responseHeaderModifier,proto3" json:"response_header_modifier,omitempty"` - // URLRewrite defines a schema for a filter that modifies a request during - // forwarding. - UrlRewrite *HTTPURLRewriteFilter `protobuf:"bytes,5,opt,name=url_rewrite,json=urlRewrite,proto3" json:"url_rewrite,omitempty"` -} - -func (x *HTTPRouteFilter) Reset() { - *x = HTTPRouteFilter{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPRouteFilter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPRouteFilter) ProtoMessage() {} - -func (x *HTTPRouteFilter) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPRouteFilter.ProtoReflect.Descriptor instead. -func (*HTTPRouteFilter) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{6} -} - -func (x *HTTPRouteFilter) GetRequestHeaderModifier() *HTTPHeaderFilter { - if x != nil { - return x.RequestHeaderModifier - } - return nil -} - -func (x *HTTPRouteFilter) GetResponseHeaderModifier() *HTTPHeaderFilter { - if x != nil { - return x.ResponseHeaderModifier - } - return nil -} - -func (x *HTTPRouteFilter) GetUrlRewrite() *HTTPURLRewriteFilter { - if x != nil { - return x.UrlRewrite - } - return nil -} - -type HTTPHeaderFilter struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Set overwrites the request with the given header (name, value) before the - // action. - Set []*HTTPHeader `protobuf:"bytes,1,rep,name=set,proto3" json:"set,omitempty"` - // Add adds the given header(s) (name, value) to the request before the - // action. It appends to any existing values associated with the header name. - Add []*HTTPHeader `protobuf:"bytes,2,rep,name=add,proto3" json:"add,omitempty"` - // Remove the given header(s) from the HTTP request before the action. The - // value of Remove is a list of HTTP header names. Note that the header names - // are case-insensitive (see - // https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - Remove []string `protobuf:"bytes,3,rep,name=remove,proto3" json:"remove,omitempty"` -} - -func (x *HTTPHeaderFilter) Reset() { - *x = HTTPHeaderFilter{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPHeaderFilter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPHeaderFilter) ProtoMessage() {} - -func (x *HTTPHeaderFilter) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPHeaderFilter.ProtoReflect.Descriptor instead. -func (*HTTPHeaderFilter) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{7} -} - -func (x *HTTPHeaderFilter) GetSet() []*HTTPHeader { - if x != nil { - return x.Set - } - return nil -} - -func (x *HTTPHeaderFilter) GetAdd() []*HTTPHeader { - if x != nil { - return x.Add - } - return nil -} - -func (x *HTTPHeaderFilter) GetRemove() []string { - if x != nil { - return x.Remove - } - return nil -} - -type HTTPHeader struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *HTTPHeader) Reset() { - *x = HTTPHeader{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPHeader) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPHeader) ProtoMessage() {} - -func (x *HTTPHeader) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPHeader.ProtoReflect.Descriptor instead. -func (*HTTPHeader) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{8} -} - -func (x *HTTPHeader) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *HTTPHeader) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -type HTTPURLRewriteFilter struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PathPrefix string `protobuf:"bytes,1,opt,name=path_prefix,json=pathPrefix,proto3" json:"path_prefix,omitempty"` -} - -func (x *HTTPURLRewriteFilter) Reset() { - *x = HTTPURLRewriteFilter{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPURLRewriteFilter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPURLRewriteFilter) ProtoMessage() {} - -func (x *HTTPURLRewriteFilter) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPURLRewriteFilter.ProtoReflect.Descriptor instead. -func (*HTTPURLRewriteFilter) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{9} -} - -func (x *HTTPURLRewriteFilter) GetPathPrefix() string { - if x != nil { - return x.PathPrefix - } - return "" -} - -type HTTPBackendRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - BackendRef *BackendReference `protobuf:"bytes,1,opt,name=backend_ref,json=backendRef,proto3" json:"backend_ref,omitempty"` - // Weight specifies the proportion of requests forwarded to the referenced - // backend. This is computed as weight/(sum of all weights in this - // BackendRefs list). For non-zero values, there may be some epsilon from the - // exact proportion defined here depending on the precision an implementation - // supports. Weight is not a percentage and the sum of weights does not need - // to equal 100. - // - // If only one backend is specified and it has a weight greater than 0, 100% - // of the traffic is forwarded to that backend. If weight is set to 0, no - // traffic should be forwarded for this entry. If unspecified, weight defaults - // to 1. - Weight uint32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` - // Filters defined at this level should be executed if and only if the - // request is being forwarded to the backend defined here. - Filters []*HTTPRouteFilter `protobuf:"bytes,3,rep,name=filters,proto3" json:"filters,omitempty"` -} - -func (x *HTTPBackendRef) Reset() { - *x = HTTPBackendRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPBackendRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPBackendRef) ProtoMessage() {} - -func (x *HTTPBackendRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPBackendRef.ProtoReflect.Descriptor instead. -func (*HTTPBackendRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_proto_rawDescGZIP(), []int{10} -} - -func (x *HTTPBackendRef) GetBackendRef() *BackendReference { - if x != nil { - return x.BackendRef - } - return nil -} - -func (x *HTTPBackendRef) GetWeight() uint32 { - if x != nil { - return x.Weight - } - return 0 -} - -func (x *HTTPBackendRef) GetFilters() []*HTTPRouteFilter { - if x != nil { - return x.Filters - } - return nil -} - -var File_pbmesh_v2beta1_http_route_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_http_route_proto_rawDesc = []byte{ - 0x0a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x1a, 0x1b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, - 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, - 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x28, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, - 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc6, - 0x01, 0x0a, 0x09, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0b, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x73, 0x12, 0x1c, 0x0a, - 0x09, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x05, 0x72, - 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x3a, - 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x8d, 0x03, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x47, 0x0a, 0x07, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x50, 0x0a, 0x0c, - 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, - 0x66, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x73, 0x12, 0x4c, - 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x73, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x07, - 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, - 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x07, - 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x8b, 0x02, 0x0a, 0x0e, 0x48, 0x54, 0x54, 0x50, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x40, 0x0a, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, - 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x48, 0x0a, 0x07, - 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, - 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x68, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x55, 0x0a, 0x0c, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, - 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x0b, 0x71, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, - 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x67, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, - 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x40, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x97, - 0x01, 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x12, 0x42, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x22, 0x87, 0x01, 0x0a, 0x13, 0x48, 0x54, 0x54, - 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x12, 0x46, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0xbb, 0x02, 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x67, 0x0a, 0x17, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x15, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, - 0x69, 0x0a, 0x18, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x5f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x52, 0x16, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x0b, 0x75, 0x72, - 0x6c, 0x5f, 0x72, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x48, 0x54, 0x54, 0x50, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x75, 0x72, 0x6c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x22, 0xa4, 0x01, 0x0a, 0x10, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x03, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x03, 0x73, - 0x65, 0x74, 0x12, 0x3b, 0x0a, 0x03, 0x61, 0x64, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x03, 0x61, 0x64, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x36, 0x0a, 0x0a, 0x48, 0x54, 0x54, 0x50, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x37, 0x0a, 0x14, 0x48, 0x54, 0x54, 0x50, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x74, 0x68, 0x5f, - 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, - 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0xc4, 0x01, 0x0a, 0x0e, 0x48, 0x54, 0x54, - 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x50, 0x0a, 0x0b, 0x62, - 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x16, 0x0a, - 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x48, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x2a, - 0x82, 0x01, 0x0a, 0x0d, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x41, 0x43, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, - 0x16, 0x50, 0x41, 0x54, 0x48, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x41, 0x54, - 0x48, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x47, - 0x45, 0x58, 0x10, 0x03, 0x2a, 0xc9, 0x01, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x48, 0x45, 0x41, 0x44, - 0x45, 0x52, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x48, - 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x45, 0x58, 0x41, 0x43, 0x54, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x48, 0x45, 0x41, 0x44, - 0x45, 0x52, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, - 0x47, 0x45, 0x58, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, - 0x4e, 0x54, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4d, - 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, - 0x10, 0x04, 0x12, 0x1c, 0x0a, 0x18, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x55, 0x46, 0x46, 0x49, 0x58, 0x10, 0x05, - 0x2a, 0xa5, 0x01, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x22, 0x51, 0x55, 0x45, 0x52, - 0x59, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x20, 0x0a, 0x1c, 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x5f, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x41, 0x43, 0x54, - 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x50, 0x41, 0x52, 0x41, - 0x4d, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x47, - 0x45, 0x58, 0x10, 0x02, 0x12, 0x22, 0x0a, 0x1e, 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x50, 0x41, - 0x52, 0x41, 0x4d, 0x5f, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, - 0x52, 0x45, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x42, 0x8f, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0e, - 0x48, 0x74, 0x74, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, - 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, - 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, - 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, - 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_http_route_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_http_route_proto_rawDescData = file_pbmesh_v2beta1_http_route_proto_rawDesc -) - -func file_pbmesh_v2beta1_http_route_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_http_route_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_http_route_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_http_route_proto_rawDescData) - }) - return file_pbmesh_v2beta1_http_route_proto_rawDescData -} - -var file_pbmesh_v2beta1_http_route_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_pbmesh_v2beta1_http_route_proto_msgTypes = make([]protoimpl.MessageInfo, 11) -var file_pbmesh_v2beta1_http_route_proto_goTypes = []interface{}{ - (PathMatchType)(0), // 0: hashicorp.consul.mesh.v2beta1.PathMatchType - (HeaderMatchType)(0), // 1: hashicorp.consul.mesh.v2beta1.HeaderMatchType - (QueryParamMatchType)(0), // 2: hashicorp.consul.mesh.v2beta1.QueryParamMatchType - (*HTTPRoute)(nil), // 3: hashicorp.consul.mesh.v2beta1.HTTPRoute - (*HTTPRouteRule)(nil), // 4: hashicorp.consul.mesh.v2beta1.HTTPRouteRule - (*HTTPRouteMatch)(nil), // 5: hashicorp.consul.mesh.v2beta1.HTTPRouteMatch - (*HTTPPathMatch)(nil), // 6: hashicorp.consul.mesh.v2beta1.HTTPPathMatch - (*HTTPHeaderMatch)(nil), // 7: hashicorp.consul.mesh.v2beta1.HTTPHeaderMatch - (*HTTPQueryParamMatch)(nil), // 8: hashicorp.consul.mesh.v2beta1.HTTPQueryParamMatch - (*HTTPRouteFilter)(nil), // 9: hashicorp.consul.mesh.v2beta1.HTTPRouteFilter - (*HTTPHeaderFilter)(nil), // 10: hashicorp.consul.mesh.v2beta1.HTTPHeaderFilter - (*HTTPHeader)(nil), // 11: hashicorp.consul.mesh.v2beta1.HTTPHeader - (*HTTPURLRewriteFilter)(nil), // 12: hashicorp.consul.mesh.v2beta1.HTTPURLRewriteFilter - (*HTTPBackendRef)(nil), // 13: hashicorp.consul.mesh.v2beta1.HTTPBackendRef - (*ParentReference)(nil), // 14: hashicorp.consul.mesh.v2beta1.ParentReference - (*HTTPRouteTimeouts)(nil), // 15: hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts - (*HTTPRouteRetries)(nil), // 16: hashicorp.consul.mesh.v2beta1.HTTPRouteRetries - (*BackendReference)(nil), // 17: hashicorp.consul.mesh.v2beta1.BackendReference -} -var file_pbmesh_v2beta1_http_route_proto_depIdxs = []int32{ - 14, // 0: hashicorp.consul.mesh.v2beta1.HTTPRoute.parent_refs:type_name -> hashicorp.consul.mesh.v2beta1.ParentReference - 4, // 1: hashicorp.consul.mesh.v2beta1.HTTPRoute.rules:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteRule - 5, // 2: hashicorp.consul.mesh.v2beta1.HTTPRouteRule.matches:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteMatch - 9, // 3: hashicorp.consul.mesh.v2beta1.HTTPRouteRule.filters:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteFilter - 13, // 4: hashicorp.consul.mesh.v2beta1.HTTPRouteRule.backend_refs:type_name -> hashicorp.consul.mesh.v2beta1.HTTPBackendRef - 15, // 5: hashicorp.consul.mesh.v2beta1.HTTPRouteRule.timeouts:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts - 16, // 6: hashicorp.consul.mesh.v2beta1.HTTPRouteRule.retries:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteRetries - 6, // 7: hashicorp.consul.mesh.v2beta1.HTTPRouteMatch.path:type_name -> hashicorp.consul.mesh.v2beta1.HTTPPathMatch - 7, // 8: hashicorp.consul.mesh.v2beta1.HTTPRouteMatch.headers:type_name -> hashicorp.consul.mesh.v2beta1.HTTPHeaderMatch - 8, // 9: hashicorp.consul.mesh.v2beta1.HTTPRouteMatch.query_params:type_name -> hashicorp.consul.mesh.v2beta1.HTTPQueryParamMatch - 0, // 10: hashicorp.consul.mesh.v2beta1.HTTPPathMatch.type:type_name -> hashicorp.consul.mesh.v2beta1.PathMatchType - 1, // 11: hashicorp.consul.mesh.v2beta1.HTTPHeaderMatch.type:type_name -> hashicorp.consul.mesh.v2beta1.HeaderMatchType - 2, // 12: hashicorp.consul.mesh.v2beta1.HTTPQueryParamMatch.type:type_name -> hashicorp.consul.mesh.v2beta1.QueryParamMatchType - 10, // 13: hashicorp.consul.mesh.v2beta1.HTTPRouteFilter.request_header_modifier:type_name -> hashicorp.consul.mesh.v2beta1.HTTPHeaderFilter - 10, // 14: hashicorp.consul.mesh.v2beta1.HTTPRouteFilter.response_header_modifier:type_name -> hashicorp.consul.mesh.v2beta1.HTTPHeaderFilter - 12, // 15: hashicorp.consul.mesh.v2beta1.HTTPRouteFilter.url_rewrite:type_name -> hashicorp.consul.mesh.v2beta1.HTTPURLRewriteFilter - 11, // 16: hashicorp.consul.mesh.v2beta1.HTTPHeaderFilter.set:type_name -> hashicorp.consul.mesh.v2beta1.HTTPHeader - 11, // 17: hashicorp.consul.mesh.v2beta1.HTTPHeaderFilter.add:type_name -> hashicorp.consul.mesh.v2beta1.HTTPHeader - 17, // 18: hashicorp.consul.mesh.v2beta1.HTTPBackendRef.backend_ref:type_name -> hashicorp.consul.mesh.v2beta1.BackendReference - 9, // 19: hashicorp.consul.mesh.v2beta1.HTTPBackendRef.filters:type_name -> hashicorp.consul.mesh.v2beta1.HTTPRouteFilter - 20, // [20:20] is the sub-list for method output_type - 20, // [20:20] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_http_route_proto_init() } -func file_pbmesh_v2beta1_http_route_proto_init() { - if File_pbmesh_v2beta1_http_route_proto != nil { - return - } - file_pbmesh_v2beta1_common_proto_init() - file_pbmesh_v2beta1_http_route_retries_proto_init() - file_pbmesh_v2beta1_http_route_timeouts_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_http_route_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPRoute); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPRouteRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPRouteMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPPathMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPHeaderMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPQueryParamMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPRouteFilter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPHeaderFilter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPHeader); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPURLRewriteFilter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_http_route_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPBackendRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_http_route_proto_rawDesc, - NumEnums: 3, - NumMessages: 11, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_http_route_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_http_route_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_http_route_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_http_route_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_http_route_proto = out.File - file_pbmesh_v2beta1_http_route_proto_rawDesc = nil - file_pbmesh_v2beta1_http_route_proto_goTypes = nil - file_pbmesh_v2beta1_http_route_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/http_route.proto b/proto-public/pbmesh/v2beta1/http_route.proto deleted file mode 100644 index b651921c48c03..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route.proto +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbmesh/v2beta1/common.proto"; -import "pbmesh/v2beta1/http_route_retries.proto"; -import "pbmesh/v2beta1/http_route_timeouts.proto"; -import "pbresource/annotations.proto"; - -// NOTE: this should align to the GAMMA/gateway-api version, or at least be -// easily translatable. -// -// https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.HTTPRoute -// -// This is a Resource type. -message HTTPRoute { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // ParentRefs references the resources (usually Services) that a Route wants - // to be attached to. - // - // It is invalid to reference an identical parent more than once. It is valid - // to reference multiple distinct sections within the same parent resource. - repeated ParentReference parent_refs = 1; - - // Hostnames are the hostnames for which this HTTPRoute should respond to requests. - // - // This is only valid for north/south. - repeated string hostnames = 2; - - // Rules are a list of HTTP-based routing rules that this route should - // use for constructing a routing table. - repeated HTTPRouteRule rules = 3; -} - -// HTTPRouteRule specifies the routing rules used to determine what upstream -// service an HTTP request is routed to. -message HTTPRouteRule { - repeated HTTPRouteMatch matches = 1; - repeated HTTPRouteFilter filters = 2; - - // BackendRefs defines the backend(s) where matching requests should be sent. - // - // Failure behavior here depends on how many BackendRefs are specified and - // how many are invalid. - // - // If all entries in BackendRefs are invalid, and there are also no filters - // specified in this route rule, all traffic which matches this rule MUST - // receive a 500 status code. - // - // See the HTTPBackendRef definition for the rules about what makes a single - // HTTPBackendRef invalid. - // - // When a HTTPBackendRef is invalid, 500 status codes MUST be returned for - // requests that would have otherwise been routed to an invalid backend. If - // multiple backends are specified, and some are invalid, the proportion of - // requests that would otherwise have been routed to an invalid backend MUST - // receive a 500 status code. - // - // For example, if two backends are specified with equal weights, and one is - // invalid, 50 percent of traffic must receive a 500. Implementations may - // choose how that 50 percent is determined. - repeated HTTPBackendRef backend_refs = 3; - - HTTPRouteTimeouts timeouts = 4; - HTTPRouteRetries retries = 5; -} - -message HTTPRouteMatch { - // Path specifies a HTTP request path matcher. If this field is not - // specified, a default prefix match on the “/” path is provided. - HTTPPathMatch path = 1; - - // Headers specifies HTTP request header matchers. Multiple match values are - // ANDed together, meaning, a request must match all the specified headers to - // select the route. - repeated HTTPHeaderMatch headers = 2; - - // QueryParams specifies HTTP query parameter matchers. Multiple match values - // are ANDed together, meaning, a request must match all the specified query - // parameters to select the route. - repeated HTTPQueryParamMatch query_params = 3; - - // Method specifies HTTP method matcher. When specified, this route will be - // matched only if the request has the specified method. - string method = 4; -} - -message HTTPPathMatch { - // Type specifies how to match against the path Value. - PathMatchType type = 1; - // Value of the HTTP path to match against. - string value = 2; -} - -// PathMatchType specifies the semantics of how HTTP paths should be compared. -// Valid PathMatchType values, along with their support levels, are: -// -// PathPrefix and Exact paths must be syntactically valid: -// -// - Must begin with the / character -// - Must not contain consecutive / characters (e.g. /foo///, //). -// - Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. -// -// Unknown values here must result in the implementation setting the Accepted -// Condition for the Route to status: False, with a Reason of UnsupportedValue. -// -// +kubebuilder:validation:Enum=PATH_MATCH_TYPE_UNSPECIFIED;PATH_MATCH_TYPE_EXACT;PATH_MATCH_TYPE_PREFIX;PATH_MATCH_TYPE_REGEX -// +kubebuilder:validation:Type=string -enum PathMatchType { - PATH_MATCH_TYPE_UNSPECIFIED = 0; - PATH_MATCH_TYPE_EXACT = 1; - PATH_MATCH_TYPE_PREFIX = 2; - PATH_MATCH_TYPE_REGEX = 3; -} - -message HTTPHeaderMatch { - // Type specifies how to match against the value of the header. - HeaderMatchType type = 1; - - // Name is the name of the HTTP Header to be matched. Name matching MUST be - // case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). - // - // If multiple entries specify equivalent header names, only the first entry - // with an equivalent name MUST be considered for a match. Subsequent entries - // with an equivalent header name MUST be ignored. Due to the - // case-insensitivity of header names, “foo” and “Foo” are considered - // equivalent. - // - // When a header is repeated in an HTTP request, it is - // implementation-specific behavior as to how this is represented. Generally, - // proxies should follow the guidance from the RFC: - // https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding - // processing a repeated header, with special handling for “Set-Cookie”. - string name = 2; - - // Value is the value of HTTP Header to be matched. - string value = 3; - - // NOTE: not in gamma; service-router compat - bool invert = 4; -} - -// HeaderMatchType specifies the semantics of how HTTP header values should be -// compared. Valid HeaderMatchType values, along with their conformance levels, -// are: -// -// Note that values may be added to this enum, implementations must ensure that -// unknown values will not cause a crash. -// -// Unknown values here must result in the implementation setting the Accepted -// Condition for the Route to status: False, with a Reason of UnsupportedValue. -// -// +kubebuilder:validation:Enum=HEADER_MATCH_TYPE_UNSPECIFIED;HEADER_MATCH_TYPE_EXACT;HEADER_MATCH_TYPE_REGEX;HEADER_MATCH_TYPE_PRESENT;HEADER_MATCH_TYPE_PREFIX;HEADER_MATCH_TYPE_SUFFIX -// +kubebuilder:validation:Type=string -enum HeaderMatchType { - HEADER_MATCH_TYPE_UNSPECIFIED = 0; - HEADER_MATCH_TYPE_EXACT = 1; - HEADER_MATCH_TYPE_REGEX = 2; - // consul only after this point (service-router compat) - HEADER_MATCH_TYPE_PRESENT = 3; - HEADER_MATCH_TYPE_PREFIX = 4; - HEADER_MATCH_TYPE_SUFFIX = 5; -} - -message HTTPQueryParamMatch { - // Type specifies how to match against the value of the query parameter. - QueryParamMatchType type = 1; - - // Name is the name of the HTTP query param to be matched. This must be an - // exact string match. (See - // https://tools.ietf.org/html/rfc7230#section-2.7.3). - // - // If multiple entries specify equivalent query param names, only the first - // entry with an equivalent name MUST be considered for a match. Subsequent - // entries with an equivalent query param name MUST be ignored. - // - // If a query param is repeated in an HTTP request, the behavior is purposely - // left undefined, since different data planes have different capabilities. - // However, it is recommended that implementations should match against the - // first value of the param if the data plane supports it, as this behavior - // is expected in other load balancing contexts outside of the Gateway API. - // - // Users SHOULD NOT route traffic based on repeated query params to guard - // themselves against potential differences in the implementations. - string name = 2; - - // Value is the value of HTTP query param to be matched. - string value = 3; -} - -// +kubebuilder:validation:Enum=QUERY_PARAM_MATCH_TYPE_UNSPECIFIED;QUERY_PARAM_MATCH_TYPE_EXACT;QUERY_PARAM_MATCH_TYPE_REGEX;QUERY_PARAM_MATCH_TYPE_PRESENT -// +kubebuilder:validation:Type=string -enum QueryParamMatchType { - QUERY_PARAM_MATCH_TYPE_UNSPECIFIED = 0; - QUERY_PARAM_MATCH_TYPE_EXACT = 1; - QUERY_PARAM_MATCH_TYPE_REGEX = 2; - // consul only after this point (service-router compat) - QUERY_PARAM_MATCH_TYPE_PRESENT = 3; -} - -message HTTPRouteFilter { - // RequestHeaderModifier defines a schema for a filter that modifies request - // headers. - HTTPHeaderFilter request_header_modifier = 1; - - // ResponseHeaderModifier defines a schema for a filter that modifies - // response headers. - HTTPHeaderFilter response_header_modifier = 2; - - // URLRewrite defines a schema for a filter that modifies a request during - // forwarding. - HTTPURLRewriteFilter url_rewrite = 5; -} - -message HTTPHeaderFilter { - // Set overwrites the request with the given header (name, value) before the - // action. - repeated HTTPHeader set = 1; - - // Add adds the given header(s) (name, value) to the request before the - // action. It appends to any existing values associated with the header name. - repeated HTTPHeader add = 2; - - // Remove the given header(s) from the HTTP request before the action. The - // value of Remove is a list of HTTP header names. Note that the header names - // are case-insensitive (see - // https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). - repeated string remove = 3; -} - -message HTTPHeader { - string name = 1; - string value = 2; -} - -message HTTPURLRewriteFilter { - string path_prefix = 1; -} - -message HTTPBackendRef { - BackendReference backend_ref = 1; - - // Weight specifies the proportion of requests forwarded to the referenced - // backend. This is computed as weight/(sum of all weights in this - // BackendRefs list). For non-zero values, there may be some epsilon from the - // exact proportion defined here depending on the precision an implementation - // supports. Weight is not a percentage and the sum of weights does not need - // to equal 100. - // - // If only one backend is specified and it has a weight greater than 0, 100% - // of the traffic is forwarded to that backend. If weight is set to 0, no - // traffic should be forwarded for this entry. If unspecified, weight defaults - // to 1. - uint32 weight = 2; - - // Filters defined at this level should be executed if and only if the - // request is being forwarded to the backend defined here. - repeated HTTPRouteFilter filters = 3; -} diff --git a/proto-public/pbmesh/v2beta1/http_route_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/http_route_deepcopy.gen.go deleted file mode 100644 index 6d339e5afde20..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_deepcopy.gen.go +++ /dev/null @@ -1,237 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using HTTPRoute within kubernetes types, where deepcopy-gen is used. -func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRoute. Required by controller-gen. -func (in *HTTPRoute) DeepCopy() *HTTPRoute { - if in == nil { - return nil - } - out := new(HTTPRoute) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRoute. Required by controller-gen. -func (in *HTTPRoute) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPRouteRule within kubernetes types, where deepcopy-gen is used. -func (in *HTTPRouteRule) DeepCopyInto(out *HTTPRouteRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteRule. Required by controller-gen. -func (in *HTTPRouteRule) DeepCopy() *HTTPRouteRule { - if in == nil { - return nil - } - out := new(HTTPRouteRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteRule. Required by controller-gen. -func (in *HTTPRouteRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPRouteMatch within kubernetes types, where deepcopy-gen is used. -func (in *HTTPRouteMatch) DeepCopyInto(out *HTTPRouteMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteMatch. Required by controller-gen. -func (in *HTTPRouteMatch) DeepCopy() *HTTPRouteMatch { - if in == nil { - return nil - } - out := new(HTTPRouteMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteMatch. Required by controller-gen. -func (in *HTTPRouteMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPPathMatch within kubernetes types, where deepcopy-gen is used. -func (in *HTTPPathMatch) DeepCopyInto(out *HTTPPathMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPPathMatch. Required by controller-gen. -func (in *HTTPPathMatch) DeepCopy() *HTTPPathMatch { - if in == nil { - return nil - } - out := new(HTTPPathMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPPathMatch. Required by controller-gen. -func (in *HTTPPathMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPHeaderMatch within kubernetes types, where deepcopy-gen is used. -func (in *HTTPHeaderMatch) DeepCopyInto(out *HTTPHeaderMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeaderMatch. Required by controller-gen. -func (in *HTTPHeaderMatch) DeepCopy() *HTTPHeaderMatch { - if in == nil { - return nil - } - out := new(HTTPHeaderMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeaderMatch. Required by controller-gen. -func (in *HTTPHeaderMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPQueryParamMatch within kubernetes types, where deepcopy-gen is used. -func (in *HTTPQueryParamMatch) DeepCopyInto(out *HTTPQueryParamMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPQueryParamMatch. Required by controller-gen. -func (in *HTTPQueryParamMatch) DeepCopy() *HTTPQueryParamMatch { - if in == nil { - return nil - } - out := new(HTTPQueryParamMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPQueryParamMatch. Required by controller-gen. -func (in *HTTPQueryParamMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPRouteFilter within kubernetes types, where deepcopy-gen is used. -func (in *HTTPRouteFilter) DeepCopyInto(out *HTTPRouteFilter) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteFilter. Required by controller-gen. -func (in *HTTPRouteFilter) DeepCopy() *HTTPRouteFilter { - if in == nil { - return nil - } - out := new(HTTPRouteFilter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteFilter. Required by controller-gen. -func (in *HTTPRouteFilter) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPHeaderFilter within kubernetes types, where deepcopy-gen is used. -func (in *HTTPHeaderFilter) DeepCopyInto(out *HTTPHeaderFilter) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeaderFilter. Required by controller-gen. -func (in *HTTPHeaderFilter) DeepCopy() *HTTPHeaderFilter { - if in == nil { - return nil - } - out := new(HTTPHeaderFilter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeaderFilter. Required by controller-gen. -func (in *HTTPHeaderFilter) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPHeader within kubernetes types, where deepcopy-gen is used. -func (in *HTTPHeader) DeepCopyInto(out *HTTPHeader) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeader. Required by controller-gen. -func (in *HTTPHeader) DeepCopy() *HTTPHeader { - if in == nil { - return nil - } - out := new(HTTPHeader) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeader. Required by controller-gen. -func (in *HTTPHeader) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPURLRewriteFilter within kubernetes types, where deepcopy-gen is used. -func (in *HTTPURLRewriteFilter) DeepCopyInto(out *HTTPURLRewriteFilter) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPURLRewriteFilter. Required by controller-gen. -func (in *HTTPURLRewriteFilter) DeepCopy() *HTTPURLRewriteFilter { - if in == nil { - return nil - } - out := new(HTTPURLRewriteFilter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPURLRewriteFilter. Required by controller-gen. -func (in *HTTPURLRewriteFilter) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HTTPBackendRef within kubernetes types, where deepcopy-gen is used. -func (in *HTTPBackendRef) DeepCopyInto(out *HTTPBackendRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPBackendRef. Required by controller-gen. -func (in *HTTPBackendRef) DeepCopy() *HTTPBackendRef { - if in == nil { - return nil - } - out := new(HTTPBackendRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPBackendRef. Required by controller-gen. -func (in *HTTPBackendRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/http_route_json.gen.go b/proto-public/pbmesh/v2beta1/http_route_json.gen.go deleted file mode 100644 index 2860a5a356cc9..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_json.gen.go +++ /dev/null @@ -1,132 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for HTTPRoute -func (this *HTTPRoute) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPRoute -func (this *HTTPRoute) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPRouteRule -func (this *HTTPRouteRule) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPRouteRule -func (this *HTTPRouteRule) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPRouteMatch -func (this *HTTPRouteMatch) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPRouteMatch -func (this *HTTPRouteMatch) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPPathMatch -func (this *HTTPPathMatch) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPPathMatch -func (this *HTTPPathMatch) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPHeaderMatch -func (this *HTTPHeaderMatch) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPHeaderMatch -func (this *HTTPHeaderMatch) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPQueryParamMatch -func (this *HTTPQueryParamMatch) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPQueryParamMatch -func (this *HTTPQueryParamMatch) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPRouteFilter -func (this *HTTPRouteFilter) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPRouteFilter -func (this *HTTPRouteFilter) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPHeaderFilter -func (this *HTTPHeaderFilter) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPHeaderFilter -func (this *HTTPHeaderFilter) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPHeader -func (this *HTTPHeader) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPHeader -func (this *HTTPHeader) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPURLRewriteFilter -func (this *HTTPURLRewriteFilter) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPURLRewriteFilter -func (this *HTTPURLRewriteFilter) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HTTPBackendRef -func (this *HTTPBackendRef) MarshalJSON() ([]byte, error) { - str, err := HttpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPBackendRef -func (this *HTTPBackendRef) UnmarshalJSON(b []byte) error { - return HttpRouteUnmarshaler.Unmarshal(b, this) -} - -var ( - HttpRouteMarshaler = &protojson.MarshalOptions{} - HttpRouteUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/http_route_retries.pb.binary.go b/proto-public/pbmesh/v2beta1/http_route_retries.pb.binary.go deleted file mode 100644 index 390641d255ecd..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_retries.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/http_route_retries.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPRouteRetries) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPRouteRetries) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/http_route_retries.pb.go b/proto-public/pbmesh/v2beta1/http_route_retries.pb.go deleted file mode 100644 index 49f1501fc78e5..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_retries.pb.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/http_route_retries.proto - -package meshv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type HTTPRouteRetries struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Number is the number of times to retry the request when a retryable - // result occurs. - Number *wrapperspb.UInt32Value `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty"` - // RetryOnConnectFailure allows for connection failure errors to trigger a - // retry. - OnConnectFailure bool `protobuf:"varint,2,opt,name=on_connect_failure,json=onConnectFailure,proto3" json:"on_connect_failure,omitempty"` - // RetryOn allows setting envoy specific conditions when a request should - // be automatically retried. - OnConditions []string `protobuf:"bytes,3,rep,name=on_conditions,json=onConditions,proto3" json:"on_conditions,omitempty"` - // RetryOnStatusCodes is a flat list of http response status codes that are - // eligible for retry. This again should be feasible in any reasonable proxy. - OnStatusCodes []uint32 `protobuf:"varint,4,rep,packed,name=on_status_codes,json=onStatusCodes,proto3" json:"on_status_codes,omitempty"` -} - -func (x *HTTPRouteRetries) Reset() { - *x = HTTPRouteRetries{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_retries_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPRouteRetries) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPRouteRetries) ProtoMessage() {} - -func (x *HTTPRouteRetries) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_retries_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPRouteRetries.ProtoReflect.Descriptor instead. -func (*HTTPRouteRetries) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_retries_proto_rawDescGZIP(), []int{0} -} - -func (x *HTTPRouteRetries) GetNumber() *wrapperspb.UInt32Value { - if x != nil { - return x.Number - } - return nil -} - -func (x *HTTPRouteRetries) GetOnConnectFailure() bool { - if x != nil { - return x.OnConnectFailure - } - return false -} - -func (x *HTTPRouteRetries) GetOnConditions() []string { - if x != nil { - return x.OnConditions - } - return nil -} - -func (x *HTTPRouteRetries) GetOnStatusCodes() []uint32 { - if x != nil { - return x.OnStatusCodes - } - return nil -} - -var File_pbmesh_v2beta1_http_route_retries_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_http_route_retries_proto_rawDesc = []byte{ - 0x0a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x72, - 0x69, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc3, 0x01, 0x0a, 0x10, 0x48, 0x54, 0x54, - 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x34, 0x0a, - 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x10, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, - 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0d, 0x52, - 0x0d, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x42, 0x96, - 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x15, 0x48, 0x74, 0x74, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, - 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_http_route_retries_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_http_route_retries_proto_rawDescData = file_pbmesh_v2beta1_http_route_retries_proto_rawDesc -) - -func file_pbmesh_v2beta1_http_route_retries_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_http_route_retries_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_http_route_retries_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_http_route_retries_proto_rawDescData) - }) - return file_pbmesh_v2beta1_http_route_retries_proto_rawDescData -} - -var file_pbmesh_v2beta1_http_route_retries_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmesh_v2beta1_http_route_retries_proto_goTypes = []interface{}{ - (*HTTPRouteRetries)(nil), // 0: hashicorp.consul.mesh.v2beta1.HTTPRouteRetries - (*wrapperspb.UInt32Value)(nil), // 1: google.protobuf.UInt32Value -} -var file_pbmesh_v2beta1_http_route_retries_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.mesh.v2beta1.HTTPRouteRetries.number:type_name -> google.protobuf.UInt32Value - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_http_route_retries_proto_init() } -func file_pbmesh_v2beta1_http_route_retries_proto_init() { - if File_pbmesh_v2beta1_http_route_retries_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_http_route_retries_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPRouteRetries); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_http_route_retries_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_http_route_retries_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_http_route_retries_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_http_route_retries_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_http_route_retries_proto = out.File - file_pbmesh_v2beta1_http_route_retries_proto_rawDesc = nil - file_pbmesh_v2beta1_http_route_retries_proto_goTypes = nil - file_pbmesh_v2beta1_http_route_retries_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/http_route_retries.proto b/proto-public/pbmesh/v2beta1/http_route_retries.proto deleted file mode 100644 index 7eae2545866ab..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_retries.proto +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "google/protobuf/wrappers.proto"; - -message HTTPRouteRetries { - // Number is the number of times to retry the request when a retryable - // result occurs. - google.protobuf.UInt32Value number = 1; - - // RetryOnConnectFailure allows for connection failure errors to trigger a - // retry. - bool on_connect_failure = 2; - - // RetryOn allows setting envoy specific conditions when a request should - // be automatically retried. - repeated string on_conditions = 3; - - // RetryOnStatusCodes is a flat list of http response status codes that are - // eligible for retry. This again should be feasible in any reasonable proxy. - repeated uint32 on_status_codes = 4; -} diff --git a/proto-public/pbmesh/v2beta1/http_route_retries_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/http_route_retries_deepcopy.gen.go deleted file mode 100644 index abd2a515332d4..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_retries_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using HTTPRouteRetries within kubernetes types, where deepcopy-gen is used. -func (in *HTTPRouteRetries) DeepCopyInto(out *HTTPRouteRetries) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteRetries. Required by controller-gen. -func (in *HTTPRouteRetries) DeepCopy() *HTTPRouteRetries { - if in == nil { - return nil - } - out := new(HTTPRouteRetries) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteRetries. Required by controller-gen. -func (in *HTTPRouteRetries) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/http_route_retries_json.gen.go b/proto-public/pbmesh/v2beta1/http_route_retries_json.gen.go deleted file mode 100644 index 5dfe2a5061f62..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_retries_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for HTTPRouteRetries -func (this *HTTPRouteRetries) MarshalJSON() ([]byte, error) { - str, err := HttpRouteRetriesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPRouteRetries -func (this *HTTPRouteRetries) UnmarshalJSON(b []byte) error { - return HttpRouteRetriesUnmarshaler.Unmarshal(b, this) -} - -var ( - HttpRouteRetriesMarshaler = &protojson.MarshalOptions{} - HttpRouteRetriesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/http_route_timeouts.pb.binary.go b/proto-public/pbmesh/v2beta1/http_route_timeouts.pb.binary.go deleted file mode 100644 index a85a09cf2fe23..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_timeouts.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/http_route_timeouts.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPRouteTimeouts) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPRouteTimeouts) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/http_route_timeouts.pb.go b/proto-public/pbmesh/v2beta1/http_route_timeouts.pb.go deleted file mode 100644 index 87e5ec3f578ad..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_timeouts.pb.go +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/http_route_timeouts.proto - -package meshv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// HTTPRouteTimeouts defines timeouts that can be configured for an HTTPRoute -// or GRPCRoute. -type HTTPRouteTimeouts struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // RequestTimeout is the total amount of time permitted for the entire - // downstream request (and retries) to be processed. - // +kubebuilder:validation:Format=duration - Request *durationpb.Duration `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"` - // Idle specifies the total amount of time permitted for the request stream to be idle. - // +kubebuilder:validation:Format=duration - Idle *durationpb.Duration `protobuf:"bytes,2,opt,name=idle,proto3" json:"idle,omitempty"` -} - -func (x *HTTPRouteTimeouts) Reset() { - *x = HTTPRouteTimeouts{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_http_route_timeouts_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPRouteTimeouts) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPRouteTimeouts) ProtoMessage() {} - -func (x *HTTPRouteTimeouts) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_http_route_timeouts_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPRouteTimeouts.ProtoReflect.Descriptor instead. -func (*HTTPRouteTimeouts) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_http_route_timeouts_proto_rawDescGZIP(), []int{0} -} - -func (x *HTTPRouteTimeouts) GetRequest() *durationpb.Duration { - if x != nil { - return x.Request - } - return nil -} - -func (x *HTTPRouteTimeouts) GetIdle() *durationpb.Duration { - if x != nil { - return x.Idle - } - return nil -} - -var File_pbmesh_v2beta1_http_route_timeouts_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_http_route_timeouts_proto_rawDesc = []byte{ - 0x0a, 0x28, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x77, 0x0a, 0x11, 0x48, 0x54, 0x54, - 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x12, 0x33, - 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x04, 0x69, 0x64, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x69, 0x64, - 0x6c, 0x65, 0x42, 0x97, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x16, 0x48, 0x74, 0x74, 0x70, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, - 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, - 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_http_route_timeouts_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_http_route_timeouts_proto_rawDescData = file_pbmesh_v2beta1_http_route_timeouts_proto_rawDesc -) - -func file_pbmesh_v2beta1_http_route_timeouts_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_http_route_timeouts_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_http_route_timeouts_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_http_route_timeouts_proto_rawDescData) - }) - return file_pbmesh_v2beta1_http_route_timeouts_proto_rawDescData -} - -var file_pbmesh_v2beta1_http_route_timeouts_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmesh_v2beta1_http_route_timeouts_proto_goTypes = []interface{}{ - (*HTTPRouteTimeouts)(nil), // 0: hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts - (*durationpb.Duration)(nil), // 1: google.protobuf.Duration -} -var file_pbmesh_v2beta1_http_route_timeouts_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts.request:type_name -> google.protobuf.Duration - 1, // 1: hashicorp.consul.mesh.v2beta1.HTTPRouteTimeouts.idle:type_name -> google.protobuf.Duration - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_http_route_timeouts_proto_init() } -func file_pbmesh_v2beta1_http_route_timeouts_proto_init() { - if File_pbmesh_v2beta1_http_route_timeouts_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_http_route_timeouts_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPRouteTimeouts); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_http_route_timeouts_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_http_route_timeouts_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_http_route_timeouts_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_http_route_timeouts_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_http_route_timeouts_proto = out.File - file_pbmesh_v2beta1_http_route_timeouts_proto_rawDesc = nil - file_pbmesh_v2beta1_http_route_timeouts_proto_goTypes = nil - file_pbmesh_v2beta1_http_route_timeouts_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/http_route_timeouts.proto b/proto-public/pbmesh/v2beta1/http_route_timeouts.proto deleted file mode 100644 index 246971251d5ff..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_timeouts.proto +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "google/protobuf/duration.proto"; - -// HTTPRouteTimeouts defines timeouts that can be configured for an HTTPRoute -// or GRPCRoute. -message HTTPRouteTimeouts { - // RequestTimeout is the total amount of time permitted for the entire - // downstream request (and retries) to be processed. - // +kubebuilder:validation:Format=duration - google.protobuf.Duration request = 1; - - // Idle specifies the total amount of time permitted for the request stream to be idle. - // +kubebuilder:validation:Format=duration - google.protobuf.Duration idle = 2; -} diff --git a/proto-public/pbmesh/v2beta1/http_route_timeouts_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/http_route_timeouts_deepcopy.gen.go deleted file mode 100644 index c131310e5e26e..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_timeouts_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using HTTPRouteTimeouts within kubernetes types, where deepcopy-gen is used. -func (in *HTTPRouteTimeouts) DeepCopyInto(out *HTTPRouteTimeouts) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteTimeouts. Required by controller-gen. -func (in *HTTPRouteTimeouts) DeepCopy() *HTTPRouteTimeouts { - if in == nil { - return nil - } - out := new(HTTPRouteTimeouts) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteTimeouts. Required by controller-gen. -func (in *HTTPRouteTimeouts) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/http_route_timeouts_json.gen.go b/proto-public/pbmesh/v2beta1/http_route_timeouts_json.gen.go deleted file mode 100644 index c81461d225462..0000000000000 --- a/proto-public/pbmesh/v2beta1/http_route_timeouts_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for HTTPRouteTimeouts -func (this *HTTPRouteTimeouts) MarshalJSON() ([]byte, error) { - str, err := HttpRouteTimeoutsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HTTPRouteTimeouts -func (this *HTTPRouteTimeouts) UnmarshalJSON(b []byte) error { - return HttpRouteTimeoutsUnmarshaler.Unmarshal(b, this) -} - -var ( - HttpRouteTimeoutsMarshaler = &protojson.MarshalOptions{} - HttpRouteTimeoutsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.pb.binary.go deleted file mode 100644 index 1f08bf73b6080..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/access_logs.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *AccessLogs) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *AccessLogs) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.pb.go deleted file mode 100644 index c1c30af893c63..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.pb.go +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/access_logs.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=LOG_SINK_TYPE_DEFAULT;LOG_SINK_TYPE_FILE;LOG_SINK_TYPE_STDERR;LOG_SINK_TYPE_STDOUT -// +kubebuilder:validation:Type=string -type LogSinkType int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - LogSinkType_LOG_SINK_TYPE_DEFAULT LogSinkType = 0 - LogSinkType_LOG_SINK_TYPE_FILE LogSinkType = 1 - LogSinkType_LOG_SINK_TYPE_STDERR LogSinkType = 2 - LogSinkType_LOG_SINK_TYPE_STDOUT LogSinkType = 3 -) - -// Enum value maps for LogSinkType. -var ( - LogSinkType_name = map[int32]string{ - 0: "LOG_SINK_TYPE_DEFAULT", - 1: "LOG_SINK_TYPE_FILE", - 2: "LOG_SINK_TYPE_STDERR", - 3: "LOG_SINK_TYPE_STDOUT", - } - LogSinkType_value = map[string]int32{ - "LOG_SINK_TYPE_DEFAULT": 0, - "LOG_SINK_TYPE_FILE": 1, - "LOG_SINK_TYPE_STDERR": 2, - "LOG_SINK_TYPE_STDOUT": 3, - } -) - -func (x LogSinkType) Enum() *LogSinkType { - p := new(LogSinkType) - *p = x - return p -} - -func (x LogSinkType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (LogSinkType) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_access_logs_proto_enumTypes[0].Descriptor() -} - -func (LogSinkType) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_access_logs_proto_enumTypes[0] -} - -func (x LogSinkType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use LogSinkType.Descriptor instead. -func (LogSinkType) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescGZIP(), []int{0} -} - -type AccessLogs struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // enabled enables access logging. - Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` - // disable_listener_logs turns off just listener logs for connections rejected by Envoy because they don't - // have a matching listener filter. - DisableListenerLogs bool `protobuf:"varint,2,opt,name=disable_listener_logs,json=disableListenerLogs,proto3" json:"disable_listener_logs,omitempty"` - // type selects the output for logs: "file", "stderr". "stdout" - Type LogSinkType `protobuf:"varint,3,opt,name=type,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.LogSinkType" json:"type,omitempty"` - // path is the output file to write logs - Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"` - // The presence of one format string or the other implies the access log string encoding. - // Defining both is invalid. - // - // Types that are assignable to Format: - // - // *AccessLogs_Json - // *AccessLogs_Text - Format isAccessLogs_Format `protobuf_oneof:"format"` -} - -func (x *AccessLogs) Reset() { - *x = AccessLogs{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_access_logs_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AccessLogs) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AccessLogs) ProtoMessage() {} - -func (x *AccessLogs) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_access_logs_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AccessLogs.ProtoReflect.Descriptor instead. -func (*AccessLogs) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescGZIP(), []int{0} -} - -func (x *AccessLogs) GetEnabled() bool { - if x != nil { - return x.Enabled - } - return false -} - -func (x *AccessLogs) GetDisableListenerLogs() bool { - if x != nil { - return x.DisableListenerLogs - } - return false -} - -func (x *AccessLogs) GetType() LogSinkType { - if x != nil { - return x.Type - } - return LogSinkType_LOG_SINK_TYPE_DEFAULT -} - -func (x *AccessLogs) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -func (m *AccessLogs) GetFormat() isAccessLogs_Format { - if m != nil { - return m.Format - } - return nil -} - -func (x *AccessLogs) GetJson() string { - if x, ok := x.GetFormat().(*AccessLogs_Json); ok { - return x.Json - } - return "" -} - -func (x *AccessLogs) GetText() string { - if x, ok := x.GetFormat().(*AccessLogs_Text); ok { - return x.Text - } - return "" -} - -type isAccessLogs_Format interface { - isAccessLogs_Format() -} - -type AccessLogs_Json struct { - Json string `protobuf:"bytes,5,opt,name=json,proto3,oneof"` -} - -type AccessLogs_Text struct { - Text string `protobuf:"bytes,6,opt,name=text,proto3,oneof"` -} - -func (*AccessLogs_Json) isAccessLogs_Format() {} - -func (*AccessLogs_Text) isAccessLogs_Format() {} - -var File_pbmesh_v2beta1_pbproxystate_access_logs_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDesc = []byte{ - 0x0a, 0x2d, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x2a, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xf1, 0x01, 0x0a, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x4b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x53, 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x04, 0x6a, 0x73, 0x6f, - 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x12, - 0x14, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, - 0x04, 0x74, 0x65, 0x78, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2a, - 0x74, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x53, 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, - 0x0a, 0x15, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x47, - 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, - 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4c, - 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x44, - 0x4f, 0x55, 0x54, 0x10, 0x03, 0x42, 0xd5, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x6f, 0x67, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, - 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, - 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_access_logs_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_pbproxystate_access_logs_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmesh_v2beta1_pbproxystate_access_logs_proto_goTypes = []interface{}{ - (LogSinkType)(0), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.LogSinkType - (*AccessLogs)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.AccessLogs -} -var file_pbmesh_v2beta1_pbproxystate_access_logs_proto_depIdxs = []int32{ - 0, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.AccessLogs.type:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LogSinkType - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_access_logs_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_access_logs_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_access_logs_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessLogs); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*AccessLogs_Json)(nil), - (*AccessLogs_Text)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDesc, - NumEnums: 1, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_access_logs_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_access_logs_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_pbproxystate_access_logs_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_access_logs_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_access_logs_proto = out.File - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_access_logs_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.proto b/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.proto deleted file mode 100644 index 92249a80b2ffd..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs.proto +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -message AccessLogs { - // enabled enables access logging. - bool enabled = 1; - // disable_listener_logs turns off just listener logs for connections rejected by Envoy because they don't - // have a matching listener filter. - bool disable_listener_logs = 2; - // type selects the output for logs: "file", "stderr". "stdout" - LogSinkType type = 3; - // path is the output file to write logs - string path = 4; - // The presence of one format string or the other implies the access log string encoding. - // Defining both is invalid. - oneof format { - string json = 5; - string text = 6; - } -} - -// +kubebuilder:validation:Enum=LOG_SINK_TYPE_DEFAULT;LOG_SINK_TYPE_FILE;LOG_SINK_TYPE_STDERR;LOG_SINK_TYPE_STDOUT -// +kubebuilder:validation:Type=string -enum LogSinkType { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - LOG_SINK_TYPE_DEFAULT = 0; - LOG_SINK_TYPE_FILE = 1; - LOG_SINK_TYPE_STDERR = 2; - LOG_SINK_TYPE_STDOUT = 3; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_deepcopy.gen.go deleted file mode 100644 index f4c5c96039d5d..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using AccessLogs within kubernetes types, where deepcopy-gen is used. -func (in *AccessLogs) DeepCopyInto(out *AccessLogs) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessLogs. Required by controller-gen. -func (in *AccessLogs) DeepCopy() *AccessLogs { - if in == nil { - return nil - } - out := new(AccessLogs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new AccessLogs. Required by controller-gen. -func (in *AccessLogs) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_json.gen.go deleted file mode 100644 index 09e5ffb28473d..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for AccessLogs -func (this *AccessLogs) MarshalJSON() ([]byte, error) { - str, err := AccessLogsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for AccessLogs -func (this *AccessLogs) UnmarshalJSON(b []byte) error { - return AccessLogsUnmarshaler.Unmarshal(b, this) -} - -var ( - AccessLogsMarshaler = &protojson.MarshalOptions{} - AccessLogsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/address.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/address.pb.binary.go deleted file mode 100644 index 4b509e9ed98c3..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/address.pb.binary.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/address.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HostPortAddress) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HostPortAddress) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *UnixSocketAddress) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *UnixSocketAddress) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/address.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/address.pb.go deleted file mode 100644 index 6c814f3c8f2d8..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/address.pb.go +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/address.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type HostPortAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"` - Port uint32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` -} - -func (x *HostPortAddress) Reset() { - *x = HostPortAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_address_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HostPortAddress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HostPortAddress) ProtoMessage() {} - -func (x *HostPortAddress) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_address_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HostPortAddress.ProtoReflect.Descriptor instead. -func (*HostPortAddress) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescGZIP(), []int{0} -} - -func (x *HostPortAddress) GetHost() string { - if x != nil { - return x.Host - } - return "" -} - -func (x *HostPortAddress) GetPort() uint32 { - if x != nil { - return x.Port - } - return 0 -} - -type UnixSocketAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // path is the file system path at which to bind a Unix domain socket listener. - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` - // mode is the Unix file mode for the socket file. It should be provided - // in the numeric notation, for example, "0600". - Mode string `protobuf:"bytes,2,opt,name=mode,proto3" json:"mode,omitempty"` -} - -func (x *UnixSocketAddress) Reset() { - *x = UnixSocketAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_address_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UnixSocketAddress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UnixSocketAddress) ProtoMessage() {} - -func (x *UnixSocketAddress) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_address_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UnixSocketAddress.ProtoReflect.Descriptor instead. -func (*UnixSocketAddress) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescGZIP(), []int{1} -} - -func (x *UnixSocketAddress) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -func (x *UnixSocketAddress) GetMode() string { - if x != nil { - return x.Mode - } - return "" -} - -var File_pbmesh_v2beta1_pbproxystate_address_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_address_proto_rawDesc = []byte{ - 0x0a, 0x29, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x39, 0x0a, 0x0f, 0x48, 0x6f, 0x73, 0x74, 0x50, - 0x6f, 0x72, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, - 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, - 0x72, 0x74, 0x22, 0x3b, 0x0a, 0x11, 0x55, 0x6e, 0x69, 0x78, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6d, - 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x42, - 0xd2, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x42, 0x0c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, - 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, - 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, - 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, - 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_address_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_address_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_address_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbmesh_v2beta1_pbproxystate_address_proto_goTypes = []interface{}{ - (*HostPortAddress)(nil), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.HostPortAddress - (*UnixSocketAddress)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.UnixSocketAddress -} -var file_pbmesh_v2beta1_pbproxystate_address_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_address_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_address_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_address_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_address_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HostPortAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_address_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnixSocketAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_address_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_address_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_address_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_address_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_address_proto = out.File - file_pbmesh_v2beta1_pbproxystate_address_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_address_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_address_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/address.proto b/proto-public/pbmesh/v2beta1/pbproxystate/address.proto deleted file mode 100644 index e13bdba9bb5a0..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/address.proto +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -message HostPortAddress { - string host = 1; - uint32 port = 2; -} - -message UnixSocketAddress { - // path is the file system path at which to bind a Unix domain socket listener. - string path = 1; - - // mode is the Unix file mode for the socket file. It should be provided - // in the numeric notation, for example, "0600". - string mode = 2; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/address_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/address_deepcopy.gen.go deleted file mode 100644 index b2700f704eff6..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/address_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using HostPortAddress within kubernetes types, where deepcopy-gen is used. -func (in *HostPortAddress) DeepCopyInto(out *HostPortAddress) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPortAddress. Required by controller-gen. -func (in *HostPortAddress) DeepCopy() *HostPortAddress { - if in == nil { - return nil - } - out := new(HostPortAddress) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HostPortAddress. Required by controller-gen. -func (in *HostPortAddress) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using UnixSocketAddress within kubernetes types, where deepcopy-gen is used. -func (in *UnixSocketAddress) DeepCopyInto(out *UnixSocketAddress) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnixSocketAddress. Required by controller-gen. -func (in *UnixSocketAddress) DeepCopy() *UnixSocketAddress { - if in == nil { - return nil - } - out := new(UnixSocketAddress) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new UnixSocketAddress. Required by controller-gen. -func (in *UnixSocketAddress) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/address_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/address_json.gen.go deleted file mode 100644 index c4de5d527048f..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/address_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for HostPortAddress -func (this *HostPortAddress) MarshalJSON() ([]byte, error) { - str, err := AddressMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HostPortAddress -func (this *HostPortAddress) UnmarshalJSON(b []byte) error { - return AddressUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for UnixSocketAddress -func (this *UnixSocketAddress) MarshalJSON() ([]byte, error) { - str, err := AddressMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for UnixSocketAddress -func (this *UnixSocketAddress) UnmarshalJSON(b []byte) error { - return AddressUnmarshaler.Unmarshal(b, this) -} - -var ( - AddressMarshaler = &protojson.MarshalOptions{} - AddressUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.binary.go deleted file mode 100644 index eab6e1626c724..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.binary.go +++ /dev/null @@ -1,268 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/cluster.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Cluster) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Cluster) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *FailoverGroup) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *FailoverGroup) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *FailoverGroupConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *FailoverGroupConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *EndpointGroup) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *EndpointGroup) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DynamicEndpointGroup) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DynamicEndpointGroup) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *PassthroughEndpointGroup) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PassthroughEndpointGroup) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DNSEndpointGroup) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DNSEndpointGroup) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *StaticEndpointGroup) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *StaticEndpointGroup) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationCluster) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationCluster) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *L4WeightedClusterGroup) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *L4WeightedClusterGroup) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *L7WeightedClusterGroup) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *L7WeightedClusterGroup) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *L4WeightedDestinationCluster) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *L4WeightedDestinationCluster) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *L7WeightedDestinationCluster) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *L7WeightedDestinationCluster) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DynamicEndpointGroupConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DynamicEndpointGroupConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LBPolicyLeastRequest) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LBPolicyLeastRequest) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LBPolicyRoundRobin) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LBPolicyRoundRobin) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LBPolicyRandom) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LBPolicyRandom) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LBPolicyRingHash) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LBPolicyRingHash) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LBPolicyMaglev) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LBPolicyMaglev) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *CircuitBreakers) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *CircuitBreakers) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *UpstreamLimits) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *UpstreamLimits) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *OutlierDetection) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *OutlierDetection) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *UpstreamConnectionOptions) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *UpstreamConnectionOptions) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *PassthroughEndpointGroupConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PassthroughEndpointGroupConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DNSEndpointGroupConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DNSEndpointGroupConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *StaticEndpointGroupConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *StaticEndpointGroupConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.go deleted file mode 100644 index ba7386f527e00..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.go +++ /dev/null @@ -1,2643 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/cluster.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=DISCOVERY_TYPE_LOGICAL;DISCOVERY_TYPE_STRICT -// +kubebuilder:validation:Type=string -type DiscoveryType int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - DiscoveryType_DISCOVERY_TYPE_LOGICAL DiscoveryType = 0 - DiscoveryType_DISCOVERY_TYPE_STRICT DiscoveryType = 1 -) - -// Enum value maps for DiscoveryType. -var ( - DiscoveryType_name = map[int32]string{ - 0: "DISCOVERY_TYPE_LOGICAL", - 1: "DISCOVERY_TYPE_STRICT", - } - DiscoveryType_value = map[string]int32{ - "DISCOVERY_TYPE_LOGICAL": 0, - "DISCOVERY_TYPE_STRICT": 1, - } -) - -func (x DiscoveryType) Enum() *DiscoveryType { - p := new(DiscoveryType) - *p = x - return p -} - -func (x DiscoveryType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (DiscoveryType) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_enumTypes[0].Descriptor() -} - -func (DiscoveryType) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_cluster_proto_enumTypes[0] -} - -func (x DiscoveryType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use DiscoveryType.Descriptor instead. -func (DiscoveryType) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{0} -} - -type Cluster struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name is the name of the cluster. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // group is either a failover group or endpoint group. If this cluster needs to failover to other clusters, use the failover group. If this cluster routes directly to endpoints, use the endpoint group. - // - // Types that are assignable to Group: - // - // *Cluster_FailoverGroup - // *Cluster_EndpointGroup - Group isCluster_Group `protobuf_oneof:"group"` - // escape_hatch_cluster_json configures a user configured escape hatch cluster. - EscapeHatchClusterJson string `protobuf:"bytes,4,opt,name=escape_hatch_cluster_json,json=escapeHatchClusterJson,proto3" json:"escape_hatch_cluster_json,omitempty"` - // alt_stat_name is the name used for observability in place of cluster name if provided. - AltStatName string `protobuf:"bytes,5,opt,name=alt_stat_name,json=altStatName,proto3" json:"alt_stat_name,omitempty"` - // protocol is the local path protocol or the service protocol. - Protocol Protocol `protobuf:"varint,6,opt,name=protocol,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.Protocol" json:"protocol,omitempty"` -} - -func (x *Cluster) Reset() { - *x = Cluster{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Cluster) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Cluster) ProtoMessage() {} - -func (x *Cluster) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Cluster.ProtoReflect.Descriptor instead. -func (*Cluster) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{0} -} - -func (x *Cluster) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (m *Cluster) GetGroup() isCluster_Group { - if m != nil { - return m.Group - } - return nil -} - -func (x *Cluster) GetFailoverGroup() *FailoverGroup { - if x, ok := x.GetGroup().(*Cluster_FailoverGroup); ok { - return x.FailoverGroup - } - return nil -} - -func (x *Cluster) GetEndpointGroup() *EndpointGroup { - if x, ok := x.GetGroup().(*Cluster_EndpointGroup); ok { - return x.EndpointGroup - } - return nil -} - -func (x *Cluster) GetEscapeHatchClusterJson() string { - if x != nil { - return x.EscapeHatchClusterJson - } - return "" -} - -func (x *Cluster) GetAltStatName() string { - if x != nil { - return x.AltStatName - } - return "" -} - -func (x *Cluster) GetProtocol() Protocol { - if x != nil { - return x.Protocol - } - return Protocol_PROTOCOL_UNSPECIFIED -} - -type isCluster_Group interface { - isCluster_Group() -} - -type Cluster_FailoverGroup struct { - FailoverGroup *FailoverGroup `protobuf:"bytes,2,opt,name=failover_group,json=failoverGroup,proto3,oneof"` -} - -type Cluster_EndpointGroup struct { - EndpointGroup *EndpointGroup `protobuf:"bytes,3,opt,name=endpoint_group,json=endpointGroup,proto3,oneof"` -} - -func (*Cluster_FailoverGroup) isCluster_Group() {} - -func (*Cluster_EndpointGroup) isCluster_Group() {} - -type FailoverGroup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // endpoint_groups is an ordered list of which groups to failover to. - EndpointGroups []*EndpointGroup `protobuf:"bytes,1,rep,name=endpoint_groups,json=endpointGroups,proto3" json:"endpoint_groups,omitempty"` - Config *FailoverGroupConfig `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` -} - -func (x *FailoverGroup) Reset() { - *x = FailoverGroup{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FailoverGroup) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FailoverGroup) ProtoMessage() {} - -func (x *FailoverGroup) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FailoverGroup.ProtoReflect.Descriptor instead. -func (*FailoverGroup) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{1} -} - -func (x *FailoverGroup) GetEndpointGroups() []*EndpointGroup { - if x != nil { - return x.EndpointGroups - } - return nil -} - -func (x *FailoverGroup) GetConfig() *FailoverGroupConfig { - if x != nil { - return x.Config - } - return nil -} - -type FailoverGroupConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UseAltStatName bool `protobuf:"varint,1,opt,name=use_alt_stat_name,json=useAltStatName,proto3" json:"use_alt_stat_name,omitempty"` - // +kubebuilder:validation:Type=string - ConnectTimeout *durationpb.Duration `protobuf:"bytes,2,opt,name=connect_timeout,json=connectTimeout,proto3" json:"connect_timeout,omitempty"` -} - -func (x *FailoverGroupConfig) Reset() { - *x = FailoverGroupConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FailoverGroupConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FailoverGroupConfig) ProtoMessage() {} - -func (x *FailoverGroupConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FailoverGroupConfig.ProtoReflect.Descriptor instead. -func (*FailoverGroupConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{2} -} - -func (x *FailoverGroupConfig) GetUseAltStatName() bool { - if x != nil { - return x.UseAltStatName - } - return false -} - -func (x *FailoverGroupConfig) GetConnectTimeout() *durationpb.Duration { - if x != nil { - return x.ConnectTimeout - } - return nil -} - -type EndpointGroup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name is used to name the cluster created. This is only required when used inside of a FailoverGroup. - Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` - // Types that are assignable to Group: - // - // *EndpointGroup_Dynamic - // *EndpointGroup_Static - // *EndpointGroup_Dns - // *EndpointGroup_Passthrough - Group isEndpointGroup_Group `protobuf_oneof:"group"` -} - -func (x *EndpointGroup) Reset() { - *x = EndpointGroup{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EndpointGroup) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EndpointGroup) ProtoMessage() {} - -func (x *EndpointGroup) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EndpointGroup.ProtoReflect.Descriptor instead. -func (*EndpointGroup) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{3} -} - -func (x *EndpointGroup) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (m *EndpointGroup) GetGroup() isEndpointGroup_Group { - if m != nil { - return m.Group - } - return nil -} - -func (x *EndpointGroup) GetDynamic() *DynamicEndpointGroup { - if x, ok := x.GetGroup().(*EndpointGroup_Dynamic); ok { - return x.Dynamic - } - return nil -} - -func (x *EndpointGroup) GetStatic() *StaticEndpointGroup { - if x, ok := x.GetGroup().(*EndpointGroup_Static); ok { - return x.Static - } - return nil -} - -func (x *EndpointGroup) GetDns() *DNSEndpointGroup { - if x, ok := x.GetGroup().(*EndpointGroup_Dns); ok { - return x.Dns - } - return nil -} - -func (x *EndpointGroup) GetPassthrough() *PassthroughEndpointGroup { - if x, ok := x.GetGroup().(*EndpointGroup_Passthrough); ok { - return x.Passthrough - } - return nil -} - -type isEndpointGroup_Group interface { - isEndpointGroup_Group() -} - -type EndpointGroup_Dynamic struct { - // dynamic endpoint group is used to reach mesh destinations that are dynamically configured from Consul's catalog. - Dynamic *DynamicEndpointGroup `protobuf:"bytes,1,opt,name=dynamic,proto3,oneof"` -} - -type EndpointGroup_Static struct { - // static endpoint group is used to reach local app ports. - Static *StaticEndpointGroup `protobuf:"bytes,2,opt,name=static,proto3,oneof"` -} - -type EndpointGroup_Dns struct { - // dns is used to reach mesh and non-mesh destinations using a hostname. - Dns *DNSEndpointGroup `protobuf:"bytes,3,opt,name=dns,proto3,oneof"` -} - -type EndpointGroup_Passthrough struct { - // passthrough is used to reach destinations that don't have endpoints saved in Consul. - Passthrough *PassthroughEndpointGroup `protobuf:"bytes,4,opt,name=passthrough,proto3,oneof"` -} - -func (*EndpointGroup_Dynamic) isEndpointGroup_Group() {} - -func (*EndpointGroup_Static) isEndpointGroup_Group() {} - -func (*EndpointGroup_Dns) isEndpointGroup_Group() {} - -func (*EndpointGroup_Passthrough) isEndpointGroup_Group() {} - -type DynamicEndpointGroup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // config configures how to connect to the endpoints. - Config *DynamicEndpointGroupConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` - // outbound_tls will configure what TLS information to use when connecting to an upstream. - OutboundTls *TransportSocket `protobuf:"bytes,2,opt,name=outbound_tls,json=outboundTls,proto3" json:"outbound_tls,omitempty"` -} - -func (x *DynamicEndpointGroup) Reset() { - *x = DynamicEndpointGroup{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DynamicEndpointGroup) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DynamicEndpointGroup) ProtoMessage() {} - -func (x *DynamicEndpointGroup) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DynamicEndpointGroup.ProtoReflect.Descriptor instead. -func (*DynamicEndpointGroup) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{4} -} - -func (x *DynamicEndpointGroup) GetConfig() *DynamicEndpointGroupConfig { - if x != nil { - return x.Config - } - return nil -} - -func (x *DynamicEndpointGroup) GetOutboundTls() *TransportSocket { - if x != nil { - return x.OutboundTls - } - return nil -} - -type PassthroughEndpointGroup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // config configures how to connect to the endpoints. - Config *PassthroughEndpointGroupConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` - // outbound_tls will configure what TLS information to use when connecting to an upstream. - OutboundTls *TransportSocket `protobuf:"bytes,2,opt,name=outbound_tls,json=outboundTls,proto3" json:"outbound_tls,omitempty"` -} - -func (x *PassthroughEndpointGroup) Reset() { - *x = PassthroughEndpointGroup{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PassthroughEndpointGroup) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PassthroughEndpointGroup) ProtoMessage() {} - -func (x *PassthroughEndpointGroup) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PassthroughEndpointGroup.ProtoReflect.Descriptor instead. -func (*PassthroughEndpointGroup) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{5} -} - -func (x *PassthroughEndpointGroup) GetConfig() *PassthroughEndpointGroupConfig { - if x != nil { - return x.Config - } - return nil -} - -func (x *PassthroughEndpointGroup) GetOutboundTls() *TransportSocket { - if x != nil { - return x.OutboundTls - } - return nil -} - -type DNSEndpointGroup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // config configures how to connect to the endpoints. - Config *DNSEndpointGroupConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` - // outbound_tls will configure what TLS information to use when connecting to an upstream. - OutboundTls *TransportSocket `protobuf:"bytes,2,opt,name=outbound_tls,json=outboundTls,proto3" json:"outbound_tls,omitempty"` -} - -func (x *DNSEndpointGroup) Reset() { - *x = DNSEndpointGroup{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DNSEndpointGroup) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DNSEndpointGroup) ProtoMessage() {} - -func (x *DNSEndpointGroup) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DNSEndpointGroup.ProtoReflect.Descriptor instead. -func (*DNSEndpointGroup) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{6} -} - -func (x *DNSEndpointGroup) GetConfig() *DNSEndpointGroupConfig { - if x != nil { - return x.Config - } - return nil -} - -func (x *DNSEndpointGroup) GetOutboundTls() *TransportSocket { - if x != nil { - return x.OutboundTls - } - return nil -} - -// StaticEndpointGroup is used to reach local app ports. -type StaticEndpointGroup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // config configures how to connect to the endpoints. - Config *StaticEndpointGroupConfig `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"` -} - -func (x *StaticEndpointGroup) Reset() { - *x = StaticEndpointGroup{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StaticEndpointGroup) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StaticEndpointGroup) ProtoMessage() {} - -func (x *StaticEndpointGroup) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StaticEndpointGroup.ProtoReflect.Descriptor instead. -func (*StaticEndpointGroup) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{7} -} - -func (x *StaticEndpointGroup) GetConfig() *StaticEndpointGroupConfig { - if x != nil { - return x.Config - } - return nil -} - -type DestinationCluster struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name is the name of the cluster. This will be used to look up a cluster in the clusters map. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *DestinationCluster) Reset() { - *x = DestinationCluster{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationCluster) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationCluster) ProtoMessage() {} - -func (x *DestinationCluster) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationCluster.ProtoReflect.Descriptor instead. -func (*DestinationCluster) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{8} -} - -func (x *DestinationCluster) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type L4WeightedClusterGroup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // clusters to route to by weight. - Clusters []*L4WeightedDestinationCluster `protobuf:"bytes,1,rep,name=clusters,proto3" json:"clusters,omitempty"` -} - -func (x *L4WeightedClusterGroup) Reset() { - *x = L4WeightedClusterGroup{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L4WeightedClusterGroup) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L4WeightedClusterGroup) ProtoMessage() {} - -func (x *L4WeightedClusterGroup) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L4WeightedClusterGroup.ProtoReflect.Descriptor instead. -func (*L4WeightedClusterGroup) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{9} -} - -func (x *L4WeightedClusterGroup) GetClusters() []*L4WeightedDestinationCluster { - if x != nil { - return x.Clusters - } - return nil -} - -type L7WeightedClusterGroup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // clusters to route to by weight. - Clusters []*L7WeightedDestinationCluster `protobuf:"bytes,1,rep,name=clusters,proto3" json:"clusters,omitempty"` -} - -func (x *L7WeightedClusterGroup) Reset() { - *x = L7WeightedClusterGroup{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L7WeightedClusterGroup) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L7WeightedClusterGroup) ProtoMessage() {} - -func (x *L7WeightedClusterGroup) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L7WeightedClusterGroup.ProtoReflect.Descriptor instead. -func (*L7WeightedClusterGroup) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{10} -} - -func (x *L7WeightedClusterGroup) GetClusters() []*L7WeightedDestinationCluster { - if x != nil { - return x.Clusters - } - return nil -} - -type L4WeightedDestinationCluster struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name is the name of the cluster. This will be used to look up a cluster in the clusters map. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Weight *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=weight,proto3" json:"weight,omitempty"` -} - -func (x *L4WeightedDestinationCluster) Reset() { - *x = L4WeightedDestinationCluster{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L4WeightedDestinationCluster) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L4WeightedDestinationCluster) ProtoMessage() {} - -func (x *L4WeightedDestinationCluster) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L4WeightedDestinationCluster.ProtoReflect.Descriptor instead. -func (*L4WeightedDestinationCluster) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{11} -} - -func (x *L4WeightedDestinationCluster) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *L4WeightedDestinationCluster) GetWeight() *wrapperspb.UInt32Value { - if x != nil { - return x.Weight - } - return nil -} - -type L7WeightedDestinationCluster struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name is the name of the cluster. This will be used to look up a cluster in the clusters map. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Weight *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=weight,proto3" json:"weight,omitempty"` - HeaderMutations []*HeaderMutation `protobuf:"bytes,3,rep,name=header_mutations,json=headerMutations,proto3" json:"header_mutations,omitempty"` -} - -func (x *L7WeightedDestinationCluster) Reset() { - *x = L7WeightedDestinationCluster{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L7WeightedDestinationCluster) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L7WeightedDestinationCluster) ProtoMessage() {} - -func (x *L7WeightedDestinationCluster) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L7WeightedDestinationCluster.ProtoReflect.Descriptor instead. -func (*L7WeightedDestinationCluster) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{12} -} - -func (x *L7WeightedDestinationCluster) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *L7WeightedDestinationCluster) GetWeight() *wrapperspb.UInt32Value { - if x != nil { - return x.Weight - } - return nil -} - -func (x *L7WeightedDestinationCluster) GetHeaderMutations() []*HeaderMutation { - if x != nil { - return x.HeaderMutations - } - return nil -} - -type DynamicEndpointGroupConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // +kubebuilder:validation:Format=duration - ConnectTimeout *durationpb.Duration `protobuf:"bytes,1,opt,name=connect_timeout,json=connectTimeout,proto3" json:"connect_timeout,omitempty"` - DisablePanicThreshold bool `protobuf:"varint,2,opt,name=disable_panic_threshold,json=disablePanicThreshold,proto3" json:"disable_panic_threshold,omitempty"` - // Types that are assignable to LbPolicy: - // - // *DynamicEndpointGroupConfig_LeastRequest - // *DynamicEndpointGroupConfig_RoundRobin - // *DynamicEndpointGroupConfig_Random - // *DynamicEndpointGroupConfig_RingHash - // *DynamicEndpointGroupConfig_Maglev - LbPolicy isDynamicEndpointGroupConfig_LbPolicy `protobuf_oneof:"lb_policy"` - CircuitBreakers *CircuitBreakers `protobuf:"bytes,8,opt,name=circuit_breakers,json=circuitBreakers,proto3" json:"circuit_breakers,omitempty"` - OutlierDetection *OutlierDetection `protobuf:"bytes,9,opt,name=outlier_detection,json=outlierDetection,proto3" json:"outlier_detection,omitempty"` - UpstreamConnectionOptions *UpstreamConnectionOptions `protobuf:"bytes,10,opt,name=upstream_connection_options,json=upstreamConnectionOptions,proto3" json:"upstream_connection_options,omitempty"` - UseAltStatName bool `protobuf:"varint,11,opt,name=use_alt_stat_name,json=useAltStatName,proto3" json:"use_alt_stat_name,omitempty"` -} - -func (x *DynamicEndpointGroupConfig) Reset() { - *x = DynamicEndpointGroupConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DynamicEndpointGroupConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DynamicEndpointGroupConfig) ProtoMessage() {} - -func (x *DynamicEndpointGroupConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DynamicEndpointGroupConfig.ProtoReflect.Descriptor instead. -func (*DynamicEndpointGroupConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{13} -} - -func (x *DynamicEndpointGroupConfig) GetConnectTimeout() *durationpb.Duration { - if x != nil { - return x.ConnectTimeout - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetDisablePanicThreshold() bool { - if x != nil { - return x.DisablePanicThreshold - } - return false -} - -func (m *DynamicEndpointGroupConfig) GetLbPolicy() isDynamicEndpointGroupConfig_LbPolicy { - if m != nil { - return m.LbPolicy - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetLeastRequest() *LBPolicyLeastRequest { - if x, ok := x.GetLbPolicy().(*DynamicEndpointGroupConfig_LeastRequest); ok { - return x.LeastRequest - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetRoundRobin() *LBPolicyRoundRobin { - if x, ok := x.GetLbPolicy().(*DynamicEndpointGroupConfig_RoundRobin); ok { - return x.RoundRobin - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetRandom() *LBPolicyRandom { - if x, ok := x.GetLbPolicy().(*DynamicEndpointGroupConfig_Random); ok { - return x.Random - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetRingHash() *LBPolicyRingHash { - if x, ok := x.GetLbPolicy().(*DynamicEndpointGroupConfig_RingHash); ok { - return x.RingHash - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetMaglev() *LBPolicyMaglev { - if x, ok := x.GetLbPolicy().(*DynamicEndpointGroupConfig_Maglev); ok { - return x.Maglev - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetCircuitBreakers() *CircuitBreakers { - if x != nil { - return x.CircuitBreakers - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetOutlierDetection() *OutlierDetection { - if x != nil { - return x.OutlierDetection - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetUpstreamConnectionOptions() *UpstreamConnectionOptions { - if x != nil { - return x.UpstreamConnectionOptions - } - return nil -} - -func (x *DynamicEndpointGroupConfig) GetUseAltStatName() bool { - if x != nil { - return x.UseAltStatName - } - return false -} - -type isDynamicEndpointGroupConfig_LbPolicy interface { - isDynamicEndpointGroupConfig_LbPolicy() -} - -type DynamicEndpointGroupConfig_LeastRequest struct { - LeastRequest *LBPolicyLeastRequest `protobuf:"bytes,3,opt,name=least_request,json=leastRequest,proto3,oneof"` -} - -type DynamicEndpointGroupConfig_RoundRobin struct { - RoundRobin *LBPolicyRoundRobin `protobuf:"bytes,4,opt,name=round_robin,json=roundRobin,proto3,oneof"` -} - -type DynamicEndpointGroupConfig_Random struct { - Random *LBPolicyRandom `protobuf:"bytes,5,opt,name=random,proto3,oneof"` -} - -type DynamicEndpointGroupConfig_RingHash struct { - RingHash *LBPolicyRingHash `protobuf:"bytes,6,opt,name=ring_hash,json=ringHash,proto3,oneof"` -} - -type DynamicEndpointGroupConfig_Maglev struct { - Maglev *LBPolicyMaglev `protobuf:"bytes,7,opt,name=maglev,proto3,oneof"` -} - -func (*DynamicEndpointGroupConfig_LeastRequest) isDynamicEndpointGroupConfig_LbPolicy() {} - -func (*DynamicEndpointGroupConfig_RoundRobin) isDynamicEndpointGroupConfig_LbPolicy() {} - -func (*DynamicEndpointGroupConfig_Random) isDynamicEndpointGroupConfig_LbPolicy() {} - -func (*DynamicEndpointGroupConfig_RingHash) isDynamicEndpointGroupConfig_LbPolicy() {} - -func (*DynamicEndpointGroupConfig_Maglev) isDynamicEndpointGroupConfig_LbPolicy() {} - -type LBPolicyLeastRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ChoiceCount *wrapperspb.UInt32Value `protobuf:"bytes,1,opt,name=choice_count,json=choiceCount,proto3" json:"choice_count,omitempty"` -} - -func (x *LBPolicyLeastRequest) Reset() { - *x = LBPolicyLeastRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LBPolicyLeastRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LBPolicyLeastRequest) ProtoMessage() {} - -func (x *LBPolicyLeastRequest) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LBPolicyLeastRequest.ProtoReflect.Descriptor instead. -func (*LBPolicyLeastRequest) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{14} -} - -func (x *LBPolicyLeastRequest) GetChoiceCount() *wrapperspb.UInt32Value { - if x != nil { - return x.ChoiceCount - } - return nil -} - -type LBPolicyRoundRobin struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *LBPolicyRoundRobin) Reset() { - *x = LBPolicyRoundRobin{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LBPolicyRoundRobin) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LBPolicyRoundRobin) ProtoMessage() {} - -func (x *LBPolicyRoundRobin) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LBPolicyRoundRobin.ProtoReflect.Descriptor instead. -func (*LBPolicyRoundRobin) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{15} -} - -type LBPolicyRandom struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *LBPolicyRandom) Reset() { - *x = LBPolicyRandom{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LBPolicyRandom) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LBPolicyRandom) ProtoMessage() {} - -func (x *LBPolicyRandom) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LBPolicyRandom.ProtoReflect.Descriptor instead. -func (*LBPolicyRandom) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{16} -} - -type LBPolicyRingHash struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MinimumRingSize *wrapperspb.UInt64Value `protobuf:"bytes,1,opt,name=minimum_ring_size,json=minimumRingSize,proto3" json:"minimum_ring_size,omitempty"` - MaximumRingSize *wrapperspb.UInt64Value `protobuf:"bytes,2,opt,name=maximum_ring_size,json=maximumRingSize,proto3" json:"maximum_ring_size,omitempty"` -} - -func (x *LBPolicyRingHash) Reset() { - *x = LBPolicyRingHash{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LBPolicyRingHash) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LBPolicyRingHash) ProtoMessage() {} - -func (x *LBPolicyRingHash) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LBPolicyRingHash.ProtoReflect.Descriptor instead. -func (*LBPolicyRingHash) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{17} -} - -func (x *LBPolicyRingHash) GetMinimumRingSize() *wrapperspb.UInt64Value { - if x != nil { - return x.MinimumRingSize - } - return nil -} - -func (x *LBPolicyRingHash) GetMaximumRingSize() *wrapperspb.UInt64Value { - if x != nil { - return x.MaximumRingSize - } - return nil -} - -type LBPolicyMaglev struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *LBPolicyMaglev) Reset() { - *x = LBPolicyMaglev{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LBPolicyMaglev) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LBPolicyMaglev) ProtoMessage() {} - -func (x *LBPolicyMaglev) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LBPolicyMaglev.ProtoReflect.Descriptor instead. -func (*LBPolicyMaglev) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{18} -} - -type CircuitBreakers struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UpstreamLimits *UpstreamLimits `protobuf:"bytes,1,opt,name=upstream_limits,json=upstreamLimits,proto3" json:"upstream_limits,omitempty"` -} - -func (x *CircuitBreakers) Reset() { - *x = CircuitBreakers{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CircuitBreakers) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CircuitBreakers) ProtoMessage() {} - -func (x *CircuitBreakers) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CircuitBreakers.ProtoReflect.Descriptor instead. -func (*CircuitBreakers) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{19} -} - -func (x *CircuitBreakers) GetUpstreamLimits() *UpstreamLimits { - if x != nil { - return x.UpstreamLimits - } - return nil -} - -type UpstreamLimits struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MaxConnections *wrapperspb.UInt32Value `protobuf:"bytes,1,opt,name=max_connections,json=maxConnections,proto3" json:"max_connections,omitempty"` - MaxPendingRequests *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=max_pending_requests,json=maxPendingRequests,proto3" json:"max_pending_requests,omitempty"` - MaxConcurrentRequests *wrapperspb.UInt32Value `protobuf:"bytes,3,opt,name=max_concurrent_requests,json=maxConcurrentRequests,proto3" json:"max_concurrent_requests,omitempty"` -} - -func (x *UpstreamLimits) Reset() { - *x = UpstreamLimits{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpstreamLimits) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpstreamLimits) ProtoMessage() {} - -func (x *UpstreamLimits) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpstreamLimits.ProtoReflect.Descriptor instead. -func (*UpstreamLimits) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{20} -} - -func (x *UpstreamLimits) GetMaxConnections() *wrapperspb.UInt32Value { - if x != nil { - return x.MaxConnections - } - return nil -} - -func (x *UpstreamLimits) GetMaxPendingRequests() *wrapperspb.UInt32Value { - if x != nil { - return x.MaxPendingRequests - } - return nil -} - -func (x *UpstreamLimits) GetMaxConcurrentRequests() *wrapperspb.UInt32Value { - if x != nil { - return x.MaxConcurrentRequests - } - return nil -} - -type OutlierDetection struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // +kubebuilder:validation:Format=duration - Interval *durationpb.Duration `protobuf:"bytes,1,opt,name=interval,proto3" json:"interval,omitempty"` - Consecutive_5Xx *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=consecutive_5xx,json=consecutive5xx,proto3" json:"consecutive_5xx,omitempty"` - EnforcingConsecutive_5Xx *wrapperspb.UInt32Value `protobuf:"bytes,3,opt,name=enforcing_consecutive_5xx,json=enforcingConsecutive5xx,proto3" json:"enforcing_consecutive_5xx,omitempty"` - MaxEjectionPercent *wrapperspb.UInt32Value `protobuf:"bytes,4,opt,name=max_ejection_percent,json=maxEjectionPercent,proto3" json:"max_ejection_percent,omitempty"` - // +kubebuilder:validation:Format=duration - BaseEjectionTime *durationpb.Duration `protobuf:"bytes,5,opt,name=base_ejection_time,json=baseEjectionTime,proto3" json:"base_ejection_time,omitempty"` -} - -func (x *OutlierDetection) Reset() { - *x = OutlierDetection{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OutlierDetection) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OutlierDetection) ProtoMessage() {} - -func (x *OutlierDetection) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OutlierDetection.ProtoReflect.Descriptor instead. -func (*OutlierDetection) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{21} -} - -func (x *OutlierDetection) GetInterval() *durationpb.Duration { - if x != nil { - return x.Interval - } - return nil -} - -func (x *OutlierDetection) GetConsecutive_5Xx() *wrapperspb.UInt32Value { - if x != nil { - return x.Consecutive_5Xx - } - return nil -} - -func (x *OutlierDetection) GetEnforcingConsecutive_5Xx() *wrapperspb.UInt32Value { - if x != nil { - return x.EnforcingConsecutive_5Xx - } - return nil -} - -func (x *OutlierDetection) GetMaxEjectionPercent() *wrapperspb.UInt32Value { - if x != nil { - return x.MaxEjectionPercent - } - return nil -} - -func (x *OutlierDetection) GetBaseEjectionTime() *durationpb.Duration { - if x != nil { - return x.BaseEjectionTime - } - return nil -} - -type UpstreamConnectionOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TcpKeepaliveTime *wrapperspb.UInt32Value `protobuf:"bytes,1,opt,name=tcp_keepalive_time,json=tcpKeepaliveTime,proto3" json:"tcp_keepalive_time,omitempty"` - TcpKeepaliveInterval *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=tcp_keepalive_interval,json=tcpKeepaliveInterval,proto3" json:"tcp_keepalive_interval,omitempty"` - TcpKeepaliveProbes *wrapperspb.UInt32Value `protobuf:"bytes,3,opt,name=tcp_keepalive_probes,json=tcpKeepaliveProbes,proto3" json:"tcp_keepalive_probes,omitempty"` -} - -func (x *UpstreamConnectionOptions) Reset() { - *x = UpstreamConnectionOptions{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpstreamConnectionOptions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpstreamConnectionOptions) ProtoMessage() {} - -func (x *UpstreamConnectionOptions) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpstreamConnectionOptions.ProtoReflect.Descriptor instead. -func (*UpstreamConnectionOptions) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{22} -} - -func (x *UpstreamConnectionOptions) GetTcpKeepaliveTime() *wrapperspb.UInt32Value { - if x != nil { - return x.TcpKeepaliveTime - } - return nil -} - -func (x *UpstreamConnectionOptions) GetTcpKeepaliveInterval() *wrapperspb.UInt32Value { - if x != nil { - return x.TcpKeepaliveInterval - } - return nil -} - -func (x *UpstreamConnectionOptions) GetTcpKeepaliveProbes() *wrapperspb.UInt32Value { - if x != nil { - return x.TcpKeepaliveProbes - } - return nil -} - -type PassthroughEndpointGroupConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // +kubebuilder:validation:Format=duration - ConnectTimeout *durationpb.Duration `protobuf:"bytes,1,opt,name=connect_timeout,json=connectTimeout,proto3" json:"connect_timeout,omitempty"` -} - -func (x *PassthroughEndpointGroupConfig) Reset() { - *x = PassthroughEndpointGroupConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PassthroughEndpointGroupConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PassthroughEndpointGroupConfig) ProtoMessage() {} - -func (x *PassthroughEndpointGroupConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PassthroughEndpointGroupConfig.ProtoReflect.Descriptor instead. -func (*PassthroughEndpointGroupConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{23} -} - -func (x *PassthroughEndpointGroupConfig) GetConnectTimeout() *durationpb.Duration { - if x != nil { - return x.ConnectTimeout - } - return nil -} - -type DNSEndpointGroupConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // +kubebuilder:validation:Format=duration - ConnectTimeout *durationpb.Duration `protobuf:"bytes,1,opt,name=connect_timeout,json=connectTimeout,proto3" json:"connect_timeout,omitempty"` - DisablePanicThreshold bool `protobuf:"varint,2,opt,name=disable_panic_threshold,json=disablePanicThreshold,proto3" json:"disable_panic_threshold,omitempty"` - DiscoveryType DiscoveryType `protobuf:"varint,3,opt,name=discovery_type,json=discoveryType,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.DiscoveryType" json:"discovery_type,omitempty"` - CircuitBreakers *CircuitBreakers `protobuf:"bytes,4,opt,name=circuit_breakers,json=circuitBreakers,proto3" json:"circuit_breakers,omitempty"` - OutlierDetection *OutlierDetection `protobuf:"bytes,5,opt,name=outlier_detection,json=outlierDetection,proto3" json:"outlier_detection,omitempty"` - UpstreamConnectionOptions *UpstreamConnectionOptions `protobuf:"bytes,6,opt,name=upstream_connection_options,json=upstreamConnectionOptions,proto3" json:"upstream_connection_options,omitempty"` - UseAltStatName bool `protobuf:"varint,7,opt,name=use_alt_stat_name,json=useAltStatName,proto3" json:"use_alt_stat_name,omitempty"` -} - -func (x *DNSEndpointGroupConfig) Reset() { - *x = DNSEndpointGroupConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DNSEndpointGroupConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DNSEndpointGroupConfig) ProtoMessage() {} - -func (x *DNSEndpointGroupConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DNSEndpointGroupConfig.ProtoReflect.Descriptor instead. -func (*DNSEndpointGroupConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{24} -} - -func (x *DNSEndpointGroupConfig) GetConnectTimeout() *durationpb.Duration { - if x != nil { - return x.ConnectTimeout - } - return nil -} - -func (x *DNSEndpointGroupConfig) GetDisablePanicThreshold() bool { - if x != nil { - return x.DisablePanicThreshold - } - return false -} - -func (x *DNSEndpointGroupConfig) GetDiscoveryType() DiscoveryType { - if x != nil { - return x.DiscoveryType - } - return DiscoveryType_DISCOVERY_TYPE_LOGICAL -} - -func (x *DNSEndpointGroupConfig) GetCircuitBreakers() *CircuitBreakers { - if x != nil { - return x.CircuitBreakers - } - return nil -} - -func (x *DNSEndpointGroupConfig) GetOutlierDetection() *OutlierDetection { - if x != nil { - return x.OutlierDetection - } - return nil -} - -func (x *DNSEndpointGroupConfig) GetUpstreamConnectionOptions() *UpstreamConnectionOptions { - if x != nil { - return x.UpstreamConnectionOptions - } - return nil -} - -func (x *DNSEndpointGroupConfig) GetUseAltStatName() bool { - if x != nil { - return x.UseAltStatName - } - return false -} - -type StaticEndpointGroupConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // +kubebuilder:validation:Format=duration - ConnectTimeout *durationpb.Duration `protobuf:"bytes,1,opt,name=connect_timeout,json=connectTimeout,proto3" json:"connect_timeout,omitempty"` - CircuitBreakers *CircuitBreakers `protobuf:"bytes,2,opt,name=circuit_breakers,json=circuitBreakers,proto3" json:"circuit_breakers,omitempty"` -} - -func (x *StaticEndpointGroupConfig) Reset() { - *x = StaticEndpointGroupConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StaticEndpointGroupConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StaticEndpointGroupConfig) ProtoMessage() {} - -func (x *StaticEndpointGroupConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StaticEndpointGroupConfig.ProtoReflect.Descriptor instead. -func (*StaticEndpointGroupConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP(), []int{25} -} - -func (x *StaticEndpointGroupConfig) GetConnectTimeout() *durationpb.Duration { - if x != nil { - return x.ConnectTimeout - } - return nil -} - -func (x *StaticEndpointGroupConfig) GetCircuitBreakers() *CircuitBreakers { - if x != nil { - return x.CircuitBreakers - } - return nil -} - -var File_pbmesh_v2beta1_pbproxystate_cluster_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDesc = []byte{ - 0x0a, 0x29, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x75, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x70, 0x62, 0x6d, - 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, - 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9f, 0x03, 0x0a, 0x07, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x62, 0x0a, 0x0e, 0x66, - 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, - 0x52, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, - 0x62, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x12, 0x39, 0x0a, 0x19, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x5f, 0x68, 0x61, - 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, - 0x74, 0x63, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x22, - 0x0a, 0x0d, 0x61, 0x6c, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x42, 0x07, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xcc, 0x01, - 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, - 0x62, 0x0a, 0x0f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x52, 0x0e, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x12, 0x57, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x84, 0x01, 0x0a, - 0x13, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x74, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0e, 0x75, 0x73, 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x42, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x22, 0xa1, 0x03, 0x0a, 0x0d, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x5c, 0x0a, 0x07, 0x64, 0x79, 0x6e, - 0x61, 0x6d, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x07, - 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x12, 0x59, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x12, 0x50, 0x0a, 0x03, 0x64, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x4e, 0x53, - 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, - 0x03, 0x64, 0x6e, 0x73, 0x12, 0x68, 0x0a, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, - 0x75, 0x67, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, - 0x67, 0x68, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, - 0x00, 0x52, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x42, 0x07, - 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xd6, 0x01, 0x0a, 0x14, 0x44, 0x79, 0x6e, 0x61, - 0x6d, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x12, 0x5e, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x46, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x79, - 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x5e, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x6c, 0x73, - 0x22, 0xde, 0x01, 0x0a, 0x18, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, - 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x62, 0x0a, - 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4a, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x74, - 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x5e, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, - 0x63, 0x6b, 0x65, 0x74, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x6c, - 0x73, 0x22, 0xce, 0x01, 0x0a, 0x10, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5a, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x5e, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, - 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, - 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, - 0x6c, 0x73, 0x22, 0x74, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5d, 0x0a, 0x06, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x28, 0x0a, 0x12, 0x44, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0x7e, 0x0a, 0x16, 0x4c, 0x34, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x08, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x34, 0x57, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x22, 0x7e, 0x0a, 0x16, 0x4c, 0x37, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x08, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x37, 0x57, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x73, 0x22, 0x68, 0x0a, 0x1c, 0x4c, 0x34, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, - 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xcf, 0x01, 0x0a, - 0x1c, 0x4c, 0x37, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x34, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x65, 0x0a, 0x10, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x68, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x80, - 0x08, 0x0a, 0x1a, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, - 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x6e, - 0x69, 0x63, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x6e, 0x69, 0x63, - 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x67, 0x0a, 0x0d, 0x6c, 0x65, 0x61, - 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x61, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x6f, 0x62, 0x69, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x6f, 0x75, - 0x6e, 0x64, 0x52, 0x6f, 0x62, 0x69, 0x6e, 0x48, 0x00, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, - 0x52, 0x6f, 0x62, 0x69, 0x6e, 0x12, 0x54, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x61, 0x6e, 0x64, 0x6f, - 0x6d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x5b, 0x0a, 0x09, 0x72, - 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x52, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x48, 0x00, 0x52, 0x08, - 0x72, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x12, 0x54, 0x0a, 0x06, 0x6d, 0x61, 0x67, 0x6c, - 0x65, 0x76, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x61, - 0x67, 0x6c, 0x65, 0x76, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x61, 0x67, 0x6c, 0x65, 0x76, 0x12, 0x66, - 0x0a, 0x10, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x65, - 0x72, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, - 0x61, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, - 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x69, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, - 0x72, 0x5f, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, - 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x10, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x85, 0x01, 0x0a, 0x1b, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, - 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, - 0x5f, 0x61, 0x6c, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6c, 0x62, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x22, 0x57, 0x0a, 0x14, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4c, 0x65, 0x61, - 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0c, 0x63, 0x68, 0x6f, - 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x63, - 0x68, 0x6f, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x42, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x62, 0x69, 0x6e, - 0x22, 0x10, 0x0a, 0x0e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x61, 0x6e, 0x64, - 0x6f, 0x6d, 0x22, 0xa6, 0x01, 0x0a, 0x10, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, - 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x12, 0x48, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x69, 0x6d, - 0x75, 0x6d, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, - 0x65, 0x12, 0x48, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x72, 0x69, 0x6e, - 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, - 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x69, - 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x4c, - 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x61, 0x67, 0x6c, 0x65, 0x76, 0x22, 0x76, 0x0a, - 0x0f, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, - 0x12, 0x63, 0x0a, 0x0f, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x0e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x73, 0x22, 0xfd, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x4e, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x6d, 0x61, 0x78, - 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, - 0x54, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x15, - 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x83, 0x03, 0x0a, 0x10, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, - 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, - 0x6c, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x35, 0x78, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, - 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, - 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, 0x78, 0x78, 0x12, 0x58, 0x0a, 0x19, 0x65, 0x6e, 0x66, 0x6f, - 0x72, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x35, 0x78, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, - 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x17, 0x65, 0x6e, 0x66, 0x6f, 0x72, - 0x63, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, - 0x78, 0x78, 0x12, 0x4e, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, - 0x6d, 0x61, 0x78, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x63, 0x65, - 0x6e, 0x74, 0x12, 0x47, 0x0a, 0x12, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x65, 0x6a, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x62, 0x61, 0x73, 0x65, 0x45, - 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x8b, 0x02, 0x0a, 0x19, - 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x74, 0x63, 0x70, - 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x10, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x52, 0x0a, 0x16, 0x74, 0x63, 0x70, 0x5f, 0x6b, 0x65, 0x65, - 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x14, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, - 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x4e, 0x0a, 0x14, 0x74, 0x63, 0x70, - 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x62, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, - 0x69, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x1e, 0x50, 0x61, 0x73, - 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, - 0xfc, 0x04, 0x0a, 0x16, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x36, - 0x0a, 0x17, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x5f, - 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x54, 0x68, 0x72, - 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x60, 0x0a, 0x0e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x6f, - 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x66, 0x0a, 0x10, 0x63, 0x69, 0x72, 0x63, - 0x75, 0x69, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x52, - 0x0f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, - 0x12, 0x69, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x74, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, - 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x6c, 0x69, - 0x65, 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x85, 0x01, 0x0a, 0x1b, - 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x45, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, - 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x74, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, - 0x75, 0x73, 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc7, - 0x01, 0x0a, 0x19, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x12, 0x66, 0x0a, 0x10, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, - 0x6b, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, - 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, - 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x2a, 0x46, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x49, 0x53, - 0x43, 0x4f, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x47, 0x49, - 0x43, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, - 0x52, 0x59, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x10, 0x01, - 0x42, 0xd2, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x42, 0x0c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, - 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, - 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, - 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, - 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_cluster_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes = make([]protoimpl.MessageInfo, 26) -var file_pbmesh_v2beta1_pbproxystate_cluster_proto_goTypes = []interface{}{ - (DiscoveryType)(0), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.DiscoveryType - (*Cluster)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster - (*FailoverGroup)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup - (*FailoverGroupConfig)(nil), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroupConfig - (*EndpointGroup)(nil), // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup - (*DynamicEndpointGroup)(nil), // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup - (*PassthroughEndpointGroup)(nil), // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup - (*DNSEndpointGroup)(nil), // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup - (*StaticEndpointGroup)(nil), // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroup - (*DestinationCluster)(nil), // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationCluster - (*L4WeightedClusterGroup)(nil), // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedClusterGroup - (*L7WeightedClusterGroup)(nil), // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedClusterGroup - (*L4WeightedDestinationCluster)(nil), // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedDestinationCluster - (*L7WeightedDestinationCluster)(nil), // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster - (*DynamicEndpointGroupConfig)(nil), // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig - (*LBPolicyLeastRequest)(nil), // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyLeastRequest - (*LBPolicyRoundRobin)(nil), // 16: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRoundRobin - (*LBPolicyRandom)(nil), // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRandom - (*LBPolicyRingHash)(nil), // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash - (*LBPolicyMaglev)(nil), // 19: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyMaglev - (*CircuitBreakers)(nil), // 20: hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers - (*UpstreamLimits)(nil), // 21: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits - (*OutlierDetection)(nil), // 22: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection - (*UpstreamConnectionOptions)(nil), // 23: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions - (*PassthroughEndpointGroupConfig)(nil), // 24: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroupConfig - (*DNSEndpointGroupConfig)(nil), // 25: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig - (*StaticEndpointGroupConfig)(nil), // 26: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig - (Protocol)(0), // 27: hashicorp.consul.mesh.v2beta1.pbproxystate.Protocol - (*durationpb.Duration)(nil), // 28: google.protobuf.Duration - (*TransportSocket)(nil), // 29: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - (*wrapperspb.UInt32Value)(nil), // 30: google.protobuf.UInt32Value - (*HeaderMutation)(nil), // 31: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation - (*wrapperspb.UInt64Value)(nil), // 32: google.protobuf.UInt64Value -} -var file_pbmesh_v2beta1_pbproxystate_cluster_proto_depIdxs = []int32{ - 2, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster.failover_group:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup - 4, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster.endpoint_group:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup - 27, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster.protocol:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Protocol - 4, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup.endpoint_groups:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup - 3, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroupConfig - 28, // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 5, // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.dynamic:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup - 8, // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.static:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroup - 7, // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.dns:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup - 6, // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.passthrough:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup - 14, // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig - 29, // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - 24, // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroupConfig - 29, // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - 25, // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig - 29, // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - 26, // 16: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig - 12, // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedClusterGroup.clusters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedDestinationCluster - 13, // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedClusterGroup.clusters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster - 30, // 19: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedDestinationCluster.weight:type_name -> google.protobuf.UInt32Value - 30, // 20: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster.weight:type_name -> google.protobuf.UInt32Value - 31, // 21: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster.header_mutations:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation - 28, // 22: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 15, // 23: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.least_request:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyLeastRequest - 16, // 24: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.round_robin:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRoundRobin - 17, // 25: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.random:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRandom - 18, // 26: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.ring_hash:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash - 19, // 27: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.maglev:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyMaglev - 20, // 28: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers - 22, // 29: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.outlier_detection:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection - 23, // 30: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.upstream_connection_options:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions - 30, // 31: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyLeastRequest.choice_count:type_name -> google.protobuf.UInt32Value - 32, // 32: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash.minimum_ring_size:type_name -> google.protobuf.UInt64Value - 32, // 33: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash.maximum_ring_size:type_name -> google.protobuf.UInt64Value - 21, // 34: hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers.upstream_limits:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits - 30, // 35: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_connections:type_name -> google.protobuf.UInt32Value - 30, // 36: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_pending_requests:type_name -> google.protobuf.UInt32Value - 30, // 37: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_concurrent_requests:type_name -> google.protobuf.UInt32Value - 28, // 38: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.interval:type_name -> google.protobuf.Duration - 30, // 39: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.consecutive_5xx:type_name -> google.protobuf.UInt32Value - 30, // 40: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.enforcing_consecutive_5xx:type_name -> google.protobuf.UInt32Value - 30, // 41: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.max_ejection_percent:type_name -> google.protobuf.UInt32Value - 28, // 42: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.base_ejection_time:type_name -> google.protobuf.Duration - 30, // 43: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_time:type_name -> google.protobuf.UInt32Value - 30, // 44: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_interval:type_name -> google.protobuf.UInt32Value - 30, // 45: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_probes:type_name -> google.protobuf.UInt32Value - 28, // 46: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 28, // 47: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 0, // 48: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.discovery_type:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DiscoveryType - 20, // 49: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers - 22, // 50: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.outlier_detection:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection - 23, // 51: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.upstream_connection_options:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions - 28, // 52: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 20, // 53: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers - 54, // [54:54] is the sub-list for method output_type - 54, // [54:54] is the sub-list for method input_type - 54, // [54:54] is the sub-list for extension type_name - 54, // [54:54] is the sub-list for extension extendee - 0, // [0:54] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_cluster_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_cluster_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_cluster_proto != nil { - return - } - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_init() - file_pbmesh_v2beta1_pbproxystate_protocol_proto_init() - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Cluster); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailoverGroup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailoverGroupConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EndpointGroup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DynamicEndpointGroup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PassthroughEndpointGroup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DNSEndpointGroup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StaticEndpointGroup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationCluster); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L4WeightedClusterGroup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L7WeightedClusterGroup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L4WeightedDestinationCluster); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L7WeightedDestinationCluster); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DynamicEndpointGroupConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LBPolicyLeastRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LBPolicyRoundRobin); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LBPolicyRandom); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LBPolicyRingHash); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LBPolicyMaglev); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CircuitBreakers); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpstreamLimits); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OutlierDetection); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpstreamConnectionOptions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PassthroughEndpointGroupConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DNSEndpointGroupConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StaticEndpointGroupConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*Cluster_FailoverGroup)(nil), - (*Cluster_EndpointGroup)(nil), - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[3].OneofWrappers = []interface{}{ - (*EndpointGroup_Dynamic)(nil), - (*EndpointGroup_Static)(nil), - (*EndpointGroup_Dns)(nil), - (*EndpointGroup_Passthrough)(nil), - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[13].OneofWrappers = []interface{}{ - (*DynamicEndpointGroupConfig_LeastRequest)(nil), - (*DynamicEndpointGroupConfig_RoundRobin)(nil), - (*DynamicEndpointGroupConfig_Random)(nil), - (*DynamicEndpointGroupConfig_RingHash)(nil), - (*DynamicEndpointGroupConfig_Maglev)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDesc, - NumEnums: 1, - NumMessages: 26, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_cluster_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_cluster_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_pbproxystate_cluster_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_cluster_proto = out.File - file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_cluster_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_cluster_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.proto b/proto-public/pbmesh/v2beta1/pbproxystate/cluster.proto deleted file mode 100644 index a84a3755c99b9..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.proto +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -import "google/protobuf/duration.proto"; -import "google/protobuf/wrappers.proto"; -import "pbmesh/v2beta1/pbproxystate/header_mutations.proto"; -import "pbmesh/v2beta1/pbproxystate/protocol.proto"; -import "pbmesh/v2beta1/pbproxystate/transport_socket.proto"; - -message Cluster { - // name is the name of the cluster. - string name = 1; - // group is either a failover group or endpoint group. If this cluster needs to failover to other clusters, use the failover group. If this cluster routes directly to endpoints, use the endpoint group. - oneof group { - FailoverGroup failover_group = 2; - EndpointGroup endpoint_group = 3; - } - // escape_hatch_cluster_json configures a user configured escape hatch cluster. - string escape_hatch_cluster_json = 4; - // alt_stat_name is the name used for observability in place of cluster name if provided. - string alt_stat_name = 5; - // protocol is the local path protocol or the service protocol. - Protocol protocol = 6; -} - -message FailoverGroup { - // endpoint_groups is an ordered list of which groups to failover to. - repeated EndpointGroup endpoint_groups = 1; - FailoverGroupConfig config = 2; -} - -message FailoverGroupConfig { - bool use_alt_stat_name = 1; - // +kubebuilder:validation:Type=string - google.protobuf.Duration connect_timeout = 2; -} - -message EndpointGroup { - // name is used to name the cluster created. This is only required when used inside of a FailoverGroup. - string name = 5; - oneof group { - // dynamic endpoint group is used to reach mesh destinations that are dynamically configured from Consul's catalog. - DynamicEndpointGroup dynamic = 1; - // static endpoint group is used to reach local app ports. - StaticEndpointGroup static = 2; - // dns is used to reach mesh and non-mesh destinations using a hostname. - DNSEndpointGroup dns = 3; - // passthrough is used to reach destinations that don't have endpoints saved in Consul. - PassthroughEndpointGroup passthrough = 4; - } -} - -message DynamicEndpointGroup { - // config configures how to connect to the endpoints. - DynamicEndpointGroupConfig config = 1; - // outbound_tls will configure what TLS information to use when connecting to an upstream. - TransportSocket outbound_tls = 2; -} - -message PassthroughEndpointGroup { - // config configures how to connect to the endpoints. - PassthroughEndpointGroupConfig config = 1; - // outbound_tls will configure what TLS information to use when connecting to an upstream. - TransportSocket outbound_tls = 2; -} - -message DNSEndpointGroup { - // config configures how to connect to the endpoints. - DNSEndpointGroupConfig config = 1; - // outbound_tls will configure what TLS information to use when connecting to an upstream. - TransportSocket outbound_tls = 2; -} - -// StaticEndpointGroup is used to reach local app ports. -message StaticEndpointGroup { - // config configures how to connect to the endpoints. - StaticEndpointGroupConfig config = 1; -} - -message DestinationCluster { - // name is the name of the cluster. This will be used to look up a cluster in the clusters map. - string name = 1; -} - -message L4WeightedClusterGroup { - // clusters to route to by weight. - repeated L4WeightedDestinationCluster clusters = 1; -} - -message L7WeightedClusterGroup { - // clusters to route to by weight. - repeated L7WeightedDestinationCluster clusters = 1; -} - -message L4WeightedDestinationCluster { - // name is the name of the cluster. This will be used to look up a cluster in the clusters map. - string name = 1; - google.protobuf.UInt32Value weight = 2; -} - -message L7WeightedDestinationCluster { - // name is the name of the cluster. This will be used to look up a cluster in the clusters map. - string name = 1; - google.protobuf.UInt32Value weight = 2; - repeated HeaderMutation header_mutations = 3; -} - -message DynamicEndpointGroupConfig { - // +kubebuilder:validation:Format=duration - google.protobuf.Duration connect_timeout = 1; - bool disable_panic_threshold = 2; - oneof lb_policy { - LBPolicyLeastRequest least_request = 3; - LBPolicyRoundRobin round_robin = 4; - LBPolicyRandom random = 5; - LBPolicyRingHash ring_hash = 6; - LBPolicyMaglev maglev = 7; - } - CircuitBreakers circuit_breakers = 8; - OutlierDetection outlier_detection = 9; - UpstreamConnectionOptions upstream_connection_options = 10; - bool use_alt_stat_name = 11; -} - -message LBPolicyLeastRequest { - google.protobuf.UInt32Value choice_count = 1; -} -message LBPolicyRoundRobin {} - -message LBPolicyRandom {} - -message LBPolicyRingHash { - google.protobuf.UInt64Value minimum_ring_size = 1; - google.protobuf.UInt64Value maximum_ring_size = 2; -} - -message LBPolicyMaglev {} - -message CircuitBreakers { - UpstreamLimits upstream_limits = 1; -} - -message UpstreamLimits { - google.protobuf.UInt32Value max_connections = 1; - google.protobuf.UInt32Value max_pending_requests = 2; - google.protobuf.UInt32Value max_concurrent_requests = 3; -} - -message OutlierDetection { - // +kubebuilder:validation:Format=duration - google.protobuf.Duration interval = 1; - google.protobuf.UInt32Value consecutive_5xx = 2; - google.protobuf.UInt32Value enforcing_consecutive_5xx = 3; - google.protobuf.UInt32Value max_ejection_percent = 4; - // +kubebuilder:validation:Format=duration - google.protobuf.Duration base_ejection_time = 5; -} - -message UpstreamConnectionOptions { - google.protobuf.UInt32Value tcp_keepalive_time = 1; - google.protobuf.UInt32Value tcp_keepalive_interval = 2; - google.protobuf.UInt32Value tcp_keepalive_probes = 3; -} - -message PassthroughEndpointGroupConfig { - // +kubebuilder:validation:Format=duration - google.protobuf.Duration connect_timeout = 1; -} - -message DNSEndpointGroupConfig { - // +kubebuilder:validation:Format=duration - google.protobuf.Duration connect_timeout = 1; - bool disable_panic_threshold = 2; - DiscoveryType discovery_type = 3; - CircuitBreakers circuit_breakers = 4; - OutlierDetection outlier_detection = 5; - UpstreamConnectionOptions upstream_connection_options = 6; - bool use_alt_stat_name = 7; -} - -// +kubebuilder:validation:Enum=DISCOVERY_TYPE_LOGICAL;DISCOVERY_TYPE_STRICT -// +kubebuilder:validation:Type=string -enum DiscoveryType { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - DISCOVERY_TYPE_LOGICAL = 0; - DISCOVERY_TYPE_STRICT = 1; -} - -message StaticEndpointGroupConfig { - // +kubebuilder:validation:Format=duration - google.protobuf.Duration connect_timeout = 1; - CircuitBreakers circuit_breakers = 2; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/cluster_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/cluster_deepcopy.gen.go deleted file mode 100644 index 1818a349bd458..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/cluster_deepcopy.gen.go +++ /dev/null @@ -1,552 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Cluster within kubernetes types, where deepcopy-gen is used. -func (in *Cluster) DeepCopyInto(out *Cluster) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. Required by controller-gen. -func (in *Cluster) DeepCopy() *Cluster { - if in == nil { - return nil - } - out := new(Cluster) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. Required by controller-gen. -func (in *Cluster) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using FailoverGroup within kubernetes types, where deepcopy-gen is used. -func (in *FailoverGroup) DeepCopyInto(out *FailoverGroup) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverGroup. Required by controller-gen. -func (in *FailoverGroup) DeepCopy() *FailoverGroup { - if in == nil { - return nil - } - out := new(FailoverGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new FailoverGroup. Required by controller-gen. -func (in *FailoverGroup) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using FailoverGroupConfig within kubernetes types, where deepcopy-gen is used. -func (in *FailoverGroupConfig) DeepCopyInto(out *FailoverGroupConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverGroupConfig. Required by controller-gen. -func (in *FailoverGroupConfig) DeepCopy() *FailoverGroupConfig { - if in == nil { - return nil - } - out := new(FailoverGroupConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new FailoverGroupConfig. Required by controller-gen. -func (in *FailoverGroupConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using EndpointGroup within kubernetes types, where deepcopy-gen is used. -func (in *EndpointGroup) DeepCopyInto(out *EndpointGroup) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointGroup. Required by controller-gen. -func (in *EndpointGroup) DeepCopy() *EndpointGroup { - if in == nil { - return nil - } - out := new(EndpointGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new EndpointGroup. Required by controller-gen. -func (in *EndpointGroup) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DynamicEndpointGroup within kubernetes types, where deepcopy-gen is used. -func (in *DynamicEndpointGroup) DeepCopyInto(out *DynamicEndpointGroup) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicEndpointGroup. Required by controller-gen. -func (in *DynamicEndpointGroup) DeepCopy() *DynamicEndpointGroup { - if in == nil { - return nil - } - out := new(DynamicEndpointGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DynamicEndpointGroup. Required by controller-gen. -func (in *DynamicEndpointGroup) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using PassthroughEndpointGroup within kubernetes types, where deepcopy-gen is used. -func (in *PassthroughEndpointGroup) DeepCopyInto(out *PassthroughEndpointGroup) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PassthroughEndpointGroup. Required by controller-gen. -func (in *PassthroughEndpointGroup) DeepCopy() *PassthroughEndpointGroup { - if in == nil { - return nil - } - out := new(PassthroughEndpointGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new PassthroughEndpointGroup. Required by controller-gen. -func (in *PassthroughEndpointGroup) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DNSEndpointGroup within kubernetes types, where deepcopy-gen is used. -func (in *DNSEndpointGroup) DeepCopyInto(out *DNSEndpointGroup) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointGroup. Required by controller-gen. -func (in *DNSEndpointGroup) DeepCopy() *DNSEndpointGroup { - if in == nil { - return nil - } - out := new(DNSEndpointGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointGroup. Required by controller-gen. -func (in *DNSEndpointGroup) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using StaticEndpointGroup within kubernetes types, where deepcopy-gen is used. -func (in *StaticEndpointGroup) DeepCopyInto(out *StaticEndpointGroup) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StaticEndpointGroup. Required by controller-gen. -func (in *StaticEndpointGroup) DeepCopy() *StaticEndpointGroup { - if in == nil { - return nil - } - out := new(StaticEndpointGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new StaticEndpointGroup. Required by controller-gen. -func (in *StaticEndpointGroup) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DestinationCluster within kubernetes types, where deepcopy-gen is used. -func (in *DestinationCluster) DeepCopyInto(out *DestinationCluster) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationCluster. Required by controller-gen. -func (in *DestinationCluster) DeepCopy() *DestinationCluster { - if in == nil { - return nil - } - out := new(DestinationCluster) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationCluster. Required by controller-gen. -func (in *DestinationCluster) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using L4WeightedClusterGroup within kubernetes types, where deepcopy-gen is used. -func (in *L4WeightedClusterGroup) DeepCopyInto(out *L4WeightedClusterGroup) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L4WeightedClusterGroup. Required by controller-gen. -func (in *L4WeightedClusterGroup) DeepCopy() *L4WeightedClusterGroup { - if in == nil { - return nil - } - out := new(L4WeightedClusterGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new L4WeightedClusterGroup. Required by controller-gen. -func (in *L4WeightedClusterGroup) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using L7WeightedClusterGroup within kubernetes types, where deepcopy-gen is used. -func (in *L7WeightedClusterGroup) DeepCopyInto(out *L7WeightedClusterGroup) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L7WeightedClusterGroup. Required by controller-gen. -func (in *L7WeightedClusterGroup) DeepCopy() *L7WeightedClusterGroup { - if in == nil { - return nil - } - out := new(L7WeightedClusterGroup) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new L7WeightedClusterGroup. Required by controller-gen. -func (in *L7WeightedClusterGroup) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using L4WeightedDestinationCluster within kubernetes types, where deepcopy-gen is used. -func (in *L4WeightedDestinationCluster) DeepCopyInto(out *L4WeightedDestinationCluster) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L4WeightedDestinationCluster. Required by controller-gen. -func (in *L4WeightedDestinationCluster) DeepCopy() *L4WeightedDestinationCluster { - if in == nil { - return nil - } - out := new(L4WeightedDestinationCluster) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new L4WeightedDestinationCluster. Required by controller-gen. -func (in *L4WeightedDestinationCluster) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using L7WeightedDestinationCluster within kubernetes types, where deepcopy-gen is used. -func (in *L7WeightedDestinationCluster) DeepCopyInto(out *L7WeightedDestinationCluster) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L7WeightedDestinationCluster. Required by controller-gen. -func (in *L7WeightedDestinationCluster) DeepCopy() *L7WeightedDestinationCluster { - if in == nil { - return nil - } - out := new(L7WeightedDestinationCluster) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new L7WeightedDestinationCluster. Required by controller-gen. -func (in *L7WeightedDestinationCluster) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DynamicEndpointGroupConfig within kubernetes types, where deepcopy-gen is used. -func (in *DynamicEndpointGroupConfig) DeepCopyInto(out *DynamicEndpointGroupConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicEndpointGroupConfig. Required by controller-gen. -func (in *DynamicEndpointGroupConfig) DeepCopy() *DynamicEndpointGroupConfig { - if in == nil { - return nil - } - out := new(DynamicEndpointGroupConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DynamicEndpointGroupConfig. Required by controller-gen. -func (in *DynamicEndpointGroupConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LBPolicyLeastRequest within kubernetes types, where deepcopy-gen is used. -func (in *LBPolicyLeastRequest) DeepCopyInto(out *LBPolicyLeastRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyLeastRequest. Required by controller-gen. -func (in *LBPolicyLeastRequest) DeepCopy() *LBPolicyLeastRequest { - if in == nil { - return nil - } - out := new(LBPolicyLeastRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyLeastRequest. Required by controller-gen. -func (in *LBPolicyLeastRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LBPolicyRoundRobin within kubernetes types, where deepcopy-gen is used. -func (in *LBPolicyRoundRobin) DeepCopyInto(out *LBPolicyRoundRobin) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRoundRobin. Required by controller-gen. -func (in *LBPolicyRoundRobin) DeepCopy() *LBPolicyRoundRobin { - if in == nil { - return nil - } - out := new(LBPolicyRoundRobin) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRoundRobin. Required by controller-gen. -func (in *LBPolicyRoundRobin) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LBPolicyRandom within kubernetes types, where deepcopy-gen is used. -func (in *LBPolicyRandom) DeepCopyInto(out *LBPolicyRandom) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRandom. Required by controller-gen. -func (in *LBPolicyRandom) DeepCopy() *LBPolicyRandom { - if in == nil { - return nil - } - out := new(LBPolicyRandom) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRandom. Required by controller-gen. -func (in *LBPolicyRandom) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LBPolicyRingHash within kubernetes types, where deepcopy-gen is used. -func (in *LBPolicyRingHash) DeepCopyInto(out *LBPolicyRingHash) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRingHash. Required by controller-gen. -func (in *LBPolicyRingHash) DeepCopy() *LBPolicyRingHash { - if in == nil { - return nil - } - out := new(LBPolicyRingHash) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRingHash. Required by controller-gen. -func (in *LBPolicyRingHash) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LBPolicyMaglev within kubernetes types, where deepcopy-gen is used. -func (in *LBPolicyMaglev) DeepCopyInto(out *LBPolicyMaglev) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyMaglev. Required by controller-gen. -func (in *LBPolicyMaglev) DeepCopy() *LBPolicyMaglev { - if in == nil { - return nil - } - out := new(LBPolicyMaglev) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyMaglev. Required by controller-gen. -func (in *LBPolicyMaglev) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using CircuitBreakers within kubernetes types, where deepcopy-gen is used. -func (in *CircuitBreakers) DeepCopyInto(out *CircuitBreakers) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CircuitBreakers. Required by controller-gen. -func (in *CircuitBreakers) DeepCopy() *CircuitBreakers { - if in == nil { - return nil - } - out := new(CircuitBreakers) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new CircuitBreakers. Required by controller-gen. -func (in *CircuitBreakers) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using UpstreamLimits within kubernetes types, where deepcopy-gen is used. -func (in *UpstreamLimits) DeepCopyInto(out *UpstreamLimits) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamLimits. Required by controller-gen. -func (in *UpstreamLimits) DeepCopy() *UpstreamLimits { - if in == nil { - return nil - } - out := new(UpstreamLimits) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamLimits. Required by controller-gen. -func (in *UpstreamLimits) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using OutlierDetection within kubernetes types, where deepcopy-gen is used. -func (in *OutlierDetection) DeepCopyInto(out *OutlierDetection) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OutlierDetection. Required by controller-gen. -func (in *OutlierDetection) DeepCopy() *OutlierDetection { - if in == nil { - return nil - } - out := new(OutlierDetection) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new OutlierDetection. Required by controller-gen. -func (in *OutlierDetection) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using UpstreamConnectionOptions within kubernetes types, where deepcopy-gen is used. -func (in *UpstreamConnectionOptions) DeepCopyInto(out *UpstreamConnectionOptions) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamConnectionOptions. Required by controller-gen. -func (in *UpstreamConnectionOptions) DeepCopy() *UpstreamConnectionOptions { - if in == nil { - return nil - } - out := new(UpstreamConnectionOptions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamConnectionOptions. Required by controller-gen. -func (in *UpstreamConnectionOptions) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using PassthroughEndpointGroupConfig within kubernetes types, where deepcopy-gen is used. -func (in *PassthroughEndpointGroupConfig) DeepCopyInto(out *PassthroughEndpointGroupConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PassthroughEndpointGroupConfig. Required by controller-gen. -func (in *PassthroughEndpointGroupConfig) DeepCopy() *PassthroughEndpointGroupConfig { - if in == nil { - return nil - } - out := new(PassthroughEndpointGroupConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new PassthroughEndpointGroupConfig. Required by controller-gen. -func (in *PassthroughEndpointGroupConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DNSEndpointGroupConfig within kubernetes types, where deepcopy-gen is used. -func (in *DNSEndpointGroupConfig) DeepCopyInto(out *DNSEndpointGroupConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointGroupConfig. Required by controller-gen. -func (in *DNSEndpointGroupConfig) DeepCopy() *DNSEndpointGroupConfig { - if in == nil { - return nil - } - out := new(DNSEndpointGroupConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointGroupConfig. Required by controller-gen. -func (in *DNSEndpointGroupConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using StaticEndpointGroupConfig within kubernetes types, where deepcopy-gen is used. -func (in *StaticEndpointGroupConfig) DeepCopyInto(out *StaticEndpointGroupConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StaticEndpointGroupConfig. Required by controller-gen. -func (in *StaticEndpointGroupConfig) DeepCopy() *StaticEndpointGroupConfig { - if in == nil { - return nil - } - out := new(StaticEndpointGroupConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new StaticEndpointGroupConfig. Required by controller-gen. -func (in *StaticEndpointGroupConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/cluster_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/cluster_json.gen.go deleted file mode 100644 index 570c801c000f2..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/cluster_json.gen.go +++ /dev/null @@ -1,297 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Cluster -func (this *Cluster) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Cluster -func (this *Cluster) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for FailoverGroup -func (this *FailoverGroup) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for FailoverGroup -func (this *FailoverGroup) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for FailoverGroupConfig -func (this *FailoverGroupConfig) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for FailoverGroupConfig -func (this *FailoverGroupConfig) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for EndpointGroup -func (this *EndpointGroup) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for EndpointGroup -func (this *EndpointGroup) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DynamicEndpointGroup -func (this *DynamicEndpointGroup) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DynamicEndpointGroup -func (this *DynamicEndpointGroup) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for PassthroughEndpointGroup -func (this *PassthroughEndpointGroup) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for PassthroughEndpointGroup -func (this *PassthroughEndpointGroup) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DNSEndpointGroup -func (this *DNSEndpointGroup) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DNSEndpointGroup -func (this *DNSEndpointGroup) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for StaticEndpointGroup -func (this *StaticEndpointGroup) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for StaticEndpointGroup -func (this *StaticEndpointGroup) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DestinationCluster -func (this *DestinationCluster) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationCluster -func (this *DestinationCluster) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for L4WeightedClusterGroup -func (this *L4WeightedClusterGroup) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for L4WeightedClusterGroup -func (this *L4WeightedClusterGroup) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for L7WeightedClusterGroup -func (this *L7WeightedClusterGroup) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for L7WeightedClusterGroup -func (this *L7WeightedClusterGroup) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for L4WeightedDestinationCluster -func (this *L4WeightedDestinationCluster) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for L4WeightedDestinationCluster -func (this *L4WeightedDestinationCluster) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for L7WeightedDestinationCluster -func (this *L7WeightedDestinationCluster) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for L7WeightedDestinationCluster -func (this *L7WeightedDestinationCluster) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DynamicEndpointGroupConfig -func (this *DynamicEndpointGroupConfig) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DynamicEndpointGroupConfig -func (this *DynamicEndpointGroupConfig) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LBPolicyLeastRequest -func (this *LBPolicyLeastRequest) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LBPolicyLeastRequest -func (this *LBPolicyLeastRequest) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LBPolicyRoundRobin -func (this *LBPolicyRoundRobin) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LBPolicyRoundRobin -func (this *LBPolicyRoundRobin) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LBPolicyRandom -func (this *LBPolicyRandom) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LBPolicyRandom -func (this *LBPolicyRandom) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LBPolicyRingHash -func (this *LBPolicyRingHash) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LBPolicyRingHash -func (this *LBPolicyRingHash) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LBPolicyMaglev -func (this *LBPolicyMaglev) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LBPolicyMaglev -func (this *LBPolicyMaglev) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for CircuitBreakers -func (this *CircuitBreakers) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for CircuitBreakers -func (this *CircuitBreakers) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for UpstreamLimits -func (this *UpstreamLimits) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for UpstreamLimits -func (this *UpstreamLimits) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for OutlierDetection -func (this *OutlierDetection) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for OutlierDetection -func (this *OutlierDetection) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for UpstreamConnectionOptions -func (this *UpstreamConnectionOptions) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for UpstreamConnectionOptions -func (this *UpstreamConnectionOptions) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for PassthroughEndpointGroupConfig -func (this *PassthroughEndpointGroupConfig) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for PassthroughEndpointGroupConfig -func (this *PassthroughEndpointGroupConfig) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DNSEndpointGroupConfig -func (this *DNSEndpointGroupConfig) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DNSEndpointGroupConfig -func (this *DNSEndpointGroupConfig) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for StaticEndpointGroupConfig -func (this *StaticEndpointGroupConfig) MarshalJSON() ([]byte, error) { - str, err := ClusterMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for StaticEndpointGroupConfig -func (this *StaticEndpointGroupConfig) UnmarshalJSON(b []byte) error { - return ClusterUnmarshaler.Unmarshal(b, this) -} - -var ( - ClusterMarshaler = &protojson.MarshalOptions{} - ClusterUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.pb.binary.go deleted file mode 100644 index 82ab22a39db0f..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.pb.binary.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/endpoints.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Endpoints) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Endpoints) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Endpoint) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Endpoint) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.pb.go deleted file mode 100644 index 5986ad83a12e5..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.pb.go +++ /dev/null @@ -1,387 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/endpoints.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=HEALTH_STATUS_UNKNOWN;HEALTH_STATUS_HEALTHY;HEALTH_STATUS_UNHEALTHY -// +kubebuilder:validation:Type=string -type HealthStatus int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - HealthStatus_HEALTH_STATUS_UNKNOWN HealthStatus = 0 - HealthStatus_HEALTH_STATUS_HEALTHY HealthStatus = 1 - HealthStatus_HEALTH_STATUS_UNHEALTHY HealthStatus = 2 -) - -// Enum value maps for HealthStatus. -var ( - HealthStatus_name = map[int32]string{ - 0: "HEALTH_STATUS_UNKNOWN", - 1: "HEALTH_STATUS_HEALTHY", - 2: "HEALTH_STATUS_UNHEALTHY", - } - HealthStatus_value = map[string]int32{ - "HEALTH_STATUS_UNKNOWN": 0, - "HEALTH_STATUS_HEALTHY": 1, - "HEALTH_STATUS_UNHEALTHY": 2, - } -) - -func (x HealthStatus) Enum() *HealthStatus { - p := new(HealthStatus) - *p = x - return p -} - -func (x HealthStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (HealthStatus) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_endpoints_proto_enumTypes[0].Descriptor() -} - -func (HealthStatus) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_endpoints_proto_enumTypes[0] -} - -func (x HealthStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use HealthStatus.Descriptor instead. -func (HealthStatus) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescGZIP(), []int{0} -} - -type Endpoints struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Endpoints []*Endpoint `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"` -} - -func (x *Endpoints) Reset() { - *x = Endpoints{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Endpoints) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Endpoints) ProtoMessage() {} - -func (x *Endpoints) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Endpoints.ProtoReflect.Descriptor instead. -func (*Endpoints) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescGZIP(), []int{0} -} - -func (x *Endpoints) GetEndpoints() []*Endpoint { - if x != nil { - return x.Endpoints - } - return nil -} - -type Endpoint struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Address: - // - // *Endpoint_HostPort - // *Endpoint_UnixSocket - Address isEndpoint_Address `protobuf_oneof:"address"` - HealthStatus HealthStatus `protobuf:"varint,3,opt,name=health_status,json=healthStatus,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.HealthStatus" json:"health_status,omitempty"` - LoadBalancingWeight *wrapperspb.UInt32Value `protobuf:"bytes,4,opt,name=load_balancing_weight,json=loadBalancingWeight,proto3" json:"load_balancing_weight,omitempty"` -} - -func (x *Endpoint) Reset() { - *x = Endpoint{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Endpoint) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Endpoint) ProtoMessage() {} - -func (x *Endpoint) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Endpoint.ProtoReflect.Descriptor instead. -func (*Endpoint) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescGZIP(), []int{1} -} - -func (m *Endpoint) GetAddress() isEndpoint_Address { - if m != nil { - return m.Address - } - return nil -} - -func (x *Endpoint) GetHostPort() *HostPortAddress { - if x, ok := x.GetAddress().(*Endpoint_HostPort); ok { - return x.HostPort - } - return nil -} - -func (x *Endpoint) GetUnixSocket() *UnixSocketAddress { - if x, ok := x.GetAddress().(*Endpoint_UnixSocket); ok { - return x.UnixSocket - } - return nil -} - -func (x *Endpoint) GetHealthStatus() HealthStatus { - if x != nil { - return x.HealthStatus - } - return HealthStatus_HEALTH_STATUS_UNKNOWN -} - -func (x *Endpoint) GetLoadBalancingWeight() *wrapperspb.UInt32Value { - if x != nil { - return x.LoadBalancingWeight - } - return nil -} - -type isEndpoint_Address interface { - isEndpoint_Address() -} - -type Endpoint_HostPort struct { - HostPort *HostPortAddress `protobuf:"bytes,1,opt,name=host_port,json=hostPort,proto3,oneof"` -} - -type Endpoint_UnixSocket struct { - UnixSocket *UnixSocketAddress `protobuf:"bytes,2,opt,name=unix_socket,json=unixSocket,proto3,oneof"` -} - -func (*Endpoint_HostPort) isEndpoint_Address() {} - -func (*Endpoint_UnixSocket) isEndpoint_Address() {} - -var File_pbmesh_v2beta1_pbproxystate_endpoints_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDesc = []byte{ - 0x0a, 0x2b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x6e, - 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x70, 0x62, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5f, 0x0a, 0x09, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x73, 0x12, 0x52, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x84, 0x03, 0x0a, 0x08, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x12, 0x5a, 0x0a, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x48, 0x00, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x60, - 0x0a, 0x0b, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x55, 0x6e, 0x69, 0x78, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x48, 0x00, 0x52, 0x0a, 0x75, 0x6e, 0x69, 0x78, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, - 0x12, 0x5d, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x50, 0x0a, 0x15, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, - 0x67, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x6c, 0x6f, - 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x57, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x42, 0x09, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2a, 0x61, 0x0a, 0x0c, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x15, - 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x45, 0x41, 0x4c, 0x54, - 0x48, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, - 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x02, 0x42, - 0xd4, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x42, 0x0e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, - 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, - 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, - 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, - 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, - 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, - 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_endpoints_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbmesh_v2beta1_pbproxystate_endpoints_proto_goTypes = []interface{}{ - (HealthStatus)(0), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.HealthStatus - (*Endpoints)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoints - (*Endpoint)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoint - (*HostPortAddress)(nil), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.HostPortAddress - (*UnixSocketAddress)(nil), // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.UnixSocketAddress - (*wrapperspb.UInt32Value)(nil), // 5: google.protobuf.UInt32Value -} -var file_pbmesh_v2beta1_pbproxystate_endpoints_proto_depIdxs = []int32{ - 2, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoints.endpoints:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoint - 3, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoint.host_port:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HostPortAddress - 4, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoint.unix_socket:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UnixSocketAddress - 0, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoint.health_status:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HealthStatus - 5, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoint.load_balancing_weight:type_name -> google.protobuf.UInt32Value - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_endpoints_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_endpoints_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_endpoints_proto != nil { - return - } - file_pbmesh_v2beta1_pbproxystate_address_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Endpoints); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Endpoint); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes[1].OneofWrappers = []interface{}{ - (*Endpoint_HostPort)(nil), - (*Endpoint_UnixSocket)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDesc, - NumEnums: 1, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_endpoints_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_endpoints_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_pbproxystate_endpoints_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_endpoints_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_endpoints_proto = out.File - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_endpoints_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.proto b/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.proto deleted file mode 100644 index 0612c4eb11f52..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints.proto +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -import "google/protobuf/wrappers.proto"; -import "pbmesh/v2beta1/pbproxystate/address.proto"; - -message Endpoints { - repeated Endpoint endpoints = 1; -} - -message Endpoint { - oneof address { - HostPortAddress host_port = 1; - UnixSocketAddress unix_socket = 2; - } - HealthStatus health_status = 3; - google.protobuf.UInt32Value load_balancing_weight = 4; -} - -// +kubebuilder:validation:Enum=HEALTH_STATUS_UNKNOWN;HEALTH_STATUS_HEALTHY;HEALTH_STATUS_UNHEALTHY -// +kubebuilder:validation:Type=string -enum HealthStatus { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - HEALTH_STATUS_UNKNOWN = 0; - HEALTH_STATUS_HEALTHY = 1; - HEALTH_STATUS_UNHEALTHY = 2; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_deepcopy.gen.go deleted file mode 100644 index eeb1daa5d23c2..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Endpoints within kubernetes types, where deepcopy-gen is used. -func (in *Endpoints) DeepCopyInto(out *Endpoints) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoints. Required by controller-gen. -func (in *Endpoints) DeepCopy() *Endpoints { - if in == nil { - return nil - } - out := new(Endpoints) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Endpoints. Required by controller-gen. -func (in *Endpoints) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Endpoint within kubernetes types, where deepcopy-gen is used. -func (in *Endpoint) DeepCopyInto(out *Endpoint) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. Required by controller-gen. -func (in *Endpoint) DeepCopy() *Endpoint { - if in == nil { - return nil - } - out := new(Endpoint) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. Required by controller-gen. -func (in *Endpoint) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_json.gen.go deleted file mode 100644 index 45b9fbf321e98..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Endpoints -func (this *Endpoints) MarshalJSON() ([]byte, error) { - str, err := EndpointsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Endpoints -func (this *Endpoints) UnmarshalJSON(b []byte) error { - return EndpointsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Endpoint -func (this *Endpoint) MarshalJSON() ([]byte, error) { - str, err := EndpointsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Endpoint -func (this *Endpoint) UnmarshalJSON(b []byte) error { - return EndpointsUnmarshaler.Unmarshal(b, this) -} - -var ( - EndpointsMarshaler = &protojson.MarshalOptions{} - EndpointsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.pb.binary.go deleted file mode 100644 index e266a07be25dc..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/escape_hatches.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *EscapeHatches) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *EscapeHatches) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.pb.go deleted file mode 100644 index 91e549564ced1..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.pb.go +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/escape_hatches.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type EscapeHatches struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // listener_tracing_json contains user provided tracing configuration. - ListenerTracingJson string `protobuf:"bytes,1,opt,name=listener_tracing_json,json=listenerTracingJson,proto3" json:"listener_tracing_json,omitempty"` -} - -func (x *EscapeHatches) Reset() { - *x = EscapeHatches{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EscapeHatches) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EscapeHatches) ProtoMessage() {} - -func (x *EscapeHatches) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EscapeHatches.ProtoReflect.Descriptor instead. -func (*EscapeHatches) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDescGZIP(), []int{0} -} - -func (x *EscapeHatches) GetListenerTracingJson() string { - if x != nil { - return x.ListenerTracingJson - } - return "" -} - -var File_pbmesh_v2beta1_pbproxystate_escape_hatches_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDesc = []byte{ - 0x0a, 0x30, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x73, - 0x63, 0x61, 0x70, 0x65, 0x5f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x43, - 0x0a, 0x0d, 0x45, 0x73, 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x63, - 0x69, 0x6e, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x4a, - 0x73, 0x6f, 0x6e, 0x42, 0xd8, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x12, 0x45, 0x73, 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, - 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_goTypes = []interface{}{ - (*EscapeHatches)(nil), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.EscapeHatches -} -var file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_escape_hatches_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EscapeHatches); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_escape_hatches_proto = out.File - file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_escape_hatches_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.proto b/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.proto deleted file mode 100644 index 566fc4f06bf6a..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches.proto +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -message EscapeHatches { - // listener_tracing_json contains user provided tracing configuration. - string listener_tracing_json = 1; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_deepcopy.gen.go deleted file mode 100644 index 41fcb73d46620..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using EscapeHatches within kubernetes types, where deepcopy-gen is used. -func (in *EscapeHatches) DeepCopyInto(out *EscapeHatches) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscapeHatches. Required by controller-gen. -func (in *EscapeHatches) DeepCopy() *EscapeHatches { - if in == nil { - return nil - } - out := new(EscapeHatches) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new EscapeHatches. Required by controller-gen. -func (in *EscapeHatches) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_json.gen.go deleted file mode 100644 index ecda76eb2284c..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for EscapeHatches -func (this *EscapeHatches) MarshalJSON() ([]byte, error) { - str, err := EscapeHatchesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for EscapeHatches -func (this *EscapeHatches) UnmarshalJSON(b []byte) error { - return EscapeHatchesUnmarshaler.Unmarshal(b, this) -} - -var ( - EscapeHatchesMarshaler = &protojson.MarshalOptions{} - EscapeHatchesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.pb.binary.go deleted file mode 100644 index 35b0b8969eaf0..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.pb.binary.go +++ /dev/null @@ -1,68 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/header_mutations.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HeaderMutation) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HeaderMutation) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RequestHeaderAdd) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RequestHeaderAdd) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RequestHeaderRemove) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RequestHeaderRemove) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ResponseHeaderAdd) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ResponseHeaderAdd) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ResponseHeaderRemove) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ResponseHeaderRemove) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Header) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Header) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.pb.go deleted file mode 100644 index 54bc797892fdc..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.pb.go +++ /dev/null @@ -1,694 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/header_mutations.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD;APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD -// +kubebuilder:validation:Type=string -type AppendAction int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD AppendAction = 0 - AppendAction_APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD AppendAction = 1 -) - -// Enum value maps for AppendAction. -var ( - AppendAction_name = map[int32]string{ - 0: "APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD", - 1: "APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD", - } - AppendAction_value = map[string]int32{ - "APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD": 0, - "APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD": 1, - } -) - -func (x AppendAction) Enum() *AppendAction { - p := new(AppendAction) - *p = x - return p -} - -func (x AppendAction) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (AppendAction) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_enumTypes[0].Descriptor() -} - -func (AppendAction) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_enumTypes[0] -} - -func (x AppendAction) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use AppendAction.Descriptor instead. -func (AppendAction) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescGZIP(), []int{0} -} - -// Note: it's nice to have this list of header mutations as opposed to configuration similar to Envoy because it -// translates more nicely from GAMMA HTTPRoute, and our existing service router config. Then xds code can handle turning -// it into envoy xds. -type HeaderMutation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Action: - // - // *HeaderMutation_RequestHeaderAdd - // *HeaderMutation_RequestHeaderRemove - // *HeaderMutation_ResponseHeaderAdd - // *HeaderMutation_ResponseHeaderRemove - Action isHeaderMutation_Action `protobuf_oneof:"action"` -} - -func (x *HeaderMutation) Reset() { - *x = HeaderMutation{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HeaderMutation) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HeaderMutation) ProtoMessage() {} - -func (x *HeaderMutation) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HeaderMutation.ProtoReflect.Descriptor instead. -func (*HeaderMutation) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescGZIP(), []int{0} -} - -func (m *HeaderMutation) GetAction() isHeaderMutation_Action { - if m != nil { - return m.Action - } - return nil -} - -func (x *HeaderMutation) GetRequestHeaderAdd() *RequestHeaderAdd { - if x, ok := x.GetAction().(*HeaderMutation_RequestHeaderAdd); ok { - return x.RequestHeaderAdd - } - return nil -} - -func (x *HeaderMutation) GetRequestHeaderRemove() *RequestHeaderRemove { - if x, ok := x.GetAction().(*HeaderMutation_RequestHeaderRemove); ok { - return x.RequestHeaderRemove - } - return nil -} - -func (x *HeaderMutation) GetResponseHeaderAdd() *ResponseHeaderAdd { - if x, ok := x.GetAction().(*HeaderMutation_ResponseHeaderAdd); ok { - return x.ResponseHeaderAdd - } - return nil -} - -func (x *HeaderMutation) GetResponseHeaderRemove() *ResponseHeaderRemove { - if x, ok := x.GetAction().(*HeaderMutation_ResponseHeaderRemove); ok { - return x.ResponseHeaderRemove - } - return nil -} - -type isHeaderMutation_Action interface { - isHeaderMutation_Action() -} - -type HeaderMutation_RequestHeaderAdd struct { - RequestHeaderAdd *RequestHeaderAdd `protobuf:"bytes,1,opt,name=request_header_add,json=requestHeaderAdd,proto3,oneof"` -} - -type HeaderMutation_RequestHeaderRemove struct { - RequestHeaderRemove *RequestHeaderRemove `protobuf:"bytes,2,opt,name=request_header_remove,json=requestHeaderRemove,proto3,oneof"` -} - -type HeaderMutation_ResponseHeaderAdd struct { - ResponseHeaderAdd *ResponseHeaderAdd `protobuf:"bytes,3,opt,name=response_header_add,json=responseHeaderAdd,proto3,oneof"` -} - -type HeaderMutation_ResponseHeaderRemove struct { - ResponseHeaderRemove *ResponseHeaderRemove `protobuf:"bytes,4,opt,name=response_header_remove,json=responseHeaderRemove,proto3,oneof"` -} - -func (*HeaderMutation_RequestHeaderAdd) isHeaderMutation_Action() {} - -func (*HeaderMutation_RequestHeaderRemove) isHeaderMutation_Action() {} - -func (*HeaderMutation_ResponseHeaderAdd) isHeaderMutation_Action() {} - -func (*HeaderMutation_ResponseHeaderRemove) isHeaderMutation_Action() {} - -type RequestHeaderAdd struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Header *Header `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` - AppendAction AppendAction `protobuf:"varint,2,opt,name=append_action,json=appendAction,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.AppendAction" json:"append_action,omitempty"` -} - -func (x *RequestHeaderAdd) Reset() { - *x = RequestHeaderAdd{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RequestHeaderAdd) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RequestHeaderAdd) ProtoMessage() {} - -func (x *RequestHeaderAdd) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RequestHeaderAdd.ProtoReflect.Descriptor instead. -func (*RequestHeaderAdd) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescGZIP(), []int{1} -} - -func (x *RequestHeaderAdd) GetHeader() *Header { - if x != nil { - return x.Header - } - return nil -} - -func (x *RequestHeaderAdd) GetAppendAction() AppendAction { - if x != nil { - return x.AppendAction - } - return AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD -} - -type RequestHeaderRemove struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - HeaderKeys []string `protobuf:"bytes,1,rep,name=header_keys,json=headerKeys,proto3" json:"header_keys,omitempty"` -} - -func (x *RequestHeaderRemove) Reset() { - *x = RequestHeaderRemove{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RequestHeaderRemove) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RequestHeaderRemove) ProtoMessage() {} - -func (x *RequestHeaderRemove) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RequestHeaderRemove.ProtoReflect.Descriptor instead. -func (*RequestHeaderRemove) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescGZIP(), []int{2} -} - -func (x *RequestHeaderRemove) GetHeaderKeys() []string { - if x != nil { - return x.HeaderKeys - } - return nil -} - -type ResponseHeaderAdd struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Header *Header `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` - AppendAction AppendAction `protobuf:"varint,2,opt,name=append_action,json=appendAction,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.AppendAction" json:"append_action,omitempty"` -} - -func (x *ResponseHeaderAdd) Reset() { - *x = ResponseHeaderAdd{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResponseHeaderAdd) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResponseHeaderAdd) ProtoMessage() {} - -func (x *ResponseHeaderAdd) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResponseHeaderAdd.ProtoReflect.Descriptor instead. -func (*ResponseHeaderAdd) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescGZIP(), []int{3} -} - -func (x *ResponseHeaderAdd) GetHeader() *Header { - if x != nil { - return x.Header - } - return nil -} - -func (x *ResponseHeaderAdd) GetAppendAction() AppendAction { - if x != nil { - return x.AppendAction - } - return AppendAction_APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD -} - -type ResponseHeaderRemove struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - HeaderKeys []string `protobuf:"bytes,1,rep,name=header_keys,json=headerKeys,proto3" json:"header_keys,omitempty"` -} - -func (x *ResponseHeaderRemove) Reset() { - *x = ResponseHeaderRemove{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResponseHeaderRemove) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResponseHeaderRemove) ProtoMessage() {} - -func (x *ResponseHeaderRemove) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResponseHeaderRemove.ProtoReflect.Descriptor instead. -func (*ResponseHeaderRemove) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescGZIP(), []int{4} -} - -func (x *ResponseHeaderRemove) GetHeaderKeys() []string { - if x != nil { - return x.HeaderKeys - } - return nil -} - -type Header struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *Header) Reset() { - *x = Header{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Header) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Header) ProtoMessage() {} - -func (x *Header) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Header.ProtoReflect.Descriptor instead. -func (*Header) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescGZIP(), []int{5} -} - -func (x *Header) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *Header) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -var File_pbmesh_v2beta1_pbproxystate_header_mutations_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDesc = []byte{ - 0x0a, 0x32, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x22, 0xea, 0x03, 0x0a, 0x0e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x68, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x48, 0x00, 0x52, - 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x64, - 0x64, 0x12, 0x75, 0x0a, 0x15, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x48, 0x00, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x6f, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x41, 0x64, 0x64, 0x48, 0x00, 0x52, 0x11, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x12, 0x78, 0x0a, 0x16, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x48, 0x00, 0x52, 0x14, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xbd, 0x01, - 0x0a, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, - 0x64, 0x64, 0x12, 0x4a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x5d, - 0x0a, 0x0d, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x0c, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x36, 0x0a, - 0x13, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x4b, 0x65, 0x79, 0x73, 0x22, 0xbe, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, 0x12, 0x4a, 0x0a, 0x06, 0x68, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, - 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x5d, 0x0a, 0x0d, 0x61, 0x70, 0x70, 0x65, 0x6e, - 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x65, - 0x6e, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x37, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x22, - 0x30, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x2a, 0x67, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x29, 0x0a, 0x25, 0x41, 0x50, 0x50, 0x45, 0x4e, 0x44, 0x5f, 0x41, 0x43, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x41, 0x50, 0x50, 0x45, 0x4e, 0x44, 0x5f, 0x49, 0x46, 0x5f, 0x45, 0x58, 0x49, - 0x53, 0x54, 0x53, 0x5f, 0x4f, 0x52, 0x5f, 0x41, 0x44, 0x44, 0x10, 0x00, 0x12, 0x2c, 0x0a, 0x28, - 0x41, 0x50, 0x50, 0x45, 0x4e, 0x44, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4f, 0x56, - 0x45, 0x52, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x49, 0x46, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, - 0x53, 0x5f, 0x4f, 0x52, 0x5f, 0x41, 0x44, 0x44, 0x10, 0x01, 0x42, 0xda, 0x02, 0x0a, 0x2e, 0x63, - 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x14, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, - 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, - 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, - 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_goTypes = []interface{}{ - (AppendAction)(0), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.AppendAction - (*HeaderMutation)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation - (*RequestHeaderAdd)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.RequestHeaderAdd - (*RequestHeaderRemove)(nil), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.RequestHeaderRemove - (*ResponseHeaderAdd)(nil), // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.ResponseHeaderAdd - (*ResponseHeaderRemove)(nil), // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.ResponseHeaderRemove - (*Header)(nil), // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.Header -} -var file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_depIdxs = []int32{ - 2, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation.request_header_add:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.RequestHeaderAdd - 3, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation.request_header_remove:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.RequestHeaderRemove - 4, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation.response_header_add:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.ResponseHeaderAdd - 5, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation.response_header_remove:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.ResponseHeaderRemove - 6, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.RequestHeaderAdd.header:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Header - 0, // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.RequestHeaderAdd.append_action:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.AppendAction - 6, // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.ResponseHeaderAdd.header:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Header - 0, // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.ResponseHeaderAdd.append_action:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.AppendAction - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_header_mutations_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeaderMutation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RequestHeaderAdd); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RequestHeaderRemove); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResponseHeaderAdd); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResponseHeaderRemove); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Header); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*HeaderMutation_RequestHeaderAdd)(nil), - (*HeaderMutation_RequestHeaderRemove)(nil), - (*HeaderMutation_ResponseHeaderAdd)(nil), - (*HeaderMutation_ResponseHeaderRemove)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDesc, - NumEnums: 1, - NumMessages: 6, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_header_mutations_proto = out.File - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.proto b/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.proto deleted file mode 100644 index 63a4bf83f6cca..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations.proto +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -// Note: it's nice to have this list of header mutations as opposed to configuration similar to Envoy because it -// translates more nicely from GAMMA HTTPRoute, and our existing service router config. Then xds code can handle turning -// it into envoy xds. -message HeaderMutation { - oneof action { - RequestHeaderAdd request_header_add = 1; - RequestHeaderRemove request_header_remove = 2; - ResponseHeaderAdd response_header_add = 3; - ResponseHeaderRemove response_header_remove = 4; - } -} - -message RequestHeaderAdd { - Header header = 1; - AppendAction append_action = 2; -} - -message RequestHeaderRemove { - repeated string header_keys = 1; -} - -message ResponseHeaderAdd { - Header header = 1; - AppendAction append_action = 2; -} - -message ResponseHeaderRemove { - repeated string header_keys = 1; -} - -message Header { - string key = 1; - string value = 2; -} - -// +kubebuilder:validation:Enum=APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD;APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD -// +kubebuilder:validation:Type=string -enum AppendAction { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - APPEND_ACTION_APPEND_IF_EXISTS_OR_ADD = 0; - APPEND_ACTION_OVERWRITE_IF_EXISTS_OR_ADD = 1; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_deepcopy.gen.go deleted file mode 100644 index 97a77c7fc4029..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_deepcopy.gen.go +++ /dev/null @@ -1,132 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using HeaderMutation within kubernetes types, where deepcopy-gen is used. -func (in *HeaderMutation) DeepCopyInto(out *HeaderMutation) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMutation. Required by controller-gen. -func (in *HeaderMutation) DeepCopy() *HeaderMutation { - if in == nil { - return nil - } - out := new(HeaderMutation) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMutation. Required by controller-gen. -func (in *HeaderMutation) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using RequestHeaderAdd within kubernetes types, where deepcopy-gen is used. -func (in *RequestHeaderAdd) DeepCopyInto(out *RequestHeaderAdd) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestHeaderAdd. Required by controller-gen. -func (in *RequestHeaderAdd) DeepCopy() *RequestHeaderAdd { - if in == nil { - return nil - } - out := new(RequestHeaderAdd) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new RequestHeaderAdd. Required by controller-gen. -func (in *RequestHeaderAdd) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using RequestHeaderRemove within kubernetes types, where deepcopy-gen is used. -func (in *RequestHeaderRemove) DeepCopyInto(out *RequestHeaderRemove) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestHeaderRemove. Required by controller-gen. -func (in *RequestHeaderRemove) DeepCopy() *RequestHeaderRemove { - if in == nil { - return nil - } - out := new(RequestHeaderRemove) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new RequestHeaderRemove. Required by controller-gen. -func (in *RequestHeaderRemove) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ResponseHeaderAdd within kubernetes types, where deepcopy-gen is used. -func (in *ResponseHeaderAdd) DeepCopyInto(out *ResponseHeaderAdd) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResponseHeaderAdd. Required by controller-gen. -func (in *ResponseHeaderAdd) DeepCopy() *ResponseHeaderAdd { - if in == nil { - return nil - } - out := new(ResponseHeaderAdd) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ResponseHeaderAdd. Required by controller-gen. -func (in *ResponseHeaderAdd) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ResponseHeaderRemove within kubernetes types, where deepcopy-gen is used. -func (in *ResponseHeaderRemove) DeepCopyInto(out *ResponseHeaderRemove) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResponseHeaderRemove. Required by controller-gen. -func (in *ResponseHeaderRemove) DeepCopy() *ResponseHeaderRemove { - if in == nil { - return nil - } - out := new(ResponseHeaderRemove) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ResponseHeaderRemove. Required by controller-gen. -func (in *ResponseHeaderRemove) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Header within kubernetes types, where deepcopy-gen is used. -func (in *Header) DeepCopyInto(out *Header) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Header. Required by controller-gen. -func (in *Header) DeepCopy() *Header { - if in == nil { - return nil - } - out := new(Header) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Header. Required by controller-gen. -func (in *Header) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_json.gen.go deleted file mode 100644 index 53c422f75278c..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_json.gen.go +++ /dev/null @@ -1,77 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for HeaderMutation -func (this *HeaderMutation) MarshalJSON() ([]byte, error) { - str, err := HeaderMutationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HeaderMutation -func (this *HeaderMutation) UnmarshalJSON(b []byte) error { - return HeaderMutationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for RequestHeaderAdd -func (this *RequestHeaderAdd) MarshalJSON() ([]byte, error) { - str, err := HeaderMutationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for RequestHeaderAdd -func (this *RequestHeaderAdd) UnmarshalJSON(b []byte) error { - return HeaderMutationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for RequestHeaderRemove -func (this *RequestHeaderRemove) MarshalJSON() ([]byte, error) { - str, err := HeaderMutationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for RequestHeaderRemove -func (this *RequestHeaderRemove) UnmarshalJSON(b []byte) error { - return HeaderMutationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ResponseHeaderAdd -func (this *ResponseHeaderAdd) MarshalJSON() ([]byte, error) { - str, err := HeaderMutationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ResponseHeaderAdd -func (this *ResponseHeaderAdd) UnmarshalJSON(b []byte) error { - return HeaderMutationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ResponseHeaderRemove -func (this *ResponseHeaderRemove) MarshalJSON() ([]byte, error) { - str, err := HeaderMutationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ResponseHeaderRemove -func (this *ResponseHeaderRemove) UnmarshalJSON(b []byte) error { - return HeaderMutationsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Header -func (this *Header) MarshalJSON() ([]byte, error) { - str, err := HeaderMutationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Header -func (this *Header) UnmarshalJSON(b []byte) error { - return HeaderMutationsUnmarshaler.Unmarshal(b, this) -} - -var ( - HeaderMutationsMarshaler = &protojson.MarshalOptions{} - HeaderMutationsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/intentions.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/intentions.pb.go deleted file mode 100644 index 96ca59240fa45..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/intentions.pb.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/intentions.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type L7Intention struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *L7Intention) Reset() { - *x = L7Intention{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_intentions_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L7Intention) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L7Intention) ProtoMessage() {} - -func (x *L7Intention) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_intentions_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L7Intention.ProtoReflect.Descriptor instead. -func (*L7Intention) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescGZIP(), []int{0} -} - -type L4Intention struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *L4Intention) Reset() { - *x = L4Intention{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_intentions_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L4Intention) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L4Intention) ProtoMessage() {} - -func (x *L4Intention) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_intentions_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L4Intention.ProtoReflect.Descriptor instead. -func (*L4Intention) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescGZIP(), []int{1} -} - -var File_pbmesh_v2beta1_pbproxystate_intentions_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDesc = []byte{ - 0x0a, 0x2c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x37, - 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x34, 0x49, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0xd5, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0f, 0x49, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, - 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_intentions_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_pbmesh_v2beta1_pbproxystate_intentions_proto_goTypes = []interface{}{ - (*L7Intention)(nil), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.L7Intention - (*L4Intention)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.L4Intention -} -var file_pbmesh_v2beta1_pbproxystate_intentions_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_intentions_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_intentions_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_intentions_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_intentions_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L7Intention); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_intentions_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L4Intention); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_intentions_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_intentions_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_intentions_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_intentions_proto = out.File - file_pbmesh_v2beta1_pbproxystate_intentions_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_intentions_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_intentions_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/listener.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/listener.pb.go deleted file mode 100644 index a7d7273163dab..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/listener.pb.go +++ /dev/null @@ -1,1500 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/listener.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=DIRECTION_UNSPECIFIED;DIRECTION_INBOUND;DIRECTION_OUTBOUND -// +kubebuilder:validation:Type=string -type Direction int32 - -const ( - // DIRECTION_UNSPECIFIED is used by mesh gateway listeners. - Direction_DIRECTION_UNSPECIFIED Direction = 0 - Direction_DIRECTION_INBOUND Direction = 1 - Direction_DIRECTION_OUTBOUND Direction = 2 -) - -// Enum value maps for Direction. -var ( - Direction_name = map[int32]string{ - 0: "DIRECTION_UNSPECIFIED", - 1: "DIRECTION_INBOUND", - 2: "DIRECTION_OUTBOUND", - } - Direction_value = map[string]int32{ - "DIRECTION_UNSPECIFIED": 0, - "DIRECTION_INBOUND": 1, - "DIRECTION_OUTBOUND": 2, - } -) - -func (x Direction) Enum() *Direction { - p := new(Direction) - *p = x - return p -} - -func (x Direction) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Direction) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[0].Descriptor() -} - -func (Direction) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[0] -} - -func (x Direction) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Direction.Descriptor instead. -func (Direction) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{0} -} - -// +kubebuilder:validation:Enum=BALANCE_CONNECTIONS_DEFAULT;BALANCE_CONNECTIONS_EXACT -// +kubebuilder:validation:Type=string -type BalanceConnections int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - BalanceConnections_BALANCE_CONNECTIONS_DEFAULT BalanceConnections = 0 - BalanceConnections_BALANCE_CONNECTIONS_EXACT BalanceConnections = 1 -) - -// Enum value maps for BalanceConnections. -var ( - BalanceConnections_name = map[int32]string{ - 0: "BALANCE_CONNECTIONS_DEFAULT", - 1: "BALANCE_CONNECTIONS_EXACT", - } - BalanceConnections_value = map[string]int32{ - "BALANCE_CONNECTIONS_DEFAULT": 0, - "BALANCE_CONNECTIONS_EXACT": 1, - } -) - -func (x BalanceConnections) Enum() *BalanceConnections { - p := new(BalanceConnections) - *p = x - return p -} - -func (x BalanceConnections) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (BalanceConnections) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[1].Descriptor() -} - -func (BalanceConnections) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[1] -} - -func (x BalanceConnections) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use BalanceConnections.Descriptor instead. -func (BalanceConnections) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{1} -} - -// Capabilities map to proxy functionality to enable. These enable tproxy, l7 protocol/alpn inspection, or l4 sni/alpn inspection. -// -// +kubebuilder:validation:Enum=CAPABILITY_TRANSPARENT;CAPABILITY_L7_PROTOCOL_INSPECTION;CAPABILITY_L4_TLS_INSPECTION -// +kubebuilder:validation:Type=string -type Capability int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - Capability_CAPABILITY_TRANSPARENT Capability = 0 - Capability_CAPABILITY_L7_PROTOCOL_INSPECTION Capability = 1 - Capability_CAPABILITY_L4_TLS_INSPECTION Capability = 2 -) - -// Enum value maps for Capability. -var ( - Capability_name = map[int32]string{ - 0: "CAPABILITY_TRANSPARENT", - 1: "CAPABILITY_L7_PROTOCOL_INSPECTION", - 2: "CAPABILITY_L4_TLS_INSPECTION", - } - Capability_value = map[string]int32{ - "CAPABILITY_TRANSPARENT": 0, - "CAPABILITY_L7_PROTOCOL_INSPECTION": 1, - "CAPABILITY_L4_TLS_INSPECTION": 2, - } -) - -func (x Capability) Enum() *Capability { - p := new(Capability) - *p = x - return p -} - -func (x Capability) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Capability) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[2].Descriptor() -} - -func (Capability) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[2] -} - -func (x Capability) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Capability.Descriptor instead. -func (Capability) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{2} -} - -// +kubebuilder:validation:Enum=XFCC_POLICY_SANITIZE;XFCC_POLICY_FORWARD_ONLY;XFCC_POLICY_APPEND_FORWARD;XFCC_POLICY_SANITIZE_SET;XFCC_POLICY_ALWAYS_FORWARD_ONLY -// +kubebuilder:validation:Type=string -type XFCCPolicy int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - // Do not send the XFCC header to the next hop. This is the default value. - XFCCPolicy_XFCC_POLICY_SANITIZE XFCCPolicy = 0 - // When the client connection is mTLS (Mutual TLS), forward the XFCC header - // in the request. - XFCCPolicy_XFCC_POLICY_FORWARD_ONLY XFCCPolicy = 1 - // When the client connection is mTLS, append the client certificate - // information to the request’s XFCC header and forward it. - XFCCPolicy_XFCC_POLICY_APPEND_FORWARD XFCCPolicy = 2 - // When the client connection is mTLS, reset the XFCC header with the client - // certificate information and send it to the next hop. - XFCCPolicy_XFCC_POLICY_SANITIZE_SET XFCCPolicy = 3 - // Always forward the XFCC header in the request, regardless of whether the - // client connection is mTLS. - XFCCPolicy_XFCC_POLICY_ALWAYS_FORWARD_ONLY XFCCPolicy = 4 -) - -// Enum value maps for XFCCPolicy. -var ( - XFCCPolicy_name = map[int32]string{ - 0: "XFCC_POLICY_SANITIZE", - 1: "XFCC_POLICY_FORWARD_ONLY", - 2: "XFCC_POLICY_APPEND_FORWARD", - 3: "XFCC_POLICY_SANITIZE_SET", - 4: "XFCC_POLICY_ALWAYS_FORWARD_ONLY", - } - XFCCPolicy_value = map[string]int32{ - "XFCC_POLICY_SANITIZE": 0, - "XFCC_POLICY_FORWARD_ONLY": 1, - "XFCC_POLICY_APPEND_FORWARD": 2, - "XFCC_POLICY_SANITIZE_SET": 3, - "XFCC_POLICY_ALWAYS_FORWARD_ONLY": 4, - } -) - -func (x XFCCPolicy) Enum() *XFCCPolicy { - p := new(XFCCPolicy) - *p = x - return p -} - -func (x XFCCPolicy) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (XFCCPolicy) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[3].Descriptor() -} - -func (XFCCPolicy) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[3] -} - -func (x XFCCPolicy) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use XFCCPolicy.Descriptor instead. -func (XFCCPolicy) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{3} -} - -// +kubebuilder:validation:Enum=L7_PROTOCOL_HTTP;L7_PROTOCOL_HTTP2;L7_PROTOCOL_GRPC -// +kubebuilder:validation:Type=string -type L7Protocol int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - L7Protocol_L7_PROTOCOL_HTTP L7Protocol = 0 - L7Protocol_L7_PROTOCOL_HTTP2 L7Protocol = 1 - L7Protocol_L7_PROTOCOL_GRPC L7Protocol = 2 -) - -// Enum value maps for L7Protocol. -var ( - L7Protocol_name = map[int32]string{ - 0: "L7_PROTOCOL_HTTP", - 1: "L7_PROTOCOL_HTTP2", - 2: "L7_PROTOCOL_GRPC", - } - L7Protocol_value = map[string]int32{ - "L7_PROTOCOL_HTTP": 0, - "L7_PROTOCOL_HTTP2": 1, - "L7_PROTOCOL_GRPC": 2, - } -) - -func (x L7Protocol) Enum() *L7Protocol { - p := new(L7Protocol) - *p = x - return p -} - -func (x L7Protocol) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (L7Protocol) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[4].Descriptor() -} - -func (L7Protocol) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes[4] -} - -func (x L7Protocol) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use L7Protocol.Descriptor instead. -func (L7Protocol) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{4} -} - -type Listener struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name is the name of the listener. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // direction tells the listener the direction of traffic. - Direction Direction `protobuf:"varint,2,opt,name=direction,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.Direction" json:"direction,omitempty"` - // bind_address describes where to listen. - // - // Types that are assignable to BindAddress: - // - // *Listener_HostPort - // *Listener_UnixSocket - BindAddress isListener_BindAddress `protobuf_oneof:"bind_address"` - // routers describes how to route traffic from this listener. - Routers []*Router `protobuf:"bytes,5,rep,name=routers,proto3" json:"routers,omitempty"` - // default_router describes where to route if none of the other router matches match the connection. - DefaultRouter *Router `protobuf:"bytes,6,opt,name=default_router,json=defaultRouter,proto3" json:"default_router,omitempty"` - // capabilities describe Envoy proxy functionality to enable. These map closely to Envoy listener filters. - Capabilities []Capability `protobuf:"varint,7,rep,packed,name=capabilities,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.Capability" json:"capabilities,omitempty"` - // balance_connections configures how the listener should balance connections. - BalanceConnections BalanceConnections `protobuf:"varint,8,opt,name=balance_connections,json=balanceConnections,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.BalanceConnections" json:"balance_connections,omitempty"` - // escape_hatch_listener_json configures a user configured escape hatch listener. - EscapeHatchListener string `protobuf:"bytes,9,opt,name=escape_hatch_listener,json=escapeHatchListener,proto3" json:"escape_hatch_listener,omitempty"` - // use_escape_hatch_tracing configures whether to use the top level user configured tracing escape hatch for this listener. - UseEscapeHatchTracing bool `protobuf:"varint,10,opt,name=use_escape_hatch_tracing,json=useEscapeHatchTracing,proto3" json:"use_escape_hatch_tracing,omitempty"` -} - -func (x *Listener) Reset() { - *x = Listener{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Listener) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Listener) ProtoMessage() {} - -func (x *Listener) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Listener.ProtoReflect.Descriptor instead. -func (*Listener) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{0} -} - -func (x *Listener) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Listener) GetDirection() Direction { - if x != nil { - return x.Direction - } - return Direction_DIRECTION_UNSPECIFIED -} - -func (m *Listener) GetBindAddress() isListener_BindAddress { - if m != nil { - return m.BindAddress - } - return nil -} - -func (x *Listener) GetHostPort() *HostPortAddress { - if x, ok := x.GetBindAddress().(*Listener_HostPort); ok { - return x.HostPort - } - return nil -} - -func (x *Listener) GetUnixSocket() *UnixSocketAddress { - if x, ok := x.GetBindAddress().(*Listener_UnixSocket); ok { - return x.UnixSocket - } - return nil -} - -func (x *Listener) GetRouters() []*Router { - if x != nil { - return x.Routers - } - return nil -} - -func (x *Listener) GetDefaultRouter() *Router { - if x != nil { - return x.DefaultRouter - } - return nil -} - -func (x *Listener) GetCapabilities() []Capability { - if x != nil { - return x.Capabilities - } - return nil -} - -func (x *Listener) GetBalanceConnections() BalanceConnections { - if x != nil { - return x.BalanceConnections - } - return BalanceConnections_BALANCE_CONNECTIONS_DEFAULT -} - -func (x *Listener) GetEscapeHatchListener() string { - if x != nil { - return x.EscapeHatchListener - } - return "" -} - -func (x *Listener) GetUseEscapeHatchTracing() bool { - if x != nil { - return x.UseEscapeHatchTracing - } - return false -} - -type isListener_BindAddress interface { - isListener_BindAddress() -} - -type Listener_HostPort struct { - HostPort *HostPortAddress `protobuf:"bytes,3,opt,name=host_port,json=hostPort,proto3,oneof"` -} - -type Listener_UnixSocket struct { - UnixSocket *UnixSocketAddress `protobuf:"bytes,4,opt,name=unix_socket,json=unixSocket,proto3,oneof"` -} - -func (*Listener_HostPort) isListener_BindAddress() {} - -func (*Listener_UnixSocket) isListener_BindAddress() {} - -type Router struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // match specifies how to match traffic coming into this listener. If the traffic matches, it will be routed to the - // destination. - Match *Match `protobuf:"bytes,1,opt,name=match,proto3" json:"match,omitempty"` - // Types that are assignable to Destination: - // - // *Router_L4 - // *Router_L7 - // *Router_Sni - Destination isRouter_Destination `protobuf_oneof:"destination"` - // inbound_tls is used by inbound listeners that terminate TLS. - InboundTls *TransportSocket `protobuf:"bytes,5,opt,name=inbound_tls,json=inboundTls,proto3" json:"inbound_tls,omitempty"` -} - -func (x *Router) Reset() { - *x = Router{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Router) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Router) ProtoMessage() {} - -func (x *Router) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Router.ProtoReflect.Descriptor instead. -func (*Router) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{1} -} - -func (x *Router) GetMatch() *Match { - if x != nil { - return x.Match - } - return nil -} - -func (m *Router) GetDestination() isRouter_Destination { - if m != nil { - return m.Destination - } - return nil -} - -func (x *Router) GetL4() *L4Destination { - if x, ok := x.GetDestination().(*Router_L4); ok { - return x.L4 - } - return nil -} - -func (x *Router) GetL7() *L7Destination { - if x, ok := x.GetDestination().(*Router_L7); ok { - return x.L7 - } - return nil -} - -func (x *Router) GetSni() *SNIDestination { - if x, ok := x.GetDestination().(*Router_Sni); ok { - return x.Sni - } - return nil -} - -func (x *Router) GetInboundTls() *TransportSocket { - if x != nil { - return x.InboundTls - } - return nil -} - -type isRouter_Destination interface { - isRouter_Destination() -} - -type Router_L4 struct { - // l4 is an l4 destination to route to, which will have a reference to a cluster. - L4 *L4Destination `protobuf:"bytes,2,opt,name=l4,proto3,oneof"` -} - -type Router_L7 struct { - // l7 is an l7 destination to route to, which will have a reference to a route. - L7 *L7Destination `protobuf:"bytes,3,opt,name=l7,proto3,oneof"` -} - -type Router_Sni struct { - // sni is an SNI destination, which means there will be no references, but the SNI name will be tied to the cluster - // name, so we should generate all clusters. - Sni *SNIDestination `protobuf:"bytes,4,opt,name=sni,proto3,oneof"` -} - -func (*Router_L4) isRouter_Destination() {} - -func (*Router_L7) isRouter_Destination() {} - -func (*Router_Sni) isRouter_Destination() {} - -type Match struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AlpnProtocols []string `protobuf:"bytes,1,rep,name=alpn_protocols,json=alpnProtocols,proto3" json:"alpn_protocols,omitempty"` - DestinationPort *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=destination_port,json=destinationPort,proto3" json:"destination_port,omitempty"` - PrefixRanges []*CidrRange `protobuf:"bytes,3,rep,name=prefix_ranges,json=prefixRanges,proto3" json:"prefix_ranges,omitempty"` - SourcePrefixRanges []*CidrRange `protobuf:"bytes,4,rep,name=source_prefix_ranges,json=sourcePrefixRanges,proto3" json:"source_prefix_ranges,omitempty"` - // server_names matches based on SNI of the incoming request. - ServerNames []string `protobuf:"bytes,5,rep,name=server_names,json=serverNames,proto3" json:"server_names,omitempty"` -} - -func (x *Match) Reset() { - *x = Match{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Match) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Match) ProtoMessage() {} - -func (x *Match) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Match.ProtoReflect.Descriptor instead. -func (*Match) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{2} -} - -func (x *Match) GetAlpnProtocols() []string { - if x != nil { - return x.AlpnProtocols - } - return nil -} - -func (x *Match) GetDestinationPort() *wrapperspb.UInt32Value { - if x != nil { - return x.DestinationPort - } - return nil -} - -func (x *Match) GetPrefixRanges() []*CidrRange { - if x != nil { - return x.PrefixRanges - } - return nil -} - -func (x *Match) GetSourcePrefixRanges() []*CidrRange { - if x != nil { - return x.SourcePrefixRanges - } - return nil -} - -func (x *Match) GetServerNames() []string { - if x != nil { - return x.ServerNames - } - return nil -} - -type CidrRange struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AddressPrefix string `protobuf:"bytes,1,opt,name=address_prefix,json=addressPrefix,proto3" json:"address_prefix,omitempty"` - PrefixLen *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=prefix_len,json=prefixLen,proto3" json:"prefix_len,omitempty"` -} - -func (x *CidrRange) Reset() { - *x = CidrRange{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CidrRange) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CidrRange) ProtoMessage() {} - -func (x *CidrRange) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CidrRange.ProtoReflect.Descriptor instead. -func (*CidrRange) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{3} -} - -func (x *CidrRange) GetAddressPrefix() string { - if x != nil { - return x.AddressPrefix - } - return "" -} - -func (x *CidrRange) GetPrefixLen() *wrapperspb.UInt32Value { - if x != nil { - return x.PrefixLen - } - return nil -} - -type L4Destination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // destination is one or more clusters to route to. - // - // Types that are assignable to Destination: - // - // *L4Destination_Cluster - // *L4Destination_WeightedClusters - Destination isL4Destination_Destination `protobuf_oneof:"destination"` - // stat_prefix is for compatibility with v1 xds configuration, so it is generated in exactly the same way. - StatPrefix string `protobuf:"bytes,3,opt,name=stat_prefix,json=statPrefix,proto3" json:"stat_prefix,omitempty"` - // traffic_permissions is a list of traffic permissions for this destination. - TrafficPermissions *TrafficPermissions `protobuf:"bytes,4,opt,name=traffic_permissions,json=trafficPermissions,proto3" json:"traffic_permissions,omitempty"` - // max_inbound_connections specifies how many connections this destination can accept. - MaxInboundConnections uint64 `protobuf:"varint,5,opt,name=max_inbound_connections,json=maxInboundConnections,proto3" json:"max_inbound_connections,omitempty"` -} - -func (x *L4Destination) Reset() { - *x = L4Destination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L4Destination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L4Destination) ProtoMessage() {} - -func (x *L4Destination) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L4Destination.ProtoReflect.Descriptor instead. -func (*L4Destination) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{4} -} - -func (m *L4Destination) GetDestination() isL4Destination_Destination { - if m != nil { - return m.Destination - } - return nil -} - -func (x *L4Destination) GetCluster() *DestinationCluster { - if x, ok := x.GetDestination().(*L4Destination_Cluster); ok { - return x.Cluster - } - return nil -} - -func (x *L4Destination) GetWeightedClusters() *L4WeightedClusterGroup { - if x, ok := x.GetDestination().(*L4Destination_WeightedClusters); ok { - return x.WeightedClusters - } - return nil -} - -func (x *L4Destination) GetStatPrefix() string { - if x != nil { - return x.StatPrefix - } - return "" -} - -func (x *L4Destination) GetTrafficPermissions() *TrafficPermissions { - if x != nil { - return x.TrafficPermissions - } - return nil -} - -func (x *L4Destination) GetMaxInboundConnections() uint64 { - if x != nil { - return x.MaxInboundConnections - } - return 0 -} - -type isL4Destination_Destination interface { - isL4Destination_Destination() -} - -type L4Destination_Cluster struct { - Cluster *DestinationCluster `protobuf:"bytes,1,opt,name=cluster,proto3,oneof"` -} - -type L4Destination_WeightedClusters struct { - WeightedClusters *L4WeightedClusterGroup `protobuf:"bytes,2,opt,name=weighted_clusters,json=weightedClusters,proto3,oneof"` -} - -func (*L4Destination_Cluster) isL4Destination_Destination() {} - -func (*L4Destination_WeightedClusters) isL4Destination_Destination() {} - -type L7DestinationRoute struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name is a key in the top level routes map. This specifies which route to go to in this L7 destination. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *L7DestinationRoute) Reset() { - *x = L7DestinationRoute{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L7DestinationRoute) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L7DestinationRoute) ProtoMessage() {} - -func (x *L7DestinationRoute) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L7DestinationRoute.ProtoReflect.Descriptor instead. -func (*L7DestinationRoute) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{5} -} - -func (x *L7DestinationRoute) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type L7Destination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // route specifies which route to go to in this L7 destination. - Route *L7DestinationRoute `protobuf:"bytes,1,opt,name=route,proto3" json:"route,omitempty"` - // stat_prefix is for compatibility with v1 xds configuration, so it is generated in exactly the same way. - StatPrefix string `protobuf:"bytes,2,opt,name=stat_prefix,json=statPrefix,proto3" json:"stat_prefix,omitempty"` - // protocol for the destination. - Protocol L7Protocol `protobuf:"varint,3,opt,name=protocol,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.L7Protocol" json:"protocol,omitempty"` - // traffic_permissions is a list of intentions for this destination. - TrafficPermissions *TrafficPermissions `protobuf:"bytes,4,opt,name=traffic_permissions,json=trafficPermissions,proto3" json:"traffic_permissions,omitempty"` - // include_xfcc specifies whether to add an xfcc policy for handling xfcc headers. - IncludeXfccPolicy bool `protobuf:"varint,5,opt,name=include_xfcc_policy,json=includeXfccPolicy,proto3" json:"include_xfcc_policy,omitempty"` - // xfcc_policy determines how to handle xfcc headers. - XfccPolicy XFCCPolicy `protobuf:"varint,6,opt,name=xfcc_policy,json=xfccPolicy,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.XFCCPolicy" json:"xfcc_policy,omitempty"` - // parse_xfcc_headers determines whether to add filters to parse xfcc headers on incoming connections. - ParseXfccHeaders bool `protobuf:"varint,7,opt,name=parse_xfcc_headers,json=parseXfccHeaders,proto3" json:"parse_xfcc_headers,omitempty"` - // static_route specifies whether this is a static route that is inlined in the listener filter. This is required to - // match existing xds config. - StaticRoute bool `protobuf:"varint,8,opt,name=static_route,json=staticRoute,proto3" json:"static_route,omitempty"` - // max_inbound_connections specifies how many connections this destination can accept. - MaxInboundConnections uint64 `protobuf:"varint,9,opt,name=max_inbound_connections,json=maxInboundConnections,proto3" json:"max_inbound_connections,omitempty"` -} - -func (x *L7Destination) Reset() { - *x = L7Destination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *L7Destination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*L7Destination) ProtoMessage() {} - -func (x *L7Destination) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use L7Destination.ProtoReflect.Descriptor instead. -func (*L7Destination) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{6} -} - -func (x *L7Destination) GetRoute() *L7DestinationRoute { - if x != nil { - return x.Route - } - return nil -} - -func (x *L7Destination) GetStatPrefix() string { - if x != nil { - return x.StatPrefix - } - return "" -} - -func (x *L7Destination) GetProtocol() L7Protocol { - if x != nil { - return x.Protocol - } - return L7Protocol_L7_PROTOCOL_HTTP -} - -func (x *L7Destination) GetTrafficPermissions() *TrafficPermissions { - if x != nil { - return x.TrafficPermissions - } - return nil -} - -func (x *L7Destination) GetIncludeXfccPolicy() bool { - if x != nil { - return x.IncludeXfccPolicy - } - return false -} - -func (x *L7Destination) GetXfccPolicy() XFCCPolicy { - if x != nil { - return x.XfccPolicy - } - return XFCCPolicy_XFCC_POLICY_SANITIZE -} - -func (x *L7Destination) GetParseXfccHeaders() bool { - if x != nil { - return x.ParseXfccHeaders - } - return false -} - -func (x *L7Destination) GetStaticRoute() bool { - if x != nil { - return x.StaticRoute - } - return false -} - -func (x *L7Destination) GetMaxInboundConnections() uint64 { - if x != nil { - return x.MaxInboundConnections - } - return 0 -} - -type SNIDestination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // stat_prefix is for compatibility with v1 xds configuration, so it is generated in exactly the same way. - StatPrefix string `protobuf:"bytes,1,opt,name=stat_prefix,json=statPrefix,proto3" json:"stat_prefix,omitempty"` -} - -func (x *SNIDestination) Reset() { - *x = SNIDestination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SNIDestination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SNIDestination) ProtoMessage() {} - -func (x *SNIDestination) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SNIDestination.ProtoReflect.Descriptor instead. -func (*SNIDestination) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP(), []int{7} -} - -func (x *SNIDestination) GetStatPrefix() string { - if x != nil { - return x.StatPrefix - } - return "" -} - -var File_pbmesh_v2beta1_pbproxystate_listener_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDesc = []byte{ - 0x0a, 0x2a, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x35, - 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x66, - 0x66, 0x69, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x06, 0x0a, 0x08, 0x4c, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x53, 0x0a, 0x09, 0x64, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x5a, 0x0a, 0x09, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x48, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, - 0x00, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x60, 0x0a, 0x0b, 0x75, - 0x6e, 0x69, 0x78, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x3d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x6e, - 0x69, 0x78, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, - 0x00, 0x52, 0x0a, 0x75, 0x6e, 0x69, 0x78, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x4c, 0x0a, - 0x07, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x52, 0x07, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x73, 0x12, 0x59, 0x0a, 0x0e, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x63, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, - 0x65, 0x73, 0x12, 0x6f, 0x0a, 0x13, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x12, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x5f, 0x68, 0x61, - 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x13, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, 0x74, 0x63, 0x68, 0x4c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x18, 0x75, 0x73, 0x65, 0x5f, 0x65, - 0x73, 0x63, 0x61, 0x70, 0x65, 0x5f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x74, 0x72, 0x61, 0x63, - 0x69, 0x6e, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x75, 0x73, 0x65, 0x45, 0x73, - 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, 0x74, 0x63, 0x68, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, - 0x42, 0x0e, 0x0a, 0x0c, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x22, 0xa8, 0x03, 0x0a, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x12, 0x47, 0x0a, 0x05, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x12, 0x4b, 0x0a, 0x02, 0x6c, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x34, - 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x02, 0x6c, - 0x34, 0x12, 0x4b, 0x0a, 0x02, 0x6c, 0x37, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x37, 0x44, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x02, 0x6c, 0x37, 0x12, 0x4e, - 0x0a, 0x03, 0x73, 0x6e, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x4e, 0x49, 0x44, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x03, 0x73, 0x6e, 0x69, 0x12, 0x5c, - 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, - 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x6c, 0x73, 0x42, 0x0d, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xdf, 0x02, 0x0a, 0x05, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x61, - 0x6c, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x10, - 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x5a, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, 0x64, 0x72, 0x52, 0x61, - 0x6e, 0x67, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x73, 0x12, 0x67, 0x0a, 0x14, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, - 0x69, 0x78, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, 0x64, - 0x72, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x12, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x6f, 0x0a, - 0x09, 0x43, 0x69, 0x64, 0x72, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, - 0x78, 0x12, 0x3b, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x09, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x4c, 0x65, 0x6e, 0x22, 0xb7, - 0x03, 0x0a, 0x0d, 0x4c, 0x34, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x5a, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x71, 0x0a, 0x11, - 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x34, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x10, 0x77, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, - 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x12, 0x6f, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, - 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, - 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, - 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x36, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x28, 0x0a, 0x12, 0x4c, 0x37, 0x44, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0xdd, 0x04, 0x0a, 0x0d, 0x4c, 0x37, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x4c, 0x37, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, - 0x61, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x73, 0x74, 0x61, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x52, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x37, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, - 0x6f, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, - 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, - 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x78, 0x66, 0x63, 0x63, - 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x58, 0x66, 0x63, 0x63, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x12, 0x57, 0x0a, 0x0b, 0x78, 0x66, 0x63, 0x63, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x58, 0x46, 0x43, 0x43, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0a, 0x78, - 0x66, 0x63, 0x63, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x61, 0x72, - 0x73, 0x65, 0x5f, 0x78, 0x66, 0x63, 0x63, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x70, 0x61, 0x72, 0x73, 0x65, 0x58, 0x66, 0x63, 0x63, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x6d, 0x61, - 0x78, 0x5f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x6d, 0x61, 0x78, - 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0x31, 0x0a, 0x0e, 0x53, 0x4e, 0x49, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x70, 0x72, 0x65, - 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x50, - 0x72, 0x65, 0x66, 0x69, 0x78, 0x2a, 0x55, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, - 0x11, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x42, 0x4f, 0x55, - 0x4e, 0x44, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x4f, 0x55, 0x54, 0x42, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x2a, 0x54, 0x0a, 0x12, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x43, 0x4f, - 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, - 0x54, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x43, - 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x5f, 0x45, 0x58, 0x41, 0x43, 0x54, - 0x10, 0x01, 0x2a, 0x71, 0x0a, 0x0a, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x41, 0x50, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x54, - 0x52, 0x41, 0x4e, 0x53, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x25, 0x0a, 0x21, - 0x43, 0x41, 0x50, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x4c, 0x37, 0x5f, 0x50, 0x52, - 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x49, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x54, 0x49, 0x4f, - 0x4e, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x41, 0x50, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, - 0x59, 0x5f, 0x4c, 0x34, 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x49, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x54, - 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x2a, 0xa7, 0x01, 0x0a, 0x0a, 0x58, 0x46, 0x43, 0x43, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x12, 0x18, 0x0a, 0x14, 0x58, 0x46, 0x43, 0x43, 0x5f, 0x50, 0x4f, 0x4c, - 0x49, 0x43, 0x59, 0x5f, 0x53, 0x41, 0x4e, 0x49, 0x54, 0x49, 0x5a, 0x45, 0x10, 0x00, 0x12, 0x1c, - 0x0a, 0x18, 0x58, 0x46, 0x43, 0x43, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x46, 0x4f, - 0x52, 0x57, 0x41, 0x52, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, - 0x58, 0x46, 0x43, 0x43, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x41, 0x50, 0x50, 0x45, - 0x4e, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x57, 0x41, 0x52, 0x44, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, - 0x58, 0x46, 0x43, 0x43, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x53, 0x41, 0x4e, 0x49, - 0x54, 0x49, 0x5a, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x03, 0x12, 0x23, 0x0a, 0x1f, 0x58, 0x46, - 0x43, 0x43, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x41, 0x4c, 0x57, 0x41, 0x59, 0x53, - 0x5f, 0x46, 0x4f, 0x52, 0x57, 0x41, 0x52, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x04, 0x2a, - 0x4f, 0x0a, 0x0a, 0x4c, 0x37, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x14, 0x0a, - 0x10, 0x4c, 0x37, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, - 0x50, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x37, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, - 0x4f, 0x4c, 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4c, 0x37, - 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x02, - 0x42, 0xd3, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x42, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, - 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, - 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, - 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, - 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, - 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, - 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_pbmesh_v2beta1_pbproxystate_listener_proto_goTypes = []interface{}{ - (Direction)(0), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Direction - (BalanceConnections)(0), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.BalanceConnections - (Capability)(0), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Capability - (XFCCPolicy)(0), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.XFCCPolicy - (L7Protocol)(0), // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.L7Protocol - (*Listener)(nil), // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener - (*Router)(nil), // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.Router - (*Match)(nil), // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.Match - (*CidrRange)(nil), // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.CidrRange - (*L4Destination)(nil), // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.L4Destination - (*L7DestinationRoute)(nil), // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.L7DestinationRoute - (*L7Destination)(nil), // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.L7Destination - (*SNIDestination)(nil), // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.SNIDestination - (*HostPortAddress)(nil), // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.HostPortAddress - (*UnixSocketAddress)(nil), // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.UnixSocketAddress - (*TransportSocket)(nil), // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - (*wrapperspb.UInt32Value)(nil), // 16: google.protobuf.UInt32Value - (*DestinationCluster)(nil), // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationCluster - (*L4WeightedClusterGroup)(nil), // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedClusterGroup - (*TrafficPermissions)(nil), // 19: hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions -} -var file_pbmesh_v2beta1_pbproxystate_listener_proto_depIdxs = []int32{ - 0, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener.direction:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Direction - 13, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener.host_port:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HostPortAddress - 14, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener.unix_socket:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UnixSocketAddress - 6, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener.routers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Router - 6, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener.default_router:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Router - 2, // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener.capabilities:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Capability - 1, // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener.balance_connections:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.BalanceConnections - 7, // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.Router.match:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Match - 9, // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.Router.l4:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L4Destination - 11, // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.Router.l7:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L7Destination - 12, // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.Router.sni:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.SNIDestination - 15, // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.Router.inbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - 16, // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.Match.destination_port:type_name -> google.protobuf.UInt32Value - 8, // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.Match.prefix_ranges:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CidrRange - 8, // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.Match.source_prefix_ranges:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CidrRange - 16, // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.CidrRange.prefix_len:type_name -> google.protobuf.UInt32Value - 17, // 16: hashicorp.consul.mesh.v2beta1.pbproxystate.L4Destination.cluster:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationCluster - 18, // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.L4Destination.weighted_clusters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedClusterGroup - 19, // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.L4Destination.traffic_permissions:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions - 10, // 19: hashicorp.consul.mesh.v2beta1.pbproxystate.L7Destination.route:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L7DestinationRoute - 4, // 20: hashicorp.consul.mesh.v2beta1.pbproxystate.L7Destination.protocol:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L7Protocol - 19, // 21: hashicorp.consul.mesh.v2beta1.pbproxystate.L7Destination.traffic_permissions:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions - 3, // 22: hashicorp.consul.mesh.v2beta1.pbproxystate.L7Destination.xfcc_policy:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.XFCCPolicy - 23, // [23:23] is the sub-list for method output_type - 23, // [23:23] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_listener_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_listener_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_listener_proto != nil { - return - } - file_pbmesh_v2beta1_pbproxystate_address_proto_init() - file_pbmesh_v2beta1_pbproxystate_cluster_proto_init() - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_init() - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Listener); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Router); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Match); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CidrRange); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L4Destination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L7DestinationRoute); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*L7Destination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SNIDestination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*Listener_HostPort)(nil), - (*Listener_UnixSocket)(nil), - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[1].OneofWrappers = []interface{}{ - (*Router_L4)(nil), - (*Router_L7)(nil), - (*Router_Sni)(nil), - } - file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes[4].OneofWrappers = []interface{}{ - (*L4Destination_Cluster)(nil), - (*L4Destination_WeightedClusters)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDesc, - NumEnums: 5, - NumMessages: 8, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_listener_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_listener_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_pbproxystate_listener_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_listener_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_listener_proto = out.File - file_pbmesh_v2beta1_pbproxystate_listener_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_listener_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_listener_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/listener.proto b/proto-public/pbmesh/v2beta1/pbproxystate/listener.proto deleted file mode 100644 index 95ba97556b9d2..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/listener.proto +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -import "google/protobuf/wrappers.proto"; -import "pbmesh/v2beta1/pbproxystate/address.proto"; -import "pbmesh/v2beta1/pbproxystate/cluster.proto"; -import "pbmesh/v2beta1/pbproxystate/traffic_permissions.proto"; -import "pbmesh/v2beta1/pbproxystate/transport_socket.proto"; - -message Listener { - // name is the name of the listener. - string name = 1; - // direction tells the listener the direction of traffic. - Direction direction = 2; - // bind_address describes where to listen. - oneof bind_address { - HostPortAddress host_port = 3; - UnixSocketAddress unix_socket = 4; - } - - // routers describes how to route traffic from this listener. - repeated Router routers = 5; - // default_router describes where to route if none of the other router matches match the connection. - Router default_router = 6; - // capabilities describe Envoy proxy functionality to enable. These map closely to Envoy listener filters. - repeated Capability capabilities = 7; - // balance_connections configures how the listener should balance connections. - BalanceConnections balance_connections = 8; - // escape_hatch_listener_json configures a user configured escape hatch listener. - string escape_hatch_listener = 9; - // use_escape_hatch_tracing configures whether to use the top level user configured tracing escape hatch for this listener. - bool use_escape_hatch_tracing = 10; -} - -// +kubebuilder:validation:Enum=DIRECTION_UNSPECIFIED;DIRECTION_INBOUND;DIRECTION_OUTBOUND -// +kubebuilder:validation:Type=string -enum Direction { - // DIRECTION_UNSPECIFIED is used by mesh gateway listeners. - DIRECTION_UNSPECIFIED = 0; - DIRECTION_INBOUND = 1; - DIRECTION_OUTBOUND = 2; -} - -// +kubebuilder:validation:Enum=BALANCE_CONNECTIONS_DEFAULT;BALANCE_CONNECTIONS_EXACT -// +kubebuilder:validation:Type=string -enum BalanceConnections { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - BALANCE_CONNECTIONS_DEFAULT = 0; - BALANCE_CONNECTIONS_EXACT = 1; -} - -// Capabilities map to proxy functionality to enable. These enable tproxy, l7 protocol/alpn inspection, or l4 sni/alpn inspection. -// -// +kubebuilder:validation:Enum=CAPABILITY_TRANSPARENT;CAPABILITY_L7_PROTOCOL_INSPECTION;CAPABILITY_L4_TLS_INSPECTION -// +kubebuilder:validation:Type=string -enum Capability { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - CAPABILITY_TRANSPARENT = 0; - CAPABILITY_L7_PROTOCOL_INSPECTION = 1; - CAPABILITY_L4_TLS_INSPECTION = 2; -} - -message Router { - // match specifies how to match traffic coming into this listener. If the traffic matches, it will be routed to the - // destination. - Match match = 1; - oneof destination { - // l4 is an l4 destination to route to, which will have a reference to a cluster. - L4Destination l4 = 2; - // l7 is an l7 destination to route to, which will have a reference to a route. - L7Destination l7 = 3; - // sni is an SNI destination, which means there will be no references, but the SNI name will be tied to the cluster - // name, so we should generate all clusters. - SNIDestination sni = 4; - } - // inbound_tls is used by inbound listeners that terminate TLS. - TransportSocket inbound_tls = 5; -} - -message Match { - repeated string alpn_protocols = 1; - google.protobuf.UInt32Value destination_port = 2; - repeated CidrRange prefix_ranges = 3; - repeated CidrRange source_prefix_ranges = 4; - // server_names matches based on SNI of the incoming request. - repeated string server_names = 5; -} - -message CidrRange { - string address_prefix = 1; - google.protobuf.UInt32Value prefix_len = 2; -} - -message L4Destination { - // destination is one or more clusters to route to. - oneof destination { - DestinationCluster cluster = 1; - L4WeightedClusterGroup weighted_clusters = 2; - } - // stat_prefix is for compatibility with v1 xds configuration, so it is generated in exactly the same way. - string stat_prefix = 3; - // traffic_permissions is a list of traffic permissions for this destination. - TrafficPermissions traffic_permissions = 4; - // max_inbound_connections specifies how many connections this destination can accept. - uint64 max_inbound_connections = 5; -} - -message L7DestinationRoute { - // name is a key in the top level routes map. This specifies which route to go to in this L7 destination. - string name = 1; -} - -message L7Destination { - // route specifies which route to go to in this L7 destination. - L7DestinationRoute route = 1; - // stat_prefix is for compatibility with v1 xds configuration, so it is generated in exactly the same way. - string stat_prefix = 2; - // protocol for the destination. - L7Protocol protocol = 3; - // traffic_permissions is a list of intentions for this destination. - TrafficPermissions traffic_permissions = 4; - // include_xfcc specifies whether to add an xfcc policy for handling xfcc headers. - bool include_xfcc_policy = 5; - // xfcc_policy determines how to handle xfcc headers. - XFCCPolicy xfcc_policy = 6; - // parse_xfcc_headers determines whether to add filters to parse xfcc headers on incoming connections. - bool parse_xfcc_headers = 7; - // static_route specifies whether this is a static route that is inlined in the listener filter. This is required to - // match existing xds config. - bool static_route = 8; - // max_inbound_connections specifies how many connections this destination can accept. - uint64 max_inbound_connections = 9; -} - -// +kubebuilder:validation:Enum=XFCC_POLICY_SANITIZE;XFCC_POLICY_FORWARD_ONLY;XFCC_POLICY_APPEND_FORWARD;XFCC_POLICY_SANITIZE_SET;XFCC_POLICY_ALWAYS_FORWARD_ONLY -// +kubebuilder:validation:Type=string -enum XFCCPolicy { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - // Do not send the XFCC header to the next hop. This is the default value. - XFCC_POLICY_SANITIZE = 0; - // When the client connection is mTLS (Mutual TLS), forward the XFCC header - // in the request. - XFCC_POLICY_FORWARD_ONLY = 1; - // When the client connection is mTLS, append the client certificate - // information to the request’s XFCC header and forward it. - XFCC_POLICY_APPEND_FORWARD = 2; - // When the client connection is mTLS, reset the XFCC header with the client - // certificate information and send it to the next hop. - XFCC_POLICY_SANITIZE_SET = 3; - // Always forward the XFCC header in the request, regardless of whether the - // client connection is mTLS. - XFCC_POLICY_ALWAYS_FORWARD_ONLY = 4; -} - -// +kubebuilder:validation:Enum=L7_PROTOCOL_HTTP;L7_PROTOCOL_HTTP2;L7_PROTOCOL_GRPC -// +kubebuilder:validation:Type=string -enum L7Protocol { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - L7_PROTOCOL_HTTP = 0; - L7_PROTOCOL_HTTP2 = 1; - L7_PROTOCOL_GRPC = 2; -} - -message SNIDestination { - // stat_prefix is for compatibility with v1 xds configuration, so it is generated in exactly the same way. - string stat_prefix = 1; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/listener_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/listener_deepcopy.gen.go deleted file mode 100644 index c721f40cbb91e..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/listener_deepcopy.gen.go +++ /dev/null @@ -1,174 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Listener within kubernetes types, where deepcopy-gen is used. -func (in *Listener) DeepCopyInto(out *Listener) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Listener. Required by controller-gen. -func (in *Listener) DeepCopy() *Listener { - if in == nil { - return nil - } - out := new(Listener) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Listener. Required by controller-gen. -func (in *Listener) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Router within kubernetes types, where deepcopy-gen is used. -func (in *Router) DeepCopyInto(out *Router) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Router. Required by controller-gen. -func (in *Router) DeepCopy() *Router { - if in == nil { - return nil - } - out := new(Router) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Router. Required by controller-gen. -func (in *Router) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Match within kubernetes types, where deepcopy-gen is used. -func (in *Match) DeepCopyInto(out *Match) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Match. Required by controller-gen. -func (in *Match) DeepCopy() *Match { - if in == nil { - return nil - } - out := new(Match) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Match. Required by controller-gen. -func (in *Match) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using CidrRange within kubernetes types, where deepcopy-gen is used. -func (in *CidrRange) DeepCopyInto(out *CidrRange) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CidrRange. Required by controller-gen. -func (in *CidrRange) DeepCopy() *CidrRange { - if in == nil { - return nil - } - out := new(CidrRange) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new CidrRange. Required by controller-gen. -func (in *CidrRange) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using L4Destination within kubernetes types, where deepcopy-gen is used. -func (in *L4Destination) DeepCopyInto(out *L4Destination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L4Destination. Required by controller-gen. -func (in *L4Destination) DeepCopy() *L4Destination { - if in == nil { - return nil - } - out := new(L4Destination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new L4Destination. Required by controller-gen. -func (in *L4Destination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using L7DestinationRoute within kubernetes types, where deepcopy-gen is used. -func (in *L7DestinationRoute) DeepCopyInto(out *L7DestinationRoute) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L7DestinationRoute. Required by controller-gen. -func (in *L7DestinationRoute) DeepCopy() *L7DestinationRoute { - if in == nil { - return nil - } - out := new(L7DestinationRoute) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new L7DestinationRoute. Required by controller-gen. -func (in *L7DestinationRoute) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using L7Destination within kubernetes types, where deepcopy-gen is used. -func (in *L7Destination) DeepCopyInto(out *L7Destination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L7Destination. Required by controller-gen. -func (in *L7Destination) DeepCopy() *L7Destination { - if in == nil { - return nil - } - out := new(L7Destination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new L7Destination. Required by controller-gen. -func (in *L7Destination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using SNIDestination within kubernetes types, where deepcopy-gen is used. -func (in *SNIDestination) DeepCopyInto(out *SNIDestination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SNIDestination. Required by controller-gen. -func (in *SNIDestination) DeepCopy() *SNIDestination { - if in == nil { - return nil - } - out := new(SNIDestination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new SNIDestination. Required by controller-gen. -func (in *SNIDestination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/listener_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/listener_json.gen.go deleted file mode 100644 index fe77b7be1ffd7..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/listener_json.gen.go +++ /dev/null @@ -1,99 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Listener -func (this *Listener) MarshalJSON() ([]byte, error) { - str, err := ListenerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Listener -func (this *Listener) UnmarshalJSON(b []byte) error { - return ListenerUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Router -func (this *Router) MarshalJSON() ([]byte, error) { - str, err := ListenerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Router -func (this *Router) UnmarshalJSON(b []byte) error { - return ListenerUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Match -func (this *Match) MarshalJSON() ([]byte, error) { - str, err := ListenerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Match -func (this *Match) UnmarshalJSON(b []byte) error { - return ListenerUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for CidrRange -func (this *CidrRange) MarshalJSON() ([]byte, error) { - str, err := ListenerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for CidrRange -func (this *CidrRange) UnmarshalJSON(b []byte) error { - return ListenerUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for L4Destination -func (this *L4Destination) MarshalJSON() ([]byte, error) { - str, err := ListenerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for L4Destination -func (this *L4Destination) UnmarshalJSON(b []byte) error { - return ListenerUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for L7DestinationRoute -func (this *L7DestinationRoute) MarshalJSON() ([]byte, error) { - str, err := ListenerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for L7DestinationRoute -func (this *L7DestinationRoute) UnmarshalJSON(b []byte) error { - return ListenerUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for L7Destination -func (this *L7Destination) MarshalJSON() ([]byte, error) { - str, err := ListenerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for L7Destination -func (this *L7Destination) UnmarshalJSON(b []byte) error { - return ListenerUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for SNIDestination -func (this *SNIDestination) MarshalJSON() ([]byte, error) { - str, err := ListenerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for SNIDestination -func (this *SNIDestination) UnmarshalJSON(b []byte) error { - return ListenerUnmarshaler.Unmarshal(b, this) -} - -var ( - ListenerMarshaler = &protojson.MarshalOptions{} - ListenerUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/protocol.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/protocol.pb.go deleted file mode 100644 index a14cdf986de6b..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/protocol.pb.go +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/protocol.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=PROTOCOL_UNSPECIFIED;PROTOCOL_TCP;PROTOCOL_HTTP;PROTOCOL_HTTP2;PROTOCOL_GRPC -// +kubebuilder:validation:Type=string -type Protocol int32 - -const ( - Protocol_PROTOCOL_UNSPECIFIED Protocol = 0 - Protocol_PROTOCOL_TCP Protocol = 1 - Protocol_PROTOCOL_HTTP Protocol = 2 - Protocol_PROTOCOL_HTTP2 Protocol = 3 - Protocol_PROTOCOL_GRPC Protocol = 4 - // Protocol Mesh indicates that this port can speak Consul's mTLS based mesh protocol. - Protocol_PROTOCOL_MESH Protocol = 5 -) - -// Enum value maps for Protocol. -var ( - Protocol_name = map[int32]string{ - 0: "PROTOCOL_UNSPECIFIED", - 1: "PROTOCOL_TCP", - 2: "PROTOCOL_HTTP", - 3: "PROTOCOL_HTTP2", - 4: "PROTOCOL_GRPC", - 5: "PROTOCOL_MESH", - } - Protocol_value = map[string]int32{ - "PROTOCOL_UNSPECIFIED": 0, - "PROTOCOL_TCP": 1, - "PROTOCOL_HTTP": 2, - "PROTOCOL_HTTP2": 3, - "PROTOCOL_GRPC": 4, - "PROTOCOL_MESH": 5, - } -) - -func (x Protocol) Enum() *Protocol { - p := new(Protocol) - *p = x - return p -} - -func (x Protocol) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Protocol) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_protocol_proto_enumTypes[0].Descriptor() -} - -func (Protocol) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_protocol_proto_enumTypes[0] -} - -func (x Protocol) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Protocol.Descriptor instead. -func (Protocol) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescGZIP(), []int{0} -} - -var File_pbmesh_v2beta1_pbproxystate_protocol_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDesc = []byte{ - 0x0a, 0x2a, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x83, 0x01, 0x0a, 0x08, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, - 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x43, 0x50, 0x10, - 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, - 0x54, 0x50, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, - 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, - 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x50, - 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x4d, 0x45, 0x53, 0x48, 0x10, 0x05, 0x42, 0xd3, - 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x42, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, - 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, - 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, - 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, - 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_protocol_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_pbproxystate_protocol_proto_goTypes = []interface{}{ - (Protocol)(0), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Protocol -} -var file_pbmesh_v2beta1_pbproxystate_protocol_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_protocol_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_protocol_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_protocol_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDesc, - NumEnums: 1, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_protocol_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_protocol_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_pbproxystate_protocol_proto_enumTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_protocol_proto = out.File - file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_protocol_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_protocol_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/protocol.proto b/proto-public/pbmesh/v2beta1/pbproxystate/protocol.proto deleted file mode 100644 index afe3ff17523e3..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/protocol.proto +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -// +kubebuilder:validation:Enum=PROTOCOL_UNSPECIFIED;PROTOCOL_TCP;PROTOCOL_HTTP;PROTOCOL_HTTP2;PROTOCOL_GRPC -// +kubebuilder:validation:Type=string -enum Protocol { - PROTOCOL_UNSPECIFIED = 0; - PROTOCOL_TCP = 1; - PROTOCOL_HTTP = 2; - PROTOCOL_HTTP2 = 3; - PROTOCOL_GRPC = 4; - - // Protocol Mesh indicates that this port can speak Consul's mTLS based mesh protocol. - PROTOCOL_MESH = 5; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/protocol_test.go b/proto-public/pbmesh/v2beta1/pbproxystate/protocol_test.go deleted file mode 100644 index 683f84452f13b..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/protocol_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package pbproxystate - -import ( - "testing" - - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - "github.com/stretchr/testify/require" -) - -// TestMirrorsCatalogProtocol ensures that there is no unintended drift between pbcatalog.Protocol and -// pbproxystate.Protocol. -func TestMirrorsCatalogProtocol(t *testing.T) { - require.Equal(t, pbcatalog.Protocol_value, Protocol_value, "pbcatalog.Protocol and pbproxystate.Protocol have diverged") - for i := range pbcatalog.Protocol_name { - require.Equal(t, pbcatalog.Protocol_name[i], Protocol_name[i], - "pbcatalog.Protocol and pbproxystate.Protocol ordinals do not match;"+ - " ordinals for equivalent values must match so that casting between them produces expected results") - } -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/references.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/references.pb.binary.go deleted file mode 100644 index ddcc32fc56171..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/references.pb.binary.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/references.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LeafCertificateRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LeafCertificateRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TrustBundleRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TrustBundleRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *EndpointRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *EndpointRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/references.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/references.pb.go deleted file mode 100644 index c544d28030954..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/references.pb.go +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/references.proto - -package pbproxystate - -import ( - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type LeafCertificateRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` - Partition string `protobuf:"bytes,3,opt,name=partition,proto3" json:"partition,omitempty"` - Host string `protobuf:"bytes,4,opt,name=host,proto3" json:"host,omitempty"` - Datacenter string `protobuf:"bytes,5,opt,name=datacenter,proto3" json:"datacenter,omitempty"` - DnsSan []string `protobuf:"bytes,6,rep,name=dns_san,json=dnsSan,proto3" json:"dns_san,omitempty"` -} - -func (x *LeafCertificateRef) Reset() { - *x = LeafCertificateRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LeafCertificateRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LeafCertificateRef) ProtoMessage() {} - -func (x *LeafCertificateRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LeafCertificateRef.ProtoReflect.Descriptor instead. -func (*LeafCertificateRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescGZIP(), []int{0} -} - -func (x *LeafCertificateRef) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *LeafCertificateRef) GetNamespace() string { - if x != nil { - return x.Namespace - } - return "" -} - -func (x *LeafCertificateRef) GetPartition() string { - if x != nil { - return x.Partition - } - return "" -} - -func (x *LeafCertificateRef) GetHost() string { - if x != nil { - return x.Host - } - return "" -} - -func (x *LeafCertificateRef) GetDatacenter() string { - if x != nil { - return x.Datacenter - } - return "" -} - -func (x *LeafCertificateRef) GetDnsSan() []string { - if x != nil { - return x.DnsSan - } - return nil -} - -type TrustBundleRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Peer string `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"` - TrustDomain string `protobuf:"bytes,2,opt,name=trust_domain,json=trustDomain,proto3" json:"trust_domain,omitempty"` -} - -func (x *TrustBundleRef) Reset() { - *x = TrustBundleRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TrustBundleRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TrustBundleRef) ProtoMessage() {} - -func (x *TrustBundleRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TrustBundleRef.ProtoReflect.Descriptor instead. -func (*TrustBundleRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescGZIP(), []int{1} -} - -func (x *TrustBundleRef) GetPeer() string { - if x != nil { - return x.Peer - } - return "" -} - -func (x *TrustBundleRef) GetTrustDomain() string { - if x != nil { - return x.TrustDomain - } - return "" -} - -type EndpointRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // id is the ServiceEndpoints resource id. - Id *pbresource.ID `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // port is the name of the port in the ServiceEndpoints to generate the Endpoints from. - Port string `protobuf:"bytes,2,opt,name=port,proto3" json:"port,omitempty"` -} - -func (x *EndpointRef) Reset() { - *x = EndpointRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EndpointRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EndpointRef) ProtoMessage() {} - -func (x *EndpointRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EndpointRef.ProtoReflect.Descriptor instead. -func (*EndpointRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescGZIP(), []int{2} -} - -func (x *EndpointRef) GetId() *pbresource.ID { - if x != nil { - return x.Id - } - return nil -} - -func (x *EndpointRef) GetPort() string { - if x != nil { - return x.Port - } - return "" -} - -var File_pbmesh_v2beta1_pbproxystate_references_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_references_proto_rawDesc = []byte{ - 0x0a, 0x2c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x19, 0x70, 0x62, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x01, 0x0a, 0x12, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, - 0x68, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, - 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, - 0x12, 0x17, 0x0a, 0x07, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x61, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x06, 0x64, 0x6e, 0x73, 0x53, 0x61, 0x6e, 0x22, 0x47, 0x0a, 0x0e, 0x54, 0x72, 0x75, - 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, - 0x21, 0x0a, 0x0c, 0x74, 0x72, 0x75, 0x73, 0x74, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x72, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x22, 0x50, 0x0a, 0x0b, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, - 0x66, 0x12, 0x2d, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x70, 0x6f, 0x72, 0x74, 0x42, 0xd5, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x0f, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, - 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, - 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, - 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_references_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_references_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_pbmesh_v2beta1_pbproxystate_references_proto_goTypes = []interface{}{ - (*LeafCertificateRef)(nil), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.LeafCertificateRef - (*TrustBundleRef)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.TrustBundleRef - (*EndpointRef)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointRef - (*pbresource.ID)(nil), // 3: hashicorp.consul.resource.ID -} -var file_pbmesh_v2beta1_pbproxystate_references_proto_depIdxs = []int32{ - 3, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointRef.id:type_name -> hashicorp.consul.resource.ID - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_references_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_references_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_references_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LeafCertificateRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TrustBundleRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EndpointRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_references_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_references_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_references_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_references_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_references_proto = out.File - file_pbmesh_v2beta1_pbproxystate_references_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_references_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_references_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/references.proto b/proto-public/pbmesh/v2beta1/pbproxystate/references.proto deleted file mode 100644 index b169019c603e1..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/references.proto +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -import "pbresource/resource.proto"; - -message LeafCertificateRef { - string name = 1; - string namespace = 2; - string partition = 3; - string host = 4; - string datacenter = 5; - repeated string dns_san = 6; -} - -message TrustBundleRef { - string peer = 1; - string trust_domain = 2; -} - -message EndpointRef { - // id is the ServiceEndpoints resource id. - hashicorp.consul.resource.ID id = 1; - // port is the name of the port in the ServiceEndpoints to generate the Endpoints from. - string port = 2; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/references_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/references_deepcopy.gen.go deleted file mode 100644 index 2cbe25a91750c..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/references_deepcopy.gen.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using LeafCertificateRef within kubernetes types, where deepcopy-gen is used. -func (in *LeafCertificateRef) DeepCopyInto(out *LeafCertificateRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeafCertificateRef. Required by controller-gen. -func (in *LeafCertificateRef) DeepCopy() *LeafCertificateRef { - if in == nil { - return nil - } - out := new(LeafCertificateRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LeafCertificateRef. Required by controller-gen. -func (in *LeafCertificateRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TrustBundleRef within kubernetes types, where deepcopy-gen is used. -func (in *TrustBundleRef) DeepCopyInto(out *TrustBundleRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrustBundleRef. Required by controller-gen. -func (in *TrustBundleRef) DeepCopy() *TrustBundleRef { - if in == nil { - return nil - } - out := new(TrustBundleRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TrustBundleRef. Required by controller-gen. -func (in *TrustBundleRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using EndpointRef within kubernetes types, where deepcopy-gen is used. -func (in *EndpointRef) DeepCopyInto(out *EndpointRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointRef. Required by controller-gen. -func (in *EndpointRef) DeepCopy() *EndpointRef { - if in == nil { - return nil - } - out := new(EndpointRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new EndpointRef. Required by controller-gen. -func (in *EndpointRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/references_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/references_json.gen.go deleted file mode 100644 index 91a178b9b3660..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/references_json.gen.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for LeafCertificateRef -func (this *LeafCertificateRef) MarshalJSON() ([]byte, error) { - str, err := ReferencesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LeafCertificateRef -func (this *LeafCertificateRef) UnmarshalJSON(b []byte) error { - return ReferencesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TrustBundleRef -func (this *TrustBundleRef) MarshalJSON() ([]byte, error) { - str, err := ReferencesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TrustBundleRef -func (this *TrustBundleRef) UnmarshalJSON(b []byte) error { - return ReferencesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for EndpointRef -func (this *EndpointRef) MarshalJSON() ([]byte, error) { - str, err := ReferencesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for EndpointRef -func (this *EndpointRef) UnmarshalJSON(b []byte) error { - return ReferencesUnmarshaler.Unmarshal(b, this) -} - -var ( - ReferencesMarshaler = &protojson.MarshalOptions{} - ReferencesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/route.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/route.pb.binary.go deleted file mode 100644 index d6b057e379f11..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/route.pb.binary.go +++ /dev/null @@ -1,168 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/route.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Route) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Route) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *VirtualHost) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *VirtualHost) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RouteRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RouteRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RouteMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RouteMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *PathMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PathMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *QueryParameterMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *QueryParameterMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HeaderMatch) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HeaderMatch) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RouteDestination) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RouteDestination) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *DestinationConfiguration) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *DestinationConfiguration) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RetryPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RetryPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TimeoutConfig) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TimeoutConfig) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LoadBalancerHashPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LoadBalancerHashPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *CookiePolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *CookiePolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HeaderPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HeaderPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *QueryParameterPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *QueryParameterPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ConnectionPropertiesPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ConnectionPropertiesPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/route.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/route.pb.go deleted file mode 100644 index 0d88a016eb6f8..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/route.pb.go +++ /dev/null @@ -1,1830 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/route.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Route struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // virtual_hosts is a list of virtual hosts. A virtual host is selected based on an incoming request's host header. - VirtualHosts []*VirtualHost `protobuf:"bytes,1,rep,name=virtual_hosts,json=virtualHosts,proto3" json:"virtual_hosts,omitempty"` -} - -func (x *Route) Reset() { - *x = Route{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Route) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Route) ProtoMessage() {} - -func (x *Route) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Route.ProtoReflect.Descriptor instead. -func (*Route) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{0} -} - -func (x *Route) GetVirtualHosts() []*VirtualHost { - if x != nil { - return x.VirtualHosts - } - return nil -} - -type VirtualHost struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // domains are used to match an incoming request's host header and determine which virtual host to use. - Domains []string `protobuf:"bytes,2,rep,name=domains,proto3" json:"domains,omitempty"` - // header_mutations to apply to the request when it matches this virtual host. These are applied after any headers in - // the RouteRule. - HeaderMutations []*HeaderMutation `protobuf:"bytes,3,rep,name=header_mutations,json=headerMutations,proto3" json:"header_mutations,omitempty"` - // route_rules are a list of rules to use for what to do next with this request. The first rule with a match will be - // used. - RouteRules []*RouteRule `protobuf:"bytes,4,rep,name=route_rules,json=routeRules,proto3" json:"route_rules,omitempty"` -} - -func (x *VirtualHost) Reset() { - *x = VirtualHost{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *VirtualHost) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*VirtualHost) ProtoMessage() {} - -func (x *VirtualHost) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use VirtualHost.ProtoReflect.Descriptor instead. -func (*VirtualHost) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{1} -} - -func (x *VirtualHost) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *VirtualHost) GetDomains() []string { - if x != nil { - return x.Domains - } - return nil -} - -func (x *VirtualHost) GetHeaderMutations() []*HeaderMutation { - if x != nil { - return x.HeaderMutations - } - return nil -} - -func (x *VirtualHost) GetRouteRules() []*RouteRule { - if x != nil { - return x.RouteRules - } - return nil -} - -type RouteRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // match determines how to match the request. The first match determines which destination the request will go to. - Match *RouteMatch `protobuf:"bytes,1,opt,name=match,proto3" json:"match,omitempty"` - // destination is where to send the request to. - Destination *RouteDestination `protobuf:"bytes,2,opt,name=destination,proto3" json:"destination,omitempty"` - // header_mutations to apply to the request. These are applied before the VirtualHost header mutations. - HeaderMutations []*HeaderMutation `protobuf:"bytes,3,rep,name=header_mutations,json=headerMutations,proto3" json:"header_mutations,omitempty"` -} - -func (x *RouteRule) Reset() { - *x = RouteRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RouteRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RouteRule) ProtoMessage() {} - -func (x *RouteRule) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RouteRule.ProtoReflect.Descriptor instead. -func (*RouteRule) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{2} -} - -func (x *RouteRule) GetMatch() *RouteMatch { - if x != nil { - return x.Match - } - return nil -} - -func (x *RouteRule) GetDestination() *RouteDestination { - if x != nil { - return x.Destination - } - return nil -} - -func (x *RouteRule) GetHeaderMutations() []*HeaderMutation { - if x != nil { - return x.HeaderMutations - } - return nil -} - -// RouteMatch has configuration to match a request. -type RouteMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PathMatch *PathMatch `protobuf:"bytes,1,opt,name=path_match,json=pathMatch,proto3" json:"path_match,omitempty"` - HeaderMatches []*HeaderMatch `protobuf:"bytes,2,rep,name=header_matches,json=headerMatches,proto3" json:"header_matches,omitempty"` - MethodMatches []string `protobuf:"bytes,3,rep,name=method_matches,json=methodMatches,proto3" json:"method_matches,omitempty"` - QueryParameterMatches []*QueryParameterMatch `protobuf:"bytes,4,rep,name=query_parameter_matches,json=queryParameterMatches,proto3" json:"query_parameter_matches,omitempty"` -} - -func (x *RouteMatch) Reset() { - *x = RouteMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RouteMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RouteMatch) ProtoMessage() {} - -func (x *RouteMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RouteMatch.ProtoReflect.Descriptor instead. -func (*RouteMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{3} -} - -func (x *RouteMatch) GetPathMatch() *PathMatch { - if x != nil { - return x.PathMatch - } - return nil -} - -func (x *RouteMatch) GetHeaderMatches() []*HeaderMatch { - if x != nil { - return x.HeaderMatches - } - return nil -} - -func (x *RouteMatch) GetMethodMatches() []string { - if x != nil { - return x.MethodMatches - } - return nil -} - -func (x *RouteMatch) GetQueryParameterMatches() []*QueryParameterMatch { - if x != nil { - return x.QueryParameterMatches - } - return nil -} - -type PathMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to PathMatch: - // - // *PathMatch_Exact - // *PathMatch_Prefix - // *PathMatch_Regex - PathMatch isPathMatch_PathMatch `protobuf_oneof:"path_match"` -} - -func (x *PathMatch) Reset() { - *x = PathMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PathMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PathMatch) ProtoMessage() {} - -func (x *PathMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PathMatch.ProtoReflect.Descriptor instead. -func (*PathMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{4} -} - -func (m *PathMatch) GetPathMatch() isPathMatch_PathMatch { - if m != nil { - return m.PathMatch - } - return nil -} - -func (x *PathMatch) GetExact() string { - if x, ok := x.GetPathMatch().(*PathMatch_Exact); ok { - return x.Exact - } - return "" -} - -func (x *PathMatch) GetPrefix() string { - if x, ok := x.GetPathMatch().(*PathMatch_Prefix); ok { - return x.Prefix - } - return "" -} - -func (x *PathMatch) GetRegex() string { - if x, ok := x.GetPathMatch().(*PathMatch_Regex); ok { - return x.Regex - } - return "" -} - -type isPathMatch_PathMatch interface { - isPathMatch_PathMatch() -} - -type PathMatch_Exact struct { - Exact string `protobuf:"bytes,1,opt,name=exact,proto3,oneof"` -} - -type PathMatch_Prefix struct { - Prefix string `protobuf:"bytes,2,opt,name=prefix,proto3,oneof"` -} - -type PathMatch_Regex struct { - Regex string `protobuf:"bytes,3,opt,name=regex,proto3,oneof"` -} - -func (*PathMatch_Exact) isPathMatch_PathMatch() {} - -func (*PathMatch_Prefix) isPathMatch_PathMatch() {} - -func (*PathMatch_Regex) isPathMatch_PathMatch() {} - -type QueryParameterMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Types that are assignable to Match: - // - // *QueryParameterMatch_Exact - // *QueryParameterMatch_Regex - // *QueryParameterMatch_Present - Match isQueryParameterMatch_Match `protobuf_oneof:"match"` -} - -func (x *QueryParameterMatch) Reset() { - *x = QueryParameterMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QueryParameterMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryParameterMatch) ProtoMessage() {} - -func (x *QueryParameterMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use QueryParameterMatch.ProtoReflect.Descriptor instead. -func (*QueryParameterMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{5} -} - -func (x *QueryParameterMatch) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (m *QueryParameterMatch) GetMatch() isQueryParameterMatch_Match { - if m != nil { - return m.Match - } - return nil -} - -func (x *QueryParameterMatch) GetExact() string { - if x, ok := x.GetMatch().(*QueryParameterMatch_Exact); ok { - return x.Exact - } - return "" -} - -func (x *QueryParameterMatch) GetRegex() string { - if x, ok := x.GetMatch().(*QueryParameterMatch_Regex); ok { - return x.Regex - } - return "" -} - -func (x *QueryParameterMatch) GetPresent() bool { - if x, ok := x.GetMatch().(*QueryParameterMatch_Present); ok { - return x.Present - } - return false -} - -type isQueryParameterMatch_Match interface { - isQueryParameterMatch_Match() -} - -type QueryParameterMatch_Exact struct { - Exact string `protobuf:"bytes,2,opt,name=exact,proto3,oneof"` -} - -type QueryParameterMatch_Regex struct { - Regex string `protobuf:"bytes,3,opt,name=regex,proto3,oneof"` -} - -type QueryParameterMatch_Present struct { - Present bool `protobuf:"varint,4,opt,name=present,proto3,oneof"` -} - -func (*QueryParameterMatch_Exact) isQueryParameterMatch_Match() {} - -func (*QueryParameterMatch_Regex) isQueryParameterMatch_Match() {} - -func (*QueryParameterMatch_Present) isQueryParameterMatch_Match() {} - -type HeaderMatch struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Types that are assignable to Match: - // - // *HeaderMatch_Exact - // *HeaderMatch_Prefix - // *HeaderMatch_Suffix - // *HeaderMatch_Regex - // *HeaderMatch_Present - Match isHeaderMatch_Match `protobuf_oneof:"match"` - InvertMatch bool `protobuf:"varint,7,opt,name=invert_match,json=invertMatch,proto3" json:"invert_match,omitempty"` -} - -func (x *HeaderMatch) Reset() { - *x = HeaderMatch{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HeaderMatch) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HeaderMatch) ProtoMessage() {} - -func (x *HeaderMatch) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HeaderMatch.ProtoReflect.Descriptor instead. -func (*HeaderMatch) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{6} -} - -func (x *HeaderMatch) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (m *HeaderMatch) GetMatch() isHeaderMatch_Match { - if m != nil { - return m.Match - } - return nil -} - -func (x *HeaderMatch) GetExact() string { - if x, ok := x.GetMatch().(*HeaderMatch_Exact); ok { - return x.Exact - } - return "" -} - -func (x *HeaderMatch) GetPrefix() string { - if x, ok := x.GetMatch().(*HeaderMatch_Prefix); ok { - return x.Prefix - } - return "" -} - -func (x *HeaderMatch) GetSuffix() string { - if x, ok := x.GetMatch().(*HeaderMatch_Suffix); ok { - return x.Suffix - } - return "" -} - -func (x *HeaderMatch) GetRegex() string { - if x, ok := x.GetMatch().(*HeaderMatch_Regex); ok { - return x.Regex - } - return "" -} - -func (x *HeaderMatch) GetPresent() bool { - if x, ok := x.GetMatch().(*HeaderMatch_Present); ok { - return x.Present - } - return false -} - -func (x *HeaderMatch) GetInvertMatch() bool { - if x != nil { - return x.InvertMatch - } - return false -} - -type isHeaderMatch_Match interface { - isHeaderMatch_Match() -} - -type HeaderMatch_Exact struct { - Exact string `protobuf:"bytes,2,opt,name=exact,proto3,oneof"` -} - -type HeaderMatch_Prefix struct { - Prefix string `protobuf:"bytes,3,opt,name=prefix,proto3,oneof"` -} - -type HeaderMatch_Suffix struct { - Suffix string `protobuf:"bytes,4,opt,name=suffix,proto3,oneof"` -} - -type HeaderMatch_Regex struct { - Regex string `protobuf:"bytes,5,opt,name=regex,proto3,oneof"` -} - -type HeaderMatch_Present struct { - Present bool `protobuf:"varint,6,opt,name=present,proto3,oneof"` -} - -func (*HeaderMatch_Exact) isHeaderMatch_Match() {} - -func (*HeaderMatch_Prefix) isHeaderMatch_Match() {} - -func (*HeaderMatch_Suffix) isHeaderMatch_Match() {} - -func (*HeaderMatch_Regex) isHeaderMatch_Match() {} - -func (*HeaderMatch_Present) isHeaderMatch_Match() {} - -// RouteDestination has configuration for where to send a request. -type RouteDestination struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // destination is one or more clusters to route to. - // - // Types that are assignable to Destination: - // - // *RouteDestination_Cluster - // *RouteDestination_WeightedClusters - Destination isRouteDestination_Destination `protobuf_oneof:"destination"` - DestinationConfiguration *DestinationConfiguration `protobuf:"bytes,3,opt,name=destination_configuration,json=destinationConfiguration,proto3" json:"destination_configuration,omitempty"` -} - -func (x *RouteDestination) Reset() { - *x = RouteDestination{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RouteDestination) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RouteDestination) ProtoMessage() {} - -func (x *RouteDestination) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RouteDestination.ProtoReflect.Descriptor instead. -func (*RouteDestination) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{7} -} - -func (m *RouteDestination) GetDestination() isRouteDestination_Destination { - if m != nil { - return m.Destination - } - return nil -} - -func (x *RouteDestination) GetCluster() *DestinationCluster { - if x, ok := x.GetDestination().(*RouteDestination_Cluster); ok { - return x.Cluster - } - return nil -} - -func (x *RouteDestination) GetWeightedClusters() *L7WeightedClusterGroup { - if x, ok := x.GetDestination().(*RouteDestination_WeightedClusters); ok { - return x.WeightedClusters - } - return nil -} - -func (x *RouteDestination) GetDestinationConfiguration() *DestinationConfiguration { - if x != nil { - return x.DestinationConfiguration - } - return nil -} - -type isRouteDestination_Destination interface { - isRouteDestination_Destination() -} - -type RouteDestination_Cluster struct { - Cluster *DestinationCluster `protobuf:"bytes,1,opt,name=cluster,proto3,oneof"` -} - -type RouteDestination_WeightedClusters struct { - WeightedClusters *L7WeightedClusterGroup `protobuf:"bytes,2,opt,name=weighted_clusters,json=weightedClusters,proto3,oneof"` -} - -func (*RouteDestination_Cluster) isRouteDestination_Destination() {} - -func (*RouteDestination_WeightedClusters) isRouteDestination_Destination() {} - -type DestinationConfiguration struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AutoHostRewrite *wrapperspb.BoolValue `protobuf:"bytes,1,opt,name=auto_host_rewrite,json=autoHostRewrite,proto3" json:"auto_host_rewrite,omitempty"` - HashPolicies []*LoadBalancerHashPolicy `protobuf:"bytes,2,rep,name=hash_policies,json=hashPolicies,proto3" json:"hash_policies,omitempty"` - TimeoutConfig *TimeoutConfig `protobuf:"bytes,3,opt,name=timeout_config,json=timeoutConfig,proto3" json:"timeout_config,omitempty"` - PrefixRewrite string `protobuf:"bytes,4,opt,name=prefix_rewrite,json=prefixRewrite,proto3" json:"prefix_rewrite,omitempty"` - RetryPolicy *RetryPolicy `protobuf:"bytes,5,opt,name=retry_policy,json=retryPolicy,proto3" json:"retry_policy,omitempty"` -} - -func (x *DestinationConfiguration) Reset() { - *x = DestinationConfiguration{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DestinationConfiguration) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DestinationConfiguration) ProtoMessage() {} - -func (x *DestinationConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DestinationConfiguration.ProtoReflect.Descriptor instead. -func (*DestinationConfiguration) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{8} -} - -func (x *DestinationConfiguration) GetAutoHostRewrite() *wrapperspb.BoolValue { - if x != nil { - return x.AutoHostRewrite - } - return nil -} - -func (x *DestinationConfiguration) GetHashPolicies() []*LoadBalancerHashPolicy { - if x != nil { - return x.HashPolicies - } - return nil -} - -func (x *DestinationConfiguration) GetTimeoutConfig() *TimeoutConfig { - if x != nil { - return x.TimeoutConfig - } - return nil -} - -func (x *DestinationConfiguration) GetPrefixRewrite() string { - if x != nil { - return x.PrefixRewrite - } - return "" -} - -func (x *DestinationConfiguration) GetRetryPolicy() *RetryPolicy { - if x != nil { - return x.RetryPolicy - } - return nil -} - -type RetryPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - RetryOn string `protobuf:"bytes,1,opt,name=retry_on,json=retryOn,proto3" json:"retry_on,omitempty"` - NumRetries *wrapperspb.UInt32Value `protobuf:"bytes,2,opt,name=num_retries,json=numRetries,proto3" json:"num_retries,omitempty"` - RetriableStatusCodes []uint32 `protobuf:"varint,3,rep,packed,name=retriable_status_codes,json=retriableStatusCodes,proto3" json:"retriable_status_codes,omitempty"` -} - -func (x *RetryPolicy) Reset() { - *x = RetryPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RetryPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RetryPolicy) ProtoMessage() {} - -func (x *RetryPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RetryPolicy.ProtoReflect.Descriptor instead. -func (*RetryPolicy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{9} -} - -func (x *RetryPolicy) GetRetryOn() string { - if x != nil { - return x.RetryOn - } - return "" -} - -func (x *RetryPolicy) GetNumRetries() *wrapperspb.UInt32Value { - if x != nil { - return x.NumRetries - } - return nil -} - -func (x *RetryPolicy) GetRetriableStatusCodes() []uint32 { - if x != nil { - return x.RetriableStatusCodes - } - return nil -} - -type TimeoutConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // +kubebuilder:validation:Format=duration - Timeout *durationpb.Duration `protobuf:"bytes,1,opt,name=timeout,proto3" json:"timeout,omitempty"` - // +kubebuilder:validation:Format=duration - IdleTimeout *durationpb.Duration `protobuf:"bytes,2,opt,name=idle_timeout,json=idleTimeout,proto3" json:"idle_timeout,omitempty"` -} - -func (x *TimeoutConfig) Reset() { - *x = TimeoutConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TimeoutConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TimeoutConfig) ProtoMessage() {} - -func (x *TimeoutConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TimeoutConfig.ProtoReflect.Descriptor instead. -func (*TimeoutConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{10} -} - -func (x *TimeoutConfig) GetTimeout() *durationpb.Duration { - if x != nil { - return x.Timeout - } - return nil -} - -func (x *TimeoutConfig) GetIdleTimeout() *durationpb.Duration { - if x != nil { - return x.IdleTimeout - } - return nil -} - -type LoadBalancerHashPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Policy: - // - // *LoadBalancerHashPolicy_Cookie - // *LoadBalancerHashPolicy_Header - // *LoadBalancerHashPolicy_QueryParameter - // *LoadBalancerHashPolicy_ConnectionProperties - Policy isLoadBalancerHashPolicy_Policy `protobuf_oneof:"policy"` -} - -func (x *LoadBalancerHashPolicy) Reset() { - *x = LoadBalancerHashPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LoadBalancerHashPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LoadBalancerHashPolicy) ProtoMessage() {} - -func (x *LoadBalancerHashPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LoadBalancerHashPolicy.ProtoReflect.Descriptor instead. -func (*LoadBalancerHashPolicy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{11} -} - -func (m *LoadBalancerHashPolicy) GetPolicy() isLoadBalancerHashPolicy_Policy { - if m != nil { - return m.Policy - } - return nil -} - -func (x *LoadBalancerHashPolicy) GetCookie() *CookiePolicy { - if x, ok := x.GetPolicy().(*LoadBalancerHashPolicy_Cookie); ok { - return x.Cookie - } - return nil -} - -func (x *LoadBalancerHashPolicy) GetHeader() *HeaderPolicy { - if x, ok := x.GetPolicy().(*LoadBalancerHashPolicy_Header); ok { - return x.Header - } - return nil -} - -func (x *LoadBalancerHashPolicy) GetQueryParameter() *QueryParameterPolicy { - if x, ok := x.GetPolicy().(*LoadBalancerHashPolicy_QueryParameter); ok { - return x.QueryParameter - } - return nil -} - -func (x *LoadBalancerHashPolicy) GetConnectionProperties() *ConnectionPropertiesPolicy { - if x, ok := x.GetPolicy().(*LoadBalancerHashPolicy_ConnectionProperties); ok { - return x.ConnectionProperties - } - return nil -} - -type isLoadBalancerHashPolicy_Policy interface { - isLoadBalancerHashPolicy_Policy() -} - -type LoadBalancerHashPolicy_Cookie struct { - Cookie *CookiePolicy `protobuf:"bytes,1,opt,name=cookie,proto3,oneof"` -} - -type LoadBalancerHashPolicy_Header struct { - Header *HeaderPolicy `protobuf:"bytes,2,opt,name=header,proto3,oneof"` -} - -type LoadBalancerHashPolicy_QueryParameter struct { - QueryParameter *QueryParameterPolicy `protobuf:"bytes,3,opt,name=query_parameter,json=queryParameter,proto3,oneof"` -} - -type LoadBalancerHashPolicy_ConnectionProperties struct { - ConnectionProperties *ConnectionPropertiesPolicy `protobuf:"bytes,4,opt,name=connection_properties,json=connectionProperties,proto3,oneof"` -} - -func (*LoadBalancerHashPolicy_Cookie) isLoadBalancerHashPolicy_Policy() {} - -func (*LoadBalancerHashPolicy_Header) isLoadBalancerHashPolicy_Policy() {} - -func (*LoadBalancerHashPolicy_QueryParameter) isLoadBalancerHashPolicy_Policy() {} - -func (*LoadBalancerHashPolicy_ConnectionProperties) isLoadBalancerHashPolicy_Policy() {} - -type CookiePolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // +kubebuilder:validation:Format=duration - Ttl *durationpb.Duration `protobuf:"bytes,2,opt,name=ttl,proto3" json:"ttl,omitempty"` - Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` - Terminal bool `protobuf:"varint,4,opt,name=terminal,proto3" json:"terminal,omitempty"` -} - -func (x *CookiePolicy) Reset() { - *x = CookiePolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CookiePolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CookiePolicy) ProtoMessage() {} - -func (x *CookiePolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CookiePolicy.ProtoReflect.Descriptor instead. -func (*CookiePolicy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{12} -} - -func (x *CookiePolicy) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *CookiePolicy) GetTtl() *durationpb.Duration { - if x != nil { - return x.Ttl - } - return nil -} - -func (x *CookiePolicy) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -func (x *CookiePolicy) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -type HeaderPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Terminal bool `protobuf:"varint,2,opt,name=terminal,proto3" json:"terminal,omitempty"` -} - -func (x *HeaderPolicy) Reset() { - *x = HeaderPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HeaderPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HeaderPolicy) ProtoMessage() {} - -func (x *HeaderPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HeaderPolicy.ProtoReflect.Descriptor instead. -func (*HeaderPolicy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{13} -} - -func (x *HeaderPolicy) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *HeaderPolicy) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -type QueryParameterPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Terminal bool `protobuf:"varint,2,opt,name=terminal,proto3" json:"terminal,omitempty"` -} - -func (x *QueryParameterPolicy) Reset() { - *x = QueryParameterPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *QueryParameterPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryParameterPolicy) ProtoMessage() {} - -func (x *QueryParameterPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use QueryParameterPolicy.ProtoReflect.Descriptor instead. -func (*QueryParameterPolicy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{14} -} - -func (x *QueryParameterPolicy) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *QueryParameterPolicy) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -type ConnectionPropertiesPolicy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - SourceIp bool `protobuf:"varint,1,opt,name=source_ip,json=sourceIp,proto3" json:"source_ip,omitempty"` - Terminal bool `protobuf:"varint,2,opt,name=terminal,proto3" json:"terminal,omitempty"` -} - -func (x *ConnectionPropertiesPolicy) Reset() { - *x = ConnectionPropertiesPolicy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ConnectionPropertiesPolicy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConnectionPropertiesPolicy) ProtoMessage() {} - -func (x *ConnectionPropertiesPolicy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConnectionPropertiesPolicy.ProtoReflect.Descriptor instead. -func (*ConnectionPropertiesPolicy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP(), []int{15} -} - -func (x *ConnectionPropertiesPolicy) GetSourceIp() bool { - if x != nil { - return x.SourceIp - } - return false -} - -func (x *ConnectionPropertiesPolicy) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -var File_pbmesh_v2beta1_pbproxystate_route_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_route_proto_rawDesc = []byte{ - 0x0a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x32, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x65, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x5c, 0x0a, - 0x0d, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x0c, 0x76, - 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x0b, - 0x56, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x65, 0x0a, 0x10, 0x68, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x0f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x56, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0a, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xa0, 0x02, 0x0a, 0x09, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x4c, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x12, 0x5e, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x44, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x65, 0x0a, 0x10, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6d, - 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe2, 0x02, 0x0a, 0x0a, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x54, 0x0a, 0x0a, 0x70, 0x61, - 0x74, 0x68, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x61, 0x74, 0x68, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x09, 0x70, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x12, 0x5e, 0x0a, 0x0e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x0d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, - 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x77, 0x0a, 0x17, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x15, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, - 0x22, 0x63, 0x0a, 0x09, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, - 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, - 0x65, 0x78, 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, - 0x16, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, - 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x61, 0x74, 0x68, 0x5f, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x7e, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x16, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, - 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, - 0x12, 0x1a, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x48, 0x00, 0x52, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x42, 0x07, 0x0a, 0x05, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0xcd, 0x01, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x78, 0x61, - 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x78, 0x61, 0x63, - 0x74, 0x12, 0x18, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x18, 0x0a, 0x06, 0x73, - 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, - 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x16, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, 0x1a, 0x0a, - 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, - 0x52, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x76, - 0x65, 0x72, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0b, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, 0x07, 0x0a, 0x05, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0xf4, 0x02, 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x44, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5a, 0x0a, 0x07, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x07, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x71, 0x0a, 0x11, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, - 0x37, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x10, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, - 0x64, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x81, 0x01, 0x0a, 0x19, 0x64, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x18, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0d, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb0, 0x03, 0x0a, - 0x18, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x46, 0x0a, 0x11, 0x61, 0x75, 0x74, - 0x6f, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x0f, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x12, 0x67, 0x0a, 0x0d, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x72, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0c, 0x68, 0x61, - 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x60, 0x0a, 0x0e, 0x74, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, - 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x72, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x65, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x12, 0x5a, 0x0a, 0x0c, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x0b, 0x72, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, - 0x9d, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, - 0x19, 0x0a, 0x08, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x72, 0x65, 0x74, 0x72, 0x79, 0x4f, 0x6e, 0x12, 0x3d, 0x0a, 0x0b, 0x6e, 0x75, - 0x6d, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0a, 0x6e, - 0x75, 0x6d, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x74, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, - 0x64, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x14, 0x72, 0x65, 0x74, 0x72, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x22, - 0x82, 0x01, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x69, 0x64, 0x6c, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69, 0x64, 0x6c, 0x65, 0x54, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x22, 0xb6, 0x03, 0x0a, 0x16, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x72, 0x48, 0x61, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, - 0x52, 0x0a, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x6f, - 0x6b, 0x69, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6f, - 0x6b, 0x69, 0x65, 0x12, 0x52, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, - 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x6b, 0x0a, 0x0f, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x48, 0x00, 0x52, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x12, 0x7d, 0x0a, 0x15, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x46, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, - 0x72, 0x74, 0x69, 0x65, 0x73, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x14, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x69, 0x65, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x7f, 0x0a, - 0x0c, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x2b, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x12, - 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x22, 0x3e, - 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x22, 0x46, - 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x22, 0x55, 0x0a, 0x1a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, - 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, - 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x42, 0xd0, 0x02, - 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x42, 0x0a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, - 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_route_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_route_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes = make([]protoimpl.MessageInfo, 16) -var file_pbmesh_v2beta1_pbproxystate_route_proto_goTypes = []interface{}{ - (*Route)(nil), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Route - (*VirtualHost)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.VirtualHost - (*RouteRule)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteRule - (*RouteMatch)(nil), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteMatch - (*PathMatch)(nil), // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.PathMatch - (*QueryParameterMatch)(nil), // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.QueryParameterMatch - (*HeaderMatch)(nil), // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMatch - (*RouteDestination)(nil), // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteDestination - (*DestinationConfiguration)(nil), // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationConfiguration - (*RetryPolicy)(nil), // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.RetryPolicy - (*TimeoutConfig)(nil), // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.TimeoutConfig - (*LoadBalancerHashPolicy)(nil), // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.LoadBalancerHashPolicy - (*CookiePolicy)(nil), // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.CookiePolicy - (*HeaderPolicy)(nil), // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderPolicy - (*QueryParameterPolicy)(nil), // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.QueryParameterPolicy - (*ConnectionPropertiesPolicy)(nil), // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.ConnectionPropertiesPolicy - (*HeaderMutation)(nil), // 16: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation - (*DestinationCluster)(nil), // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationCluster - (*L7WeightedClusterGroup)(nil), // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedClusterGroup - (*wrapperspb.BoolValue)(nil), // 19: google.protobuf.BoolValue - (*wrapperspb.UInt32Value)(nil), // 20: google.protobuf.UInt32Value - (*durationpb.Duration)(nil), // 21: google.protobuf.Duration -} -var file_pbmesh_v2beta1_pbproxystate_route_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Route.virtual_hosts:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.VirtualHost - 16, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.VirtualHost.header_mutations:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation - 2, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.VirtualHost.route_rules:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.RouteRule - 3, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteRule.match:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.RouteMatch - 7, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteRule.destination:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.RouteDestination - 16, // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteRule.header_mutations:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation - 4, // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteMatch.path_match:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.PathMatch - 6, // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteMatch.header_matches:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMatch - 5, // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteMatch.query_parameter_matches:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.QueryParameterMatch - 17, // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteDestination.cluster:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationCluster - 18, // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteDestination.weighted_clusters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedClusterGroup - 8, // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.RouteDestination.destination_configuration:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationConfiguration - 19, // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationConfiguration.auto_host_rewrite:type_name -> google.protobuf.BoolValue - 11, // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationConfiguration.hash_policies:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LoadBalancerHashPolicy - 10, // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationConfiguration.timeout_config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TimeoutConfig - 9, // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationConfiguration.retry_policy:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.RetryPolicy - 20, // 16: hashicorp.consul.mesh.v2beta1.pbproxystate.RetryPolicy.num_retries:type_name -> google.protobuf.UInt32Value - 21, // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.TimeoutConfig.timeout:type_name -> google.protobuf.Duration - 21, // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.TimeoutConfig.idle_timeout:type_name -> google.protobuf.Duration - 12, // 19: hashicorp.consul.mesh.v2beta1.pbproxystate.LoadBalancerHashPolicy.cookie:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CookiePolicy - 13, // 20: hashicorp.consul.mesh.v2beta1.pbproxystate.LoadBalancerHashPolicy.header:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderPolicy - 14, // 21: hashicorp.consul.mesh.v2beta1.pbproxystate.LoadBalancerHashPolicy.query_parameter:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.QueryParameterPolicy - 15, // 22: hashicorp.consul.mesh.v2beta1.pbproxystate.LoadBalancerHashPolicy.connection_properties:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.ConnectionPropertiesPolicy - 21, // 23: hashicorp.consul.mesh.v2beta1.pbproxystate.CookiePolicy.ttl:type_name -> google.protobuf.Duration - 24, // [24:24] is the sub-list for method output_type - 24, // [24:24] is the sub-list for method input_type - 24, // [24:24] is the sub-list for extension type_name - 24, // [24:24] is the sub-list for extension extendee - 0, // [0:24] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_route_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_route_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_route_proto != nil { - return - } - file_pbmesh_v2beta1_pbproxystate_cluster_proto_init() - file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Route); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VirtualHost); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouteRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouteMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PathMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryParameterMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeaderMatch); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RouteDestination); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DestinationConfiguration); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RetryPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TimeoutConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LoadBalancerHashPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CookiePolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeaderPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryParameterPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ConnectionPropertiesPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[4].OneofWrappers = []interface{}{ - (*PathMatch_Exact)(nil), - (*PathMatch_Prefix)(nil), - (*PathMatch_Regex)(nil), - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[5].OneofWrappers = []interface{}{ - (*QueryParameterMatch_Exact)(nil), - (*QueryParameterMatch_Regex)(nil), - (*QueryParameterMatch_Present)(nil), - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[6].OneofWrappers = []interface{}{ - (*HeaderMatch_Exact)(nil), - (*HeaderMatch_Prefix)(nil), - (*HeaderMatch_Suffix)(nil), - (*HeaderMatch_Regex)(nil), - (*HeaderMatch_Present)(nil), - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[7].OneofWrappers = []interface{}{ - (*RouteDestination_Cluster)(nil), - (*RouteDestination_WeightedClusters)(nil), - } - file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes[11].OneofWrappers = []interface{}{ - (*LoadBalancerHashPolicy_Cookie)(nil), - (*LoadBalancerHashPolicy_Header)(nil), - (*LoadBalancerHashPolicy_QueryParameter)(nil), - (*LoadBalancerHashPolicy_ConnectionProperties)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_route_proto_rawDesc, - NumEnums: 0, - NumMessages: 16, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_route_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_route_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_route_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_route_proto = out.File - file_pbmesh_v2beta1_pbproxystate_route_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_route_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_route_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/route.proto b/proto-public/pbmesh/v2beta1/pbproxystate/route.proto deleted file mode 100644 index d9b9c8dcd6422..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/route.proto +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -import "google/protobuf/duration.proto"; -import "google/protobuf/wrappers.proto"; -import "pbmesh/v2beta1/pbproxystate/cluster.proto"; -import "pbmesh/v2beta1/pbproxystate/header_mutations.proto"; - -message Route { - // virtual_hosts is a list of virtual hosts. A virtual host is selected based on an incoming request's host header. - repeated VirtualHost virtual_hosts = 1; -} - -message VirtualHost { - string name = 1; - // domains are used to match an incoming request's host header and determine which virtual host to use. - repeated string domains = 2; - // header_mutations to apply to the request when it matches this virtual host. These are applied after any headers in - // the RouteRule. - repeated HeaderMutation header_mutations = 3; - // route_rules are a list of rules to use for what to do next with this request. The first rule with a match will be - // used. - repeated RouteRule route_rules = 4; -} - -message RouteRule { - // match determines how to match the request. The first match determines which destination the request will go to. - RouteMatch match = 1; - // destination is where to send the request to. - RouteDestination destination = 2; - // header_mutations to apply to the request. These are applied before the VirtualHost header mutations. - repeated HeaderMutation header_mutations = 3; -} - -// RouteMatch has configuration to match a request. -message RouteMatch { - PathMatch path_match = 1; - repeated HeaderMatch header_matches = 2; - repeated string method_matches = 3; - repeated QueryParameterMatch query_parameter_matches = 4; -} - -message PathMatch { - oneof path_match { - string exact = 1; - string prefix = 2; - string regex = 3; - } -} - -message QueryParameterMatch { - string name = 1; - oneof match { - string exact = 2; - string regex = 3; - bool present = 4; - } -} - -message HeaderMatch { - string name = 1; - oneof match { - string exact = 2; - string prefix = 3; - string suffix = 4; - string regex = 5; - bool present = 6; - } - bool invert_match = 7; -} - -// RouteDestination has configuration for where to send a request. -message RouteDestination { - // destination is one or more clusters to route to. - oneof destination { - DestinationCluster cluster = 1; - L7WeightedClusterGroup weighted_clusters = 2; - } - DestinationConfiguration destination_configuration = 3; -} - -message DestinationConfiguration { - google.protobuf.BoolValue auto_host_rewrite = 1; - repeated LoadBalancerHashPolicy hash_policies = 2; - TimeoutConfig timeout_config = 3; - string prefix_rewrite = 4; - RetryPolicy retry_policy = 5; -} - -message RetryPolicy { - string retry_on = 1; - google.protobuf.UInt32Value num_retries = 2; - repeated uint32 retriable_status_codes = 3; -} - -message TimeoutConfig { - // +kubebuilder:validation:Format=duration - google.protobuf.Duration timeout = 1; - // +kubebuilder:validation:Format=duration - google.protobuf.Duration idle_timeout = 2; -} - -message LoadBalancerHashPolicy { - oneof policy { - CookiePolicy cookie = 1; - HeaderPolicy header = 2; - QueryParameterPolicy query_parameter = 3; - ConnectionPropertiesPolicy connection_properties = 4; - } -} - -message CookiePolicy { - string name = 1; - // +kubebuilder:validation:Format=duration - google.protobuf.Duration ttl = 2; - string path = 3; - bool terminal = 4; -} -message HeaderPolicy { - string name = 1; - bool terminal = 2; -} -message QueryParameterPolicy { - string name = 1; - bool terminal = 2; -} -message ConnectionPropertiesPolicy { - bool source_ip = 1; - bool terminal = 2; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/route_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/route_deepcopy.gen.go deleted file mode 100644 index e2eea4e78b5e3..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/route_deepcopy.gen.go +++ /dev/null @@ -1,342 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Route within kubernetes types, where deepcopy-gen is used. -func (in *Route) DeepCopyInto(out *Route) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route. Required by controller-gen. -func (in *Route) DeepCopy() *Route { - if in == nil { - return nil - } - out := new(Route) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Route. Required by controller-gen. -func (in *Route) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using VirtualHost within kubernetes types, where deepcopy-gen is used. -func (in *VirtualHost) DeepCopyInto(out *VirtualHost) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualHost. Required by controller-gen. -func (in *VirtualHost) DeepCopy() *VirtualHost { - if in == nil { - return nil - } - out := new(VirtualHost) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new VirtualHost. Required by controller-gen. -func (in *VirtualHost) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using RouteRule within kubernetes types, where deepcopy-gen is used. -func (in *RouteRule) DeepCopyInto(out *RouteRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteRule. Required by controller-gen. -func (in *RouteRule) DeepCopy() *RouteRule { - if in == nil { - return nil - } - out := new(RouteRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new RouteRule. Required by controller-gen. -func (in *RouteRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using RouteMatch within kubernetes types, where deepcopy-gen is used. -func (in *RouteMatch) DeepCopyInto(out *RouteMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteMatch. Required by controller-gen. -func (in *RouteMatch) DeepCopy() *RouteMatch { - if in == nil { - return nil - } - out := new(RouteMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new RouteMatch. Required by controller-gen. -func (in *RouteMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using PathMatch within kubernetes types, where deepcopy-gen is used. -func (in *PathMatch) DeepCopyInto(out *PathMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PathMatch. Required by controller-gen. -func (in *PathMatch) DeepCopy() *PathMatch { - if in == nil { - return nil - } - out := new(PathMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new PathMatch. Required by controller-gen. -func (in *PathMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using QueryParameterMatch within kubernetes types, where deepcopy-gen is used. -func (in *QueryParameterMatch) DeepCopyInto(out *QueryParameterMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryParameterMatch. Required by controller-gen. -func (in *QueryParameterMatch) DeepCopy() *QueryParameterMatch { - if in == nil { - return nil - } - out := new(QueryParameterMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new QueryParameterMatch. Required by controller-gen. -func (in *QueryParameterMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HeaderMatch within kubernetes types, where deepcopy-gen is used. -func (in *HeaderMatch) DeepCopyInto(out *HeaderMatch) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMatch. Required by controller-gen. -func (in *HeaderMatch) DeepCopy() *HeaderMatch { - if in == nil { - return nil - } - out := new(HeaderMatch) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMatch. Required by controller-gen. -func (in *HeaderMatch) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using RouteDestination within kubernetes types, where deepcopy-gen is used. -func (in *RouteDestination) DeepCopyInto(out *RouteDestination) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteDestination. Required by controller-gen. -func (in *RouteDestination) DeepCopy() *RouteDestination { - if in == nil { - return nil - } - out := new(RouteDestination) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new RouteDestination. Required by controller-gen. -func (in *RouteDestination) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DestinationConfiguration within kubernetes types, where deepcopy-gen is used. -func (in *DestinationConfiguration) DeepCopyInto(out *DestinationConfiguration) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfiguration. Required by controller-gen. -func (in *DestinationConfiguration) DeepCopy() *DestinationConfiguration { - if in == nil { - return nil - } - out := new(DestinationConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfiguration. Required by controller-gen. -func (in *DestinationConfiguration) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using RetryPolicy within kubernetes types, where deepcopy-gen is used. -func (in *RetryPolicy) DeepCopyInto(out *RetryPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RetryPolicy. Required by controller-gen. -func (in *RetryPolicy) DeepCopy() *RetryPolicy { - if in == nil { - return nil - } - out := new(RetryPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new RetryPolicy. Required by controller-gen. -func (in *RetryPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TimeoutConfig within kubernetes types, where deepcopy-gen is used. -func (in *TimeoutConfig) DeepCopyInto(out *TimeoutConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TimeoutConfig. Required by controller-gen. -func (in *TimeoutConfig) DeepCopy() *TimeoutConfig { - if in == nil { - return nil - } - out := new(TimeoutConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TimeoutConfig. Required by controller-gen. -func (in *TimeoutConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LoadBalancerHashPolicy within kubernetes types, where deepcopy-gen is used. -func (in *LoadBalancerHashPolicy) DeepCopyInto(out *LoadBalancerHashPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancerHashPolicy. Required by controller-gen. -func (in *LoadBalancerHashPolicy) DeepCopy() *LoadBalancerHashPolicy { - if in == nil { - return nil - } - out := new(LoadBalancerHashPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancerHashPolicy. Required by controller-gen. -func (in *LoadBalancerHashPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using CookiePolicy within kubernetes types, where deepcopy-gen is used. -func (in *CookiePolicy) DeepCopyInto(out *CookiePolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookiePolicy. Required by controller-gen. -func (in *CookiePolicy) DeepCopy() *CookiePolicy { - if in == nil { - return nil - } - out := new(CookiePolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new CookiePolicy. Required by controller-gen. -func (in *CookiePolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using HeaderPolicy within kubernetes types, where deepcopy-gen is used. -func (in *HeaderPolicy) DeepCopyInto(out *HeaderPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderPolicy. Required by controller-gen. -func (in *HeaderPolicy) DeepCopy() *HeaderPolicy { - if in == nil { - return nil - } - out := new(HeaderPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new HeaderPolicy. Required by controller-gen. -func (in *HeaderPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using QueryParameterPolicy within kubernetes types, where deepcopy-gen is used. -func (in *QueryParameterPolicy) DeepCopyInto(out *QueryParameterPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryParameterPolicy. Required by controller-gen. -func (in *QueryParameterPolicy) DeepCopy() *QueryParameterPolicy { - if in == nil { - return nil - } - out := new(QueryParameterPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new QueryParameterPolicy. Required by controller-gen. -func (in *QueryParameterPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ConnectionPropertiesPolicy within kubernetes types, where deepcopy-gen is used. -func (in *ConnectionPropertiesPolicy) DeepCopyInto(out *ConnectionPropertiesPolicy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionPropertiesPolicy. Required by controller-gen. -func (in *ConnectionPropertiesPolicy) DeepCopy() *ConnectionPropertiesPolicy { - if in == nil { - return nil - } - out := new(ConnectionPropertiesPolicy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionPropertiesPolicy. Required by controller-gen. -func (in *ConnectionPropertiesPolicy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/route_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/route_json.gen.go deleted file mode 100644 index 23682dc572778..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/route_json.gen.go +++ /dev/null @@ -1,187 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Route -func (this *Route) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Route -func (this *Route) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for VirtualHost -func (this *VirtualHost) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for VirtualHost -func (this *VirtualHost) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for RouteRule -func (this *RouteRule) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for RouteRule -func (this *RouteRule) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for RouteMatch -func (this *RouteMatch) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for RouteMatch -func (this *RouteMatch) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for PathMatch -func (this *PathMatch) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for PathMatch -func (this *PathMatch) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for QueryParameterMatch -func (this *QueryParameterMatch) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for QueryParameterMatch -func (this *QueryParameterMatch) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HeaderMatch -func (this *HeaderMatch) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HeaderMatch -func (this *HeaderMatch) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for RouteDestination -func (this *RouteDestination) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for RouteDestination -func (this *RouteDestination) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DestinationConfiguration -func (this *DestinationConfiguration) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DestinationConfiguration -func (this *DestinationConfiguration) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for RetryPolicy -func (this *RetryPolicy) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for RetryPolicy -func (this *RetryPolicy) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TimeoutConfig -func (this *TimeoutConfig) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TimeoutConfig -func (this *TimeoutConfig) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LoadBalancerHashPolicy -func (this *LoadBalancerHashPolicy) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LoadBalancerHashPolicy -func (this *LoadBalancerHashPolicy) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for CookiePolicy -func (this *CookiePolicy) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for CookiePolicy -func (this *CookiePolicy) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for HeaderPolicy -func (this *HeaderPolicy) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for HeaderPolicy -func (this *HeaderPolicy) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for QueryParameterPolicy -func (this *QueryParameterPolicy) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for QueryParameterPolicy -func (this *QueryParameterPolicy) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ConnectionPropertiesPolicy -func (this *ConnectionPropertiesPolicy) MarshalJSON() ([]byte, error) { - str, err := RouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ConnectionPropertiesPolicy -func (this *ConnectionPropertiesPolicy) UnmarshalJSON(b []byte) error { - return RouteUnmarshaler.Unmarshal(b, this) -} - -var ( - RouteMarshaler = &protojson.MarshalOptions{} - RouteUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.binary.go deleted file mode 100644 index 403b64f4699e0..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.binary.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/traffic_permissions.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TrafficPermissions) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TrafficPermissions) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Permission) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Permission) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Principal) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Principal) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Spiffe) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Spiffe) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go deleted file mode 100644 index def42e933f97d..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go +++ /dev/null @@ -1,429 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/traffic_permissions.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type TrafficPermissions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AllowPermissions []*Permission `protobuf:"bytes,1,rep,name=allow_permissions,json=allowPermissions,proto3" json:"allow_permissions,omitempty"` - DenyPermissions []*Permission `protobuf:"bytes,2,rep,name=deny_permissions,json=denyPermissions,proto3" json:"deny_permissions,omitempty"` - // default_allow determines if the workload is in default allow mode. This is determined - // by combining the cluster's default allow setting with the is_default property on - // computed traffic permissions. - DefaultAllow bool `protobuf:"varint,4,opt,name=default_allow,json=defaultAllow,proto3" json:"default_allow,omitempty"` -} - -func (x *TrafficPermissions) Reset() { - *x = TrafficPermissions{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TrafficPermissions) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TrafficPermissions) ProtoMessage() {} - -func (x *TrafficPermissions) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TrafficPermissions.ProtoReflect.Descriptor instead. -func (*TrafficPermissions) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescGZIP(), []int{0} -} - -func (x *TrafficPermissions) GetAllowPermissions() []*Permission { - if x != nil { - return x.AllowPermissions - } - return nil -} - -func (x *TrafficPermissions) GetDenyPermissions() []*Permission { - if x != nil { - return x.DenyPermissions - } - return nil -} - -func (x *TrafficPermissions) GetDefaultAllow() bool { - if x != nil { - return x.DefaultAllow - } - return false -} - -type Permission struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Principals []*Principal `protobuf:"bytes,1,rep,name=principals,proto3" json:"principals,omitempty"` -} - -func (x *Permission) Reset() { - *x = Permission{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Permission) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Permission) ProtoMessage() {} - -func (x *Permission) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Permission.ProtoReflect.Descriptor instead. -func (*Permission) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescGZIP(), []int{1} -} - -func (x *Permission) GetPrincipals() []*Principal { - if x != nil { - return x.Principals - } - return nil -} - -type Principal struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Spiffe *Spiffe `protobuf:"bytes,1,opt,name=spiffe,proto3" json:"spiffe,omitempty"` - ExcludeSpiffes []*Spiffe `protobuf:"bytes,2,rep,name=exclude_spiffes,json=excludeSpiffes,proto3" json:"exclude_spiffes,omitempty"` -} - -func (x *Principal) Reset() { - *x = Principal{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Principal) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Principal) ProtoMessage() {} - -func (x *Principal) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Principal.ProtoReflect.Descriptor instead. -func (*Principal) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescGZIP(), []int{2} -} - -func (x *Principal) GetSpiffe() *Spiffe { - if x != nil { - return x.Spiffe - } - return nil -} - -func (x *Principal) GetExcludeSpiffes() []*Spiffe { - if x != nil { - return x.ExcludeSpiffes - } - return nil -} - -type Spiffe struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // regex is the regular expression for matching spiffe ids. - Regex string `protobuf:"bytes,1,opt,name=regex,proto3" json:"regex,omitempty"` - // xfcc_regex specifies that Envoy needs to find the spiffe id in an xfcc header. - // It is currently unused, but considering this is important for to avoid breaking changes. - XfccRegex string `protobuf:"bytes,2,opt,name=xfcc_regex,json=xfccRegex,proto3" json:"xfcc_regex,omitempty"` -} - -func (x *Spiffe) Reset() { - *x = Spiffe{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Spiffe) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Spiffe) ProtoMessage() {} - -func (x *Spiffe) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Spiffe.ProtoReflect.Descriptor instead. -func (*Spiffe) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescGZIP(), []int{3} -} - -func (x *Spiffe) GetRegex() string { - if x != nil { - return x.Regex - } - return "" -} - -func (x *Spiffe) GetXfccRegex() string { - if x != nil { - return x.XfccRegex - } - return "" -} - -var File_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc = []byte{ - 0x0a, 0x35, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, 0x72, - 0x61, 0x66, 0x66, 0x69, 0x63, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x22, 0x81, 0x02, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x63, 0x0a, 0x11, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x61, 0x0a, 0x10, 0x64, 0x65, 0x6e, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x0f, 0x64, 0x65, 0x6e, 0x79, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x22, 0x63, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, - 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, - 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x22, 0xb4, 0x01, 0x0a, - 0x09, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x70, - 0x69, 0x66, 0x66, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x52, 0x06, - 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x12, 0x5b, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x5f, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, - 0x66, 0x66, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x70, 0x69, 0x66, - 0x66, 0x65, 0x73, 0x22, 0x3d, 0x0a, 0x06, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, - 0x67, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x78, 0x66, 0x63, 0x63, 0x5f, 0x72, 0x65, 0x67, 0x65, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x78, 0x66, 0x63, 0x63, 0x52, 0x65, 0x67, - 0x65, 0x78, 0x42, 0xdd, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x17, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, - 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, - 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_goTypes = []interface{}{ - (*TrafficPermissions)(nil), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions - (*Permission)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Permission - (*Principal)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal - (*Spiffe)(nil), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe -} -var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions.allow_permissions:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Permission - 1, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions.deny_permissions:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Permission - 2, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Permission.principals:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Principal - 3, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal.spiffe:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe - 3, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal.exclude_spiffes:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TrafficPermissions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Permission); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Principal); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Spiffe); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto = out.File - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto deleted file mode 100644 index 918b092c0a36e..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -message TrafficPermissions { - repeated Permission allow_permissions = 1; - repeated Permission deny_permissions = 2; - // default_allow determines if the workload is in default allow mode. This is determined - // by combining the cluster's default allow setting with the is_default property on - // computed traffic permissions. - bool default_allow = 4; -} - -message Permission { - repeated Principal principals = 1; - - // We don't need destination rules here yet because they either apply to L7 features or multi-ports. - // In the case of multiple ports, the sidecar proxy controller is responsible for filtering - // per-port permissions. -} - -message Principal { - Spiffe spiffe = 1; - repeated Spiffe exclude_spiffes = 2; -} - -message Spiffe { - // regex is the regular expression for matching spiffe ids. - string regex = 1; - - // xfcc_regex specifies that Envoy needs to find the spiffe id in an xfcc header. - // It is currently unused, but considering this is important for to avoid breaking changes. - string xfcc_regex = 2; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go deleted file mode 100644 index b45d2a79261a6..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go +++ /dev/null @@ -1,90 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using TrafficPermissions within kubernetes types, where deepcopy-gen is used. -func (in *TrafficPermissions) DeepCopyInto(out *TrafficPermissions) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficPermissions. Required by controller-gen. -func (in *TrafficPermissions) DeepCopy() *TrafficPermissions { - if in == nil { - return nil - } - out := new(TrafficPermissions) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TrafficPermissions. Required by controller-gen. -func (in *TrafficPermissions) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Permission within kubernetes types, where deepcopy-gen is used. -func (in *Permission) DeepCopyInto(out *Permission) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Permission. Required by controller-gen. -func (in *Permission) DeepCopy() *Permission { - if in == nil { - return nil - } - out := new(Permission) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Permission. Required by controller-gen. -func (in *Permission) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Principal within kubernetes types, where deepcopy-gen is used. -func (in *Principal) DeepCopyInto(out *Principal) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal. Required by controller-gen. -func (in *Principal) DeepCopy() *Principal { - if in == nil { - return nil - } - out := new(Principal) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Principal. Required by controller-gen. -func (in *Principal) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Spiffe within kubernetes types, where deepcopy-gen is used. -func (in *Spiffe) DeepCopyInto(out *Spiffe) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Spiffe. Required by controller-gen. -func (in *Spiffe) DeepCopy() *Spiffe { - if in == nil { - return nil - } - out := new(Spiffe) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Spiffe. Required by controller-gen. -func (in *Spiffe) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_json.gen.go deleted file mode 100644 index 3651fcabcabe9..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_json.gen.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for TrafficPermissions -func (this *TrafficPermissions) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TrafficPermissions -func (this *TrafficPermissions) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Permission -func (this *Permission) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Permission -func (this *Permission) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Principal -func (this *Principal) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Principal -func (this *Principal) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Spiffe -func (this *Spiffe) MarshalJSON() ([]byte, error) { - str, err := TrafficPermissionsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Spiffe -func (this *Spiffe) UnmarshalJSON(b []byte) error { - return TrafficPermissionsUnmarshaler.Unmarshal(b, this) -} - -var ( - TrafficPermissionsMarshaler = &protojson.MarshalOptions{} - TrafficPermissionsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.pb.binary.go deleted file mode 100644 index 867d974415386..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.pb.binary.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/pbproxystate/transport_socket.proto - -package pbproxystate - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TLS) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TLS) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TransportSocket) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TransportSocket) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *InboundMeshMTLS) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *InboundMeshMTLS) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *OutboundMeshMTLS) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *OutboundMeshMTLS) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *InboundNonMeshTLS) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *InboundNonMeshTLS) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *OutboundNonMeshTLS) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *OutboundNonMeshTLS) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *MeshInboundValidationContext) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *MeshInboundValidationContext) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *MeshOutboundValidationContext) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *MeshOutboundValidationContext) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *NonMeshOutboundValidationContext) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *NonMeshOutboundValidationContext) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *SDSCertificate) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *SDSCertificate) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TLSParameters) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TLSParameters) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *LeafCertificate) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *LeafCertificate) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TrustBundle) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TrustBundle) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.pb.go deleted file mode 100644 index d3acedebd182f..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.pb.go +++ /dev/null @@ -1,1507 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/pbproxystate/transport_socket.proto - -package pbproxystate - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=TLS_VERSION_AUTO;TLS_VERSION_1_0;TLS_VERSION_1_1;TLS_VERSION_1_2;TLS_VERSION_1_3;TLS_VERSION_INVALID;TLS_VERSION_UNSPECIFIED -// +kubebuilder:validation:Type=string -type TLSVersion int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - TLSVersion_TLS_VERSION_AUTO TLSVersion = 0 - TLSVersion_TLS_VERSION_1_0 TLSVersion = 1 - TLSVersion_TLS_VERSION_1_1 TLSVersion = 2 - TLSVersion_TLS_VERSION_1_2 TLSVersion = 3 - TLSVersion_TLS_VERSION_1_3 TLSVersion = 4 - TLSVersion_TLS_VERSION_INVALID TLSVersion = 5 - TLSVersion_TLS_VERSION_UNSPECIFIED TLSVersion = 6 -) - -// Enum value maps for TLSVersion. -var ( - TLSVersion_name = map[int32]string{ - 0: "TLS_VERSION_AUTO", - 1: "TLS_VERSION_1_0", - 2: "TLS_VERSION_1_1", - 3: "TLS_VERSION_1_2", - 4: "TLS_VERSION_1_3", - 5: "TLS_VERSION_INVALID", - 6: "TLS_VERSION_UNSPECIFIED", - } - TLSVersion_value = map[string]int32{ - "TLS_VERSION_AUTO": 0, - "TLS_VERSION_1_0": 1, - "TLS_VERSION_1_1": 2, - "TLS_VERSION_1_2": 3, - "TLS_VERSION_1_3": 4, - "TLS_VERSION_INVALID": 5, - "TLS_VERSION_UNSPECIFIED": 6, - } -) - -func (x TLSVersion) Enum() *TLSVersion { - p := new(TLSVersion) - *p = x - return p -} - -func (x TLSVersion) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (TLSVersion) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_enumTypes[0].Descriptor() -} - -func (TLSVersion) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_enumTypes[0] -} - -func (x TLSVersion) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use TLSVersion.Descriptor instead. -func (TLSVersion) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{0} -} - -// +kubebuilder:validation:Enum=TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256;TLS_CIPHER_SUITE_AES256_SHA;TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305;TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256;TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305;TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA;TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA;TLS_CIPHER_SUITE_AES128_GCM_SHA256;TLS_CIPHER_SUITE_AES128_SHA;TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384;TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384;TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA;TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA;TLS_CIPHER_SUITE_AES256_GCM_SHA384 -// +kubebuilder:validation:Type=string -type TLSCipherSuite int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256 TLSCipherSuite = 0 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305 TLSCipherSuite = 1 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256 TLSCipherSuite = 2 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305 TLSCipherSuite = 3 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA TLSCipherSuite = 4 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA TLSCipherSuite = 5 - TLSCipherSuite_TLS_CIPHER_SUITE_AES128_GCM_SHA256 TLSCipherSuite = 6 - TLSCipherSuite_TLS_CIPHER_SUITE_AES128_SHA TLSCipherSuite = 7 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384 TLSCipherSuite = 8 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384 TLSCipherSuite = 9 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA TLSCipherSuite = 10 - TLSCipherSuite_TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA TLSCipherSuite = 11 - TLSCipherSuite_TLS_CIPHER_SUITE_AES256_GCM_SHA384 TLSCipherSuite = 12 - TLSCipherSuite_TLS_CIPHER_SUITE_AES256_SHA TLSCipherSuite = 13 -) - -// Enum value maps for TLSCipherSuite. -var ( - TLSCipherSuite_name = map[int32]string{ - 0: "TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256", - 1: "TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305", - 2: "TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256", - 3: "TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305", - 4: "TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA", - 5: "TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA", - 6: "TLS_CIPHER_SUITE_AES128_GCM_SHA256", - 7: "TLS_CIPHER_SUITE_AES128_SHA", - 8: "TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384", - 9: "TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384", - 10: "TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA", - 11: "TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA", - 12: "TLS_CIPHER_SUITE_AES256_GCM_SHA384", - 13: "TLS_CIPHER_SUITE_AES256_SHA", - } - TLSCipherSuite_value = map[string]int32{ - "TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256": 0, - "TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305": 1, - "TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256": 2, - "TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305": 3, - "TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA": 4, - "TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA": 5, - "TLS_CIPHER_SUITE_AES128_GCM_SHA256": 6, - "TLS_CIPHER_SUITE_AES128_SHA": 7, - "TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384": 8, - "TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384": 9, - "TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA": 10, - "TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA": 11, - "TLS_CIPHER_SUITE_AES256_GCM_SHA384": 12, - "TLS_CIPHER_SUITE_AES256_SHA": 13, - } -) - -func (x TLSCipherSuite) Enum() *TLSCipherSuite { - p := new(TLSCipherSuite) - *p = x - return p -} - -func (x TLSCipherSuite) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (TLSCipherSuite) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_enumTypes[1].Descriptor() -} - -func (TLSCipherSuite) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_enumTypes[1] -} - -func (x TLSCipherSuite) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use TLSCipherSuite.Descriptor instead. -func (TLSCipherSuite) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{1} -} - -type TLS struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // inbound_tls_parameters has default TLS parameter configuration for inbound connections. These can be overridden per - // transport socket. - InboundTlsParameters *TLSParameters `protobuf:"bytes,1,opt,name=inbound_tls_parameters,json=inboundTlsParameters,proto3" json:"inbound_tls_parameters,omitempty"` - // outbound_tls_parameters has default TLS parameter configuration for inbound connections. These can be overridden per transport socket. - OutboundTlsParameters *TLSParameters `protobuf:"bytes,2,opt,name=outbound_tls_parameters,json=outboundTlsParameters,proto3" json:"outbound_tls_parameters,omitempty"` -} - -func (x *TLS) Reset() { - *x = TLS{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TLS) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TLS) ProtoMessage() {} - -func (x *TLS) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TLS.ProtoReflect.Descriptor instead. -func (*TLS) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{0} -} - -func (x *TLS) GetInboundTlsParameters() *TLSParameters { - if x != nil { - return x.InboundTlsParameters - } - return nil -} - -func (x *TLS) GetOutboundTlsParameters() *TLSParameters { - if x != nil { - return x.OutboundTlsParameters - } - return nil -} - -type TransportSocket struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // name of the transport socket - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Types that are assignable to ConnectionTls: - // - // *TransportSocket_InboundMesh - // *TransportSocket_OutboundMesh - // *TransportSocket_InboundNonMesh - // *TransportSocket_OutboundNonMesh - ConnectionTls isTransportSocket_ConnectionTls `protobuf_oneof:"connection_tls"` - // tls_parameters can override any top level tls parameters that are configured. - TlsParameters *TLSParameters `protobuf:"bytes,6,opt,name=tls_parameters,json=tlsParameters,proto3" json:"tls_parameters,omitempty"` - AlpnProtocols []string `protobuf:"bytes,7,rep,name=alpn_protocols,json=alpnProtocols,proto3" json:"alpn_protocols,omitempty"` -} - -func (x *TransportSocket) Reset() { - *x = TransportSocket{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TransportSocket) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TransportSocket) ProtoMessage() {} - -func (x *TransportSocket) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TransportSocket.ProtoReflect.Descriptor instead. -func (*TransportSocket) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{1} -} - -func (x *TransportSocket) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (m *TransportSocket) GetConnectionTls() isTransportSocket_ConnectionTls { - if m != nil { - return m.ConnectionTls - } - return nil -} - -func (x *TransportSocket) GetInboundMesh() *InboundMeshMTLS { - if x, ok := x.GetConnectionTls().(*TransportSocket_InboundMesh); ok { - return x.InboundMesh - } - return nil -} - -func (x *TransportSocket) GetOutboundMesh() *OutboundMeshMTLS { - if x, ok := x.GetConnectionTls().(*TransportSocket_OutboundMesh); ok { - return x.OutboundMesh - } - return nil -} - -func (x *TransportSocket) GetInboundNonMesh() *InboundNonMeshTLS { - if x, ok := x.GetConnectionTls().(*TransportSocket_InboundNonMesh); ok { - return x.InboundNonMesh - } - return nil -} - -func (x *TransportSocket) GetOutboundNonMesh() *OutboundNonMeshTLS { - if x, ok := x.GetConnectionTls().(*TransportSocket_OutboundNonMesh); ok { - return x.OutboundNonMesh - } - return nil -} - -func (x *TransportSocket) GetTlsParameters() *TLSParameters { - if x != nil { - return x.TlsParameters - } - return nil -} - -func (x *TransportSocket) GetAlpnProtocols() []string { - if x != nil { - return x.AlpnProtocols - } - return nil -} - -type isTransportSocket_ConnectionTls interface { - isTransportSocket_ConnectionTls() -} - -type TransportSocket_InboundMesh struct { - // inbound_mesh is for incoming connections FROM the mesh. - InboundMesh *InboundMeshMTLS `protobuf:"bytes,2,opt,name=inbound_mesh,json=inboundMesh,proto3,oneof"` -} - -type TransportSocket_OutboundMesh struct { - // outbound_mesh is for outbound connections TO mesh destinations. - OutboundMesh *OutboundMeshMTLS `protobuf:"bytes,3,opt,name=outbound_mesh,json=outboundMesh,proto3,oneof"` -} - -type TransportSocket_InboundNonMesh struct { - // inbound_non_mesh is for incoming connections FROM non mesh. - InboundNonMesh *InboundNonMeshTLS `protobuf:"bytes,4,opt,name=inbound_non_mesh,json=inboundNonMesh,proto3,oneof"` -} - -type TransportSocket_OutboundNonMesh struct { - // outbound_non_mesh is for outbound connections TO non mesh destinations. - OutboundNonMesh *OutboundNonMeshTLS `protobuf:"bytes,5,opt,name=outbound_non_mesh,json=outboundNonMesh,proto3,oneof"` -} - -func (*TransportSocket_InboundMesh) isTransportSocket_ConnectionTls() {} - -func (*TransportSocket_OutboundMesh) isTransportSocket_ConnectionTls() {} - -func (*TransportSocket_InboundNonMesh) isTransportSocket_ConnectionTls() {} - -func (*TransportSocket_OutboundNonMesh) isTransportSocket_ConnectionTls() {} - -type InboundMeshMTLS struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // identity_key is UUID key to use to look up the leaf certificate in ProxyState to present for incoming connections. - IdentityKey string `protobuf:"bytes,1,opt,name=identity_key,json=identityKey,proto3" json:"identity_key,omitempty"` - // validation_context has what is needed to validate incoming connections. - ValidationContext *MeshInboundValidationContext `protobuf:"bytes,2,opt,name=validation_context,json=validationContext,proto3" json:"validation_context,omitempty"` -} - -func (x *InboundMeshMTLS) Reset() { - *x = InboundMeshMTLS{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InboundMeshMTLS) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InboundMeshMTLS) ProtoMessage() {} - -func (x *InboundMeshMTLS) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InboundMeshMTLS.ProtoReflect.Descriptor instead. -func (*InboundMeshMTLS) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{2} -} - -func (x *InboundMeshMTLS) GetIdentityKey() string { - if x != nil { - return x.IdentityKey - } - return "" -} - -func (x *InboundMeshMTLS) GetValidationContext() *MeshInboundValidationContext { - if x != nil { - return x.ValidationContext - } - return nil -} - -type OutboundMeshMTLS struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // identity_key is UUID key to use to look up the leaf certificate in ProxyState when connecting to destinations. - IdentityKey string `protobuf:"bytes,1,opt,name=identity_key,json=identityKey,proto3" json:"identity_key,omitempty"` - // validation_context has what is needed to validate the destination. - ValidationContext *MeshOutboundValidationContext `protobuf:"bytes,2,opt,name=validation_context,json=validationContext,proto3" json:"validation_context,omitempty"` - // sni to use when connecting to the destination. - Sni string `protobuf:"bytes,3,opt,name=sni,proto3" json:"sni,omitempty"` -} - -func (x *OutboundMeshMTLS) Reset() { - *x = OutboundMeshMTLS{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OutboundMeshMTLS) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OutboundMeshMTLS) ProtoMessage() {} - -func (x *OutboundMeshMTLS) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OutboundMeshMTLS.ProtoReflect.Descriptor instead. -func (*OutboundMeshMTLS) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{3} -} - -func (x *OutboundMeshMTLS) GetIdentityKey() string { - if x != nil { - return x.IdentityKey - } - return "" -} - -func (x *OutboundMeshMTLS) GetValidationContext() *MeshOutboundValidationContext { - if x != nil { - return x.ValidationContext - } - return nil -} - -func (x *OutboundMeshMTLS) GetSni() string { - if x != nil { - return x.Sni - } - return "" -} - -type InboundNonMeshTLS struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // identity is the reference to the leaf certificate to present for incoming connections. - // - // Types that are assignable to Identity: - // - // *InboundNonMeshTLS_LeafKey - // *InboundNonMeshTLS_Sds - Identity isInboundNonMeshTLS_Identity `protobuf_oneof:"identity"` -} - -func (x *InboundNonMeshTLS) Reset() { - *x = InboundNonMeshTLS{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InboundNonMeshTLS) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InboundNonMeshTLS) ProtoMessage() {} - -func (x *InboundNonMeshTLS) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InboundNonMeshTLS.ProtoReflect.Descriptor instead. -func (*InboundNonMeshTLS) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{4} -} - -func (m *InboundNonMeshTLS) GetIdentity() isInboundNonMeshTLS_Identity { - if m != nil { - return m.Identity - } - return nil -} - -func (x *InboundNonMeshTLS) GetLeafKey() string { - if x, ok := x.GetIdentity().(*InboundNonMeshTLS_LeafKey); ok { - return x.LeafKey - } - return "" -} - -func (x *InboundNonMeshTLS) GetSds() *SDSCertificate { - if x, ok := x.GetIdentity().(*InboundNonMeshTLS_Sds); ok { - return x.Sds - } - return nil -} - -type isInboundNonMeshTLS_Identity interface { - isInboundNonMeshTLS_Identity() -} - -type InboundNonMeshTLS_LeafKey struct { - // leaf_key is the UUID key to use to look up the leaf certificate in the ProxyState leaf certificate map. - LeafKey string `protobuf:"bytes,1,opt,name=leaf_key,json=leafKey,proto3,oneof"` -} - -type InboundNonMeshTLS_Sds struct { - // sds refers to certificates retrieved via Envoy SDS. - Sds *SDSCertificate `protobuf:"bytes,2,opt,name=sds,proto3,oneof"` -} - -func (*InboundNonMeshTLS_LeafKey) isInboundNonMeshTLS_Identity() {} - -func (*InboundNonMeshTLS_Sds) isInboundNonMeshTLS_Identity() {} - -type OutboundNonMeshTLS struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // cert_file is a filename for a certificate to present for outbound connections. - CertFile string `protobuf:"bytes,1,opt,name=cert_file,json=certFile,proto3" json:"cert_file,omitempty"` - // key_file is a filename for a key for outbound connections. - KeyFile string `protobuf:"bytes,2,opt,name=key_file,json=keyFile,proto3" json:"key_file,omitempty"` - // validation_context has what is needed to validate the destination. - ValidationContext *NonMeshOutboundValidationContext `protobuf:"bytes,3,opt,name=validation_context,json=validationContext,proto3" json:"validation_context,omitempty"` -} - -func (x *OutboundNonMeshTLS) Reset() { - *x = OutboundNonMeshTLS{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OutboundNonMeshTLS) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OutboundNonMeshTLS) ProtoMessage() {} - -func (x *OutboundNonMeshTLS) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use OutboundNonMeshTLS.ProtoReflect.Descriptor instead. -func (*OutboundNonMeshTLS) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{5} -} - -func (x *OutboundNonMeshTLS) GetCertFile() string { - if x != nil { - return x.CertFile - } - return "" -} - -func (x *OutboundNonMeshTLS) GetKeyFile() string { - if x != nil { - return x.KeyFile - } - return "" -} - -func (x *OutboundNonMeshTLS) GetValidationContext() *NonMeshOutboundValidationContext { - if x != nil { - return x.ValidationContext - } - return nil -} - -type MeshInboundValidationContext struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // trust_bundle_peer_name_keys is which trust bundles to use for validating incoming connections. If this workload is exported - // to peers, the incoming connection could be from a different peer, requiring that trust bundle to validate the - // connection. These could be local or peered trust bundles. This will be a key in the trust bundle map. - TrustBundlePeerNameKeys []string `protobuf:"bytes,1,rep,name=trust_bundle_peer_name_keys,json=trustBundlePeerNameKeys,proto3" json:"trust_bundle_peer_name_keys,omitempty"` -} - -func (x *MeshInboundValidationContext) Reset() { - *x = MeshInboundValidationContext{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MeshInboundValidationContext) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MeshInboundValidationContext) ProtoMessage() {} - -func (x *MeshInboundValidationContext) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MeshInboundValidationContext.ProtoReflect.Descriptor instead. -func (*MeshInboundValidationContext) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{6} -} - -func (x *MeshInboundValidationContext) GetTrustBundlePeerNameKeys() []string { - if x != nil { - return x.TrustBundlePeerNameKeys - } - return nil -} - -type MeshOutboundValidationContext struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // trust_bundle_peer_name_key is which trust bundle to use for the destination. It could be the local or a peer's trust bundle. - // This will be a key in the trust bundle map. - TrustBundlePeerNameKey string `protobuf:"bytes,1,opt,name=trust_bundle_peer_name_key,json=trustBundlePeerNameKey,proto3" json:"trust_bundle_peer_name_key,omitempty"` - // spiffe_ids is one or more spiffe IDs to validate. - SpiffeIds []string `protobuf:"bytes,2,rep,name=spiffe_ids,json=spiffeIds,proto3" json:"spiffe_ids,omitempty"` -} - -func (x *MeshOutboundValidationContext) Reset() { - *x = MeshOutboundValidationContext{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MeshOutboundValidationContext) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MeshOutboundValidationContext) ProtoMessage() {} - -func (x *MeshOutboundValidationContext) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MeshOutboundValidationContext.ProtoReflect.Descriptor instead. -func (*MeshOutboundValidationContext) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{7} -} - -func (x *MeshOutboundValidationContext) GetTrustBundlePeerNameKey() string { - if x != nil { - return x.TrustBundlePeerNameKey - } - return "" -} - -func (x *MeshOutboundValidationContext) GetSpiffeIds() []string { - if x != nil { - return x.SpiffeIds - } - return nil -} - -type NonMeshOutboundValidationContext struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ca_file is a filename for a ca for outbound connections to validate the destination. - CaFile string `protobuf:"bytes,1,opt,name=ca_file,json=caFile,proto3" json:"ca_file,omitempty"` -} - -func (x *NonMeshOutboundValidationContext) Reset() { - *x = NonMeshOutboundValidationContext{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NonMeshOutboundValidationContext) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NonMeshOutboundValidationContext) ProtoMessage() {} - -func (x *NonMeshOutboundValidationContext) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NonMeshOutboundValidationContext.ProtoReflect.Descriptor instead. -func (*NonMeshOutboundValidationContext) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{8} -} - -func (x *NonMeshOutboundValidationContext) GetCaFile() string { - if x != nil { - return x.CaFile - } - return "" -} - -type SDSCertificate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ClusterName string `protobuf:"bytes,1,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"` - CertResource string `protobuf:"bytes,2,opt,name=cert_resource,json=certResource,proto3" json:"cert_resource,omitempty"` -} - -func (x *SDSCertificate) Reset() { - *x = SDSCertificate{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SDSCertificate) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SDSCertificate) ProtoMessage() {} - -func (x *SDSCertificate) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SDSCertificate.ProtoReflect.Descriptor instead. -func (*SDSCertificate) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{9} -} - -func (x *SDSCertificate) GetClusterName() string { - if x != nil { - return x.ClusterName - } - return "" -} - -func (x *SDSCertificate) GetCertResource() string { - if x != nil { - return x.CertResource - } - return "" -} - -type TLSParameters struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MinVersion TLSVersion `protobuf:"varint,1,opt,name=min_version,json=minVersion,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.TLSVersion" json:"min_version,omitempty"` - MaxVersion TLSVersion `protobuf:"varint,2,opt,name=max_version,json=maxVersion,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.TLSVersion" json:"max_version,omitempty"` - CipherSuites []TLSCipherSuite `protobuf:"varint,3,rep,packed,name=cipher_suites,json=cipherSuites,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.TLSCipherSuite" json:"cipher_suites,omitempty"` -} - -func (x *TLSParameters) Reset() { - *x = TLSParameters{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TLSParameters) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TLSParameters) ProtoMessage() {} - -func (x *TLSParameters) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TLSParameters.ProtoReflect.Descriptor instead. -func (*TLSParameters) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{10} -} - -func (x *TLSParameters) GetMinVersion() TLSVersion { - if x != nil { - return x.MinVersion - } - return TLSVersion_TLS_VERSION_AUTO -} - -func (x *TLSParameters) GetMaxVersion() TLSVersion { - if x != nil { - return x.MaxVersion - } - return TLSVersion_TLS_VERSION_AUTO -} - -func (x *TLSParameters) GetCipherSuites() []TLSCipherSuite { - if x != nil { - return x.CipherSuites - } - return nil -} - -type LeafCertificate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Cert string `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"` - Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` -} - -func (x *LeafCertificate) Reset() { - *x = LeafCertificate{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LeafCertificate) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LeafCertificate) ProtoMessage() {} - -func (x *LeafCertificate) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LeafCertificate.ProtoReflect.Descriptor instead. -func (*LeafCertificate) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{11} -} - -func (x *LeafCertificate) GetCert() string { - if x != nil { - return x.Cert - } - return "" -} - -func (x *LeafCertificate) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -type TrustBundle struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TrustDomain string `protobuf:"bytes,1,opt,name=trust_domain,json=trustDomain,proto3" json:"trust_domain,omitempty"` - Roots []string `protobuf:"bytes,2,rep,name=roots,proto3" json:"roots,omitempty"` -} - -func (x *TrustBundle) Reset() { - *x = TrustBundle{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TrustBundle) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TrustBundle) ProtoMessage() {} - -func (x *TrustBundle) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TrustBundle.ProtoReflect.Descriptor instead. -func (*TrustBundle) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP(), []int{12} -} - -func (x *TrustBundle) GetTrustDomain() string { - if x != nil { - return x.TrustDomain - } - return "" -} - -func (x *TrustBundle) GetRoots() []string { - if x != nil { - return x.Roots - } - return nil -} - -var File_pbmesh_v2beta1_pbproxystate_transport_socket_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDesc = []byte{ - 0x0a, 0x32, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, 0x72, - 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x22, 0xe9, 0x01, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x12, 0x6f, 0x0a, 0x16, 0x69, 0x6e, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x4c, 0x53, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x73, 0x52, 0x14, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x6c, 0x73, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x71, 0x0a, 0x17, 0x6f, 0x75, 0x74, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x4c, 0x53, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x15, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, - 0x6c, 0x73, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0xe0, 0x04, 0x0a, - 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x60, 0x0a, 0x0c, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, - 0x6d, 0x65, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, - 0x65, 0x73, 0x68, 0x4d, 0x54, 0x4c, 0x53, 0x48, 0x00, 0x52, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x68, 0x12, 0x63, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x68, 0x4d, 0x54, 0x4c, 0x53, 0x48, 0x00, 0x52, 0x0c, 0x6f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x68, 0x12, 0x69, 0x0a, 0x10, 0x69, - 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x73, 0x68, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4e, 0x6f, 0x6e, 0x4d, 0x65, 0x73, - 0x68, 0x54, 0x4c, 0x53, 0x48, 0x00, 0x52, 0x0e, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4e, - 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x12, 0x6c, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x5f, 0x6e, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4e, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x54, 0x4c, - 0x53, 0x48, 0x00, 0x52, 0x0f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4e, 0x6f, 0x6e, - 0x4d, 0x65, 0x73, 0x68, 0x12, 0x60, 0x0a, 0x0e, 0x74, 0x6c, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x4c, 0x53, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0d, 0x74, 0x6c, 0x73, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x70, 0x6e, 0x5f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, - 0x61, 0x6c, 0x70, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x42, 0x10, 0x0a, - 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6c, 0x73, 0x22, - 0xad, 0x01, 0x0a, 0x0f, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x68, 0x4d, - 0x54, 0x4c, 0x53, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x77, 0x0a, 0x12, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x4d, 0x65, 0x73, 0x68, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x11, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, - 0xc1, 0x01, 0x0a, 0x10, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x68, - 0x4d, 0x54, 0x4c, 0x53, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x78, 0x0a, 0x12, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x49, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x11, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x73, 0x6e, 0x69, 0x22, 0x8c, 0x01, 0x0a, 0x11, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4e, - 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x54, 0x4c, 0x53, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x65, 0x61, - 0x66, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6c, - 0x65, 0x61, 0x66, 0x4b, 0x65, 0x79, 0x12, 0x4e, 0x0a, 0x03, 0x73, 0x64, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x53, 0x44, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x48, - 0x00, 0x52, 0x03, 0x73, 0x64, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x22, 0xc9, 0x01, 0x0a, 0x12, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4e, - 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x68, 0x54, 0x4c, 0x53, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x65, 0x72, - 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x65, - 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, - 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x46, 0x69, 0x6c, - 0x65, 0x12, 0x7b, 0x0a, 0x12, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4e, 0x6f, 0x6e, 0x4d, 0x65, - 0x73, 0x68, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x11, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x5c, - 0x0a, 0x1c, 0x4d, 0x65, 0x73, 0x68, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x3c, - 0x0a, 0x1b, 0x74, 0x72, 0x75, 0x73, 0x74, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x70, - 0x65, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x17, 0x74, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x7a, 0x0a, 0x1d, - 0x4d, 0x65, 0x73, 0x68, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x3a, 0x0a, - 0x1a, 0x74, 0x72, 0x75, 0x73, 0x74, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x70, 0x65, - 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x16, 0x74, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x50, 0x65, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x70, 0x69, - 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, - 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, 0x64, 0x73, 0x22, 0x3b, 0x0a, 0x20, 0x4e, 0x6f, 0x6e, 0x4d, - 0x65, 0x73, 0x68, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x17, 0x0a, 0x07, - 0x63, 0x61, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, - 0x61, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x58, 0x0a, 0x0e, 0x53, 0x44, 0x53, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x65, - 0x72, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x63, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, - 0xa2, 0x02, 0x0a, 0x0d, 0x54, 0x4c, 0x53, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x73, 0x12, 0x57, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, - 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x0b, 0x6d, 0x61, - 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x4c, 0x53, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x0d, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, - 0x69, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x4c, 0x53, 0x43, 0x69, 0x70, 0x68, 0x65, - 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, - 0x69, 0x74, 0x65, 0x73, 0x22, 0x37, 0x0a, 0x0f, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x72, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x46, 0x0a, - 0x0b, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x74, 0x72, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x2a, 0xac, 0x01, 0x0a, 0x0a, 0x54, 0x4c, 0x53, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, - 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x55, 0x54, 0x4f, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, - 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x30, 0x10, 0x01, 0x12, - 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, - 0x5f, 0x31, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, - 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x32, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x4c, 0x53, - 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x33, 0x10, 0x04, 0x12, 0x17, - 0x0a, 0x13, 0x54, 0x4c, 0x53, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x4c, 0x53, 0x5f, 0x56, - 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x06, 0x2a, 0x84, 0x05, 0x0a, 0x0e, 0x54, 0x4c, 0x53, 0x43, 0x69, 0x70, 0x68, - 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x2e, 0x54, 0x4c, 0x53, 0x5f, 0x43, - 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, - 0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x41, 0x45, 0x53, 0x31, 0x32, 0x38, 0x5f, 0x47, - 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x00, 0x12, 0x32, 0x0a, 0x2e, 0x54, - 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, - 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x43, 0x48, 0x41, 0x43, - 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, 0x35, 0x10, 0x01, 0x12, - 0x30, 0x0a, 0x2c, 0x54, 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x55, - 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x41, 0x45, - 0x53, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, - 0x02, 0x12, 0x30, 0x0a, 0x2c, 0x54, 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, - 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x52, 0x53, 0x41, 0x5f, - 0x43, 0x48, 0x41, 0x43, 0x48, 0x41, 0x32, 0x30, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x31, 0x33, 0x30, - 0x35, 0x10, 0x03, 0x12, 0x2b, 0x0a, 0x27, 0x54, 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, - 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, - 0x44, 0x53, 0x41, 0x5f, 0x41, 0x45, 0x53, 0x31, 0x32, 0x38, 0x5f, 0x53, 0x48, 0x41, 0x10, 0x04, - 0x12, 0x29, 0x0a, 0x25, 0x54, 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, - 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x41, - 0x45, 0x53, 0x31, 0x32, 0x38, 0x5f, 0x53, 0x48, 0x41, 0x10, 0x05, 0x12, 0x26, 0x0a, 0x22, 0x54, - 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, - 0x41, 0x45, 0x53, 0x31, 0x32, 0x38, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, - 0x36, 0x10, 0x06, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, - 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x41, 0x45, 0x53, 0x31, 0x32, 0x38, 0x5f, 0x53, - 0x48, 0x41, 0x10, 0x07, 0x12, 0x32, 0x0a, 0x2e, 0x54, 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, - 0x45, 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, - 0x43, 0x44, 0x53, 0x41, 0x5f, 0x41, 0x45, 0x53, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, 0x4d, 0x5f, - 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x08, 0x12, 0x30, 0x0a, 0x2c, 0x54, 0x4c, 0x53, 0x5f, - 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, - 0x48, 0x45, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x41, 0x45, 0x53, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, - 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x09, 0x12, 0x2b, 0x0a, 0x27, 0x54, 0x4c, - 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, - 0x43, 0x44, 0x48, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x41, 0x45, 0x53, 0x32, 0x35, - 0x36, 0x5f, 0x53, 0x48, 0x41, 0x10, 0x0a, 0x12, 0x29, 0x0a, 0x25, 0x54, 0x4c, 0x53, 0x5f, 0x43, - 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x43, 0x44, 0x48, - 0x45, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x41, 0x45, 0x53, 0x32, 0x35, 0x36, 0x5f, 0x53, 0x48, 0x41, - 0x10, 0x0b, 0x12, 0x26, 0x0a, 0x22, 0x54, 0x4c, 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, - 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x41, 0x45, 0x53, 0x32, 0x35, 0x36, 0x5f, 0x47, 0x43, - 0x4d, 0x5f, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34, 0x10, 0x0c, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x4c, - 0x53, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x5f, 0x53, 0x55, 0x49, 0x54, 0x45, 0x5f, 0x41, - 0x45, 0x53, 0x32, 0x35, 0x36, 0x5f, 0x53, 0x48, 0x41, 0x10, 0x0d, 0x42, 0xda, 0x02, 0x0a, 0x2e, - 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x42, 0x14, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, - 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, - 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, - 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDesc -) - -func file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescData) - }) - return file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDescData -} - -var file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes = make([]protoimpl.MessageInfo, 13) -var file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_goTypes = []interface{}{ - (TLSVersion)(0), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.TLSVersion - (TLSCipherSuite)(0), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.TLSCipherSuite - (*TLS)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.TLS - (*TransportSocket)(nil), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - (*InboundMeshMTLS)(nil), // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.InboundMeshMTLS - (*OutboundMeshMTLS)(nil), // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.OutboundMeshMTLS - (*InboundNonMeshTLS)(nil), // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.InboundNonMeshTLS - (*OutboundNonMeshTLS)(nil), // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.OutboundNonMeshTLS - (*MeshInboundValidationContext)(nil), // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.MeshInboundValidationContext - (*MeshOutboundValidationContext)(nil), // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.MeshOutboundValidationContext - (*NonMeshOutboundValidationContext)(nil), // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.NonMeshOutboundValidationContext - (*SDSCertificate)(nil), // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.SDSCertificate - (*TLSParameters)(nil), // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.TLSParameters - (*LeafCertificate)(nil), // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.LeafCertificate - (*TrustBundle)(nil), // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.TrustBundle -} -var file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_depIdxs = []int32{ - 12, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.TLS.inbound_tls_parameters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TLSParameters - 12, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.TLS.outbound_tls_parameters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TLSParameters - 4, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket.inbound_mesh:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.InboundMeshMTLS - 5, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket.outbound_mesh:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.OutboundMeshMTLS - 6, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket.inbound_non_mesh:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.InboundNonMeshTLS - 7, // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket.outbound_non_mesh:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.OutboundNonMeshTLS - 12, // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket.tls_parameters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TLSParameters - 8, // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.InboundMeshMTLS.validation_context:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.MeshInboundValidationContext - 9, // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.OutboundMeshMTLS.validation_context:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.MeshOutboundValidationContext - 11, // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.InboundNonMeshTLS.sds:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.SDSCertificate - 10, // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.OutboundNonMeshTLS.validation_context:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.NonMeshOutboundValidationContext - 0, // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.TLSParameters.min_version:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TLSVersion - 0, // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.TLSParameters.max_version:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TLSVersion - 1, // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.TLSParameters.cipher_suites:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TLSCipherSuite - 14, // [14:14] is the sub-list for method output_type - 14, // [14:14] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_init() } -func file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_init() { - if File_pbmesh_v2beta1_pbproxystate_transport_socket_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TLS); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TransportSocket); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InboundMeshMTLS); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OutboundMeshMTLS); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InboundNonMeshTLS); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OutboundNonMeshTLS); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MeshInboundValidationContext); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MeshOutboundValidationContext); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NonMeshOutboundValidationContext); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SDSCertificate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TLSParameters); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LeafCertificate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TrustBundle); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[1].OneofWrappers = []interface{}{ - (*TransportSocket_InboundMesh)(nil), - (*TransportSocket_OutboundMesh)(nil), - (*TransportSocket_InboundNonMesh)(nil), - (*TransportSocket_OutboundNonMesh)(nil), - } - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes[4].OneofWrappers = []interface{}{ - (*InboundNonMeshTLS_LeafKey)(nil), - (*InboundNonMeshTLS_Sds)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDesc, - NumEnums: 2, - NumMessages: 13, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_pbproxystate_transport_socket_proto = out.File - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_rawDesc = nil - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_goTypes = nil - file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.proto b/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.proto deleted file mode 100644 index 9ff4f001de9d3..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket.proto +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1.pbproxystate; - -message TLS { - // inbound_tls_parameters has default TLS parameter configuration for inbound connections. These can be overridden per - // transport socket. - TLSParameters inbound_tls_parameters = 1; - // outbound_tls_parameters has default TLS parameter configuration for inbound connections. These can be overridden per transport socket. - TLSParameters outbound_tls_parameters = 2; -} - -message TransportSocket { - // name of the transport socket - string name = 1; - oneof connection_tls { - // inbound_mesh is for incoming connections FROM the mesh. - InboundMeshMTLS inbound_mesh = 2; - // outbound_mesh is for outbound connections TO mesh destinations. - OutboundMeshMTLS outbound_mesh = 3; - // inbound_non_mesh is for incoming connections FROM non mesh. - InboundNonMeshTLS inbound_non_mesh = 4; - // outbound_non_mesh is for outbound connections TO non mesh destinations. - OutboundNonMeshTLS outbound_non_mesh = 5; - } - // tls_parameters can override any top level tls parameters that are configured. - TLSParameters tls_parameters = 6; - repeated string alpn_protocols = 7; -} - -message InboundMeshMTLS { - // identity_key is UUID key to use to look up the leaf certificate in ProxyState to present for incoming connections. - string identity_key = 1; - // validation_context has what is needed to validate incoming connections. - MeshInboundValidationContext validation_context = 2; -} - -message OutboundMeshMTLS { - // identity_key is UUID key to use to look up the leaf certificate in ProxyState when connecting to destinations. - string identity_key = 1; - // validation_context has what is needed to validate the destination. - MeshOutboundValidationContext validation_context = 2; - // sni to use when connecting to the destination. - string sni = 3; -} - -message InboundNonMeshTLS { - // identity is the reference to the leaf certificate to present for incoming connections. - oneof identity { - // leaf_key is the UUID key to use to look up the leaf certificate in the ProxyState leaf certificate map. - string leaf_key = 1; - // sds refers to certificates retrieved via Envoy SDS. - SDSCertificate sds = 2; - } -} - -message OutboundNonMeshTLS { - // cert_file is a filename for a certificate to present for outbound connections. - string cert_file = 1; - // key_file is a filename for a key for outbound connections. - string key_file = 2; - // validation_context has what is needed to validate the destination. - NonMeshOutboundValidationContext validation_context = 3; -} - -message MeshInboundValidationContext { - // trust_bundle_peer_name_keys is which trust bundles to use for validating incoming connections. If this workload is exported - // to peers, the incoming connection could be from a different peer, requiring that trust bundle to validate the - // connection. These could be local or peered trust bundles. This will be a key in the trust bundle map. - repeated string trust_bundle_peer_name_keys = 1; -} - -message MeshOutboundValidationContext { - // trust_bundle_peer_name_key is which trust bundle to use for the destination. It could be the local or a peer's trust bundle. - // This will be a key in the trust bundle map. - string trust_bundle_peer_name_key = 1; - // spiffe_ids is one or more spiffe IDs to validate. - repeated string spiffe_ids = 2; -} - -message NonMeshOutboundValidationContext { - // ca_file is a filename for a ca for outbound connections to validate the destination. - string ca_file = 1; -} - -message SDSCertificate { - string cluster_name = 1; - string cert_resource = 2; -} - -message TLSParameters { - TLSVersion min_version = 1; - TLSVersion max_version = 2; - repeated TLSCipherSuite cipher_suites = 3; -} - -message LeafCertificate { - string cert = 1; - string key = 2; -} - -message TrustBundle { - string trust_domain = 1; - repeated string roots = 2; -} - -// +kubebuilder:validation:Enum=TLS_VERSION_AUTO;TLS_VERSION_1_0;TLS_VERSION_1_1;TLS_VERSION_1_2;TLS_VERSION_1_3;TLS_VERSION_INVALID;TLS_VERSION_UNSPECIFIED -// +kubebuilder:validation:Type=string -enum TLSVersion { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - TLS_VERSION_AUTO = 0; - TLS_VERSION_1_0 = 1; - TLS_VERSION_1_1 = 2; - TLS_VERSION_1_2 = 3; - TLS_VERSION_1_3 = 4; - TLS_VERSION_INVALID = 5; - TLS_VERSION_UNSPECIFIED = 6; -} - -// +kubebuilder:validation:Enum=TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256;TLS_CIPHER_SUITE_AES256_SHA;TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305;TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256;TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305;TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA;TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA;TLS_CIPHER_SUITE_AES128_GCM_SHA256;TLS_CIPHER_SUITE_AES128_SHA;TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384;TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384;TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA;TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA;TLS_CIPHER_SUITE_AES256_GCM_SHA384 -// +kubebuilder:validation:Type=string -enum TLSCipherSuite { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_GCM_SHA256 = 0; - TLS_CIPHER_SUITE_ECDHE_ECDSA_CHACHA20_POLY1305 = 1; - TLS_CIPHER_SUITE_ECDHE_RSA_AES128_GCM_SHA256 = 2; - TLS_CIPHER_SUITE_ECDHE_RSA_CHACHA20_POLY1305 = 3; - TLS_CIPHER_SUITE_ECDHE_ECDSA_AES128_SHA = 4; - TLS_CIPHER_SUITE_ECDHE_RSA_AES128_SHA = 5; - TLS_CIPHER_SUITE_AES128_GCM_SHA256 = 6; - TLS_CIPHER_SUITE_AES128_SHA = 7; - TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_GCM_SHA384 = 8; - TLS_CIPHER_SUITE_ECDHE_RSA_AES256_GCM_SHA384 = 9; - TLS_CIPHER_SUITE_ECDHE_ECDSA_AES256_SHA = 10; - TLS_CIPHER_SUITE_ECDHE_RSA_AES256_SHA = 11; - TLS_CIPHER_SUITE_AES256_GCM_SHA384 = 12; - TLS_CIPHER_SUITE_AES256_SHA = 13; -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_deepcopy.gen.go deleted file mode 100644 index 0d0520e328b5e..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_deepcopy.gen.go +++ /dev/null @@ -1,279 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbproxystate - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using TLS within kubernetes types, where deepcopy-gen is used. -func (in *TLS) DeepCopyInto(out *TLS) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLS. Required by controller-gen. -func (in *TLS) DeepCopy() *TLS { - if in == nil { - return nil - } - out := new(TLS) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TLS. Required by controller-gen. -func (in *TLS) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TransportSocket within kubernetes types, where deepcopy-gen is used. -func (in *TransportSocket) DeepCopyInto(out *TransportSocket) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransportSocket. Required by controller-gen. -func (in *TransportSocket) DeepCopy() *TransportSocket { - if in == nil { - return nil - } - out := new(TransportSocket) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TransportSocket. Required by controller-gen. -func (in *TransportSocket) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using InboundMeshMTLS within kubernetes types, where deepcopy-gen is used. -func (in *InboundMeshMTLS) DeepCopyInto(out *InboundMeshMTLS) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InboundMeshMTLS. Required by controller-gen. -func (in *InboundMeshMTLS) DeepCopy() *InboundMeshMTLS { - if in == nil { - return nil - } - out := new(InboundMeshMTLS) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new InboundMeshMTLS. Required by controller-gen. -func (in *InboundMeshMTLS) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using OutboundMeshMTLS within kubernetes types, where deepcopy-gen is used. -func (in *OutboundMeshMTLS) DeepCopyInto(out *OutboundMeshMTLS) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OutboundMeshMTLS. Required by controller-gen. -func (in *OutboundMeshMTLS) DeepCopy() *OutboundMeshMTLS { - if in == nil { - return nil - } - out := new(OutboundMeshMTLS) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new OutboundMeshMTLS. Required by controller-gen. -func (in *OutboundMeshMTLS) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using InboundNonMeshTLS within kubernetes types, where deepcopy-gen is used. -func (in *InboundNonMeshTLS) DeepCopyInto(out *InboundNonMeshTLS) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InboundNonMeshTLS. Required by controller-gen. -func (in *InboundNonMeshTLS) DeepCopy() *InboundNonMeshTLS { - if in == nil { - return nil - } - out := new(InboundNonMeshTLS) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new InboundNonMeshTLS. Required by controller-gen. -func (in *InboundNonMeshTLS) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using OutboundNonMeshTLS within kubernetes types, where deepcopy-gen is used. -func (in *OutboundNonMeshTLS) DeepCopyInto(out *OutboundNonMeshTLS) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OutboundNonMeshTLS. Required by controller-gen. -func (in *OutboundNonMeshTLS) DeepCopy() *OutboundNonMeshTLS { - if in == nil { - return nil - } - out := new(OutboundNonMeshTLS) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new OutboundNonMeshTLS. Required by controller-gen. -func (in *OutboundNonMeshTLS) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using MeshInboundValidationContext within kubernetes types, where deepcopy-gen is used. -func (in *MeshInboundValidationContext) DeepCopyInto(out *MeshInboundValidationContext) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshInboundValidationContext. Required by controller-gen. -func (in *MeshInboundValidationContext) DeepCopy() *MeshInboundValidationContext { - if in == nil { - return nil - } - out := new(MeshInboundValidationContext) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new MeshInboundValidationContext. Required by controller-gen. -func (in *MeshInboundValidationContext) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using MeshOutboundValidationContext within kubernetes types, where deepcopy-gen is used. -func (in *MeshOutboundValidationContext) DeepCopyInto(out *MeshOutboundValidationContext) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshOutboundValidationContext. Required by controller-gen. -func (in *MeshOutboundValidationContext) DeepCopy() *MeshOutboundValidationContext { - if in == nil { - return nil - } - out := new(MeshOutboundValidationContext) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new MeshOutboundValidationContext. Required by controller-gen. -func (in *MeshOutboundValidationContext) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using NonMeshOutboundValidationContext within kubernetes types, where deepcopy-gen is used. -func (in *NonMeshOutboundValidationContext) DeepCopyInto(out *NonMeshOutboundValidationContext) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NonMeshOutboundValidationContext. Required by controller-gen. -func (in *NonMeshOutboundValidationContext) DeepCopy() *NonMeshOutboundValidationContext { - if in == nil { - return nil - } - out := new(NonMeshOutboundValidationContext) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new NonMeshOutboundValidationContext. Required by controller-gen. -func (in *NonMeshOutboundValidationContext) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using SDSCertificate within kubernetes types, where deepcopy-gen is used. -func (in *SDSCertificate) DeepCopyInto(out *SDSCertificate) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SDSCertificate. Required by controller-gen. -func (in *SDSCertificate) DeepCopy() *SDSCertificate { - if in == nil { - return nil - } - out := new(SDSCertificate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new SDSCertificate. Required by controller-gen. -func (in *SDSCertificate) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TLSParameters within kubernetes types, where deepcopy-gen is used. -func (in *TLSParameters) DeepCopyInto(out *TLSParameters) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSParameters. Required by controller-gen. -func (in *TLSParameters) DeepCopy() *TLSParameters { - if in == nil { - return nil - } - out := new(TLSParameters) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TLSParameters. Required by controller-gen. -func (in *TLSParameters) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using LeafCertificate within kubernetes types, where deepcopy-gen is used. -func (in *LeafCertificate) DeepCopyInto(out *LeafCertificate) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeafCertificate. Required by controller-gen. -func (in *LeafCertificate) DeepCopy() *LeafCertificate { - if in == nil { - return nil - } - out := new(LeafCertificate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new LeafCertificate. Required by controller-gen. -func (in *LeafCertificate) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TrustBundle within kubernetes types, where deepcopy-gen is used. -func (in *TrustBundle) DeepCopyInto(out *TrustBundle) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrustBundle. Required by controller-gen. -func (in *TrustBundle) DeepCopy() *TrustBundle { - if in == nil { - return nil - } - out := new(TrustBundle) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TrustBundle. Required by controller-gen. -func (in *TrustBundle) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_json.gen.go deleted file mode 100644 index 4c83b4d87d9a6..0000000000000 --- a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_json.gen.go +++ /dev/null @@ -1,154 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbproxystate - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for TLS -func (this *TLS) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TLS -func (this *TLS) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TransportSocket -func (this *TransportSocket) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TransportSocket -func (this *TransportSocket) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for InboundMeshMTLS -func (this *InboundMeshMTLS) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for InboundMeshMTLS -func (this *InboundMeshMTLS) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for OutboundMeshMTLS -func (this *OutboundMeshMTLS) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for OutboundMeshMTLS -func (this *OutboundMeshMTLS) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for InboundNonMeshTLS -func (this *InboundNonMeshTLS) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for InboundNonMeshTLS -func (this *InboundNonMeshTLS) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for OutboundNonMeshTLS -func (this *OutboundNonMeshTLS) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for OutboundNonMeshTLS -func (this *OutboundNonMeshTLS) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for MeshInboundValidationContext -func (this *MeshInboundValidationContext) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for MeshInboundValidationContext -func (this *MeshInboundValidationContext) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for MeshOutboundValidationContext -func (this *MeshOutboundValidationContext) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for MeshOutboundValidationContext -func (this *MeshOutboundValidationContext) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for NonMeshOutboundValidationContext -func (this *NonMeshOutboundValidationContext) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for NonMeshOutboundValidationContext -func (this *NonMeshOutboundValidationContext) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for SDSCertificate -func (this *SDSCertificate) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for SDSCertificate -func (this *SDSCertificate) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TLSParameters -func (this *TLSParameters) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TLSParameters -func (this *TLSParameters) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for LeafCertificate -func (this *LeafCertificate) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for LeafCertificate -func (this *LeafCertificate) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TrustBundle -func (this *TrustBundle) MarshalJSON() ([]byte, error) { - str, err := TransportSocketMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TrustBundle -func (this *TrustBundle) UnmarshalJSON(b []byte) error { - return TransportSocketUnmarshaler.Unmarshal(b, this) -} - -var ( - TransportSocketMarshaler = &protojson.MarshalOptions{} - TransportSocketUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration.pb.go b/proto-public/pbmesh/v2beta1/proxy_configuration.pb.go deleted file mode 100644 index a374848fd20e0..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_configuration.pb.go +++ /dev/null @@ -1,1227 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/proxy_configuration.proto - -package meshv2beta1 - -import ( - v2beta1 "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - structpb "google.golang.org/protobuf/types/known/structpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=PROXY_MODE_DEFAULT;PROXY_MODE_TRANSPARENT;PROXY_MODE_DIRECT -// +kubebuilder:validation:Type=string -type ProxyMode int32 - -const ( - // ProxyModeDefault represents no specific mode and should - // be used to indicate that a different layer of the configuration - // chain should take precedence - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - ProxyMode_PROXY_MODE_DEFAULT ProxyMode = 0 - // ProxyModeTransparent represents that inbound and outbound application - // traffic is being captured and redirected through the proxy. - ProxyMode_PROXY_MODE_TRANSPARENT ProxyMode = 1 - // ProxyModeDirect represents that the proxy's listeners must be dialed directly - // by the local application and other proxies. - ProxyMode_PROXY_MODE_DIRECT ProxyMode = 2 -) - -// Enum value maps for ProxyMode. -var ( - ProxyMode_name = map[int32]string{ - 0: "PROXY_MODE_DEFAULT", - 1: "PROXY_MODE_TRANSPARENT", - 2: "PROXY_MODE_DIRECT", - } - ProxyMode_value = map[string]int32{ - "PROXY_MODE_DEFAULT": 0, - "PROXY_MODE_TRANSPARENT": 1, - "PROXY_MODE_DIRECT": 2, - } -) - -func (x ProxyMode) Enum() *ProxyMode { - p := new(ProxyMode) - *p = x - return p -} - -func (x ProxyMode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (ProxyMode) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_proxy_configuration_proto_enumTypes[0].Descriptor() -} - -func (ProxyMode) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_proxy_configuration_proto_enumTypes[0] -} - -func (x ProxyMode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ProxyMode.Descriptor instead. -func (ProxyMode) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{0} -} - -// +kubebuilder:validation:Enum=LOG_SINK_TYPE_DEFAULT;LOG_SINK_TYPE_FILE;LOG_SINK_TYPE_STDERR;LOG_SINK_TYPE_STDOUT -// +kubebuilder:validation:Type=string -type LogSinkType int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - LogSinkType_LOG_SINK_TYPE_DEFAULT LogSinkType = 0 - LogSinkType_LOG_SINK_TYPE_FILE LogSinkType = 1 - LogSinkType_LOG_SINK_TYPE_STDERR LogSinkType = 2 - LogSinkType_LOG_SINK_TYPE_STDOUT LogSinkType = 3 -) - -// Enum value maps for LogSinkType. -var ( - LogSinkType_name = map[int32]string{ - 0: "LOG_SINK_TYPE_DEFAULT", - 1: "LOG_SINK_TYPE_FILE", - 2: "LOG_SINK_TYPE_STDERR", - 3: "LOG_SINK_TYPE_STDOUT", - } - LogSinkType_value = map[string]int32{ - "LOG_SINK_TYPE_DEFAULT": 0, - "LOG_SINK_TYPE_FILE": 1, - "LOG_SINK_TYPE_STDERR": 2, - "LOG_SINK_TYPE_STDOUT": 3, - } -) - -func (x LogSinkType) Enum() *LogSinkType { - p := new(LogSinkType) - *p = x - return p -} - -func (x LogSinkType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (LogSinkType) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_proxy_configuration_proto_enumTypes[1].Descriptor() -} - -func (LogSinkType) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_proxy_configuration_proto_enumTypes[1] -} - -func (x LogSinkType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use LogSinkType.Descriptor instead. -func (LogSinkType) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{1} -} - -// +kubebuilder:validation:Enum=MUTUAL_TLS_MODE_DEFAULT;MUTUAL_TLS_MODE_STRICT;MUTUAL_TLS_MODE_PERMISSIVE -// +kubebuilder:validation:Type=string -type MutualTLSMode int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - MutualTLSMode_MUTUAL_TLS_MODE_DEFAULT MutualTLSMode = 0 - MutualTLSMode_MUTUAL_TLS_MODE_STRICT MutualTLSMode = 1 - MutualTLSMode_MUTUAL_TLS_MODE_PERMISSIVE MutualTLSMode = 2 -) - -// Enum value maps for MutualTLSMode. -var ( - MutualTLSMode_name = map[int32]string{ - 0: "MUTUAL_TLS_MODE_DEFAULT", - 1: "MUTUAL_TLS_MODE_STRICT", - 2: "MUTUAL_TLS_MODE_PERMISSIVE", - } - MutualTLSMode_value = map[string]int32{ - "MUTUAL_TLS_MODE_DEFAULT": 0, - "MUTUAL_TLS_MODE_STRICT": 1, - "MUTUAL_TLS_MODE_PERMISSIVE": 2, - } -) - -func (x MutualTLSMode) Enum() *MutualTLSMode { - p := new(MutualTLSMode) - *p = x - return p -} - -func (x MutualTLSMode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (MutualTLSMode) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_proxy_configuration_proto_enumTypes[2].Descriptor() -} - -func (MutualTLSMode) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_proxy_configuration_proto_enumTypes[2] -} - -func (x MutualTLSMode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use MutualTLSMode.Descriptor instead. -func (MutualTLSMode) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{2} -} - -// This is a Resource type. -type ProxyConfiguration struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Selection of workloads this proxy configuration should apply to. - // These can be prefixes or specific workload names. - Workloads *v2beta1.WorkloadSelector `protobuf:"bytes,1,opt,name=workloads,proto3" json:"workloads,omitempty"` - // dynamic_config is the configuration that could be changed - // dynamically (i.e. without needing restart). - DynamicConfig *DynamicConfig `protobuf:"bytes,2,opt,name=dynamic_config,json=dynamicConfig,proto3" json:"dynamic_config,omitempty"` - // bootstrap_config is the configuration that requires proxies - // to be restarted to be applied. - BootstrapConfig *BootstrapConfig `protobuf:"bytes,3,opt,name=bootstrap_config,json=bootstrapConfig,proto3" json:"bootstrap_config,omitempty"` - // deprecated: prevent usage when using v2 APIs directly. - // needed for backwards compatibility - // - // +kubebuilder:validation:Type=object - // +kubebuilder:validation:Schemaless - // +kubebuilder:pruning:PreserveUnknownFields - // - // Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. - OpaqueConfig *structpb.Struct `protobuf:"bytes,4,opt,name=opaque_config,json=opaqueConfig,proto3" json:"opaque_config,omitempty"` -} - -func (x *ProxyConfiguration) Reset() { - *x = ProxyConfiguration{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProxyConfiguration) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProxyConfiguration) ProtoMessage() {} - -func (x *ProxyConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProxyConfiguration.ProtoReflect.Descriptor instead. -func (*ProxyConfiguration) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{0} -} - -func (x *ProxyConfiguration) GetWorkloads() *v2beta1.WorkloadSelector { - if x != nil { - return x.Workloads - } - return nil -} - -func (x *ProxyConfiguration) GetDynamicConfig() *DynamicConfig { - if x != nil { - return x.DynamicConfig - } - return nil -} - -func (x *ProxyConfiguration) GetBootstrapConfig() *BootstrapConfig { - if x != nil { - return x.BootstrapConfig - } - return nil -} - -// Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. -func (x *ProxyConfiguration) GetOpaqueConfig() *structpb.Struct { - if x != nil { - return x.OpaqueConfig - } - return nil -} - -type DynamicConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // mode indicates the proxy's mode. This will default to 'transparent'. - Mode ProxyMode `protobuf:"varint,1,opt,name=mode,proto3,enum=hashicorp.consul.mesh.v2beta1.ProxyMode" json:"mode,omitempty"` - TransparentProxy *TransparentProxy `protobuf:"bytes,2,opt,name=transparent_proxy,json=transparentProxy,proto3" json:"transparent_proxy,omitempty"` - MutualTlsMode MutualTLSMode `protobuf:"varint,3,opt,name=mutual_tls_mode,json=mutualTlsMode,proto3,enum=hashicorp.consul.mesh.v2beta1.MutualTLSMode" json:"mutual_tls_mode,omitempty"` - // local_connection is the configuration that should be used - // to connect to the local application provided per-port. - // The map keys should correspond to port names on the workload. - LocalConnection map[string]*ConnectionConfig `protobuf:"bytes,4,rep,name=local_connection,json=localConnection,proto3" json:"local_connection,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // inbound_connections configures inbound connections to the proxy. - InboundConnections *InboundConnectionsConfig `protobuf:"bytes,5,opt,name=inbound_connections,json=inboundConnections,proto3" json:"inbound_connections,omitempty"` - MeshGatewayMode MeshGatewayMode `protobuf:"varint,6,opt,name=mesh_gateway_mode,json=meshGatewayMode,proto3,enum=hashicorp.consul.mesh.v2beta1.MeshGatewayMode" json:"mesh_gateway_mode,omitempty"` - ExposeConfig *ExposeConfig `protobuf:"bytes,7,opt,name=expose_config,json=exposeConfig,proto3" json:"expose_config,omitempty"` - // AccessLogs configures the output and format of Envoy access logs - AccessLogs *AccessLogsConfig `protobuf:"bytes,8,opt,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` - PublicListenerJson string `protobuf:"bytes,9,opt,name=public_listener_json,json=publicListenerJson,proto3" json:"public_listener_json,omitempty"` - ListenerTracingJson string `protobuf:"bytes,10,opt,name=listener_tracing_json,json=listenerTracingJson,proto3" json:"listener_tracing_json,omitempty"` - LocalClusterJson string `protobuf:"bytes,11,opt,name=local_cluster_json,json=localClusterJson,proto3" json:"local_cluster_json,omitempty"` - // deprecated: - // local_workload_address, local_workload_port, and local_workload_socket_path - // are deprecated and are only needed for migration of existing resources. - // - // Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. - LocalWorkloadAddress string `protobuf:"bytes,12,opt,name=local_workload_address,json=localWorkloadAddress,proto3" json:"local_workload_address,omitempty"` - // Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. - LocalWorkloadPort uint32 `protobuf:"varint,13,opt,name=local_workload_port,json=localWorkloadPort,proto3" json:"local_workload_port,omitempty"` - // Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. - LocalWorkloadSocketPath string `protobuf:"bytes,14,opt,name=local_workload_socket_path,json=localWorkloadSocketPath,proto3" json:"local_workload_socket_path,omitempty"` -} - -func (x *DynamicConfig) Reset() { - *x = DynamicConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DynamicConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DynamicConfig) ProtoMessage() {} - -func (x *DynamicConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DynamicConfig.ProtoReflect.Descriptor instead. -func (*DynamicConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{1} -} - -func (x *DynamicConfig) GetMode() ProxyMode { - if x != nil { - return x.Mode - } - return ProxyMode_PROXY_MODE_DEFAULT -} - -func (x *DynamicConfig) GetTransparentProxy() *TransparentProxy { - if x != nil { - return x.TransparentProxy - } - return nil -} - -func (x *DynamicConfig) GetMutualTlsMode() MutualTLSMode { - if x != nil { - return x.MutualTlsMode - } - return MutualTLSMode_MUTUAL_TLS_MODE_DEFAULT -} - -func (x *DynamicConfig) GetLocalConnection() map[string]*ConnectionConfig { - if x != nil { - return x.LocalConnection - } - return nil -} - -func (x *DynamicConfig) GetInboundConnections() *InboundConnectionsConfig { - if x != nil { - return x.InboundConnections - } - return nil -} - -func (x *DynamicConfig) GetMeshGatewayMode() MeshGatewayMode { - if x != nil { - return x.MeshGatewayMode - } - return MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED -} - -func (x *DynamicConfig) GetExposeConfig() *ExposeConfig { - if x != nil { - return x.ExposeConfig - } - return nil -} - -func (x *DynamicConfig) GetAccessLogs() *AccessLogsConfig { - if x != nil { - return x.AccessLogs - } - return nil -} - -func (x *DynamicConfig) GetPublicListenerJson() string { - if x != nil { - return x.PublicListenerJson - } - return "" -} - -func (x *DynamicConfig) GetListenerTracingJson() string { - if x != nil { - return x.ListenerTracingJson - } - return "" -} - -func (x *DynamicConfig) GetLocalClusterJson() string { - if x != nil { - return x.LocalClusterJson - } - return "" -} - -// Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. -func (x *DynamicConfig) GetLocalWorkloadAddress() string { - if x != nil { - return x.LocalWorkloadAddress - } - return "" -} - -// Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. -func (x *DynamicConfig) GetLocalWorkloadPort() uint32 { - if x != nil { - return x.LocalWorkloadPort - } - return 0 -} - -// Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. -func (x *DynamicConfig) GetLocalWorkloadSocketPath() string { - if x != nil { - return x.LocalWorkloadSocketPath - } - return "" -} - -type TransparentProxy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // outbound_listener_port is the port for the proxy's outbound listener. - // This defaults to 15001. - OutboundListenerPort uint32 `protobuf:"varint,1,opt,name=outbound_listener_port,json=outboundListenerPort,proto3" json:"outbound_listener_port,omitempty"` - // dialed_directly indicates whether this proxy should be dialed using original destination IP - // in the connection rather than load balance between all endpoints. - DialedDirectly bool `protobuf:"varint,2,opt,name=dialed_directly,json=dialedDirectly,proto3" json:"dialed_directly,omitempty"` -} - -func (x *TransparentProxy) Reset() { - *x = TransparentProxy{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TransparentProxy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TransparentProxy) ProtoMessage() {} - -func (x *TransparentProxy) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TransparentProxy.ProtoReflect.Descriptor instead. -func (*TransparentProxy) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{2} -} - -func (x *TransparentProxy) GetOutboundListenerPort() uint32 { - if x != nil { - return x.OutboundListenerPort - } - return 0 -} - -func (x *TransparentProxy) GetDialedDirectly() bool { - if x != nil { - return x.DialedDirectly - } - return false -} - -// BootstrapConfig is equivalent to configuration defined -// in our docs. -type BootstrapConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - StatsdUrl string `protobuf:"bytes,1,opt,name=statsd_url,json=statsdUrl,proto3" json:"statsd_url,omitempty"` - DogstatsdUrl string `protobuf:"bytes,2,opt,name=dogstatsd_url,json=dogstatsdUrl,proto3" json:"dogstatsd_url,omitempty"` - StatsTags []string `protobuf:"bytes,3,rep,name=stats_tags,json=statsTags,proto3" json:"stats_tags,omitempty"` - PrometheusBindAddr string `protobuf:"bytes,4,opt,name=prometheus_bind_addr,json=prometheusBindAddr,proto3" json:"prometheus_bind_addr,omitempty"` - StatsBindAddr string `protobuf:"bytes,5,opt,name=stats_bind_addr,json=statsBindAddr,proto3" json:"stats_bind_addr,omitempty"` - ReadyBindAddr string `protobuf:"bytes,6,opt,name=ready_bind_addr,json=readyBindAddr,proto3" json:"ready_bind_addr,omitempty"` - OverrideJsonTpl string `protobuf:"bytes,7,opt,name=override_json_tpl,json=overrideJsonTpl,proto3" json:"override_json_tpl,omitempty"` - StaticClustersJson string `protobuf:"bytes,8,opt,name=static_clusters_json,json=staticClustersJson,proto3" json:"static_clusters_json,omitempty"` - StaticListenersJson string `protobuf:"bytes,9,opt,name=static_listeners_json,json=staticListenersJson,proto3" json:"static_listeners_json,omitempty"` - StatsSinksJson string `protobuf:"bytes,10,opt,name=stats_sinks_json,json=statsSinksJson,proto3" json:"stats_sinks_json,omitempty"` - StatsConfigJson string `protobuf:"bytes,11,opt,name=stats_config_json,json=statsConfigJson,proto3" json:"stats_config_json,omitempty"` - StatsFlushInterval string `protobuf:"bytes,12,opt,name=stats_flush_interval,json=statsFlushInterval,proto3" json:"stats_flush_interval,omitempty"` - TracingConfigJson string `protobuf:"bytes,13,opt,name=tracing_config_json,json=tracingConfigJson,proto3" json:"tracing_config_json,omitempty"` - TelemetryCollectorBindSocketDir string `protobuf:"bytes,14,opt,name=telemetry_collector_bind_socket_dir,json=telemetryCollectorBindSocketDir,proto3" json:"telemetry_collector_bind_socket_dir,omitempty"` -} - -func (x *BootstrapConfig) Reset() { - *x = BootstrapConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BootstrapConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BootstrapConfig) ProtoMessage() {} - -func (x *BootstrapConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use BootstrapConfig.ProtoReflect.Descriptor instead. -func (*BootstrapConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{3} -} - -func (x *BootstrapConfig) GetStatsdUrl() string { - if x != nil { - return x.StatsdUrl - } - return "" -} - -func (x *BootstrapConfig) GetDogstatsdUrl() string { - if x != nil { - return x.DogstatsdUrl - } - return "" -} - -func (x *BootstrapConfig) GetStatsTags() []string { - if x != nil { - return x.StatsTags - } - return nil -} - -func (x *BootstrapConfig) GetPrometheusBindAddr() string { - if x != nil { - return x.PrometheusBindAddr - } - return "" -} - -func (x *BootstrapConfig) GetStatsBindAddr() string { - if x != nil { - return x.StatsBindAddr - } - return "" -} - -func (x *BootstrapConfig) GetReadyBindAddr() string { - if x != nil { - return x.ReadyBindAddr - } - return "" -} - -func (x *BootstrapConfig) GetOverrideJsonTpl() string { - if x != nil { - return x.OverrideJsonTpl - } - return "" -} - -func (x *BootstrapConfig) GetStaticClustersJson() string { - if x != nil { - return x.StaticClustersJson - } - return "" -} - -func (x *BootstrapConfig) GetStaticListenersJson() string { - if x != nil { - return x.StaticListenersJson - } - return "" -} - -func (x *BootstrapConfig) GetStatsSinksJson() string { - if x != nil { - return x.StatsSinksJson - } - return "" -} - -func (x *BootstrapConfig) GetStatsConfigJson() string { - if x != nil { - return x.StatsConfigJson - } - return "" -} - -func (x *BootstrapConfig) GetStatsFlushInterval() string { - if x != nil { - return x.StatsFlushInterval - } - return "" -} - -func (x *BootstrapConfig) GetTracingConfigJson() string { - if x != nil { - return x.TracingConfigJson - } - return "" -} - -func (x *BootstrapConfig) GetTelemetryCollectorBindSocketDir() string { - if x != nil { - return x.TelemetryCollectorBindSocketDir - } - return "" -} - -// AccessLogsConfig contains the associated default settings for all Envoy -// instances within the datacenter or partition -type AccessLogsConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Enabled turns off all access logging - Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` - // DisableListenerLogs turns off just listener logs for connections rejected by Envoy because they don't - // have a matching listener filter. - DisableListenerLogs bool `protobuf:"varint,2,opt,name=disable_listener_logs,json=disableListenerLogs,proto3" json:"disable_listener_logs,omitempty"` - // Type selects the output for logs: "file", "stderr". "stdout" - Type LogSinkType `protobuf:"varint,3,opt,name=type,proto3,enum=hashicorp.consul.mesh.v2beta1.LogSinkType" json:"type,omitempty"` - // Path is the output file to write logs - Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"` - // The presence of one format string or the other implies the access log string encoding. - // Defining both is invalid. - JsonFormat string `protobuf:"bytes,5,opt,name=json_format,json=jsonFormat,proto3" json:"json_format,omitempty"` - TextFormat string `protobuf:"bytes,6,opt,name=text_format,json=textFormat,proto3" json:"text_format,omitempty"` -} - -func (x *AccessLogsConfig) Reset() { - *x = AccessLogsConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AccessLogsConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AccessLogsConfig) ProtoMessage() {} - -func (x *AccessLogsConfig) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AccessLogsConfig.ProtoReflect.Descriptor instead. -func (*AccessLogsConfig) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{4} -} - -func (x *AccessLogsConfig) GetEnabled() bool { - if x != nil { - return x.Enabled - } - return false -} - -func (x *AccessLogsConfig) GetDisableListenerLogs() bool { - if x != nil { - return x.DisableListenerLogs - } - return false -} - -func (x *AccessLogsConfig) GetType() LogSinkType { - if x != nil { - return x.Type - } - return LogSinkType_LOG_SINK_TYPE_DEFAULT -} - -func (x *AccessLogsConfig) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -func (x *AccessLogsConfig) GetJsonFormat() string { - if x != nil { - return x.JsonFormat - } - return "" -} - -func (x *AccessLogsConfig) GetTextFormat() string { - if x != nil { - return x.TextFormat - } - return "" -} - -// EnvoyExtension has configuration for an extension that patches Envoy resources. -type EnvoyExtension struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty"` - // +kubebuilder:validation:Type=object - // +kubebuilder:validation:Schemaless - // +kubebuilder:pruning:PreserveUnknownFields - Arguments *structpb.Struct `protobuf:"bytes,3,opt,name=arguments,proto3" json:"arguments,omitempty"` - ConsulVersion string `protobuf:"bytes,4,opt,name=consul_version,json=consulVersion,proto3" json:"consul_version,omitempty"` - EnvoyVersion string `protobuf:"bytes,5,opt,name=envoy_version,json=envoyVersion,proto3" json:"envoy_version,omitempty"` -} - -func (x *EnvoyExtension) Reset() { - *x = EnvoyExtension{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EnvoyExtension) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EnvoyExtension) ProtoMessage() {} - -func (x *EnvoyExtension) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EnvoyExtension.ProtoReflect.Descriptor instead. -func (*EnvoyExtension) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP(), []int{5} -} - -func (x *EnvoyExtension) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *EnvoyExtension) GetRequired() bool { - if x != nil { - return x.Required - } - return false -} - -func (x *EnvoyExtension) GetArguments() *structpb.Struct { - if x != nil { - return x.Arguments - } - return nil -} - -func (x *EnvoyExtension) GetConsulVersion() string { - if x != nil { - return x.ConsulVersion - } - return "" -} - -func (x *EnvoyExtension) GetEnvoyVersion() string { - if x != nil { - return x.EnvoyVersion - } - return "" -} - -var File_pbmesh_v2beta1_proxy_configuration_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_proxy_configuration_proto_rawDesc = []byte{ - 0x0a, 0x28, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x70, 0x62, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x70, 0x62, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x70, 0x62, 0x6d, 0x65, - 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x73, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0xe0, 0x02, 0x0a, 0x12, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x09, 0x77, 0x6f, - 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x53, 0x0a, 0x0e, - 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x0d, 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x59, 0x0a, 0x10, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x6f, 0x6f, 0x74, - 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0f, 0x62, 0x6f, 0x6f, - 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x40, 0x0a, 0x0d, - 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x02, 0x18, 0x01, - 0x52, 0x0c, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x06, - 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x91, 0x09, 0x0a, 0x0d, 0x44, 0x79, 0x6e, 0x61, 0x6d, - 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, - 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x5c, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, - 0x72, 0x6f, 0x78, 0x79, 0x12, 0x54, 0x0a, 0x0f, 0x6d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x74, - 0x6c, 0x73, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x75, - 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0d, 0x6d, 0x75, 0x74, - 0x75, 0x61, 0x6c, 0x54, 0x6c, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x6c, 0x0a, 0x10, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x68, 0x0a, 0x13, 0x69, 0x6e, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x12, - 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x11, 0x6d, 0x65, 0x73, 0x68, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x65, - 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0f, 0x6d, - 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x50, - 0x0a, 0x0d, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x0c, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x50, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, - 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x12, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x5f, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x13, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x54, 0x72, 0x61, - 0x63, 0x69, 0x6e, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, - 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x14, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x32, 0x0a, 0x13, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, - 0x61, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x02, 0x18, - 0x01, 0x52, 0x11, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, - 0x50, 0x6f, 0x72, 0x74, 0x12, 0x3f, 0x0a, 0x1a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, - 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x17, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x6f, 0x63, 0x6b, 0x65, - 0x74, 0x50, 0x61, 0x74, 0x68, 0x1a, 0x73, 0x0a, 0x14, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x71, 0x0a, 0x10, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x34, - 0x0a, 0x16, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, - 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x50, 0x6f, 0x72, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x5f, 0x64, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, - 0x69, 0x61, 0x6c, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x22, 0x8e, 0x05, - 0x0a, 0x0f, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x55, 0x72, 0x6c, - 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x5f, 0x75, 0x72, - 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, - 0x73, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x74, - 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x73, - 0x54, 0x61, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, - 0x75, 0x73, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x42, 0x69, - 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, - 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x26, - 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x61, 0x64, 0x79, 0x42, 0x69, - 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, - 0x64, 0x65, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x74, 0x70, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x4a, 0x73, 0x6f, 0x6e, 0x54, - 0x70, 0x6c, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4c, 0x69, 0x73, 0x74, 0x65, - 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x74, 0x61, 0x74, - 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x6b, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x53, 0x69, 0x6e, 0x6b, 0x73, 0x4a, 0x73, - 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, - 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x30, - 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x74, - 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, - 0x12, 0x4c, 0x0a, 0x23, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x73, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1f, 0x74, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x42, 0x69, 0x6e, 0x64, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x44, 0x69, 0x72, 0x22, 0xf6, - 0x01, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x32, 0x0a, - 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, - 0x73, 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x2a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4c, 0x6f, 0x67, 0x53, 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6a, 0x73, 0x6f, 0x6e, - 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x78, - 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0xc3, 0x01, 0x0a, 0x0e, 0x45, 0x6e, 0x76, 0x6f, - 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x09, 0x61, 0x72, - 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x76, 0x6f, - 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x56, 0x0a, - 0x09, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, - 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, - 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, - 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x15, - 0x0a, 0x11, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x49, 0x52, - 0x45, 0x43, 0x54, 0x10, 0x02, 0x2a, 0x74, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x53, 0x69, 0x6e, 0x6b, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, - 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x4f, 0x47, 0x5f, 0x53, - 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x10, - 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x54, 0x44, 0x4f, 0x55, 0x54, 0x10, 0x03, 0x2a, 0x68, 0x0a, 0x0d, 0x4d, - 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x17, - 0x4d, 0x55, 0x54, 0x55, 0x41, 0x4c, 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, - 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x55, 0x54, - 0x55, 0x41, 0x4c, 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x52, - 0x49, 0x43, 0x54, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x55, 0x54, 0x55, 0x41, 0x4c, 0x5f, - 0x54, 0x4c, 0x53, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, - 0x49, 0x56, 0x45, 0x10, 0x02, 0x42, 0x98, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x17, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, - 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, - 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_proxy_configuration_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_proxy_configuration_proto_rawDescData = file_pbmesh_v2beta1_proxy_configuration_proto_rawDesc -) - -func file_pbmesh_v2beta1_proxy_configuration_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_proxy_configuration_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_proxy_configuration_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_proxy_configuration_proto_rawDescData) - }) - return file_pbmesh_v2beta1_proxy_configuration_proto_rawDescData -} - -var file_pbmesh_v2beta1_proxy_configuration_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes = make([]protoimpl.MessageInfo, 7) -var file_pbmesh_v2beta1_proxy_configuration_proto_goTypes = []interface{}{ - (ProxyMode)(0), // 0: hashicorp.consul.mesh.v2beta1.ProxyMode - (LogSinkType)(0), // 1: hashicorp.consul.mesh.v2beta1.LogSinkType - (MutualTLSMode)(0), // 2: hashicorp.consul.mesh.v2beta1.MutualTLSMode - (*ProxyConfiguration)(nil), // 3: hashicorp.consul.mesh.v2beta1.ProxyConfiguration - (*DynamicConfig)(nil), // 4: hashicorp.consul.mesh.v2beta1.DynamicConfig - (*TransparentProxy)(nil), // 5: hashicorp.consul.mesh.v2beta1.TransparentProxy - (*BootstrapConfig)(nil), // 6: hashicorp.consul.mesh.v2beta1.BootstrapConfig - (*AccessLogsConfig)(nil), // 7: hashicorp.consul.mesh.v2beta1.AccessLogsConfig - (*EnvoyExtension)(nil), // 8: hashicorp.consul.mesh.v2beta1.EnvoyExtension - nil, // 9: hashicorp.consul.mesh.v2beta1.DynamicConfig.LocalConnectionEntry - (*v2beta1.WorkloadSelector)(nil), // 10: hashicorp.consul.catalog.v2beta1.WorkloadSelector - (*structpb.Struct)(nil), // 11: google.protobuf.Struct - (*InboundConnectionsConfig)(nil), // 12: hashicorp.consul.mesh.v2beta1.InboundConnectionsConfig - (MeshGatewayMode)(0), // 13: hashicorp.consul.mesh.v2beta1.MeshGatewayMode - (*ExposeConfig)(nil), // 14: hashicorp.consul.mesh.v2beta1.ExposeConfig - (*ConnectionConfig)(nil), // 15: hashicorp.consul.mesh.v2beta1.ConnectionConfig -} -var file_pbmesh_v2beta1_proxy_configuration_proto_depIdxs = []int32{ - 10, // 0: hashicorp.consul.mesh.v2beta1.ProxyConfiguration.workloads:type_name -> hashicorp.consul.catalog.v2beta1.WorkloadSelector - 4, // 1: hashicorp.consul.mesh.v2beta1.ProxyConfiguration.dynamic_config:type_name -> hashicorp.consul.mesh.v2beta1.DynamicConfig - 6, // 2: hashicorp.consul.mesh.v2beta1.ProxyConfiguration.bootstrap_config:type_name -> hashicorp.consul.mesh.v2beta1.BootstrapConfig - 11, // 3: hashicorp.consul.mesh.v2beta1.ProxyConfiguration.opaque_config:type_name -> google.protobuf.Struct - 0, // 4: hashicorp.consul.mesh.v2beta1.DynamicConfig.mode:type_name -> hashicorp.consul.mesh.v2beta1.ProxyMode - 5, // 5: hashicorp.consul.mesh.v2beta1.DynamicConfig.transparent_proxy:type_name -> hashicorp.consul.mesh.v2beta1.TransparentProxy - 2, // 6: hashicorp.consul.mesh.v2beta1.DynamicConfig.mutual_tls_mode:type_name -> hashicorp.consul.mesh.v2beta1.MutualTLSMode - 9, // 7: hashicorp.consul.mesh.v2beta1.DynamicConfig.local_connection:type_name -> hashicorp.consul.mesh.v2beta1.DynamicConfig.LocalConnectionEntry - 12, // 8: hashicorp.consul.mesh.v2beta1.DynamicConfig.inbound_connections:type_name -> hashicorp.consul.mesh.v2beta1.InboundConnectionsConfig - 13, // 9: hashicorp.consul.mesh.v2beta1.DynamicConfig.mesh_gateway_mode:type_name -> hashicorp.consul.mesh.v2beta1.MeshGatewayMode - 14, // 10: hashicorp.consul.mesh.v2beta1.DynamicConfig.expose_config:type_name -> hashicorp.consul.mesh.v2beta1.ExposeConfig - 7, // 11: hashicorp.consul.mesh.v2beta1.DynamicConfig.access_logs:type_name -> hashicorp.consul.mesh.v2beta1.AccessLogsConfig - 1, // 12: hashicorp.consul.mesh.v2beta1.AccessLogsConfig.type:type_name -> hashicorp.consul.mesh.v2beta1.LogSinkType - 11, // 13: hashicorp.consul.mesh.v2beta1.EnvoyExtension.arguments:type_name -> google.protobuf.Struct - 15, // 14: hashicorp.consul.mesh.v2beta1.DynamicConfig.LocalConnectionEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.ConnectionConfig - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_proxy_configuration_proto_init() } -func file_pbmesh_v2beta1_proxy_configuration_proto_init() { - if File_pbmesh_v2beta1_proxy_configuration_proto != nil { - return - } - file_pbmesh_v2beta1_connection_proto_init() - file_pbmesh_v2beta1_expose_proto_init() - file_pbmesh_v2beta1_routing_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProxyConfiguration); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DynamicConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TransparentProxy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BootstrapConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessLogsConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EnvoyExtension); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_proxy_configuration_proto_rawDesc, - NumEnums: 3, - NumMessages: 7, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_proxy_configuration_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_proxy_configuration_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_proxy_configuration_proto_enumTypes, - MessageInfos: file_pbmesh_v2beta1_proxy_configuration_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_proxy_configuration_proto = out.File - file_pbmesh_v2beta1_proxy_configuration_proto_rawDesc = nil - file_pbmesh_v2beta1_proxy_configuration_proto_goTypes = nil - file_pbmesh_v2beta1_proxy_configuration_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration.proto b/proto-public/pbmesh/v2beta1/proxy_configuration.proto deleted file mode 100644 index 9a2d410d868db..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_configuration.proto +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "google/protobuf/struct.proto"; -import "pbcatalog/v2beta1/selector.proto"; -import "pbmesh/v2beta1/connection.proto"; -import "pbmesh/v2beta1/expose.proto"; -import "pbmesh/v2beta1/routing.proto"; -import "pbresource/annotations.proto"; - -// This is a Resource type. -message ProxyConfiguration { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // Selection of workloads this proxy configuration should apply to. - // These can be prefixes or specific workload names. - hashicorp.consul.catalog.v2beta1.WorkloadSelector workloads = 1; - - // dynamic_config is the configuration that could be changed - // dynamically (i.e. without needing restart). - DynamicConfig dynamic_config = 2; - - // bootstrap_config is the configuration that requires proxies - // to be restarted to be applied. - BootstrapConfig bootstrap_config = 3; - - // deprecated: prevent usage when using v2 APIs directly. - // needed for backwards compatibility - // - // +kubebuilder:validation:Type=object - // +kubebuilder:validation:Schemaless - // +kubebuilder:pruning:PreserveUnknownFields - google.protobuf.Struct opaque_config = 4 [deprecated = true]; -} - -message DynamicConfig { - // mode indicates the proxy's mode. This will default to 'transparent'. - ProxyMode mode = 1; - - TransparentProxy transparent_proxy = 2; - - MutualTLSMode mutual_tls_mode = 3; - - // local_connection is the configuration that should be used - // to connect to the local application provided per-port. - // The map keys should correspond to port names on the workload. - map local_connection = 4; - - // inbound_connections configures inbound connections to the proxy. - InboundConnectionsConfig inbound_connections = 5; - - MeshGatewayMode mesh_gateway_mode = 6; - - ExposeConfig expose_config = 7; - - // AccessLogs configures the output and format of Envoy access logs - AccessLogsConfig access_logs = 8; - - string public_listener_json = 9; - string listener_tracing_json = 10; - string local_cluster_json = 11; - - // deprecated: - // local_workload_address, local_workload_port, and local_workload_socket_path - // are deprecated and are only needed for migration of existing resources. - string local_workload_address = 12 [deprecated = true]; - uint32 local_workload_port = 13 [deprecated = true]; - string local_workload_socket_path = 14 [deprecated = true]; -} - -message TransparentProxy { - // outbound_listener_port is the port for the proxy's outbound listener. - // This defaults to 15001. - uint32 outbound_listener_port = 1; - - // dialed_directly indicates whether this proxy should be dialed using original destination IP - // in the connection rather than load balance between all endpoints. - bool dialed_directly = 2; -} - -// BootstrapConfig is equivalent to configuration defined -// in our docs. -message BootstrapConfig { - string statsd_url = 1; - string dogstatsd_url = 2; - repeated string stats_tags = 3; - string prometheus_bind_addr = 4; - string stats_bind_addr = 5; - string ready_bind_addr = 6; - string override_json_tpl = 7; - string static_clusters_json = 8; - string static_listeners_json = 9; - string stats_sinks_json = 10; - string stats_config_json = 11; - string stats_flush_interval = 12; - string tracing_config_json = 13; - string telemetry_collector_bind_socket_dir = 14; -} - -// +kubebuilder:validation:Enum=PROXY_MODE_DEFAULT;PROXY_MODE_TRANSPARENT;PROXY_MODE_DIRECT -// +kubebuilder:validation:Type=string -enum ProxyMode { - // ProxyModeDefault represents no specific mode and should - // be used to indicate that a different layer of the configuration - // chain should take precedence - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - PROXY_MODE_DEFAULT = 0; - - // ProxyModeTransparent represents that inbound and outbound application - // traffic is being captured and redirected through the proxy. - PROXY_MODE_TRANSPARENT = 1; - - // ProxyModeDirect represents that the proxy's listeners must be dialed directly - // by the local application and other proxies. - PROXY_MODE_DIRECT = 2; -} - -// AccessLogsConfig contains the associated default settings for all Envoy -// instances within the datacenter or partition -message AccessLogsConfig { - // Enabled turns off all access logging - bool enabled = 1; - - // DisableListenerLogs turns off just listener logs for connections rejected by Envoy because they don't - // have a matching listener filter. - bool disable_listener_logs = 2; - - // Type selects the output for logs: "file", "stderr". "stdout" - LogSinkType type = 3; - - // Path is the output file to write logs - string path = 4; - - // The presence of one format string or the other implies the access log string encoding. - // Defining both is invalid. - string json_format = 5; - string text_format = 6; -} - -// +kubebuilder:validation:Enum=LOG_SINK_TYPE_DEFAULT;LOG_SINK_TYPE_FILE;LOG_SINK_TYPE_STDERR;LOG_SINK_TYPE_STDOUT -// +kubebuilder:validation:Type=string -enum LogSinkType { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - LOG_SINK_TYPE_DEFAULT = 0; - LOG_SINK_TYPE_FILE = 1; - LOG_SINK_TYPE_STDERR = 2; - LOG_SINK_TYPE_STDOUT = 3; -} - -// EnvoyExtension has configuration for an extension that patches Envoy resources. -message EnvoyExtension { - string name = 1; - bool required = 2; - // +kubebuilder:validation:Type=object - // +kubebuilder:validation:Schemaless - // +kubebuilder:pruning:PreserveUnknownFields - google.protobuf.Struct arguments = 3; - string consul_version = 4; - string envoy_version = 5; -} - -// +kubebuilder:validation:Enum=MUTUAL_TLS_MODE_DEFAULT;MUTUAL_TLS_MODE_STRICT;MUTUAL_TLS_MODE_PERMISSIVE -// +kubebuilder:validation:Type=string -enum MutualTLSMode { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - MUTUAL_TLS_MODE_DEFAULT = 0; - MUTUAL_TLS_MODE_STRICT = 1; - MUTUAL_TLS_MODE_PERMISSIVE = 2; -} diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration_addon.go b/proto-public/pbmesh/v2beta1/proxy_configuration_addon.go deleted file mode 100644 index 22f013c1a7e00..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_configuration_addon.go +++ /dev/null @@ -1,11 +0,0 @@ -package meshv2beta1 - -func (p *ComputedProxyConfiguration) IsTransparentProxy() bool { - return p.GetDynamicConfig() != nil && - p.DynamicConfig.Mode == ProxyMode_PROXY_MODE_TRANSPARENT -} - -func (p *ProxyConfiguration) IsTransparentProxy() bool { - return p.GetDynamicConfig() != nil && - p.DynamicConfig.Mode == ProxyMode_PROXY_MODE_TRANSPARENT -} diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration_addon_test.go b/proto-public/pbmesh/v2beta1/proxy_configuration_addon_test.go deleted file mode 100644 index ab2dfd2dd2ddc..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_configuration_addon_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package meshv2beta1 - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestIsTransparentProxy(t *testing.T) { - cases := map[string]struct { - dynamicConfig *DynamicConfig - exp bool - }{ - "nil dynamic config": { - dynamicConfig: nil, - exp: false, - }, - "default mode": { - dynamicConfig: &DynamicConfig{ - Mode: ProxyMode_PROXY_MODE_DEFAULT, - }, - exp: false, - }, - "direct mode": { - dynamicConfig: &DynamicConfig{ - Mode: ProxyMode_PROXY_MODE_DEFAULT, - }, - exp: false, - }, - "transparent mode": { - dynamicConfig: &DynamicConfig{ - Mode: ProxyMode_PROXY_MODE_TRANSPARENT, - }, - exp: true, - }, - } - - for name, c := range cases { - t.Run(name, func(t *testing.T) { - proxyCfg := &ProxyConfiguration{ - DynamicConfig: c.dynamicConfig, - } - compProxyCfg := &ComputedProxyConfiguration{ - DynamicConfig: c.dynamicConfig, - } - require.Equal(t, c.exp, proxyCfg.IsTransparentProxy()) - require.Equal(t, c.exp, compProxyCfg.IsTransparentProxy()) - }) - } -} diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/proxy_configuration_deepcopy.gen.go deleted file mode 100644 index bc5b81a9a6fb4..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_configuration_deepcopy.gen.go +++ /dev/null @@ -1,132 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ProxyConfiguration within kubernetes types, where deepcopy-gen is used. -func (in *ProxyConfiguration) DeepCopyInto(out *ProxyConfiguration) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyConfiguration. Required by controller-gen. -func (in *ProxyConfiguration) DeepCopy() *ProxyConfiguration { - if in == nil { - return nil - } - out := new(ProxyConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ProxyConfiguration. Required by controller-gen. -func (in *ProxyConfiguration) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DynamicConfig within kubernetes types, where deepcopy-gen is used. -func (in *DynamicConfig) DeepCopyInto(out *DynamicConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicConfig. Required by controller-gen. -func (in *DynamicConfig) DeepCopy() *DynamicConfig { - if in == nil { - return nil - } - out := new(DynamicConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DynamicConfig. Required by controller-gen. -func (in *DynamicConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TransparentProxy within kubernetes types, where deepcopy-gen is used. -func (in *TransparentProxy) DeepCopyInto(out *TransparentProxy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransparentProxy. Required by controller-gen. -func (in *TransparentProxy) DeepCopy() *TransparentProxy { - if in == nil { - return nil - } - out := new(TransparentProxy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TransparentProxy. Required by controller-gen. -func (in *TransparentProxy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using BootstrapConfig within kubernetes types, where deepcopy-gen is used. -func (in *BootstrapConfig) DeepCopyInto(out *BootstrapConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootstrapConfig. Required by controller-gen. -func (in *BootstrapConfig) DeepCopy() *BootstrapConfig { - if in == nil { - return nil - } - out := new(BootstrapConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new BootstrapConfig. Required by controller-gen. -func (in *BootstrapConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using AccessLogsConfig within kubernetes types, where deepcopy-gen is used. -func (in *AccessLogsConfig) DeepCopyInto(out *AccessLogsConfig) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessLogsConfig. Required by controller-gen. -func (in *AccessLogsConfig) DeepCopy() *AccessLogsConfig { - if in == nil { - return nil - } - out := new(AccessLogsConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new AccessLogsConfig. Required by controller-gen. -func (in *AccessLogsConfig) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using EnvoyExtension within kubernetes types, where deepcopy-gen is used. -func (in *EnvoyExtension) DeepCopyInto(out *EnvoyExtension) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyExtension. Required by controller-gen. -func (in *EnvoyExtension) DeepCopy() *EnvoyExtension { - if in == nil { - return nil - } - out := new(EnvoyExtension) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyExtension. Required by controller-gen. -func (in *EnvoyExtension) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration_json.gen.go b/proto-public/pbmesh/v2beta1/proxy_configuration_json.gen.go deleted file mode 100644 index 41fcdd5ed2f65..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_configuration_json.gen.go +++ /dev/null @@ -1,77 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ProxyConfiguration -func (this *ProxyConfiguration) MarshalJSON() ([]byte, error) { - str, err := ProxyConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ProxyConfiguration -func (this *ProxyConfiguration) UnmarshalJSON(b []byte) error { - return ProxyConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DynamicConfig -func (this *DynamicConfig) MarshalJSON() ([]byte, error) { - str, err := ProxyConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DynamicConfig -func (this *DynamicConfig) UnmarshalJSON(b []byte) error { - return ProxyConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TransparentProxy -func (this *TransparentProxy) MarshalJSON() ([]byte, error) { - str, err := ProxyConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TransparentProxy -func (this *TransparentProxy) UnmarshalJSON(b []byte) error { - return ProxyConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for BootstrapConfig -func (this *BootstrapConfig) MarshalJSON() ([]byte, error) { - str, err := ProxyConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for BootstrapConfig -func (this *BootstrapConfig) UnmarshalJSON(b []byte) error { - return ProxyConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for AccessLogsConfig -func (this *AccessLogsConfig) MarshalJSON() ([]byte, error) { - str, err := ProxyConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for AccessLogsConfig -func (this *AccessLogsConfig) UnmarshalJSON(b []byte) error { - return ProxyConfigurationUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for EnvoyExtension -func (this *EnvoyExtension) MarshalJSON() ([]byte, error) { - str, err := ProxyConfigurationMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for EnvoyExtension -func (this *EnvoyExtension) UnmarshalJSON(b []byte) error { - return ProxyConfigurationUnmarshaler.Unmarshal(b, this) -} - -var ( - ProxyConfigurationMarshaler = &protojson.MarshalOptions{} - ProxyConfigurationUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/proxy_state.pb.binary.go b/proto-public/pbmesh/v2beta1/proxy_state.pb.binary.go deleted file mode 100644 index d259ba66fc796..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_state.pb.binary.go +++ /dev/null @@ -1,28 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/proxy_state.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ProxyStateTemplate) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ProxyStateTemplate) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ProxyState) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ProxyState) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/proxy_state.pb.go b/proto-public/pbmesh/v2beta1/proxy_state.pb.go deleted file mode 100644 index 5f26294a5d1c3..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_state.pb.go +++ /dev/null @@ -1,551 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/proxy_state.proto - -package meshv2beta1 - -import ( - pbproxystate "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ProxyStateTemplate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ProxyState is the partially filled out ProxyState resource. The Endpoints, LeafCertificates and TrustBundles fields will need filling in after the resource is stored. - ProxyState *ProxyState `protobuf:"bytes,1,opt,name=proxy_state,json=proxyState,proto3" json:"proxy_state,omitempty"` - // RequiredEndpoints is a map of arbitrary string names to endpoint refs that need fetching by the proxy state controller. - RequiredEndpoints map[string]*pbproxystate.EndpointRef `protobuf:"bytes,2,rep,name=required_endpoints,json=requiredEndpoints,proto3" json:"required_endpoints,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // RequiredLeafCertificates is a map of arbitrary string names to leaf certificates that need fetching/generation by the proxy state controller. - RequiredLeafCertificates map[string]*pbproxystate.LeafCertificateRef `protobuf:"bytes,3,rep,name=required_leaf_certificates,json=requiredLeafCertificates,proto3" json:"required_leaf_certificates,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // RequiredTrustBundles is a map of arbitrary string names to trust bundle refs that need fetching by the proxy state controller. - RequiredTrustBundles map[string]*pbproxystate.TrustBundleRef `protobuf:"bytes,4,rep,name=required_trust_bundles,json=requiredTrustBundles,proto3" json:"required_trust_bundles,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *ProxyStateTemplate) Reset() { - *x = ProxyStateTemplate{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_proxy_state_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProxyStateTemplate) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProxyStateTemplate) ProtoMessage() {} - -func (x *ProxyStateTemplate) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_proxy_state_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProxyStateTemplate.ProtoReflect.Descriptor instead. -func (*ProxyStateTemplate) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_state_proto_rawDescGZIP(), []int{0} -} - -func (x *ProxyStateTemplate) GetProxyState() *ProxyState { - if x != nil { - return x.ProxyState - } - return nil -} - -func (x *ProxyStateTemplate) GetRequiredEndpoints() map[string]*pbproxystate.EndpointRef { - if x != nil { - return x.RequiredEndpoints - } - return nil -} - -func (x *ProxyStateTemplate) GetRequiredLeafCertificates() map[string]*pbproxystate.LeafCertificateRef { - if x != nil { - return x.RequiredLeafCertificates - } - return nil -} - -func (x *ProxyStateTemplate) GetRequiredTrustBundles() map[string]*pbproxystate.TrustBundleRef { - if x != nil { - return x.RequiredTrustBundles - } - return nil -} - -type ProxyState struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Identity is a reference to the identity of the workload this proxy is for. - Identity *pbresource.Reference `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` - // Listeners is a list of listeners for this proxy. - Listeners []*pbproxystate.Listener `protobuf:"bytes,2,rep,name=listeners,proto3" json:"listeners,omitempty"` - // Clusters is a map from cluster name to clusters. The keys are referenced from listeners or routes. - Clusters map[string]*pbproxystate.Cluster `protobuf:"bytes,3,rep,name=clusters,proto3" json:"clusters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // Routes is a map from route name to routes. The keys are referenced from listeners. - Routes map[string]*pbproxystate.Route `protobuf:"bytes,4,rep,name=routes,proto3" json:"routes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // Endpoints is a map from cluster name to endpoints. - Endpoints map[string]*pbproxystate.Endpoints `protobuf:"bytes,5,rep,name=endpoints,proto3" json:"endpoints,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // LeafCertificates is a map from UUID to leaf certificates. - LeafCertificates map[string]*pbproxystate.LeafCertificate `protobuf:"bytes,6,rep,name=leaf_certificates,json=leafCertificates,proto3" json:"leaf_certificates,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // TrustBundles is a map from peer name to trust bundles. - TrustBundles map[string]*pbproxystate.TrustBundle `protobuf:"bytes,7,rep,name=trust_bundles,json=trustBundles,proto3" json:"trust_bundles,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // TLS has TLS configuration for this proxy. - Tls *pbproxystate.TLS `protobuf:"bytes,8,opt,name=tls,proto3" json:"tls,omitempty"` - // Escape defines top level escape hatches. These are user configured json strings that configure an entire piece of listener or cluster Envoy configuration. - Escape *pbproxystate.EscapeHatches `protobuf:"bytes,9,opt,name=escape,proto3" json:"escape,omitempty"` - // AccessLogs configures access logging for this proxy. - AccessLogs *pbproxystate.AccessLogs `protobuf:"bytes,10,opt,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` -} - -func (x *ProxyState) Reset() { - *x = ProxyState{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_proxy_state_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProxyState) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProxyState) ProtoMessage() {} - -func (x *ProxyState) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_proxy_state_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProxyState.ProtoReflect.Descriptor instead. -func (*ProxyState) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_proxy_state_proto_rawDescGZIP(), []int{1} -} - -func (x *ProxyState) GetIdentity() *pbresource.Reference { - if x != nil { - return x.Identity - } - return nil -} - -func (x *ProxyState) GetListeners() []*pbproxystate.Listener { - if x != nil { - return x.Listeners - } - return nil -} - -func (x *ProxyState) GetClusters() map[string]*pbproxystate.Cluster { - if x != nil { - return x.Clusters - } - return nil -} - -func (x *ProxyState) GetRoutes() map[string]*pbproxystate.Route { - if x != nil { - return x.Routes - } - return nil -} - -func (x *ProxyState) GetEndpoints() map[string]*pbproxystate.Endpoints { - if x != nil { - return x.Endpoints - } - return nil -} - -func (x *ProxyState) GetLeafCertificates() map[string]*pbproxystate.LeafCertificate { - if x != nil { - return x.LeafCertificates - } - return nil -} - -func (x *ProxyState) GetTrustBundles() map[string]*pbproxystate.TrustBundle { - if x != nil { - return x.TrustBundles - } - return nil -} - -func (x *ProxyState) GetTls() *pbproxystate.TLS { - if x != nil { - return x.Tls - } - return nil -} - -func (x *ProxyState) GetEscape() *pbproxystate.EscapeHatches { - if x != nil { - return x.Escape - } - return nil -} - -func (x *ProxyState) GetAccessLogs() *pbproxystate.AccessLogs { - if x != nil { - return x.AccessLogs - } - return nil -} - -var File_pbmesh_v2beta1_proxy_state_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_proxy_state_proto_rawDesc = []byte{ - 0x0a, 0x20, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x1a, 0x2d, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x29, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2b, 0x70, 0x62, 0x6d, - 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x5f, 0x68, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x70, 0x62, 0x6d, 0x65, - 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x27, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70, - 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x19, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x07, 0x0a, 0x12, 0x50, - 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, - 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x77, 0x0a, - 0x12, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x11, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x1a, 0x72, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x5f, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4f, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x52, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x18, 0x72, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x81, 0x01, 0x0a, 0x16, 0x72, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x5f, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x1a, 0x7d, 0x0a, 0x16, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x8b, 0x01, 0x0a, 0x1d, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x54, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x66, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x83, 0x01, 0x0a, 0x19, 0x52, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, - 0x65, 0x66, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x06, 0xa2, - 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xaf, 0x0b, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x52, 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, - 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x53, 0x0a, 0x08, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, - 0x4d, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x12, 0x56, - 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x65, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x6c, 0x0a, 0x11, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x65, 0x61, - 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x10, 0x6c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x73, 0x12, 0x60, 0x0a, 0x0d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x5f, 0x62, 0x75, - 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, - 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, - 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x74, 0x72, 0x75, 0x73, 0x74, 0x42, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x03, 0x74, 0x6c, 0x73, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x54, 0x4c, 0x53, 0x52, 0x03, 0x74, 0x6c, 0x73, 0x12, 0x51, 0x0a, 0x06, 0x65, 0x73, 0x63, - 0x61, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x73, 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x52, 0x06, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x12, 0x57, 0x0a, 0x0b, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x1a, 0x70, 0x0a, 0x0d, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x49, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x6c, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x73, 0x0a, 0x0e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4b, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x80, 0x01, 0x0a, 0x15, 0x4c, - 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x51, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x4c, 0x65, 0x61, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x78, 0x0a, - 0x11, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x90, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0f, 0x50, - 0x72, 0x6f, 0x78, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, - 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, - 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, - 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, - 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_proxy_state_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_proxy_state_proto_rawDescData = file_pbmesh_v2beta1_proxy_state_proto_rawDesc -) - -func file_pbmesh_v2beta1_proxy_state_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_proxy_state_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_proxy_state_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_proxy_state_proto_rawDescData) - }) - return file_pbmesh_v2beta1_proxy_state_proto_rawDescData -} - -var file_pbmesh_v2beta1_proxy_state_proto_msgTypes = make([]protoimpl.MessageInfo, 10) -var file_pbmesh_v2beta1_proxy_state_proto_goTypes = []interface{}{ - (*ProxyStateTemplate)(nil), // 0: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate - (*ProxyState)(nil), // 1: hashicorp.consul.mesh.v2beta1.ProxyState - nil, // 2: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredEndpointsEntry - nil, // 3: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredLeafCertificatesEntry - nil, // 4: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredTrustBundlesEntry - nil, // 5: hashicorp.consul.mesh.v2beta1.ProxyState.ClustersEntry - nil, // 6: hashicorp.consul.mesh.v2beta1.ProxyState.RoutesEntry - nil, // 7: hashicorp.consul.mesh.v2beta1.ProxyState.EndpointsEntry - nil, // 8: hashicorp.consul.mesh.v2beta1.ProxyState.LeafCertificatesEntry - nil, // 9: hashicorp.consul.mesh.v2beta1.ProxyState.TrustBundlesEntry - (*pbresource.Reference)(nil), // 10: hashicorp.consul.resource.Reference - (*pbproxystate.Listener)(nil), // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.Listener - (*pbproxystate.TLS)(nil), // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.TLS - (*pbproxystate.EscapeHatches)(nil), // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.EscapeHatches - (*pbproxystate.AccessLogs)(nil), // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.AccessLogs - (*pbproxystate.EndpointRef)(nil), // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointRef - (*pbproxystate.LeafCertificateRef)(nil), // 16: hashicorp.consul.mesh.v2beta1.pbproxystate.LeafCertificateRef - (*pbproxystate.TrustBundleRef)(nil), // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.TrustBundleRef - (*pbproxystate.Cluster)(nil), // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster - (*pbproxystate.Route)(nil), // 19: hashicorp.consul.mesh.v2beta1.pbproxystate.Route - (*pbproxystate.Endpoints)(nil), // 20: hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoints - (*pbproxystate.LeafCertificate)(nil), // 21: hashicorp.consul.mesh.v2beta1.pbproxystate.LeafCertificate - (*pbproxystate.TrustBundle)(nil), // 22: hashicorp.consul.mesh.v2beta1.pbproxystate.TrustBundle -} -var file_pbmesh_v2beta1_proxy_state_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.proxy_state:type_name -> hashicorp.consul.mesh.v2beta1.ProxyState - 2, // 1: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.required_endpoints:type_name -> hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredEndpointsEntry - 3, // 2: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.required_leaf_certificates:type_name -> hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredLeafCertificatesEntry - 4, // 3: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.required_trust_bundles:type_name -> hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredTrustBundlesEntry - 10, // 4: hashicorp.consul.mesh.v2beta1.ProxyState.identity:type_name -> hashicorp.consul.resource.Reference - 11, // 5: hashicorp.consul.mesh.v2beta1.ProxyState.listeners:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Listener - 5, // 6: hashicorp.consul.mesh.v2beta1.ProxyState.clusters:type_name -> hashicorp.consul.mesh.v2beta1.ProxyState.ClustersEntry - 6, // 7: hashicorp.consul.mesh.v2beta1.ProxyState.routes:type_name -> hashicorp.consul.mesh.v2beta1.ProxyState.RoutesEntry - 7, // 8: hashicorp.consul.mesh.v2beta1.ProxyState.endpoints:type_name -> hashicorp.consul.mesh.v2beta1.ProxyState.EndpointsEntry - 8, // 9: hashicorp.consul.mesh.v2beta1.ProxyState.leaf_certificates:type_name -> hashicorp.consul.mesh.v2beta1.ProxyState.LeafCertificatesEntry - 9, // 10: hashicorp.consul.mesh.v2beta1.ProxyState.trust_bundles:type_name -> hashicorp.consul.mesh.v2beta1.ProxyState.TrustBundlesEntry - 12, // 11: hashicorp.consul.mesh.v2beta1.ProxyState.tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TLS - 13, // 12: hashicorp.consul.mesh.v2beta1.ProxyState.escape:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.EscapeHatches - 14, // 13: hashicorp.consul.mesh.v2beta1.ProxyState.access_logs:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.AccessLogs - 15, // 14: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredEndpointsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointRef - 16, // 15: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredLeafCertificatesEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LeafCertificateRef - 17, // 16: hashicorp.consul.mesh.v2beta1.ProxyStateTemplate.RequiredTrustBundlesEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TrustBundleRef - 18, // 17: hashicorp.consul.mesh.v2beta1.ProxyState.ClustersEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster - 19, // 18: hashicorp.consul.mesh.v2beta1.ProxyState.RoutesEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Route - 20, // 19: hashicorp.consul.mesh.v2beta1.ProxyState.EndpointsEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Endpoints - 21, // 20: hashicorp.consul.mesh.v2beta1.ProxyState.LeafCertificatesEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LeafCertificate - 22, // 21: hashicorp.consul.mesh.v2beta1.ProxyState.TrustBundlesEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TrustBundle - 22, // [22:22] is the sub-list for method output_type - 22, // [22:22] is the sub-list for method input_type - 22, // [22:22] is the sub-list for extension type_name - 22, // [22:22] is the sub-list for extension extendee - 0, // [0:22] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_proxy_state_proto_init() } -func file_pbmesh_v2beta1_proxy_state_proto_init() { - if File_pbmesh_v2beta1_proxy_state_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_proxy_state_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProxyStateTemplate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_proxy_state_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProxyState); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_proxy_state_proto_rawDesc, - NumEnums: 0, - NumMessages: 10, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_proxy_state_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_proxy_state_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_proxy_state_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_proxy_state_proto = out.File - file_pbmesh_v2beta1_proxy_state_proto_rawDesc = nil - file_pbmesh_v2beta1_proxy_state_proto_goTypes = nil - file_pbmesh_v2beta1_proxy_state_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/proxy_state.proto b/proto-public/pbmesh/v2beta1/proxy_state.proto deleted file mode 100644 index cd70dbbd5f194..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_state.proto +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbmesh/v2beta1/pbproxystate/access_logs.proto"; -import "pbmesh/v2beta1/pbproxystate/cluster.proto"; -import "pbmesh/v2beta1/pbproxystate/endpoints.proto"; -import "pbmesh/v2beta1/pbproxystate/escape_hatches.proto"; -import "pbmesh/v2beta1/pbproxystate/listener.proto"; -import "pbmesh/v2beta1/pbproxystate/references.proto"; -import "pbmesh/v2beta1/pbproxystate/route.proto"; -import "pbmesh/v2beta1/pbproxystate/transport_socket.proto"; -import "pbresource/annotations.proto"; -import "pbresource/resource.proto"; - -message ProxyStateTemplate { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // ProxyState is the partially filled out ProxyState resource. The Endpoints, LeafCertificates and TrustBundles fields will need filling in after the resource is stored. - ProxyState proxy_state = 1; - - // RequiredEndpoints is a map of arbitrary string names to endpoint refs that need fetching by the proxy state controller. - map required_endpoints = 2; - - // RequiredLeafCertificates is a map of arbitrary string names to leaf certificates that need fetching/generation by the proxy state controller. - map required_leaf_certificates = 3; - - // RequiredTrustBundles is a map of arbitrary string names to trust bundle refs that need fetching by the proxy state controller. - map required_trust_bundles = 4; -} - -message ProxyState { - // Identity is a reference to the identity of the workload this proxy is for. - hashicorp.consul.resource.Reference identity = 1; - // Listeners is a list of listeners for this proxy. - repeated pbproxystate.Listener listeners = 2; - // Clusters is a map from cluster name to clusters. The keys are referenced from listeners or routes. - map clusters = 3; - // Routes is a map from route name to routes. The keys are referenced from listeners. - map routes = 4; - // Endpoints is a map from cluster name to endpoints. - map endpoints = 5; - // LeafCertificates is a map from UUID to leaf certificates. - map leaf_certificates = 6; - // TrustBundles is a map from peer name to trust bundles. - map trust_bundles = 7; - // TLS has TLS configuration for this proxy. - pbproxystate.TLS tls = 8; - // Escape defines top level escape hatches. These are user configured json strings that configure an entire piece of listener or cluster Envoy configuration. - pbproxystate.EscapeHatches escape = 9; - // AccessLogs configures access logging for this proxy. - pbproxystate.AccessLogs access_logs = 10; -} diff --git a/proto-public/pbmesh/v2beta1/proxy_state_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/proxy_state_deepcopy.gen.go deleted file mode 100644 index fbc6ed8420982..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_state_deepcopy.gen.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ProxyStateTemplate within kubernetes types, where deepcopy-gen is used. -func (in *ProxyStateTemplate) DeepCopyInto(out *ProxyStateTemplate) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyStateTemplate. Required by controller-gen. -func (in *ProxyStateTemplate) DeepCopy() *ProxyStateTemplate { - if in == nil { - return nil - } - out := new(ProxyStateTemplate) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ProxyStateTemplate. Required by controller-gen. -func (in *ProxyStateTemplate) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ProxyState within kubernetes types, where deepcopy-gen is used. -func (in *ProxyState) DeepCopyInto(out *ProxyState) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyState. Required by controller-gen. -func (in *ProxyState) DeepCopy() *ProxyState { - if in == nil { - return nil - } - out := new(ProxyState) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ProxyState. Required by controller-gen. -func (in *ProxyState) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/proxy_state_json.gen.go b/proto-public/pbmesh/v2beta1/proxy_state_json.gen.go deleted file mode 100644 index 8449f8bbd8f78..0000000000000 --- a/proto-public/pbmesh/v2beta1/proxy_state_json.gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ProxyStateTemplate -func (this *ProxyStateTemplate) MarshalJSON() ([]byte, error) { - str, err := ProxyStateMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ProxyStateTemplate -func (this *ProxyStateTemplate) UnmarshalJSON(b []byte) error { - return ProxyStateUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ProxyState -func (this *ProxyState) MarshalJSON() ([]byte, error) { - str, err := ProxyStateMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ProxyState -func (this *ProxyState) UnmarshalJSON(b []byte) error { - return ProxyStateUnmarshaler.Unmarshal(b, this) -} - -var ( - ProxyStateMarshaler = &protojson.MarshalOptions{} - ProxyStateUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/resource_types.gen.go b/proto-public/pbmesh/v2beta1/resource_types.gen.go deleted file mode 100644 index 68406c5d1e88d..0000000000000 --- a/proto-public/pbmesh/v2beta1/resource_types.gen.go +++ /dev/null @@ -1,92 +0,0 @@ -// Code generated by protoc-gen-resource-types. DO NOT EDIT. - -package meshv2beta1 - -import ( - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - GroupName = "mesh" - Version = "v2beta1" - - ComputedExplicitDestinationsKind = "ComputedExplicitDestinations" - ComputedProxyConfigurationKind = "ComputedProxyConfiguration" - ComputedRoutesKind = "ComputedRoutes" - DestinationPolicyKind = "DestinationPolicy" - DestinationsKind = "Destinations" - DestinationsConfigurationKind = "DestinationsConfiguration" - GRPCRouteKind = "GRPCRoute" - HTTPRouteKind = "HTTPRoute" - ProxyConfigurationKind = "ProxyConfiguration" - ProxyStateTemplateKind = "ProxyStateTemplate" - TCPRouteKind = "TCPRoute" -) - -var ( - ComputedExplicitDestinationsType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ComputedExplicitDestinationsKind, - } - - ComputedProxyConfigurationType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ComputedProxyConfigurationKind, - } - - ComputedRoutesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ComputedRoutesKind, - } - - DestinationPolicyType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: DestinationPolicyKind, - } - - DestinationsType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: DestinationsKind, - } - - DestinationsConfigurationType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: DestinationsConfigurationKind, - } - - GRPCRouteType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: GRPCRouteKind, - } - - HTTPRouteType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: HTTPRouteKind, - } - - ProxyConfigurationType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ProxyConfigurationKind, - } - - ProxyStateTemplateType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ProxyStateTemplateKind, - } - - TCPRouteType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: TCPRouteKind, - } -) diff --git a/proto-public/pbmesh/v2beta1/routing.pb.go b/proto-public/pbmesh/v2beta1/routing.pb.go deleted file mode 100644 index 4b1f648774319..0000000000000 --- a/proto-public/pbmesh/v2beta1/routing.pb.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/routing.proto - -package meshv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// +kubebuilder:validation:Enum=MESH_GATEWAY_MODE_UNSPECIFIED;MESH_GATEWAY_MODE_NONE;MESH_GATEWAY_MODE_LOCAL;MESH_GATEWAY_MODE_REMOTE -// +kubebuilder:validation:Type=string -type MeshGatewayMode int32 - -const ( - // MESH_GATEWAY_MODE_UNSPECIFIED represents no specific mode and should be - // used to indicate that the decision on the mode will be made by other - // configuration or default settings. - MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED MeshGatewayMode = 0 - // MESH_GATEWAY_MODE_NONE is the mode to use when traffic should not be - // routed through any gateway but instead be routed directly to the - // destination. - MeshGatewayMode_MESH_GATEWAY_MODE_NONE MeshGatewayMode = 1 - // MESH_GATEWAY_MODE_LOCAL is the mode to use when traffic should be routed - // to the local gateway. The local gateway will then ensure that the - // connection is proxied correctly to its final destination. This mode will - // most often be needed for workloads that are prevented from making outbound - // requests outside of their local network/environment. In this case a - // gateway will sit at the edge of sit at the edge of the network and will - // proxy outbound connections potentially to other gateways in remote - // environments. - MeshGatewayMode_MESH_GATEWAY_MODE_LOCAL MeshGatewayMode = 2 - // MESH_GATEWAY_MODE_REMOTE is the mode to use when traffic should be routed - // to a remote mesh gateway. This mode will most often be used when workloads - // can make outbound requests destined for a remote network/environment but - // where the remote network/environment will not allow direct addressing. The - // mesh gateway in the remote environment will sit at the edge and proxy - // requests into that environment. - MeshGatewayMode_MESH_GATEWAY_MODE_REMOTE MeshGatewayMode = 3 -) - -// Enum value maps for MeshGatewayMode. -var ( - MeshGatewayMode_name = map[int32]string{ - 0: "MESH_GATEWAY_MODE_UNSPECIFIED", - 1: "MESH_GATEWAY_MODE_NONE", - 2: "MESH_GATEWAY_MODE_LOCAL", - 3: "MESH_GATEWAY_MODE_REMOTE", - } - MeshGatewayMode_value = map[string]int32{ - "MESH_GATEWAY_MODE_UNSPECIFIED": 0, - "MESH_GATEWAY_MODE_NONE": 1, - "MESH_GATEWAY_MODE_LOCAL": 2, - "MESH_GATEWAY_MODE_REMOTE": 3, - } -) - -func (x MeshGatewayMode) Enum() *MeshGatewayMode { - p := new(MeshGatewayMode) - *p = x - return p -} - -func (x MeshGatewayMode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (MeshGatewayMode) Descriptor() protoreflect.EnumDescriptor { - return file_pbmesh_v2beta1_routing_proto_enumTypes[0].Descriptor() -} - -func (MeshGatewayMode) Type() protoreflect.EnumType { - return &file_pbmesh_v2beta1_routing_proto_enumTypes[0] -} - -func (x MeshGatewayMode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use MeshGatewayMode.Descriptor instead. -func (MeshGatewayMode) EnumDescriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_routing_proto_rawDescGZIP(), []int{0} -} - -var File_pbmesh_v2beta1_routing_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_routing_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2a, 0x8b, 0x01, - 0x0a, 0x0f, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, - 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, - 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, - 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x01, - 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, - 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x02, 0x12, 0x1c, 0x0a, - 0x18, 0x4d, 0x45, 0x53, 0x48, 0x5f, 0x47, 0x41, 0x54, 0x45, 0x57, 0x41, 0x59, 0x5f, 0x4d, 0x4f, - 0x44, 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x10, 0x03, 0x42, 0x8d, 0x02, 0x0a, 0x21, - 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x42, 0x0c, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, - 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, - 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, - 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, - 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_routing_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_routing_proto_rawDescData = file_pbmesh_v2beta1_routing_proto_rawDesc -) - -func file_pbmesh_v2beta1_routing_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_routing_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_routing_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_routing_proto_rawDescData) - }) - return file_pbmesh_v2beta1_routing_proto_rawDescData -} - -var file_pbmesh_v2beta1_routing_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbmesh_v2beta1_routing_proto_goTypes = []interface{}{ - (MeshGatewayMode)(0), // 0: hashicorp.consul.mesh.v2beta1.MeshGatewayMode -} -var file_pbmesh_v2beta1_routing_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_routing_proto_init() } -func file_pbmesh_v2beta1_routing_proto_init() { - if File_pbmesh_v2beta1_routing_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_routing_proto_rawDesc, - NumEnums: 1, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_routing_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_routing_proto_depIdxs, - EnumInfos: file_pbmesh_v2beta1_routing_proto_enumTypes, - }.Build() - File_pbmesh_v2beta1_routing_proto = out.File - file_pbmesh_v2beta1_routing_proto_rawDesc = nil - file_pbmesh_v2beta1_routing_proto_goTypes = nil - file_pbmesh_v2beta1_routing_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/tcp_route.pb.binary.go b/proto-public/pbmesh/v2beta1/tcp_route.pb.binary.go deleted file mode 100644 index 4c10deae5375e..0000000000000 --- a/proto-public/pbmesh/v2beta1/tcp_route.pb.binary.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/tcp_route.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TCPRoute) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TCPRoute) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TCPRouteRule) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TCPRouteRule) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TCPBackendRef) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TCPBackendRef) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/tcp_route.pb.go b/proto-public/pbmesh/v2beta1/tcp_route.pb.go deleted file mode 100644 index 5a2c401846af5..0000000000000 --- a/proto-public/pbmesh/v2beta1/tcp_route.pb.go +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/tcp_route.proto - -package meshv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// NOTE: this should align to the GAMMA/gateway-api version, or at least be -// easily translatable. -// -// https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute -// -// This is a Resource type. -type TCPRoute struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ParentRefs references the resources (usually Services) that a Route wants - // to be attached to. - // - // It is invalid to reference an identical parent more than once. It is valid - // to reference multiple distinct sections within the same parent resource. - ParentRefs []*ParentReference `protobuf:"bytes,1,rep,name=parent_refs,json=parentRefs,proto3" json:"parent_refs,omitempty"` - // Rules are a list of TCP matchers and actions. - Rules []*TCPRouteRule `protobuf:"bytes,2,rep,name=rules,proto3" json:"rules,omitempty"` -} - -func (x *TCPRoute) Reset() { - *x = TCPRoute{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_tcp_route_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TCPRoute) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TCPRoute) ProtoMessage() {} - -func (x *TCPRoute) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_tcp_route_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TCPRoute.ProtoReflect.Descriptor instead. -func (*TCPRoute) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_tcp_route_proto_rawDescGZIP(), []int{0} -} - -func (x *TCPRoute) GetParentRefs() []*ParentReference { - if x != nil { - return x.ParentRefs - } - return nil -} - -func (x *TCPRoute) GetRules() []*TCPRouteRule { - if x != nil { - return x.Rules - } - return nil -} - -type TCPRouteRule struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // BackendRefs defines the backend(s) where matching requests should be sent. - // If unspecified or invalid (refers to a non-existent resource or a Service - // with no endpoints), the underlying implementation MUST actively reject - // connection attempts to this backend. Connection rejections must respect - // weight; if an invalid backend is requested to have 80% of connections, - // then 80% of connections must be rejected instead. - BackendRefs []*TCPBackendRef `protobuf:"bytes,1,rep,name=backend_refs,json=backendRefs,proto3" json:"backend_refs,omitempty"` -} - -func (x *TCPRouteRule) Reset() { - *x = TCPRouteRule{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_tcp_route_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TCPRouteRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TCPRouteRule) ProtoMessage() {} - -func (x *TCPRouteRule) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_tcp_route_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TCPRouteRule.ProtoReflect.Descriptor instead. -func (*TCPRouteRule) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_tcp_route_proto_rawDescGZIP(), []int{1} -} - -func (x *TCPRouteRule) GetBackendRefs() []*TCPBackendRef { - if x != nil { - return x.BackendRefs - } - return nil -} - -type TCPBackendRef struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - BackendRef *BackendReference `protobuf:"bytes,1,opt,name=backend_ref,json=backendRef,proto3" json:"backend_ref,omitempty"` - // Weight specifies the proportion of requests forwarded to the referenced - // backend. This is computed as weight/(sum of all weights in this - // BackendRefs list). For non-zero values, there may be some epsilon from the - // exact proportion defined here depending on the precision an implementation - // supports. Weight is not a percentage and the sum of weights does not need - // to equal 100. - // - // If only one backend is specified and it has a weight greater than 0, 100% - // of the traffic is forwarded to that backend. If weight is set to 0, no - // traffic should be forwarded for this entry. If unspecified, weight defaults - // to 1. - Weight uint32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"` -} - -func (x *TCPBackendRef) Reset() { - *x = TCPBackendRef{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_tcp_route_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TCPBackendRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TCPBackendRef) ProtoMessage() {} - -func (x *TCPBackendRef) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_tcp_route_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TCPBackendRef.ProtoReflect.Descriptor instead. -func (*TCPBackendRef) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_tcp_route_proto_rawDescGZIP(), []int{2} -} - -func (x *TCPBackendRef) GetBackendRef() *BackendReference { - if x != nil { - return x.BackendRef - } - return nil -} - -func (x *TCPBackendRef) GetWeight() uint32 { - if x != nil { - return x.Weight - } - return 0 -} - -var File_pbmesh_v2beta1_tcp_route_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_tcp_route_proto_rawDesc = []byte{ - 0x0a, 0x1e, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x74, 0x63, 0x70, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, - 0x1b, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa6, 0x01, 0x0a, 0x08, 0x54, - 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x72, 0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x66, 0x73, 0x12, 0x41, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, - 0x02, 0x08, 0x03, 0x22, 0x5f, 0x0a, 0x0c, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, - 0x75, 0x6c, 0x65, 0x12, 0x4f, 0x0a, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x5f, 0x72, - 0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x43, 0x50, 0x42, 0x61, 0x63, - 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, - 0x52, 0x65, 0x66, 0x73, 0x22, 0x79, 0x0a, 0x0d, 0x54, 0x43, 0x50, 0x42, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x50, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, - 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, - 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x62, 0x61, 0x63, - 0x6b, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x66, 0x12, 0x16, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x42, - 0x8e, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0d, 0x54, 0x63, 0x70, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, - 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, - 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, - 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_tcp_route_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_tcp_route_proto_rawDescData = file_pbmesh_v2beta1_tcp_route_proto_rawDesc -) - -func file_pbmesh_v2beta1_tcp_route_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_tcp_route_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_tcp_route_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_tcp_route_proto_rawDescData) - }) - return file_pbmesh_v2beta1_tcp_route_proto_rawDescData -} - -var file_pbmesh_v2beta1_tcp_route_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_pbmesh_v2beta1_tcp_route_proto_goTypes = []interface{}{ - (*TCPRoute)(nil), // 0: hashicorp.consul.mesh.v2beta1.TCPRoute - (*TCPRouteRule)(nil), // 1: hashicorp.consul.mesh.v2beta1.TCPRouteRule - (*TCPBackendRef)(nil), // 2: hashicorp.consul.mesh.v2beta1.TCPBackendRef - (*ParentReference)(nil), // 3: hashicorp.consul.mesh.v2beta1.ParentReference - (*BackendReference)(nil), // 4: hashicorp.consul.mesh.v2beta1.BackendReference -} -var file_pbmesh_v2beta1_tcp_route_proto_depIdxs = []int32{ - 3, // 0: hashicorp.consul.mesh.v2beta1.TCPRoute.parent_refs:type_name -> hashicorp.consul.mesh.v2beta1.ParentReference - 1, // 1: hashicorp.consul.mesh.v2beta1.TCPRoute.rules:type_name -> hashicorp.consul.mesh.v2beta1.TCPRouteRule - 2, // 2: hashicorp.consul.mesh.v2beta1.TCPRouteRule.backend_refs:type_name -> hashicorp.consul.mesh.v2beta1.TCPBackendRef - 4, // 3: hashicorp.consul.mesh.v2beta1.TCPBackendRef.backend_ref:type_name -> hashicorp.consul.mesh.v2beta1.BackendReference - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_tcp_route_proto_init() } -func file_pbmesh_v2beta1_tcp_route_proto_init() { - if File_pbmesh_v2beta1_tcp_route_proto != nil { - return - } - file_pbmesh_v2beta1_common_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_tcp_route_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TCPRoute); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_tcp_route_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TCPRouteRule); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmesh_v2beta1_tcp_route_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TCPBackendRef); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_tcp_route_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_tcp_route_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_tcp_route_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_tcp_route_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_tcp_route_proto = out.File - file_pbmesh_v2beta1_tcp_route_proto_rawDesc = nil - file_pbmesh_v2beta1_tcp_route_proto_goTypes = nil - file_pbmesh_v2beta1_tcp_route_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/tcp_route.proto b/proto-public/pbmesh/v2beta1/tcp_route.proto deleted file mode 100644 index d3637febf6da6..0000000000000 --- a/proto-public/pbmesh/v2beta1/tcp_route.proto +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -import "pbmesh/v2beta1/common.proto"; -import "pbresource/annotations.proto"; - -// NOTE: this should align to the GAMMA/gateway-api version, or at least be -// easily translatable. -// -// https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute -// -// This is a Resource type. -message TCPRoute { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - // ParentRefs references the resources (usually Services) that a Route wants - // to be attached to. - // - // It is invalid to reference an identical parent more than once. It is valid - // to reference multiple distinct sections within the same parent resource. - repeated ParentReference parent_refs = 1; - - // Rules are a list of TCP matchers and actions. - repeated TCPRouteRule rules = 2; -} - -message TCPRouteRule { - // BackendRefs defines the backend(s) where matching requests should be sent. - // If unspecified or invalid (refers to a non-existent resource or a Service - // with no endpoints), the underlying implementation MUST actively reject - // connection attempts to this backend. Connection rejections must respect - // weight; if an invalid backend is requested to have 80% of connections, - // then 80% of connections must be rejected instead. - repeated TCPBackendRef backend_refs = 1; -} - -message TCPBackendRef { - BackendReference backend_ref = 1; - - // Weight specifies the proportion of requests forwarded to the referenced - // backend. This is computed as weight/(sum of all weights in this - // BackendRefs list). For non-zero values, there may be some epsilon from the - // exact proportion defined here depending on the precision an implementation - // supports. Weight is not a percentage and the sum of weights does not need - // to equal 100. - // - // If only one backend is specified and it has a weight greater than 0, 100% - // of the traffic is forwarded to that backend. If weight is set to 0, no - // traffic should be forwarded for this entry. If unspecified, weight defaults - // to 1. - uint32 weight = 2; -} diff --git a/proto-public/pbmesh/v2beta1/tcp_route_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/tcp_route_deepcopy.gen.go deleted file mode 100644 index 487209766f964..0000000000000 --- a/proto-public/pbmesh/v2beta1/tcp_route_deepcopy.gen.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using TCPRoute within kubernetes types, where deepcopy-gen is used. -func (in *TCPRoute) DeepCopyInto(out *TCPRoute) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPRoute. Required by controller-gen. -func (in *TCPRoute) DeepCopy() *TCPRoute { - if in == nil { - return nil - } - out := new(TCPRoute) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TCPRoute. Required by controller-gen. -func (in *TCPRoute) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TCPRouteRule within kubernetes types, where deepcopy-gen is used. -func (in *TCPRouteRule) DeepCopyInto(out *TCPRouteRule) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPRouteRule. Required by controller-gen. -func (in *TCPRouteRule) DeepCopy() *TCPRouteRule { - if in == nil { - return nil - } - out := new(TCPRouteRule) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TCPRouteRule. Required by controller-gen. -func (in *TCPRouteRule) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using TCPBackendRef within kubernetes types, where deepcopy-gen is used. -func (in *TCPBackendRef) DeepCopyInto(out *TCPBackendRef) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPBackendRef. Required by controller-gen. -func (in *TCPBackendRef) DeepCopy() *TCPBackendRef { - if in == nil { - return nil - } - out := new(TCPBackendRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new TCPBackendRef. Required by controller-gen. -func (in *TCPBackendRef) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/tcp_route_json.gen.go b/proto-public/pbmesh/v2beta1/tcp_route_json.gen.go deleted file mode 100644 index eef8800440344..0000000000000 --- a/proto-public/pbmesh/v2beta1/tcp_route_json.gen.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for TCPRoute -func (this *TCPRoute) MarshalJSON() ([]byte, error) { - str, err := TcpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TCPRoute -func (this *TCPRoute) UnmarshalJSON(b []byte) error { - return TcpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TCPRouteRule -func (this *TCPRouteRule) MarshalJSON() ([]byte, error) { - str, err := TcpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TCPRouteRule -func (this *TCPRouteRule) UnmarshalJSON(b []byte) error { - return TcpRouteUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for TCPBackendRef -func (this *TCPBackendRef) MarshalJSON() ([]byte, error) { - str, err := TcpRouteMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for TCPBackendRef -func (this *TCPBackendRef) UnmarshalJSON(b []byte) error { - return TcpRouteUnmarshaler.Unmarshal(b, this) -} - -var ( - TcpRouteMarshaler = &protojson.MarshalOptions{} - TcpRouteUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmesh/v2beta1/xroute_addons.go b/proto-public/pbmesh/v2beta1/xroute_addons.go deleted file mode 100644 index c060aea6dd33d..0000000000000 --- a/proto-public/pbmesh/v2beta1/xroute_addons.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package meshv2beta1 - -// GetUnderlyingBackendRefs will collect BackendReferences from all rules and -// bundle them up in one slice, unwrapping the HTTP-specifics in the process. -// -// This implements an XRouteWithRefs interface in the internal/mesh package. -// -// NOTE: no deduplication occurs. -func (x *HTTPRoute) GetUnderlyingBackendRefs() []*BackendReference { - if x == nil { - return nil - } - - estimate := 0 - for _, rule := range x.Rules { - estimate += len(rule.BackendRefs) - } - - backendRefs := make([]*BackendReference, 0, estimate) - for _, rule := range x.Rules { - for _, backendRef := range rule.BackendRefs { - backendRefs = append(backendRefs, backendRef.BackendRef) - } - } - return backendRefs -} - -// GetUnderlyingBackendRefs will collect BackendReferences from all rules and -// bundle them up in one slice, unwrapping the GRPC-specifics in the process. -// -// This implements an XRouteWithRefs interface in the internal/mesh package. -// -// NOTE: no deduplication occurs. -func (x *GRPCRoute) GetUnderlyingBackendRefs() []*BackendReference { - if x == nil { - return nil - } - - estimate := 0 - for _, rule := range x.Rules { - estimate += len(rule.BackendRefs) - } - - backendRefs := make([]*BackendReference, 0, estimate) - for _, rule := range x.Rules { - for _, backendRef := range rule.BackendRefs { - backendRefs = append(backendRefs, backendRef.BackendRef) - } - } - return backendRefs -} - -// GetUnderlyingBackendRefs will collect BackendReferences from all rules and -// bundle them up in one slice, unwrapping the TCP-specifics in the process. -// -// This implements an XRouteWithRefs interface in the internal/mesh package. -// -// NOTE: no deduplication occurs. -func (x *TCPRoute) GetUnderlyingBackendRefs() []*BackendReference { - if x == nil { - return nil - } - - estimate := 0 - for _, rule := range x.Rules { - estimate += len(rule.BackendRefs) - } - - backendRefs := make([]*BackendReference, 0, estimate) - - for _, rule := range x.Rules { - for _, backendRef := range rule.BackendRefs { - backendRefs = append(backendRefs, backendRef.BackendRef) - } - } - return backendRefs -} - -// IsHashBased returns true if the policy is a hash-based policy such as maglev -// or ring hash. -func (p LoadBalancerPolicy) IsHashBased() bool { - switch p { - case LoadBalancerPolicy_LOAD_BALANCER_POLICY_MAGLEV, - LoadBalancerPolicy_LOAD_BALANCER_POLICY_RING_HASH: - return true - } - return false -} diff --git a/proto-public/pbmesh/v2beta1/xroute_addons_test.go b/proto-public/pbmesh/v2beta1/xroute_addons_test.go deleted file mode 100644 index fac04a6014222..0000000000000 --- a/proto-public/pbmesh/v2beta1/xroute_addons_test.go +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package meshv2beta1 - -import ( - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" - - "github.com/hashicorp/consul/proto-public/pbresource" -) - -type routeWithAddons interface { - proto.Message - GetUnderlyingBackendRefs() []*BackendReference -} - -func TestXRoute_GetUnderlyingBackendRefs(t *testing.T) { - type testcase struct { - route routeWithAddons - expect []*BackendReference - } - - run := func(t *testing.T, tc testcase) { - got := tc.route.GetUnderlyingBackendRefs() - require.ElementsMatch(t, stringifyList(tc.expect), stringifyList(got)) - } - - cases := map[string]testcase{ - "http: nil": { - route: (*HTTPRoute)(nil), - }, - "grpc: nil": { - route: (*GRPCRoute)(nil), - }, - "tcp: nil": { - route: (*TCPRoute)(nil), - }, - "http: kitchen sink": { - route: &HTTPRoute{ - Rules: []*HTTPRouteRule{ - {BackendRefs: []*HTTPBackendRef{ - {BackendRef: newBackendRef("aa")}, - }}, - {BackendRefs: []*HTTPBackendRef{ - {BackendRef: newBackendRef("bb")}, - }}, - {BackendRefs: []*HTTPBackendRef{ - {BackendRef: newBackendRef("cc")}, - {BackendRef: newBackendRef("dd")}, - }}, - {BackendRefs: []*HTTPBackendRef{ - {BackendRef: newBackendRef("ee")}, - {BackendRef: newBackendRef("ff")}, - }}, - }, - }, - expect: []*BackendReference{ - newBackendRef("aa"), - newBackendRef("bb"), - newBackendRef("cc"), - newBackendRef("dd"), - newBackendRef("ee"), - newBackendRef("ff"), - }, - }, - "grpc: kitchen sink": { - route: &GRPCRoute{ - Rules: []*GRPCRouteRule{ - {BackendRefs: []*GRPCBackendRef{ - {BackendRef: newBackendRef("aa")}, - }}, - {BackendRefs: []*GRPCBackendRef{ - {BackendRef: newBackendRef("bb")}, - }}, - {BackendRefs: []*GRPCBackendRef{ - {BackendRef: newBackendRef("cc")}, - {BackendRef: newBackendRef("dd")}, - }}, - {BackendRefs: []*GRPCBackendRef{ - {BackendRef: newBackendRef("ee")}, - {BackendRef: newBackendRef("ff")}, - }}, - }, - }, - expect: []*BackendReference{ - newBackendRef("aa"), - newBackendRef("bb"), - newBackendRef("cc"), - newBackendRef("dd"), - newBackendRef("ee"), - newBackendRef("ff"), - }, - }, - "tcp: kitchen sink": { - route: &TCPRoute{ - Rules: []*TCPRouteRule{ - {BackendRefs: []*TCPBackendRef{ - {BackendRef: newBackendRef("aa")}, - }}, - {BackendRefs: []*TCPBackendRef{ - {BackendRef: newBackendRef("bb")}, - }}, - {BackendRefs: []*TCPBackendRef{ - {BackendRef: newBackendRef("cc")}, - {BackendRef: newBackendRef("dd")}, - }}, - {BackendRefs: []*TCPBackendRef{ - {BackendRef: newBackendRef("ee")}, - {BackendRef: newBackendRef("ff")}, - }}, - }, - }, - expect: []*BackendReference{ - newBackendRef("aa"), - newBackendRef("bb"), - newBackendRef("cc"), - newBackendRef("dd"), - newBackendRef("ee"), - newBackendRef("ff"), - }, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} - -func protoToString[V proto.Message](pb V) string { - m := protojson.MarshalOptions{ - Indent: " ", - } - gotJSON, err := m.Marshal(pb) - if err != nil { - return "" - } - return string(gotJSON) -} - -func newRouteRef(name string) *pbresource.Reference { - return &pbresource.Reference{ - Type: &pbresource.Type{ - Group: "fake", - GroupVersion: "v1alpha1", - Kind: "fake", - }, - Tenancy: &pbresource.Tenancy{ - Partition: "default", - Namespace: "default", - PeerName: "local", - }, - Name: name, - } -} - -func newBackendRef(name string) *BackendReference { - return &BackendReference{ - Ref: newRouteRef(name), - } -} - -func stringifyList[V proto.Message](list []V) []string { - out := make([]string, 0, len(list)) - for _, item := range list { - out = append(out, protoToString(item)) - } - return out -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.binary.go b/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.binary.go deleted file mode 100644 index f5b389089f42d..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.binary.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/computed_exported_services.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedExportedServices) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedExportedServices) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedExportedService) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedExportedService) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedExportedServicesConsumer) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedExportedServicesConsumer) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.go b/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.go deleted file mode 100644 index 11ebe79f9dc6f..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.go +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/computed_exported_services.proto - -package multiclusterv2beta1 - -import ( - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ComputedExportedServices struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Consumers []*ComputedExportedService `protobuf:"bytes,1,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *ComputedExportedServices) Reset() { - *x = ComputedExportedServices{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedExportedServices) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedExportedServices) ProtoMessage() {} - -func (x *ComputedExportedServices) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedExportedServices.ProtoReflect.Descriptor instead. -func (*ComputedExportedServices) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescGZIP(), []int{0} -} - -func (x *ComputedExportedServices) GetConsumers() []*ComputedExportedService { - if x != nil { - return x.Consumers - } - return nil -} - -type ComputedExportedService struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TargetRef *pbresource.Reference `protobuf:"bytes,1,opt,name=target_ref,json=targetRef,proto3" json:"target_ref,omitempty"` - Consumers []*ComputedExportedServicesConsumer `protobuf:"bytes,2,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *ComputedExportedService) Reset() { - *x = ComputedExportedService{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedExportedService) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedExportedService) ProtoMessage() {} - -func (x *ComputedExportedService) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedExportedService.ProtoReflect.Descriptor instead. -func (*ComputedExportedService) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescGZIP(), []int{1} -} - -func (x *ComputedExportedService) GetTargetRef() *pbresource.Reference { - if x != nil { - return x.TargetRef - } - return nil -} - -func (x *ComputedExportedService) GetConsumers() []*ComputedExportedServicesConsumer { - if x != nil { - return x.Consumers - } - return nil -} - -type ComputedExportedServicesConsumer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // no sameness group - // - // Types that are assignable to ConsumerTenancy: - // - // *ComputedExportedServicesConsumer_Peer - // *ComputedExportedServicesConsumer_Partition - ConsumerTenancy isComputedExportedServicesConsumer_ConsumerTenancy `protobuf_oneof:"consumer_tenancy"` -} - -func (x *ComputedExportedServicesConsumer) Reset() { - *x = ComputedExportedServicesConsumer{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedExportedServicesConsumer) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedExportedServicesConsumer) ProtoMessage() {} - -func (x *ComputedExportedServicesConsumer) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedExportedServicesConsumer.ProtoReflect.Descriptor instead. -func (*ComputedExportedServicesConsumer) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescGZIP(), []int{2} -} - -func (m *ComputedExportedServicesConsumer) GetConsumerTenancy() isComputedExportedServicesConsumer_ConsumerTenancy { - if m != nil { - return m.ConsumerTenancy - } - return nil -} - -func (x *ComputedExportedServicesConsumer) GetPeer() string { - if x, ok := x.GetConsumerTenancy().(*ComputedExportedServicesConsumer_Peer); ok { - return x.Peer - } - return "" -} - -func (x *ComputedExportedServicesConsumer) GetPartition() string { - if x, ok := x.GetConsumerTenancy().(*ComputedExportedServicesConsumer_Partition); ok { - return x.Partition - } - return "" -} - -type isComputedExportedServicesConsumer_ConsumerTenancy interface { - isComputedExportedServicesConsumer_ConsumerTenancy() -} - -type ComputedExportedServicesConsumer_Peer struct { - Peer string `protobuf:"bytes,3,opt,name=peer,proto3,oneof"` -} - -type ComputedExportedServicesConsumer_Partition struct { - Partition string `protobuf:"bytes,4,opt,name=partition,proto3,oneof"` -} - -func (*ComputedExportedServicesConsumer_Peer) isComputedExportedServicesConsumer_ConsumerTenancy() {} - -func (*ComputedExportedServicesConsumer_Partition) isComputedExportedServicesConsumer_ConsumerTenancy() { -} - -var File_pbmulticluster_v2beta1_computed_exported_services_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDesc = []byte{ - 0x0a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x64, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, - 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x80, 0x01, 0x0a, 0x18, 0x43, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x5c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x22, 0xc5, 0x01, 0x0a, - 0x17, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x65, 0x0a, - 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x47, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x73, 0x22, 0x6c, 0x0a, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, - 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x1e, - 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x12, - 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x63, 0x79, 0x42, 0xd6, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x42, 0x1d, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, - 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x28, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var ( - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescData = file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_pbmulticluster_v2beta1_computed_exported_services_proto_goTypes = []interface{}{ - (*ComputedExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2beta1.ComputedExportedServices - (*ComputedExportedService)(nil), // 1: hashicorp.consul.multicluster.v2beta1.ComputedExportedService - (*ComputedExportedServicesConsumer)(nil), // 2: hashicorp.consul.multicluster.v2beta1.ComputedExportedServicesConsumer - (*pbresource.Reference)(nil), // 3: hashicorp.consul.resource.Reference -} -var file_pbmulticluster_v2beta1_computed_exported_services_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.multicluster.v2beta1.ComputedExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ComputedExportedService - 3, // 1: hashicorp.consul.multicluster.v2beta1.ComputedExportedService.target_ref:type_name -> hashicorp.consul.resource.Reference - 2, // 2: hashicorp.consul.multicluster.v2beta1.ComputedExportedService.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ComputedExportedServicesConsumer - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_computed_exported_services_proto_init() } -func file_pbmulticluster_v2beta1_computed_exported_services_proto_init() { - if File_pbmulticluster_v2beta1_computed_exported_services_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedExportedServices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedExportedService); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedExportedServicesConsumer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[2].OneofWrappers = []interface{}{ - (*ComputedExportedServicesConsumer_Peer)(nil), - (*ComputedExportedServicesConsumer_Partition)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_computed_exported_services_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_computed_exported_services_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_computed_exported_services_proto = out.File - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDesc = nil - file_pbmulticluster_v2beta1_computed_exported_services_proto_goTypes = nil - file_pbmulticluster_v2beta1_computed_exported_services_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services.proto b/proto-public/pbmulticluster/v2beta1/computed_exported_services.proto deleted file mode 100644 index b8a619558451c..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services.proto +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -import "pbresource/annotations.proto"; -import "pbresource/resource.proto"; - -message ComputedExportedServices { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_PARTITION}; - - repeated ComputedExportedService consumers = 1; -} - -message ComputedExportedService { - hashicorp.consul.resource.Reference target_ref = 1; - repeated ComputedExportedServicesConsumer consumers = 2; -} - -message ComputedExportedServicesConsumer { - // no sameness group - oneof consumer_tenancy { - string peer = 3; - string partition = 4; - } -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/computed_exported_services_deepcopy.gen.go deleted file mode 100644 index b50f35a20bd92..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services_deepcopy.gen.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ComputedExportedServices within kubernetes types, where deepcopy-gen is used. -func (in *ComputedExportedServices) DeepCopyInto(out *ComputedExportedServices) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedServices. Required by controller-gen. -func (in *ComputedExportedServices) DeepCopy() *ComputedExportedServices { - if in == nil { - return nil - } - out := new(ComputedExportedServices) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedServices. Required by controller-gen. -func (in *ComputedExportedServices) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedExportedService within kubernetes types, where deepcopy-gen is used. -func (in *ComputedExportedService) DeepCopyInto(out *ComputedExportedService) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedService. Required by controller-gen. -func (in *ComputedExportedService) DeepCopy() *ComputedExportedService { - if in == nil { - return nil - } - out := new(ComputedExportedService) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedService. Required by controller-gen. -func (in *ComputedExportedService) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedExportedServicesConsumer within kubernetes types, where deepcopy-gen is used. -func (in *ComputedExportedServicesConsumer) DeepCopyInto(out *ComputedExportedServicesConsumer) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedServicesConsumer. Required by controller-gen. -func (in *ComputedExportedServicesConsumer) DeepCopy() *ComputedExportedServicesConsumer { - if in == nil { - return nil - } - out := new(ComputedExportedServicesConsumer) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedServicesConsumer. Required by controller-gen. -func (in *ComputedExportedServicesConsumer) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services_json.gen.go b/proto-public/pbmulticluster/v2beta1/computed_exported_services_json.gen.go deleted file mode 100644 index 709a7e6ef6b20..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services_json.gen.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ComputedExportedServices -func (this *ComputedExportedServices) MarshalJSON() ([]byte, error) { - str, err := ComputedExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedExportedServices -func (this *ComputedExportedServices) UnmarshalJSON(b []byte) error { - return ComputedExportedServicesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedExportedService -func (this *ComputedExportedService) MarshalJSON() ([]byte, error) { - str, err := ComputedExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedExportedService -func (this *ComputedExportedService) UnmarshalJSON(b []byte) error { - return ComputedExportedServicesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedExportedServicesConsumer -func (this *ComputedExportedServicesConsumer) MarshalJSON() ([]byte, error) { - str, err := ComputedExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedExportedServicesConsumer -func (this *ComputedExportedServicesConsumer) UnmarshalJSON(b []byte) error { - return ComputedExportedServicesUnmarshaler.Unmarshal(b, this) -} - -var ( - ComputedExportedServicesMarshaler = &protojson.MarshalOptions{} - ComputedExportedServicesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/exported_services.pb.binary.go b/proto-public/pbmulticluster/v2beta1/exported_services.pb.binary.go deleted file mode 100644 index 1530294804123..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/exported_services.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ExportedServices) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ExportedServices) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services.pb.go b/proto-public/pbmulticluster/v2beta1/exported_services.pb.go deleted file mode 100644 index 7e776c3a94c16..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services.pb.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/exported_services.proto - -package multiclusterv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ExportedServices struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Services []string `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"` - Consumers []*ExportedServicesConsumer `protobuf:"bytes,2,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *ExportedServices) Reset() { - *x = ExportedServices{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_exported_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExportedServices) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExportedServices) ProtoMessage() {} - -func (x *ExportedServices) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_exported_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExportedServices.ProtoReflect.Descriptor instead. -func (*ExportedServices) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_exported_services_proto_rawDescGZIP(), []int{0} -} - -func (x *ExportedServices) GetServices() []string { - if x != nil { - return x.Services - } - return nil -} - -func (x *ExportedServices) GetConsumers() []*ExportedServicesConsumer { - if x != nil { - return x.Consumers - } - return nil -} - -var File_pbmulticluster_v2beta1_exported_services_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_exported_services_proto_rawDesc = []byte{ - 0x0a, 0x2e, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x95, - 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, - 0x5d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, - 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x42, 0xce, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, - 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x28, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmulticluster_v2beta1_exported_services_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_exported_services_proto_rawDescData = file_pbmulticluster_v2beta1_exported_services_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_exported_services_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_exported_services_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_exported_services_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_exported_services_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmulticluster_v2beta1_exported_services_proto_goTypes = []interface{}{ - (*ExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2beta1.ExportedServices - (*ExportedServicesConsumer)(nil), // 1: hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer -} -var file_pbmulticluster_v2beta1_exported_services_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.multicluster.v2beta1.ExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_exported_services_proto_init() } -func file_pbmulticluster_v2beta1_exported_services_proto_init() { - if File_pbmulticluster_v2beta1_exported_services_proto != nil { - return - } - file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExportedServices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_exported_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_exported_services_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_exported_services_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_exported_services_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_exported_services_proto = out.File - file_pbmulticluster_v2beta1_exported_services_proto_rawDesc = nil - file_pbmulticluster_v2beta1_exported_services_proto_goTypes = nil - file_pbmulticluster_v2beta1_exported_services_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services.proto b/proto-public/pbmulticluster/v2beta1/exported_services.proto deleted file mode 100644 index 76cd98ad7a46f..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services.proto +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -import "pbmulticluster/v2beta1/exported_services_consumer.proto"; -import "pbresource/annotations.proto"; - -message ExportedServices { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - repeated string services = 1; - repeated ExportedServicesConsumer consumers = 2; -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.binary.go b/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.binary.go deleted file mode 100644 index 5f8eecd75158b..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/exported_services_consumer.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ExportedServicesConsumer) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ExportedServicesConsumer) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.go b/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.go deleted file mode 100644 index a254b81af0a63..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.go +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/exported_services_consumer.proto - -package multiclusterv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ExportedServicesConsumer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to ConsumerTenancy: - // - // *ExportedServicesConsumer_Peer - // *ExportedServicesConsumer_Partition - // *ExportedServicesConsumer_SamenessGroup - ConsumerTenancy isExportedServicesConsumer_ConsumerTenancy `protobuf_oneof:"consumer_tenancy"` -} - -func (x *ExportedServicesConsumer) Reset() { - *x = ExportedServicesConsumer{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExportedServicesConsumer) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExportedServicesConsumer) ProtoMessage() {} - -func (x *ExportedServicesConsumer) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExportedServicesConsumer.ProtoReflect.Descriptor instead. -func (*ExportedServicesConsumer) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescGZIP(), []int{0} -} - -func (m *ExportedServicesConsumer) GetConsumerTenancy() isExportedServicesConsumer_ConsumerTenancy { - if m != nil { - return m.ConsumerTenancy - } - return nil -} - -func (x *ExportedServicesConsumer) GetPeer() string { - if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_Peer); ok { - return x.Peer - } - return "" -} - -func (x *ExportedServicesConsumer) GetPartition() string { - if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_Partition); ok { - return x.Partition - } - return "" -} - -func (x *ExportedServicesConsumer) GetSamenessGroup() string { - if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_SamenessGroup); ok { - return x.SamenessGroup - } - return "" -} - -type isExportedServicesConsumer_ConsumerTenancy interface { - isExportedServicesConsumer_ConsumerTenancy() -} - -type ExportedServicesConsumer_Peer struct { - Peer string `protobuf:"bytes,1,opt,name=peer,proto3,oneof"` -} - -type ExportedServicesConsumer_Partition struct { - Partition string `protobuf:"bytes,2,opt,name=partition,proto3,oneof"` -} - -type ExportedServicesConsumer_SamenessGroup struct { - SamenessGroup string `protobuf:"bytes,3,opt,name=sameness_group,json=samenessGroup,proto3,oneof"` -} - -func (*ExportedServicesConsumer_Peer) isExportedServicesConsumer_ConsumerTenancy() {} - -func (*ExportedServicesConsumer_Partition) isExportedServicesConsumer_ConsumerTenancy() {} - -func (*ExportedServicesConsumer_SamenessGroup) isExportedServicesConsumer_ConsumerTenancy() {} - -var File_pbmulticluster_v2beta1_exported_services_consumer_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDesc = []byte{ - 0x0a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x22, 0x8d, 0x01, 0x0a, 0x18, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x12, 0x14, 0x0a, - 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, - 0x65, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x73, - 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x12, 0x0a, 0x10, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, - 0x42, 0xd6, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x1d, - 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x3b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x28, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescData = file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmulticluster_v2beta1_exported_services_consumer_proto_goTypes = []interface{}{ - (*ExportedServicesConsumer)(nil), // 0: hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer -} -var file_pbmulticluster_v2beta1_exported_services_consumer_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() } -func file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() { - if File_pbmulticluster_v2beta1_exported_services_consumer_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExportedServicesConsumer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*ExportedServicesConsumer_Peer)(nil), - (*ExportedServicesConsumer_Partition)(nil), - (*ExportedServicesConsumer_SamenessGroup)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_exported_services_consumer_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_exported_services_consumer_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_exported_services_consumer_proto = out.File - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDesc = nil - file_pbmulticluster_v2beta1_exported_services_consumer_proto_goTypes = nil - file_pbmulticluster_v2beta1_exported_services_consumer_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.proto b/proto-public/pbmulticluster/v2beta1/exported_services_consumer.proto deleted file mode 100644 index 1a110099dcf59..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.proto +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -message ExportedServicesConsumer { - oneof consumer_tenancy { - string peer = 1; - string partition = 2; - string sameness_group = 3; - } -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/exported_services_consumer_deepcopy.gen.go deleted file mode 100644 index 847fe0ec3e31d..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ExportedServicesConsumer within kubernetes types, where deepcopy-gen is used. -func (in *ExportedServicesConsumer) DeepCopyInto(out *ExportedServicesConsumer) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServicesConsumer. Required by controller-gen. -func (in *ExportedServicesConsumer) DeepCopy() *ExportedServicesConsumer { - if in == nil { - return nil - } - out := new(ExportedServicesConsumer) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServicesConsumer. Required by controller-gen. -func (in *ExportedServicesConsumer) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer_json.gen.go b/proto-public/pbmulticluster/v2beta1/exported_services_consumer_json.gen.go deleted file mode 100644 index 3f43f69932a19..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ExportedServicesConsumer -func (this *ExportedServicesConsumer) MarshalJSON() ([]byte, error) { - str, err := ExportedServicesConsumerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ExportedServicesConsumer -func (this *ExportedServicesConsumer) UnmarshalJSON(b []byte) error { - return ExportedServicesConsumerUnmarshaler.Unmarshal(b, this) -} - -var ( - ExportedServicesConsumerMarshaler = &protojson.MarshalOptions{} - ExportedServicesConsumerUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/exported_services_deepcopy.gen.go deleted file mode 100644 index f5897233ef8b6..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ExportedServices within kubernetes types, where deepcopy-gen is used. -func (in *ExportedServices) DeepCopyInto(out *ExportedServices) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServices. Required by controller-gen. -func (in *ExportedServices) DeepCopy() *ExportedServices { - if in == nil { - return nil - } - out := new(ExportedServices) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServices. Required by controller-gen. -func (in *ExportedServices) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_json.gen.go b/proto-public/pbmulticluster/v2beta1/exported_services_json.gen.go deleted file mode 100644 index 40a7cdc38b9b4..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ExportedServices -func (this *ExportedServices) MarshalJSON() ([]byte, error) { - str, err := ExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ExportedServices -func (this *ExportedServices) UnmarshalJSON(b []byte) error { - return ExportedServicesUnmarshaler.Unmarshal(b, this) -} - -var ( - ExportedServicesMarshaler = &protojson.MarshalOptions{} - ExportedServicesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.binary.go b/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.binary.go deleted file mode 100644 index eb000381077b7..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/namespace_exported_services.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *NamespaceExportedServices) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *NamespaceExportedServices) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.go b/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.go deleted file mode 100644 index 5936f86fda119..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/namespace_exported_services.proto - -package multiclusterv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type NamespaceExportedServices struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Consumers []*ExportedServicesConsumer `protobuf:"bytes,1,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *NamespaceExportedServices) Reset() { - *x = NamespaceExportedServices{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NamespaceExportedServices) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NamespaceExportedServices) ProtoMessage() {} - -func (x *NamespaceExportedServices) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NamespaceExportedServices.ProtoReflect.Descriptor instead. -func (*NamespaceExportedServices) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescGZIP(), []int{0} -} - -func (x *NamespaceExportedServices) GetConsumers() []*ExportedServicesConsumer { - if x != nil { - return x.Consumers - } - return nil -} - -var File_pbmulticluster_v2beta1_namespace_exported_services_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDesc = []byte{ - 0x0a, 0x38, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x1a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x01, 0x0a, 0x19, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x5d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x42, 0xd7, 0x02, - 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x1e, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, - 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x28, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescData = file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmulticluster_v2beta1_namespace_exported_services_proto_goTypes = []interface{}{ - (*NamespaceExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2beta1.NamespaceExportedServices - (*ExportedServicesConsumer)(nil), // 1: hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer -} -var file_pbmulticluster_v2beta1_namespace_exported_services_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.multicluster.v2beta1.NamespaceExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_namespace_exported_services_proto_init() } -func file_pbmulticluster_v2beta1_namespace_exported_services_proto_init() { - if File_pbmulticluster_v2beta1_namespace_exported_services_proto != nil { - return - } - file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamespaceExportedServices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_namespace_exported_services_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_namespace_exported_services_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_namespace_exported_services_proto = out.File - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDesc = nil - file_pbmulticluster_v2beta1_namespace_exported_services_proto_goTypes = nil - file_pbmulticluster_v2beta1_namespace_exported_services_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.proto b/proto-public/pbmulticluster/v2beta1/namespace_exported_services.proto deleted file mode 100644 index 074d44d36063e..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.proto +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -import "pbmulticluster/v2beta1/exported_services_consumer.proto"; -import "pbresource/annotations.proto"; - -message NamespaceExportedServices { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - repeated ExportedServicesConsumer consumers = 1; -} diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/namespace_exported_services_deepcopy.gen.go deleted file mode 100644 index 9d061a755bdae..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using NamespaceExportedServices within kubernetes types, where deepcopy-gen is used. -func (in *NamespaceExportedServices) DeepCopyInto(out *NamespaceExportedServices) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceExportedServices. Required by controller-gen. -func (in *NamespaceExportedServices) DeepCopy() *NamespaceExportedServices { - if in == nil { - return nil - } - out := new(NamespaceExportedServices) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceExportedServices. Required by controller-gen. -func (in *NamespaceExportedServices) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services_json.gen.go b/proto-public/pbmulticluster/v2beta1/namespace_exported_services_json.gen.go deleted file mode 100644 index 5d4ee1e42c7a9..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for NamespaceExportedServices -func (this *NamespaceExportedServices) MarshalJSON() ([]byte, error) { - str, err := NamespaceExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for NamespaceExportedServices -func (this *NamespaceExportedServices) UnmarshalJSON(b []byte) error { - return NamespaceExportedServicesUnmarshaler.Unmarshal(b, this) -} - -var ( - NamespaceExportedServicesMarshaler = &protojson.MarshalOptions{} - NamespaceExportedServicesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.binary.go b/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.binary.go deleted file mode 100644 index 5518b8a004053..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/partition_exported_services.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *PartitionExportedServices) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PartitionExportedServices) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.go b/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.go deleted file mode 100644 index 116e4784e6fe7..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/partition_exported_services.proto - -package multiclusterv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type PartitionExportedServices struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Consumers []*ExportedServicesConsumer `protobuf:"bytes,1,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *PartitionExportedServices) Reset() { - *x = PartitionExportedServices{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PartitionExportedServices) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PartitionExportedServices) ProtoMessage() {} - -func (x *PartitionExportedServices) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PartitionExportedServices.ProtoReflect.Descriptor instead. -func (*PartitionExportedServices) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescGZIP(), []int{0} -} - -func (x *PartitionExportedServices) GetConsumers() []*ExportedServicesConsumer { - if x != nil { - return x.Consumers - } - return nil -} - -var File_pbmulticluster_v2beta1_partition_exported_services_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDesc = []byte{ - 0x0a, 0x38, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x1a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x01, 0x0a, 0x19, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x5d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x42, 0xd7, 0x02, - 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x1e, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, - 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x28, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescData = file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmulticluster_v2beta1_partition_exported_services_proto_goTypes = []interface{}{ - (*PartitionExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2beta1.PartitionExportedServices - (*ExportedServicesConsumer)(nil), // 1: hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer -} -var file_pbmulticluster_v2beta1_partition_exported_services_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.multicluster.v2beta1.PartitionExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_partition_exported_services_proto_init() } -func file_pbmulticluster_v2beta1_partition_exported_services_proto_init() { - if File_pbmulticluster_v2beta1_partition_exported_services_proto != nil { - return - } - file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PartitionExportedServices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_partition_exported_services_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_partition_exported_services_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_partition_exported_services_proto = out.File - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDesc = nil - file_pbmulticluster_v2beta1_partition_exported_services_proto_goTypes = nil - file_pbmulticluster_v2beta1_partition_exported_services_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services.proto b/proto-public/pbmulticluster/v2beta1/partition_exported_services.proto deleted file mode 100644 index b3cf249a0c90f..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services.proto +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -import "pbmulticluster/v2beta1/exported_services_consumer.proto"; -import "pbresource/annotations.proto"; - -message PartitionExportedServices { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_PARTITION}; - - repeated ExportedServicesConsumer consumers = 1; -} diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/partition_exported_services_deepcopy.gen.go deleted file mode 100644 index 9f048e16d2008..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using PartitionExportedServices within kubernetes types, where deepcopy-gen is used. -func (in *PartitionExportedServices) DeepCopyInto(out *PartitionExportedServices) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartitionExportedServices. Required by controller-gen. -func (in *PartitionExportedServices) DeepCopy() *PartitionExportedServices { - if in == nil { - return nil - } - out := new(PartitionExportedServices) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new PartitionExportedServices. Required by controller-gen. -func (in *PartitionExportedServices) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services_json.gen.go b/proto-public/pbmulticluster/v2beta1/partition_exported_services_json.gen.go deleted file mode 100644 index e9dfafd702740..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for PartitionExportedServices -func (this *PartitionExportedServices) MarshalJSON() ([]byte, error) { - str, err := PartitionExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for PartitionExportedServices -func (this *PartitionExportedServices) UnmarshalJSON(b []byte) error { - return PartitionExportedServicesUnmarshaler.Unmarshal(b, this) -} - -var ( - PartitionExportedServicesMarshaler = &protojson.MarshalOptions{} - PartitionExportedServicesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/resource_types.gen.go b/proto-public/pbmulticluster/v2beta1/resource_types.gen.go deleted file mode 100644 index 910811b98f931..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/resource_types.gen.go +++ /dev/null @@ -1,43 +0,0 @@ -// Code generated by protoc-gen-resource-types. DO NOT EDIT. - -package multiclusterv2beta1 - -import ( - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - GroupName = "multicluster" - Version = "v2beta1" - - ComputedExportedServicesKind = "ComputedExportedServices" - ExportedServicesKind = "ExportedServices" - NamespaceExportedServicesKind = "NamespaceExportedServices" - PartitionExportedServicesKind = "PartitionExportedServices" -) - -var ( - ComputedExportedServicesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ComputedExportedServicesKind, - } - - ExportedServicesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ExportedServicesKind, - } - - NamespaceExportedServicesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: NamespaceExportedServicesKind, - } - - PartitionExportedServicesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: PartitionExportedServicesKind, - } -) diff --git a/proto-public/pbresource/annotations.pb.binary.go b/proto-public/pbresource/annotations.pb.binary.go deleted file mode 100644 index 5a2e76e3ad28f..0000000000000 --- a/proto-public/pbresource/annotations.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbresource/annotations.proto - -package pbresource - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ResourceTypeSpec) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ResourceTypeSpec) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbresource/annotations.pb.go b/proto-public/pbresource/annotations.pb.go deleted file mode 100644 index fa01056cf3d92..0000000000000 --- a/proto-public/pbresource/annotations.pb.go +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbresource/annotations.proto - -package pbresource - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Scope int32 - -const ( - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - Scope_SCOPE_UNDEFINED Scope = 0 - Scope_SCOPE_CLUSTER Scope = 1 - Scope_SCOPE_PARTITION Scope = 2 - Scope_SCOPE_NAMESPACE Scope = 3 -) - -// Enum value maps for Scope. -var ( - Scope_name = map[int32]string{ - 0: "SCOPE_UNDEFINED", - 1: "SCOPE_CLUSTER", - 2: "SCOPE_PARTITION", - 3: "SCOPE_NAMESPACE", - } - Scope_value = map[string]int32{ - "SCOPE_UNDEFINED": 0, - "SCOPE_CLUSTER": 1, - "SCOPE_PARTITION": 2, - "SCOPE_NAMESPACE": 3, - } -) - -func (x Scope) Enum() *Scope { - p := new(Scope) - *p = x - return p -} - -func (x Scope) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Scope) Descriptor() protoreflect.EnumDescriptor { - return file_pbresource_annotations_proto_enumTypes[0].Descriptor() -} - -func (Scope) Type() protoreflect.EnumType { - return &file_pbresource_annotations_proto_enumTypes[0] -} - -func (x Scope) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Scope.Descriptor instead. -func (Scope) EnumDescriptor() ([]byte, []int) { - return file_pbresource_annotations_proto_rawDescGZIP(), []int{0} -} - -type ResourceTypeSpec struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Scope Scope `protobuf:"varint,1,opt,name=scope,proto3,enum=hashicorp.consul.resource.Scope" json:"scope,omitempty"` - DontMapHttp bool `protobuf:"varint,2,opt,name=dont_map_http,json=dontMapHttp,proto3" json:"dont_map_http,omitempty"` -} - -func (x *ResourceTypeSpec) Reset() { - *x = ResourceTypeSpec{} - if protoimpl.UnsafeEnabled { - mi := &file_pbresource_annotations_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResourceTypeSpec) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResourceTypeSpec) ProtoMessage() {} - -func (x *ResourceTypeSpec) ProtoReflect() protoreflect.Message { - mi := &file_pbresource_annotations_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResourceTypeSpec.ProtoReflect.Descriptor instead. -func (*ResourceTypeSpec) Descriptor() ([]byte, []int) { - return file_pbresource_annotations_proto_rawDescGZIP(), []int{0} -} - -func (x *ResourceTypeSpec) GetScope() Scope { - if x != nil { - return x.Scope - } - return Scope_SCOPE_UNDEFINED -} - -func (x *ResourceTypeSpec) GetDontMapHttp() bool { - if x != nil { - return x.DontMapHttp - } - return false -} - -var file_pbresource_annotations_proto_extTypes = []protoimpl.ExtensionInfo{ - { - ExtendedType: (*descriptorpb.MessageOptions)(nil), - ExtensionType: (*ResourceTypeSpec)(nil), - Field: 8500, - Name: "hashicorp.consul.resource.spec", - Tag: "bytes,8500,opt,name=spec", - Filename: "pbresource/annotations.proto", - }, -} - -// Extension fields to descriptorpb.MessageOptions. -var ( - // optional hashicorp.consul.resource.ResourceTypeSpec spec = 8500; - E_Spec = &file_pbresource_annotations_proto_extTypes[0] -) - -var File_pbresource_annotations_proto protoreflect.FileDescriptor - -var file_pbresource_annotations_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6e, 0x0a, 0x10, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, - 0x36, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, - 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x64, 0x6f, 0x6e, 0x74, 0x5f, - 0x6d, 0x61, 0x70, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x64, 0x6f, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x48, 0x74, 0x74, 0x70, 0x2a, 0x59, 0x0a, 0x05, 0x53, - 0x63, 0x6f, 0x70, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x55, 0x4e, - 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x43, 0x4f, - 0x50, 0x45, 0x5f, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, - 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, - 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x53, - 0x50, 0x41, 0x43, 0x45, 0x10, 0x03, 0x3a, 0x61, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x1f, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0xb4, 0x42, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x53, - 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x42, 0xec, 0x01, 0x0a, 0x1d, 0x63, 0x6f, - 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x10, 0x41, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x52, 0xaa, 0x02, 0x19, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0xca, 0x02, 0x19, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0xe2, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1b, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbresource_annotations_proto_rawDescOnce sync.Once - file_pbresource_annotations_proto_rawDescData = file_pbresource_annotations_proto_rawDesc -) - -func file_pbresource_annotations_proto_rawDescGZIP() []byte { - file_pbresource_annotations_proto_rawDescOnce.Do(func() { - file_pbresource_annotations_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbresource_annotations_proto_rawDescData) - }) - return file_pbresource_annotations_proto_rawDescData -} - -var file_pbresource_annotations_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_pbresource_annotations_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbresource_annotations_proto_goTypes = []interface{}{ - (Scope)(0), // 0: hashicorp.consul.resource.Scope - (*ResourceTypeSpec)(nil), // 1: hashicorp.consul.resource.ResourceTypeSpec - (*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions -} -var file_pbresource_annotations_proto_depIdxs = []int32{ - 0, // 0: hashicorp.consul.resource.ResourceTypeSpec.scope:type_name -> hashicorp.consul.resource.Scope - 2, // 1: hashicorp.consul.resource.spec:extendee -> google.protobuf.MessageOptions - 1, // 2: hashicorp.consul.resource.spec:type_name -> hashicorp.consul.resource.ResourceTypeSpec - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 2, // [2:3] is the sub-list for extension type_name - 1, // [1:2] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbresource_annotations_proto_init() } -func file_pbresource_annotations_proto_init() { - if File_pbresource_annotations_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbresource_annotations_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResourceTypeSpec); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbresource_annotations_proto_rawDesc, - NumEnums: 1, - NumMessages: 1, - NumExtensions: 1, - NumServices: 0, - }, - GoTypes: file_pbresource_annotations_proto_goTypes, - DependencyIndexes: file_pbresource_annotations_proto_depIdxs, - EnumInfos: file_pbresource_annotations_proto_enumTypes, - MessageInfos: file_pbresource_annotations_proto_msgTypes, - ExtensionInfos: file_pbresource_annotations_proto_extTypes, - }.Build() - File_pbresource_annotations_proto = out.File - file_pbresource_annotations_proto_rawDesc = nil - file_pbresource_annotations_proto_goTypes = nil - file_pbresource_annotations_proto_depIdxs = nil -} diff --git a/proto-public/pbresource/annotations.proto b/proto-public/pbresource/annotations.proto deleted file mode 100644 index 55b2abc8e08fc..0000000000000 --- a/proto-public/pbresource/annotations.proto +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.resource; - -import "google/protobuf/descriptor.proto"; - -enum Scope { - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - SCOPE_UNDEFINED = 0; - SCOPE_CLUSTER = 1; - SCOPE_PARTITION = 2; - SCOPE_NAMESPACE = 3; -} - -message ResourceTypeSpec { - Scope scope = 1; - bool dont_map_http = 2; -} - -extend google.protobuf.MessageOptions { - ResourceTypeSpec spec = 8500; -} diff --git a/proto-public/pbresource/annotations_deepcopy.gen.go b/proto-public/pbresource/annotations_deepcopy.gen.go deleted file mode 100644 index 0693ee89e2e56..0000000000000 --- a/proto-public/pbresource/annotations_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbresource - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ResourceTypeSpec within kubernetes types, where deepcopy-gen is used. -func (in *ResourceTypeSpec) DeepCopyInto(out *ResourceTypeSpec) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceTypeSpec. Required by controller-gen. -func (in *ResourceTypeSpec) DeepCopy() *ResourceTypeSpec { - if in == nil { - return nil - } - out := new(ResourceTypeSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ResourceTypeSpec. Required by controller-gen. -func (in *ResourceTypeSpec) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbresource/annotations_json.gen.go b/proto-public/pbresource/annotations_json.gen.go deleted file mode 100644 index fbc414b1a9a1d..0000000000000 --- a/proto-public/pbresource/annotations_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbresource - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ResourceTypeSpec -func (this *ResourceTypeSpec) MarshalJSON() ([]byte, error) { - str, err := AnnotationsMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ResourceTypeSpec -func (this *ResourceTypeSpec) UnmarshalJSON(b []byte) error { - return AnnotationsUnmarshaler.Unmarshal(b, this) -} - -var ( - AnnotationsMarshaler = &protojson.MarshalOptions{} - AnnotationsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbresource/resource_deepcopy.gen.go b/proto-public/pbresource/resource_deepcopy.gen.go deleted file mode 100644 index 5b81e6f9dfed0..0000000000000 --- a/proto-public/pbresource/resource_deepcopy.gen.go +++ /dev/null @@ -1,468 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbresource - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Type within kubernetes types, where deepcopy-gen is used. -func (in *Type) DeepCopyInto(out *Type) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Type. Required by controller-gen. -func (in *Type) DeepCopy() *Type { - if in == nil { - return nil - } - out := new(Type) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Type. Required by controller-gen. -func (in *Type) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Tenancy within kubernetes types, where deepcopy-gen is used. -func (in *Tenancy) DeepCopyInto(out *Tenancy) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tenancy. Required by controller-gen. -func (in *Tenancy) DeepCopy() *Tenancy { - if in == nil { - return nil - } - out := new(Tenancy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Tenancy. Required by controller-gen. -func (in *Tenancy) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ID within kubernetes types, where deepcopy-gen is used. -func (in *ID) DeepCopyInto(out *ID) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ID. Required by controller-gen. -func (in *ID) DeepCopy() *ID { - if in == nil { - return nil - } - out := new(ID) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ID. Required by controller-gen. -func (in *ID) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Resource within kubernetes types, where deepcopy-gen is used. -func (in *Resource) DeepCopyInto(out *Resource) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resource. Required by controller-gen. -func (in *Resource) DeepCopy() *Resource { - if in == nil { - return nil - } - out := new(Resource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Resource. Required by controller-gen. -func (in *Resource) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Status within kubernetes types, where deepcopy-gen is used. -func (in *Status) DeepCopyInto(out *Status) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. Required by controller-gen. -func (in *Status) DeepCopy() *Status { - if in == nil { - return nil - } - out := new(Status) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Status. Required by controller-gen. -func (in *Status) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Condition within kubernetes types, where deepcopy-gen is used. -func (in *Condition) DeepCopyInto(out *Condition) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. Required by controller-gen. -func (in *Condition) DeepCopy() *Condition { - if in == nil { - return nil - } - out := new(Condition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Condition. Required by controller-gen. -func (in *Condition) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Reference within kubernetes types, where deepcopy-gen is used. -func (in *Reference) DeepCopyInto(out *Reference) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Reference. Required by controller-gen. -func (in *Reference) DeepCopy() *Reference { - if in == nil { - return nil - } - out := new(Reference) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Reference. Required by controller-gen. -func (in *Reference) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Tombstone within kubernetes types, where deepcopy-gen is used. -func (in *Tombstone) DeepCopyInto(out *Tombstone) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tombstone. Required by controller-gen. -func (in *Tombstone) DeepCopy() *Tombstone { - if in == nil { - return nil - } - out := new(Tombstone) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Tombstone. Required by controller-gen. -func (in *Tombstone) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ReadRequest within kubernetes types, where deepcopy-gen is used. -func (in *ReadRequest) DeepCopyInto(out *ReadRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadRequest. Required by controller-gen. -func (in *ReadRequest) DeepCopy() *ReadRequest { - if in == nil { - return nil - } - out := new(ReadRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ReadRequest. Required by controller-gen. -func (in *ReadRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ReadResponse within kubernetes types, where deepcopy-gen is used. -func (in *ReadResponse) DeepCopyInto(out *ReadResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadResponse. Required by controller-gen. -func (in *ReadResponse) DeepCopy() *ReadResponse { - if in == nil { - return nil - } - out := new(ReadResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ReadResponse. Required by controller-gen. -func (in *ReadResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ListRequest within kubernetes types, where deepcopy-gen is used. -func (in *ListRequest) DeepCopyInto(out *ListRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListRequest. Required by controller-gen. -func (in *ListRequest) DeepCopy() *ListRequest { - if in == nil { - return nil - } - out := new(ListRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ListRequest. Required by controller-gen. -func (in *ListRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ListResponse within kubernetes types, where deepcopy-gen is used. -func (in *ListResponse) DeepCopyInto(out *ListResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListResponse. Required by controller-gen. -func (in *ListResponse) DeepCopy() *ListResponse { - if in == nil { - return nil - } - out := new(ListResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ListResponse. Required by controller-gen. -func (in *ListResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ListByOwnerRequest within kubernetes types, where deepcopy-gen is used. -func (in *ListByOwnerRequest) DeepCopyInto(out *ListByOwnerRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListByOwnerRequest. Required by controller-gen. -func (in *ListByOwnerRequest) DeepCopy() *ListByOwnerRequest { - if in == nil { - return nil - } - out := new(ListByOwnerRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ListByOwnerRequest. Required by controller-gen. -func (in *ListByOwnerRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ListByOwnerResponse within kubernetes types, where deepcopy-gen is used. -func (in *ListByOwnerResponse) DeepCopyInto(out *ListByOwnerResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListByOwnerResponse. Required by controller-gen. -func (in *ListByOwnerResponse) DeepCopy() *ListByOwnerResponse { - if in == nil { - return nil - } - out := new(ListByOwnerResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ListByOwnerResponse. Required by controller-gen. -func (in *ListByOwnerResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WriteRequest within kubernetes types, where deepcopy-gen is used. -func (in *WriteRequest) DeepCopyInto(out *WriteRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WriteRequest. Required by controller-gen. -func (in *WriteRequest) DeepCopy() *WriteRequest { - if in == nil { - return nil - } - out := new(WriteRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WriteRequest. Required by controller-gen. -func (in *WriteRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WriteResponse within kubernetes types, where deepcopy-gen is used. -func (in *WriteResponse) DeepCopyInto(out *WriteResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WriteResponse. Required by controller-gen. -func (in *WriteResponse) DeepCopy() *WriteResponse { - if in == nil { - return nil - } - out := new(WriteResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WriteResponse. Required by controller-gen. -func (in *WriteResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WriteStatusRequest within kubernetes types, where deepcopy-gen is used. -func (in *WriteStatusRequest) DeepCopyInto(out *WriteStatusRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WriteStatusRequest. Required by controller-gen. -func (in *WriteStatusRequest) DeepCopy() *WriteStatusRequest { - if in == nil { - return nil - } - out := new(WriteStatusRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WriteStatusRequest. Required by controller-gen. -func (in *WriteStatusRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WriteStatusResponse within kubernetes types, where deepcopy-gen is used. -func (in *WriteStatusResponse) DeepCopyInto(out *WriteStatusResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WriteStatusResponse. Required by controller-gen. -func (in *WriteStatusResponse) DeepCopy() *WriteStatusResponse { - if in == nil { - return nil - } - out := new(WriteStatusResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WriteStatusResponse. Required by controller-gen. -func (in *WriteStatusResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DeleteRequest within kubernetes types, where deepcopy-gen is used. -func (in *DeleteRequest) DeepCopyInto(out *DeleteRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeleteRequest. Required by controller-gen. -func (in *DeleteRequest) DeepCopy() *DeleteRequest { - if in == nil { - return nil - } - out := new(DeleteRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DeleteRequest. Required by controller-gen. -func (in *DeleteRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using DeleteResponse within kubernetes types, where deepcopy-gen is used. -func (in *DeleteResponse) DeepCopyInto(out *DeleteResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeleteResponse. Required by controller-gen. -func (in *DeleteResponse) DeepCopy() *DeleteResponse { - if in == nil { - return nil - } - out := new(DeleteResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DeleteResponse. Required by controller-gen. -func (in *DeleteResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WatchListRequest within kubernetes types, where deepcopy-gen is used. -func (in *WatchListRequest) DeepCopyInto(out *WatchListRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchListRequest. Required by controller-gen. -func (in *WatchListRequest) DeepCopy() *WatchListRequest { - if in == nil { - return nil - } - out := new(WatchListRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WatchListRequest. Required by controller-gen. -func (in *WatchListRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WatchEvent within kubernetes types, where deepcopy-gen is used. -func (in *WatchEvent) DeepCopyInto(out *WatchEvent) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchEvent. Required by controller-gen. -func (in *WatchEvent) DeepCopy() *WatchEvent { - if in == nil { - return nil - } - out := new(WatchEvent) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WatchEvent. Required by controller-gen. -func (in *WatchEvent) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbresource/resource_json.gen.go b/proto-public/pbresource/resource_json.gen.go deleted file mode 100644 index 80c62deba9a41..0000000000000 --- a/proto-public/pbresource/resource_json.gen.go +++ /dev/null @@ -1,253 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbresource - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Type -func (this *Type) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Type -func (this *Type) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Tenancy -func (this *Tenancy) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Tenancy -func (this *Tenancy) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ID -func (this *ID) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ID -func (this *ID) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Resource -func (this *Resource) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Resource -func (this *Resource) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Status -func (this *Status) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Status -func (this *Status) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Condition -func (this *Condition) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Condition -func (this *Condition) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Reference -func (this *Reference) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Reference -func (this *Reference) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Tombstone -func (this *Tombstone) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Tombstone -func (this *Tombstone) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ReadRequest -func (this *ReadRequest) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ReadRequest -func (this *ReadRequest) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ReadResponse -func (this *ReadResponse) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ReadResponse -func (this *ReadResponse) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ListRequest -func (this *ListRequest) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ListRequest -func (this *ListRequest) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ListResponse -func (this *ListResponse) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ListResponse -func (this *ListResponse) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ListByOwnerRequest -func (this *ListByOwnerRequest) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ListByOwnerRequest -func (this *ListByOwnerRequest) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ListByOwnerResponse -func (this *ListByOwnerResponse) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ListByOwnerResponse -func (this *ListByOwnerResponse) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WriteRequest -func (this *WriteRequest) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WriteRequest -func (this *WriteRequest) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WriteResponse -func (this *WriteResponse) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WriteResponse -func (this *WriteResponse) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WriteStatusRequest -func (this *WriteStatusRequest) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WriteStatusRequest -func (this *WriteStatusRequest) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WriteStatusResponse -func (this *WriteStatusResponse) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WriteStatusResponse -func (this *WriteStatusResponse) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DeleteRequest -func (this *DeleteRequest) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DeleteRequest -func (this *DeleteRequest) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for DeleteResponse -func (this *DeleteResponse) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for DeleteResponse -func (this *DeleteResponse) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WatchListRequest -func (this *WatchListRequest) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WatchListRequest -func (this *WatchListRequest) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WatchEvent -func (this *WatchEvent) MarshalJSON() ([]byte, error) { - str, err := ResourceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WatchEvent -func (this *WatchEvent) UnmarshalJSON(b []byte) error { - return ResourceUnmarshaler.Unmarshal(b, this) -} - -var ( - ResourceMarshaler = &protojson.MarshalOptions{} - ResourceUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbserverdiscovery/serverdiscovery_deepcopy.gen.go b/proto-public/pbserverdiscovery/serverdiscovery_deepcopy.gen.go deleted file mode 100644 index 2bd82a8a891ab..0000000000000 --- a/proto-public/pbserverdiscovery/serverdiscovery_deepcopy.gen.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package pbserverdiscovery - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using WatchServersRequest within kubernetes types, where deepcopy-gen is used. -func (in *WatchServersRequest) DeepCopyInto(out *WatchServersRequest) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchServersRequest. Required by controller-gen. -func (in *WatchServersRequest) DeepCopy() *WatchServersRequest { - if in == nil { - return nil - } - out := new(WatchServersRequest) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WatchServersRequest. Required by controller-gen. -func (in *WatchServersRequest) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using WatchServersResponse within kubernetes types, where deepcopy-gen is used. -func (in *WatchServersResponse) DeepCopyInto(out *WatchServersResponse) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchServersResponse. Required by controller-gen. -func (in *WatchServersResponse) DeepCopy() *WatchServersResponse { - if in == nil { - return nil - } - out := new(WatchServersResponse) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new WatchServersResponse. Required by controller-gen. -func (in *WatchServersResponse) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using Server within kubernetes types, where deepcopy-gen is used. -func (in *Server) DeepCopyInto(out *Server) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Server. Required by controller-gen. -func (in *Server) DeepCopy() *Server { - if in == nil { - return nil - } - out := new(Server) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Server. Required by controller-gen. -func (in *Server) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbserverdiscovery/serverdiscovery_json.gen.go b/proto-public/pbserverdiscovery/serverdiscovery_json.gen.go deleted file mode 100644 index f8803895f2e01..0000000000000 --- a/proto-public/pbserverdiscovery/serverdiscovery_json.gen.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package pbserverdiscovery - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for WatchServersRequest -func (this *WatchServersRequest) MarshalJSON() ([]byte, error) { - str, err := ServerdiscoveryMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WatchServersRequest -func (this *WatchServersRequest) UnmarshalJSON(b []byte) error { - return ServerdiscoveryUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for WatchServersResponse -func (this *WatchServersResponse) MarshalJSON() ([]byte, error) { - str, err := ServerdiscoveryMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for WatchServersResponse -func (this *WatchServersResponse) UnmarshalJSON(b []byte) error { - return ServerdiscoveryUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for Server -func (this *Server) MarshalJSON() ([]byte, error) { - str, err := ServerdiscoveryMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Server -func (this *Server) UnmarshalJSON(b []byte) error { - return ServerdiscoveryUnmarshaler.Unmarshal(b, this) -} - -var ( - ServerdiscoveryMarshaler = &protojson.MarshalOptions{} - ServerdiscoveryUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbtenancy/v2beta1/namespace.pb.binary.go b/proto-public/pbtenancy/v2beta1/namespace.pb.binary.go deleted file mode 100644 index 1884a0943b0da..0000000000000 --- a/proto-public/pbtenancy/v2beta1/namespace.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbtenancy/v2beta1/namespace.proto - -package tenancyv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Namespace) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Namespace) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbtenancy/v2beta1/namespace.pb.go b/proto-public/pbtenancy/v2beta1/namespace.pb.go deleted file mode 100644 index 2118814a68a7f..0000000000000 --- a/proto-public/pbtenancy/v2beta1/namespace.pb.go +++ /dev/null @@ -1,171 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbtenancy/v2beta1/namespace.proto - -package tenancyv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// The name of the Namespace is in the outer Resource.ID.Name. -// It must be unique within a partition and must be a -// DNS hostname. There are also other reserved names that may not be used. -type Namespace struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Description is where the user puts any information they want - // about the namespace. It is not used internally. - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` -} - -func (x *Namespace) Reset() { - *x = Namespace{} - if protoimpl.UnsafeEnabled { - mi := &file_pbtenancy_v2beta1_namespace_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Namespace) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Namespace) ProtoMessage() {} - -func (x *Namespace) ProtoReflect() protoreflect.Message { - mi := &file_pbtenancy_v2beta1_namespace_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Namespace.ProtoReflect.Descriptor instead. -func (*Namespace) Descriptor() ([]byte, []int) { - return file_pbtenancy_v2beta1_namespace_proto_rawDescGZIP(), []int{0} -} - -func (x *Namespace) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -var File_pbtenancy_v2beta1_namespace_proto protoreflect.FileDescriptor - -var file_pbtenancy_v2beta1_namespace_proto_rawDesc = []byte{ - 0x0a, 0x21, 0x70, 0x62, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x42, 0xa4, 0x02, 0x0a, 0x24, 0x63, - 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x0e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, - 0x70, 0x62, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x3b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xa2, 0x02, 0x03, 0x48, 0x43, 0x54, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, - 0x79, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x54, 0x65, 0x6e, - 0x61, 0x6e, 0x63, 0x79, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, - 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, - 0x3a, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbtenancy_v2beta1_namespace_proto_rawDescOnce sync.Once - file_pbtenancy_v2beta1_namespace_proto_rawDescData = file_pbtenancy_v2beta1_namespace_proto_rawDesc -) - -func file_pbtenancy_v2beta1_namespace_proto_rawDescGZIP() []byte { - file_pbtenancy_v2beta1_namespace_proto_rawDescOnce.Do(func() { - file_pbtenancy_v2beta1_namespace_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbtenancy_v2beta1_namespace_proto_rawDescData) - }) - return file_pbtenancy_v2beta1_namespace_proto_rawDescData -} - -var file_pbtenancy_v2beta1_namespace_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbtenancy_v2beta1_namespace_proto_goTypes = []interface{}{ - (*Namespace)(nil), // 0: hashicorp.consul.tenancy.v2beta1.Namespace -} -var file_pbtenancy_v2beta1_namespace_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbtenancy_v2beta1_namespace_proto_init() } -func file_pbtenancy_v2beta1_namespace_proto_init() { - if File_pbtenancy_v2beta1_namespace_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbtenancy_v2beta1_namespace_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Namespace); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbtenancy_v2beta1_namespace_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbtenancy_v2beta1_namespace_proto_goTypes, - DependencyIndexes: file_pbtenancy_v2beta1_namespace_proto_depIdxs, - MessageInfos: file_pbtenancy_v2beta1_namespace_proto_msgTypes, - }.Build() - File_pbtenancy_v2beta1_namespace_proto = out.File - file_pbtenancy_v2beta1_namespace_proto_rawDesc = nil - file_pbtenancy_v2beta1_namespace_proto_goTypes = nil - file_pbtenancy_v2beta1_namespace_proto_depIdxs = nil -} diff --git a/proto-public/pbtenancy/v2beta1/namespace.proto b/proto-public/pbtenancy/v2beta1/namespace.proto deleted file mode 100644 index 6d4a739f6e21f..0000000000000 --- a/proto-public/pbtenancy/v2beta1/namespace.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package hashicorp.consul.tenancy.v2beta1; - -import "pbresource/annotations.proto"; - -// The name of the Namespace is in the outer Resource.ID.Name. -// It must be unique within a partition and must be a -// DNS hostname. There are also other reserved names that may not be used. -message Namespace { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_PARTITION}; - - // Description is where the user puts any information they want - // about the namespace. It is not used internally. - string description = 1; -} diff --git a/proto-public/pbtenancy/v2beta1/namespace_deepcopy.gen.go b/proto-public/pbtenancy/v2beta1/namespace_deepcopy.gen.go deleted file mode 100644 index 2384004c869f3..0000000000000 --- a/proto-public/pbtenancy/v2beta1/namespace_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package tenancyv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using Namespace within kubernetes types, where deepcopy-gen is used. -func (in *Namespace) DeepCopyInto(out *Namespace) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Namespace. Required by controller-gen. -func (in *Namespace) DeepCopy() *Namespace { - if in == nil { - return nil - } - out := new(Namespace) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Namespace. Required by controller-gen. -func (in *Namespace) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbtenancy/v2beta1/namespace_json.gen.go b/proto-public/pbtenancy/v2beta1/namespace_json.gen.go deleted file mode 100644 index 4ad7901c16c3c..0000000000000 --- a/proto-public/pbtenancy/v2beta1/namespace_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package tenancyv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for Namespace -func (this *Namespace) MarshalJSON() ([]byte, error) { - str, err := NamespaceMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for Namespace -func (this *Namespace) UnmarshalJSON(b []byte) error { - return NamespaceUnmarshaler.Unmarshal(b, this) -} - -var ( - NamespaceMarshaler = &protojson.MarshalOptions{} - NamespaceUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbtenancy/v2beta1/resource_types.gen.go b/proto-public/pbtenancy/v2beta1/resource_types.gen.go deleted file mode 100644 index b0c3040408234..0000000000000 --- a/proto-public/pbtenancy/v2beta1/resource_types.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-gen-resource-types. DO NOT EDIT. - -package tenancyv2beta1 - -import ( - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - GroupName = "tenancy" - Version = "v2beta1" - - NamespaceKind = "Namespace" -) - -var ( - NamespaceType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: NamespaceKind, - } -) diff --git a/proto/buf.gen.yaml b/proto/buf.gen.yaml index efb9703b10bae..e8a1a956ab869 100644 --- a/proto/buf.gen.yaml +++ b/proto/buf.gen.yaml @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 version: v1 managed: diff --git a/proto/buf.yaml b/proto/buf.yaml index d367418c824b0..de63034c3c1be 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -1,9 +1,7 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 version: v1 -deps: - - buf.build/hashicorp/consul lint: use: - DEFAULT diff --git a/proto/private/pbacl/acl.go b/proto/private/pbacl/acl.go index 5c9cc6285e6c7..3d3b8de5204a3 100644 --- a/proto/private/pbacl/acl.go +++ b/proto/private/pbacl/acl.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbacl diff --git a/proto/private/pbacl/acl.pb.go b/proto/private/pbacl/acl.pb.go index f6aa5c3418cf2..e8d0719e8d6bf 100644 --- a/proto/private/pbacl/acl.pb.go +++ b/proto/private/pbacl/acl.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbacl/acl.proto b/proto/private/pbacl/acl.proto index 0fa9ecd89dc6a..4a96f2671c319 100644 --- a/proto/private/pbacl/acl.proto +++ b/proto/private/pbacl/acl.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbautoconf/auto_config.go b/proto/private/pbautoconf/auto_config.go index 39d37d1dc8b0f..e2de2f18d9cc5 100644 --- a/proto/private/pbautoconf/auto_config.go +++ b/proto/private/pbautoconf/auto_config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbautoconf diff --git a/proto/private/pbautoconf/auto_config.pb.go b/proto/private/pbautoconf/auto_config.pb.go index a9b4c2c891682..55da1b07f9720 100644 --- a/proto/private/pbautoconf/auto_config.pb.go +++ b/proto/private/pbautoconf/auto_config.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbautoconf/auto_config.proto b/proto/private/pbautoconf/auto_config.proto index a0f4440d79047..a167107655939 100644 --- a/proto/private/pbautoconf/auto_config.proto +++ b/proto/private/pbautoconf/auto_config.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbautoconf/auto_config_ce.go b/proto/private/pbautoconf/auto_config_ce.go index f1050dbea87e5..1cab31f171c3f 100644 --- a/proto/private/pbautoconf/auto_config_ce.go +++ b/proto/private/pbautoconf/auto_config_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package pbautoconf diff --git a/proto/private/pbcommon/common.go b/proto/private/pbcommon/common.go index ecf935d75f142..e05c0a970a886 100644 --- a/proto/private/pbcommon/common.go +++ b/proto/private/pbcommon/common.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbcommon diff --git a/proto/private/pbcommon/common.pb.go b/proto/private/pbcommon/common.pb.go index fc6928184132d..dd6240ad85e9e 100644 --- a/proto/private/pbcommon/common.pb.go +++ b/proto/private/pbcommon/common.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbcommon/common.proto b/proto/private/pbcommon/common.proto index 2296dc69d628a..a86aa2dde53d1 100644 --- a/proto/private/pbcommon/common.proto +++ b/proto/private/pbcommon/common.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbcommon/common_ce.go b/proto/private/pbcommon/common_ce.go index c464211110baf..c0ce9b27f8503 100644 --- a/proto/private/pbcommon/common_ce.go +++ b/proto/private/pbcommon/common_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package pbcommon diff --git a/proto/private/pbcommon/convert_pbstruct.go b/proto/private/pbcommon/convert_pbstruct.go index f21d9a40ed49d..e48dce9ae6e0b 100644 --- a/proto/private/pbcommon/convert_pbstruct.go +++ b/proto/private/pbcommon/convert_pbstruct.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbcommon diff --git a/proto/private/pbcommon/convert_pbstruct_test.go b/proto/private/pbcommon/convert_pbstruct_test.go index 82f52c6992884..543129fdfd2fd 100644 --- a/proto/private/pbcommon/convert_pbstruct_test.go +++ b/proto/private/pbcommon/convert_pbstruct_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbcommon diff --git a/proto/private/pbconfig/config.pb.go b/proto/private/pbconfig/config.pb.go index ce8e43c7ce912..61c394944f7a5 100644 --- a/proto/private/pbconfig/config.pb.go +++ b/proto/private/pbconfig/config.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbconfig/config.proto b/proto/private/pbconfig/config.proto index 96a0f1cae04e5..79b4a3669e8b2 100644 --- a/proto/private/pbconfig/config.proto +++ b/proto/private/pbconfig/config.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbconfigentry/config_entry.gen.go b/proto/private/pbconfigentry/config_entry.gen.go index 6f9b53e01db79..ca75146af425e 100644 --- a/proto/private/pbconfigentry/config_entry.gen.go +++ b/proto/private/pbconfigentry/config_entry.gen.go @@ -53,16 +53,6 @@ func APIGatewayListenerToStructs(s *APIGatewayListener, t *structs.APIGatewayLis if s.TLS != nil { APIGatewayTLSConfigurationToStructs(s.TLS, &t.TLS) } - if s.Override != nil { - var x structs.APIGatewayPolicy - APIGatewayPolicyToStructs(s.Override, &x) - t.Override = &x - } - if s.Default != nil { - var x structs.APIGatewayPolicy - APIGatewayPolicyToStructs(s.Default, &x) - t.Default = &x - } } func APIGatewayListenerFromStructs(t *structs.APIGatewayListener, s *APIGatewayListener) { if s == nil { @@ -77,28 +67,6 @@ func APIGatewayListenerFromStructs(t *structs.APIGatewayListener, s *APIGatewayL APIGatewayTLSConfigurationFromStructs(&t.TLS, &x) s.TLS = &x } - if t.Override != nil { - var x APIGatewayPolicy - APIGatewayPolicyFromStructs(t.Override, &x) - s.Override = &x - } - if t.Default != nil { - var x APIGatewayPolicy - APIGatewayPolicyFromStructs(t.Default, &x) - s.Default = &x - } -} -func APIGatewayPolicyToStructs(s *APIGatewayPolicy, t *structs.APIGatewayPolicy) { - if s == nil { - return - } - t.JWT = gwJWTRequirementToStructs(s.JWT) -} -func APIGatewayPolicyFromStructs(t *structs.APIGatewayPolicy, s *APIGatewayPolicy) { - if s == nil { - return - } - s.JWT = gwJWTRequirementFromStructs(t.JWT) } func APIGatewayTLSConfigurationToStructs(s *APIGatewayTLSConfiguration, t *structs.APIGatewayTLSConfiguration) { if s == nil { @@ -401,17 +369,6 @@ func HTTPFiltersToStructs(s *HTTPFilters, t *structs.HTTPFilters) { URLRewriteToStructs(s.URLRewrite, &x) t.URLRewrite = &x } - if s.RetryFilter != nil { - var x structs.RetryFilter - RetryFilterToStructs(s.RetryFilter, &x) - t.RetryFilter = &x - } - if s.TimeoutFilter != nil { - var x structs.TimeoutFilter - TimeoutFilterToStructs(s.TimeoutFilter, &x) - t.TimeoutFilter = &x - } - t.JWT = routeJWTFilterToStructs(s.JWT) } func HTTPFiltersFromStructs(t *structs.HTTPFilters, s *HTTPFilters) { if s == nil { @@ -432,17 +389,6 @@ func HTTPFiltersFromStructs(t *structs.HTTPFilters, s *HTTPFilters) { URLRewriteFromStructs(t.URLRewrite, &x) s.URLRewrite = &x } - if t.RetryFilter != nil { - var x RetryFilter - RetryFilterFromStructs(t.RetryFilter, &x) - s.RetryFilter = &x - } - if t.TimeoutFilter != nil { - var x TimeoutFilter - TimeoutFilterFromStructs(t.TimeoutFilter, &x) - s.TimeoutFilter = &x - } - s.JWT = routeJWTFilterFromStructs(t.JWT) } func HTTPHeaderFilterToStructs(s *HTTPHeaderFilter, t *structs.HTTPHeaderFilter) { if s == nil { @@ -578,34 +524,6 @@ func HTTPQueryMatchFromStructs(t *structs.HTTPQueryMatch, s *HTTPQueryMatch) { s.Name = t.Name s.Value = t.Value } -func HTTPResponseFiltersToStructs(s *HTTPResponseFilters, t *structs.HTTPResponseFilters) { - if s == nil { - return - } - { - t.Headers = make([]structs.HTTPHeaderFilter, len(s.Headers)) - for i := range s.Headers { - if s.Headers[i] != nil { - HTTPHeaderFilterToStructs(s.Headers[i], &t.Headers[i]) - } - } - } -} -func HTTPResponseFiltersFromStructs(t *structs.HTTPResponseFilters, s *HTTPResponseFilters) { - if s == nil { - return - } - { - s.Headers = make([]*HTTPHeaderFilter, len(t.Headers)) - for i := range t.Headers { - { - var x HTTPHeaderFilter - HTTPHeaderFilterFromStructs(&t.Headers[i], &x) - s.Headers[i] = &x - } - } - } -} func HTTPRouteToStructs(s *HTTPRoute, t *structs.HTTPRouteConfigEntry) { if s == nil { return @@ -671,9 +589,6 @@ func HTTPRouteRuleToStructs(s *HTTPRouteRule, t *structs.HTTPRouteRule) { if s.Filters != nil { HTTPFiltersToStructs(s.Filters, &t.Filters) } - if s.ResponseFilters != nil { - HTTPResponseFiltersToStructs(s.ResponseFilters, &t.ResponseFilters) - } { t.Matches = make([]structs.HTTPMatch, len(s.Matches)) for i := range s.Matches { @@ -700,11 +615,6 @@ func HTTPRouteRuleFromStructs(t *structs.HTTPRouteRule, s *HTTPRouteRule) { HTTPFiltersFromStructs(&t.Filters, &x) s.Filters = &x } - { - var x HTTPResponseFilters - HTTPResponseFiltersFromStructs(&t.ResponseFilters, &x) - s.ResponseFilters = &x - } { s.Matches = make([]*HTTPMatch, len(t.Matches)) for i := range t.Matches { @@ -735,9 +645,6 @@ func HTTPServiceToStructs(s *HTTPService, t *structs.HTTPService) { if s.Filters != nil { HTTPFiltersToStructs(s.Filters, &t.Filters) } - if s.ResponseFilters != nil { - HTTPResponseFiltersToStructs(s.ResponseFilters, &t.ResponseFilters) - } t.EnterpriseMeta = enterpriseMetaToStructs(s.EnterpriseMeta) } func HTTPServiceFromStructs(t *structs.HTTPService, s *HTTPService) { @@ -751,11 +658,6 @@ func HTTPServiceFromStructs(t *structs.HTTPService, s *HTTPService) { HTTPFiltersFromStructs(&t.Filters, &x) s.Filters = &x } - { - var x HTTPResponseFilters - HTTPResponseFiltersFromStructs(&t.ResponseFilters, &x) - s.ResponseFilters = &x - } s.EnterpriseMeta = enterpriseMetaFromStructs(t.EnterpriseMeta) } func HashPolicyToStructs(s *HashPolicy, t *structs.HashPolicy) { @@ -982,58 +884,6 @@ func InlineCertificateFromStructs(t *structs.InlineCertificateConfigEntry, s *In s.PrivateKey = t.PrivateKey s.Meta = t.Meta } -func InstanceLevelRateLimitsToStructs(s *InstanceLevelRateLimits, t *structs.InstanceLevelRateLimits) { - if s == nil { - return - } - t.RequestsPerSecond = int(s.RequestsPerSecond) - t.RequestsMaxBurst = int(s.RequestsMaxBurst) - { - t.Routes = make([]structs.InstanceLevelRouteRateLimits, len(s.Routes)) - for i := range s.Routes { - if s.Routes[i] != nil { - InstanceLevelRouteRateLimitsToStructs(s.Routes[i], &t.Routes[i]) - } - } - } -} -func InstanceLevelRateLimitsFromStructs(t *structs.InstanceLevelRateLimits, s *InstanceLevelRateLimits) { - if s == nil { - return - } - s.RequestsPerSecond = uint32(t.RequestsPerSecond) - s.RequestsMaxBurst = uint32(t.RequestsMaxBurst) - { - s.Routes = make([]*InstanceLevelRouteRateLimits, len(t.Routes)) - for i := range t.Routes { - { - var x InstanceLevelRouteRateLimits - InstanceLevelRouteRateLimitsFromStructs(&t.Routes[i], &x) - s.Routes[i] = &x - } - } - } -} -func InstanceLevelRouteRateLimitsToStructs(s *InstanceLevelRouteRateLimits, t *structs.InstanceLevelRouteRateLimits) { - if s == nil { - return - } - t.PathExact = s.PathExact - t.PathPrefix = s.PathPrefix - t.PathRegex = s.PathRegex - t.RequestsPerSecond = int(s.RequestsPerSecond) - t.RequestsMaxBurst = int(s.RequestsMaxBurst) -} -func InstanceLevelRouteRateLimitsFromStructs(t *structs.InstanceLevelRouteRateLimits, s *InstanceLevelRouteRateLimits) { - if s == nil { - return - } - s.PathExact = t.PathExact - s.PathPrefix = t.PathPrefix - s.PathRegex = t.PathRegex - s.RequestsPerSecond = uint32(t.RequestsPerSecond) - s.RequestsMaxBurst = uint32(t.RequestsMaxBurst) -} func IntentionHTTPHeaderPermissionToStructs(s *IntentionHTTPHeaderPermission, t *structs.IntentionHTTPHeaderPermission) { if s == nil { return @@ -1744,24 +1594,6 @@ func PeeringMeshConfigFromStructs(t *structs.PeeringMeshConfig, s *PeeringMeshCo } s.PeerThroughMeshGateways = t.PeerThroughMeshGateways } -func RateLimitsToStructs(s *RateLimits, t *structs.RateLimits) { - if s == nil { - return - } - if s.InstanceLevel != nil { - InstanceLevelRateLimitsToStructs(s.InstanceLevel, &t.InstanceLevel) - } -} -func RateLimitsFromStructs(t *structs.RateLimits, s *RateLimits) { - if s == nil { - return - } - { - var x InstanceLevelRateLimits - InstanceLevelRateLimitsFromStructs(&t.InstanceLevel, &x) - s.InstanceLevel = &x - } -} func RemoteJWKSToStructs(s *RemoteJWKS, t *structs.RemoteJWKS) { if s == nil { return @@ -1818,24 +1650,6 @@ func ResourceReferenceFromStructs(t *structs.ResourceReference, s *ResourceRefer s.SectionName = t.SectionName s.EnterpriseMeta = enterpriseMetaFromStructs(t.EnterpriseMeta) } -func RetryFilterToStructs(s *RetryFilter, t *structs.RetryFilter) { - if s == nil { - return - } - t.NumRetries = s.NumRetries - t.RetryOn = s.RetryOn - t.RetryOnStatusCodes = s.RetryOnStatusCodes - t.RetryOnConnectFailure = s.RetryOnConnectFailure -} -func RetryFilterFromStructs(t *structs.RetryFilter, s *RetryFilter) { - if s == nil { - return - } - s.NumRetries = t.NumRetries - s.RetryOn = t.RetryOn - s.RetryOnStatusCodes = t.RetryOnStatusCodes - s.RetryOnConnectFailure = t.RetryOnConnectFailure -} func RetryPolicyBackOffToStructs(s *RetryPolicyBackOff, t *structs.RetryPolicyBackOff) { if s == nil { return @@ -1947,11 +1761,6 @@ func ServiceDefaultsToStructs(s *ServiceDefaults, t *structs.ServiceConfigEntry) t.LocalConnectTimeoutMs = int(s.LocalConnectTimeoutMs) t.LocalRequestTimeoutMs = int(s.LocalRequestTimeoutMs) t.BalanceInboundConnections = s.BalanceInboundConnections - if s.RateLimits != nil { - var x structs.RateLimits - RateLimitsToStructs(s.RateLimits, &x) - t.RateLimits = &x - } t.EnvoyExtensions = EnvoyExtensionsToStructs(s.EnvoyExtensions) t.Meta = s.Meta } @@ -1992,11 +1801,6 @@ func ServiceDefaultsFromStructs(t *structs.ServiceConfigEntry, s *ServiceDefault s.LocalConnectTimeoutMs = int32(t.LocalConnectTimeoutMs) s.LocalRequestTimeoutMs = int32(t.LocalRequestTimeoutMs) s.BalanceInboundConnections = t.BalanceInboundConnections - if t.RateLimits != nil { - var x RateLimits - RateLimitsFromStructs(t.RateLimits, &x) - s.RateLimits = &x - } s.EnvoyExtensions = EnvoyExtensionsFromStructs(t.EnvoyExtensions) s.Meta = t.Meta } @@ -2420,20 +2224,6 @@ func TCPServiceFromStructs(t *structs.TCPService, s *TCPService) { s.Name = t.Name s.EnterpriseMeta = enterpriseMetaFromStructs(t.EnterpriseMeta) } -func TimeoutFilterToStructs(s *TimeoutFilter, t *structs.TimeoutFilter) { - if s == nil { - return - } - t.RequestTimeout = structs.DurationFromProto(s.RequestTimeout) - t.IdleTimeout = structs.DurationFromProto(s.IdleTimeout) -} -func TimeoutFilterFromStructs(t *structs.TimeoutFilter, s *TimeoutFilter) { - if s == nil { - return - } - s.RequestTimeout = structs.DurationToProto(t.RequestTimeout) - s.IdleTimeout = structs.DurationToProto(t.IdleTimeout) -} func TransparentProxyConfigToStructs(s *TransparentProxyConfig, t *structs.TransparentProxyConfig) { if s == nil { return diff --git a/proto/private/pbconfigentry/config_entry.go b/proto/private/pbconfigentry/config_entry.go index 8ddfde8cccfb9..705c87d0131ef 100644 --- a/proto/private/pbconfigentry/config_entry.go +++ b/proto/private/pbconfigentry/config_entry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbconfigentry diff --git a/proto/private/pbconfigentry/config_entry.pb.binary.go b/proto/private/pbconfigentry/config_entry.pb.binary.go index a1b70cabcb652..bd9bac6c7e762 100644 --- a/proto/private/pbconfigentry/config_entry.pb.binary.go +++ b/proto/private/pbconfigentry/config_entry.pb.binary.go @@ -457,36 +457,6 @@ func (msg *DestinationConfig) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RateLimits) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RateLimits) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *InstanceLevelRateLimits) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *InstanceLevelRateLimits) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *InstanceLevelRouteRateLimits) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *InstanceLevelRouteRateLimits) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - // MarshalBinary implements encoding.BinaryMarshaler func (msg *APIGateway) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) @@ -537,46 +507,6 @@ func (msg *APIGatewayTLSConfiguration) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *APIGatewayPolicy) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *APIGatewayPolicy) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *APIGatewayJWTRequirement) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *APIGatewayJWTRequirement) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *APIGatewayJWTProvider) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *APIGatewayJWTProvider) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *APIGatewayJWTClaimVerification) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *APIGatewayJWTClaimVerification) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - // MarshalBinary implements encoding.BinaryMarshaler func (msg *ResourceReference) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) @@ -687,16 +617,6 @@ func (msg *HTTPFilters) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *HTTPResponseFilters) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *HTTPResponseFilters) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - // MarshalBinary implements encoding.BinaryMarshaler func (msg *URLRewrite) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) @@ -707,36 +627,6 @@ func (msg *URLRewrite) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RetryFilter) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RetryFilter) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *TimeoutFilter) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *TimeoutFilter) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *JWTFilter) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *JWTFilter) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - // MarshalBinary implements encoding.BinaryMarshaler func (msg *HTTPHeaderFilter) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) diff --git a/proto/private/pbconfigentry/config_entry.pb.go b/proto/private/pbconfigentry/config_entry.pb.go index 3d68e73763895..2977d593f824c 100644 --- a/proto/private/pbconfigentry/config_entry.pb.go +++ b/proto/private/pbconfigentry/config_entry.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: @@ -3475,7 +3475,6 @@ type ServiceDefaults struct { // mog: func-to=int func-from=int32 LocalRequestTimeoutMs int32 `protobuf:"varint,11,opt,name=LocalRequestTimeoutMs,proto3" json:"LocalRequestTimeoutMs,omitempty"` BalanceInboundConnections string `protobuf:"bytes,12,opt,name=BalanceInboundConnections,proto3" json:"BalanceInboundConnections,omitempty"` - RateLimits *RateLimits `protobuf:"bytes,16,opt,name=RateLimits,proto3" json:"RateLimits,omitempty"` Meta map[string]string `protobuf:"bytes,13,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // mog: func-to=EnvoyExtensionsToStructs func-from=EnvoyExtensionsFromStructs EnvoyExtensions []*pbcommon.EnvoyExtension `protobuf:"bytes,14,rep,name=EnvoyExtensions,proto3" json:"EnvoyExtensions,omitempty"` @@ -3599,13 +3598,6 @@ func (x *ServiceDefaults) GetBalanceInboundConnections() string { return "" } -func (x *ServiceDefaults) GetRateLimits() *RateLimits { - if x != nil { - return x.RateLimits - } - return nil -} - func (x *ServiceDefaults) GetMeta() map[string]string { if x != nil { return x.Meta @@ -4301,214 +4293,6 @@ func (x *DestinationConfig) GetPort() int32 { return 0 } -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.RateLimits -// output=config_entry.gen.go -// name=Structs -type RateLimits struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - InstanceLevel *InstanceLevelRateLimits `protobuf:"bytes,1,opt,name=InstanceLevel,proto3" json:"InstanceLevel,omitempty"` -} - -func (x *RateLimits) Reset() { - *x = RateLimits{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RateLimits) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RateLimits) ProtoMessage() {} - -func (x *RateLimits) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[45] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RateLimits.ProtoReflect.Descriptor instead. -func (*RateLimits) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{45} -} - -func (x *RateLimits) GetInstanceLevel() *InstanceLevelRateLimits { - if x != nil { - return x.InstanceLevel - } - return nil -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.InstanceLevelRateLimits -// output=config_entry.gen.go -// name=Structs -type InstanceLevelRateLimits struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // mog: func-to=int func-from=uint32 - RequestsPerSecond uint32 `protobuf:"varint,1,opt,name=RequestsPerSecond,proto3" json:"RequestsPerSecond,omitempty"` - // mog: func-to=int func-from=uint32 - RequestsMaxBurst uint32 `protobuf:"varint,2,opt,name=RequestsMaxBurst,proto3" json:"RequestsMaxBurst,omitempty"` - Routes []*InstanceLevelRouteRateLimits `protobuf:"bytes,3,rep,name=Routes,proto3" json:"Routes,omitempty"` -} - -func (x *InstanceLevelRateLimits) Reset() { - *x = InstanceLevelRateLimits{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InstanceLevelRateLimits) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InstanceLevelRateLimits) ProtoMessage() {} - -func (x *InstanceLevelRateLimits) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[46] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InstanceLevelRateLimits.ProtoReflect.Descriptor instead. -func (*InstanceLevelRateLimits) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{46} -} - -func (x *InstanceLevelRateLimits) GetRequestsPerSecond() uint32 { - if x != nil { - return x.RequestsPerSecond - } - return 0 -} - -func (x *InstanceLevelRateLimits) GetRequestsMaxBurst() uint32 { - if x != nil { - return x.RequestsMaxBurst - } - return 0 -} - -func (x *InstanceLevelRateLimits) GetRoutes() []*InstanceLevelRouteRateLimits { - if x != nil { - return x.Routes - } - return nil -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.InstanceLevelRouteRateLimits -// output=config_entry.gen.go -// name=Structs -type InstanceLevelRouteRateLimits struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PathExact string `protobuf:"bytes,1,opt,name=PathExact,proto3" json:"PathExact,omitempty"` - PathPrefix string `protobuf:"bytes,2,opt,name=PathPrefix,proto3" json:"PathPrefix,omitempty"` - PathRegex string `protobuf:"bytes,3,opt,name=PathRegex,proto3" json:"PathRegex,omitempty"` - // mog: func-to=int func-from=uint32 - RequestsPerSecond uint32 `protobuf:"varint,4,opt,name=RequestsPerSecond,proto3" json:"RequestsPerSecond,omitempty"` - // mog: func-to=int func-from=uint32 - RequestsMaxBurst uint32 `protobuf:"varint,5,opt,name=RequestsMaxBurst,proto3" json:"RequestsMaxBurst,omitempty"` -} - -func (x *InstanceLevelRouteRateLimits) Reset() { - *x = InstanceLevelRouteRateLimits{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[47] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InstanceLevelRouteRateLimits) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InstanceLevelRouteRateLimits) ProtoMessage() {} - -func (x *InstanceLevelRouteRateLimits) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[47] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InstanceLevelRouteRateLimits.ProtoReflect.Descriptor instead. -func (*InstanceLevelRouteRateLimits) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{47} -} - -func (x *InstanceLevelRouteRateLimits) GetPathExact() string { - if x != nil { - return x.PathExact - } - return "" -} - -func (x *InstanceLevelRouteRateLimits) GetPathPrefix() string { - if x != nil { - return x.PathPrefix - } - return "" -} - -func (x *InstanceLevelRouteRateLimits) GetPathRegex() string { - if x != nil { - return x.PathRegex - } - return "" -} - -func (x *InstanceLevelRouteRateLimits) GetRequestsPerSecond() uint32 { - if x != nil { - return x.RequestsPerSecond - } - return 0 -} - -func (x *InstanceLevelRouteRateLimits) GetRequestsMaxBurst() uint32 { - if x != nil { - return x.RequestsMaxBurst - } - return 0 -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.APIGatewayConfigEntry @@ -4528,7 +4312,7 @@ type APIGateway struct { func (x *APIGateway) Reset() { *x = APIGateway{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[48] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4541,7 +4325,7 @@ func (x *APIGateway) String() string { func (*APIGateway) ProtoMessage() {} func (x *APIGateway) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[48] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[45] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4554,7 +4338,7 @@ func (x *APIGateway) ProtoReflect() protoreflect.Message { // Deprecated: Use APIGateway.ProtoReflect.Descriptor instead. func (*APIGateway) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{48} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{45} } func (x *APIGateway) GetMeta() map[string]string { @@ -4594,7 +4378,7 @@ type Status struct { func (x *Status) Reset() { *x = Status{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[49] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4607,7 +4391,7 @@ func (x *Status) String() string { func (*Status) ProtoMessage() {} func (x *Status) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[49] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4620,7 +4404,7 @@ func (x *Status) ProtoReflect() protoreflect.Message { // Deprecated: Use Status.ProtoReflect.Descriptor instead. func (*Status) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{49} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{46} } func (x *Status) GetConditions() []*Condition { @@ -4652,7 +4436,7 @@ type Condition struct { func (x *Condition) Reset() { *x = Condition{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[50] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4665,7 +4449,7 @@ func (x *Condition) String() string { func (*Condition) ProtoMessage() {} func (x *Condition) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[50] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4678,7 +4462,7 @@ func (x *Condition) ProtoReflect() protoreflect.Message { // Deprecated: Use Condition.ProtoReflect.Descriptor instead. func (*Condition) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{50} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{47} } func (x *Condition) GetType() string { @@ -4740,14 +4524,12 @@ type APIGatewayListener struct { // mog: func-to=apiGatewayProtocolToStructs func-from=apiGatewayProtocolFromStructs Protocol APIGatewayListenerProtocol `protobuf:"varint,4,opt,name=Protocol,proto3,enum=hashicorp.consul.internal.configentry.APIGatewayListenerProtocol" json:"Protocol,omitempty"` TLS *APIGatewayTLSConfiguration `protobuf:"bytes,5,opt,name=TLS,proto3" json:"TLS,omitempty"` - Override *APIGatewayPolicy `protobuf:"bytes,6,opt,name=Override,proto3" json:"Override,omitempty"` - Default *APIGatewayPolicy `protobuf:"bytes,7,opt,name=Default,proto3" json:"Default,omitempty"` } func (x *APIGatewayListener) Reset() { *x = APIGatewayListener{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[51] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4760,7 +4542,7 @@ func (x *APIGatewayListener) String() string { func (*APIGatewayListener) ProtoMessage() {} func (x *APIGatewayListener) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[51] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4773,7 +4555,7 @@ func (x *APIGatewayListener) ProtoReflect() protoreflect.Message { // Deprecated: Use APIGatewayListener.ProtoReflect.Descriptor instead. func (*APIGatewayListener) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{51} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{48} } func (x *APIGatewayListener) GetName() string { @@ -4811,20 +4593,6 @@ func (x *APIGatewayListener) GetTLS() *APIGatewayTLSConfiguration { return nil } -func (x *APIGatewayListener) GetOverride() *APIGatewayPolicy { - if x != nil { - return x.Override - } - return nil -} - -func (x *APIGatewayListener) GetDefault() *APIGatewayPolicy { - if x != nil { - return x.Default - } - return nil -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.APIGatewayTLSConfiguration @@ -4847,7 +4615,7 @@ type APIGatewayTLSConfiguration struct { func (x *APIGatewayTLSConfiguration) Reset() { *x = APIGatewayTLSConfiguration{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[52] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4860,7 +4628,7 @@ func (x *APIGatewayTLSConfiguration) String() string { func (*APIGatewayTLSConfiguration) ProtoMessage() {} func (x *APIGatewayTLSConfiguration) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[52] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4873,7 +4641,7 @@ func (x *APIGatewayTLSConfiguration) ProtoReflect() protoreflect.Message { // Deprecated: Use APIGatewayTLSConfiguration.ProtoReflect.Descriptor instead. func (*APIGatewayTLSConfiguration) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{52} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{49} } func (x *APIGatewayTLSConfiguration) GetCertificates() []*ResourceReference { @@ -4906,35 +4674,38 @@ func (x *APIGatewayTLSConfiguration) GetCipherSuites() []string { // mog annotation: // -// target=github.com/hashicorp/consul/agent/structs.APIGatewayPolicy +// target=github.com/hashicorp/consul/agent/structs.ResourceReference // output=config_entry.gen.go // name=Structs -type APIGatewayPolicy struct { +type ResourceReference struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // mog: func-to=gwJWTRequirementToStructs func-from=gwJWTRequirementFromStructs - JWT *APIGatewayJWTRequirement `protobuf:"bytes,1,opt,name=JWT,proto3" json:"JWT,omitempty"` + Kind string `protobuf:"bytes,1,opt,name=Kind,proto3" json:"Kind,omitempty"` + Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` + SectionName string `protobuf:"bytes,3,opt,name=SectionName,proto3" json:"SectionName,omitempty"` + // mog: func-to=enterpriseMetaToStructs func-from=enterpriseMetaFromStructs + EnterpriseMeta *pbcommon.EnterpriseMeta `protobuf:"bytes,4,opt,name=EnterpriseMeta,proto3" json:"EnterpriseMeta,omitempty"` } -func (x *APIGatewayPolicy) Reset() { - *x = APIGatewayPolicy{} +func (x *ResourceReference) Reset() { + *x = ResourceReference{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[53] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *APIGatewayPolicy) String() string { +func (x *ResourceReference) String() string { return protoimpl.X.MessageStringOf(x) } -func (*APIGatewayPolicy) ProtoMessage() {} +func (*ResourceReference) ProtoMessage() {} -func (x *APIGatewayPolicy) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[53] +func (x *ResourceReference) ProtoReflect() protoreflect.Message { + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4945,271 +4716,58 @@ func (x *APIGatewayPolicy) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use APIGatewayPolicy.ProtoReflect.Descriptor instead. -func (*APIGatewayPolicy) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{53} +// Deprecated: Use ResourceReference.ProtoReflect.Descriptor instead. +func (*ResourceReference) Descriptor() ([]byte, []int) { + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{50} } -func (x *APIGatewayPolicy) GetJWT() *APIGatewayJWTRequirement { +func (x *ResourceReference) GetKind() string { if x != nil { - return x.JWT + return x.Kind + } + return "" +} + +func (x *ResourceReference) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ResourceReference) GetSectionName() string { + if x != nil { + return x.SectionName + } + return "" +} + +func (x *ResourceReference) GetEnterpriseMeta() *pbcommon.EnterpriseMeta { + if x != nil { + return x.EnterpriseMeta } return nil } -type APIGatewayJWTRequirement struct { +// mog annotation: +// +// target=github.com/hashicorp/consul/agent/structs.BoundAPIGatewayConfigEntry +// output=config_entry.gen.go +// name=Structs +// ignore-fields=Kind,Name,RaftIndex,EnterpriseMeta +type BoundAPIGateway struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Providers []*APIGatewayJWTProvider `protobuf:"bytes,1,rep,name=Providers,proto3" json:"Providers,omitempty"` + Meta map[string]string `protobuf:"bytes,1,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Listeners []*BoundAPIGatewayListener `protobuf:"bytes,2,rep,name=Listeners,proto3" json:"Listeners,omitempty"` } -func (x *APIGatewayJWTRequirement) Reset() { - *x = APIGatewayJWTRequirement{} +func (x *BoundAPIGateway) Reset() { + *x = BoundAPIGateway{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[54] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *APIGatewayJWTRequirement) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*APIGatewayJWTRequirement) ProtoMessage() {} - -func (x *APIGatewayJWTRequirement) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[54] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use APIGatewayJWTRequirement.ProtoReflect.Descriptor instead. -func (*APIGatewayJWTRequirement) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{54} -} - -func (x *APIGatewayJWTRequirement) GetProviders() []*APIGatewayJWTProvider { - if x != nil { - return x.Providers - } - return nil -} - -type APIGatewayJWTProvider struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` - VerifyClaims []*APIGatewayJWTClaimVerification `protobuf:"bytes,2,rep,name=VerifyClaims,proto3" json:"VerifyClaims,omitempty"` -} - -func (x *APIGatewayJWTProvider) Reset() { - *x = APIGatewayJWTProvider{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[55] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *APIGatewayJWTProvider) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*APIGatewayJWTProvider) ProtoMessage() {} - -func (x *APIGatewayJWTProvider) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[55] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use APIGatewayJWTProvider.ProtoReflect.Descriptor instead. -func (*APIGatewayJWTProvider) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{55} -} - -func (x *APIGatewayJWTProvider) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *APIGatewayJWTProvider) GetVerifyClaims() []*APIGatewayJWTClaimVerification { - if x != nil { - return x.VerifyClaims - } - return nil -} - -type APIGatewayJWTClaimVerification struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Path []string `protobuf:"bytes,1,rep,name=Path,proto3" json:"Path,omitempty"` - Value string `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"` -} - -func (x *APIGatewayJWTClaimVerification) Reset() { - *x = APIGatewayJWTClaimVerification{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[56] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *APIGatewayJWTClaimVerification) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*APIGatewayJWTClaimVerification) ProtoMessage() {} - -func (x *APIGatewayJWTClaimVerification) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[56] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use APIGatewayJWTClaimVerification.ProtoReflect.Descriptor instead. -func (*APIGatewayJWTClaimVerification) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{56} -} - -func (x *APIGatewayJWTClaimVerification) GetPath() []string { - if x != nil { - return x.Path - } - return nil -} - -func (x *APIGatewayJWTClaimVerification) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.ResourceReference -// output=config_entry.gen.go -// name=Structs -type ResourceReference struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Kind string `protobuf:"bytes,1,opt,name=Kind,proto3" json:"Kind,omitempty"` - Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` - SectionName string `protobuf:"bytes,3,opt,name=SectionName,proto3" json:"SectionName,omitempty"` - // mog: func-to=enterpriseMetaToStructs func-from=enterpriseMetaFromStructs - EnterpriseMeta *pbcommon.EnterpriseMeta `protobuf:"bytes,4,opt,name=EnterpriseMeta,proto3" json:"EnterpriseMeta,omitempty"` -} - -func (x *ResourceReference) Reset() { - *x = ResourceReference{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[57] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResourceReference) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResourceReference) ProtoMessage() {} - -func (x *ResourceReference) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[57] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResourceReference.ProtoReflect.Descriptor instead. -func (*ResourceReference) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{57} -} - -func (x *ResourceReference) GetKind() string { - if x != nil { - return x.Kind - } - return "" -} - -func (x *ResourceReference) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ResourceReference) GetSectionName() string { - if x != nil { - return x.SectionName - } - return "" -} - -func (x *ResourceReference) GetEnterpriseMeta() *pbcommon.EnterpriseMeta { - if x != nil { - return x.EnterpriseMeta - } - return nil -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.BoundAPIGatewayConfigEntry -// output=config_entry.gen.go -// name=Structs -// ignore-fields=Kind,Name,RaftIndex,EnterpriseMeta -type BoundAPIGateway struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Meta map[string]string `protobuf:"bytes,1,rep,name=Meta,proto3" json:"Meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Listeners []*BoundAPIGatewayListener `protobuf:"bytes,2,rep,name=Listeners,proto3" json:"Listeners,omitempty"` -} - -func (x *BoundAPIGateway) Reset() { - *x = BoundAPIGateway{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[58] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5222,7 +4780,7 @@ func (x *BoundAPIGateway) String() string { func (*BoundAPIGateway) ProtoMessage() {} func (x *BoundAPIGateway) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[58] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5235,7 +4793,7 @@ func (x *BoundAPIGateway) ProtoReflect() protoreflect.Message { // Deprecated: Use BoundAPIGateway.ProtoReflect.Descriptor instead. func (*BoundAPIGateway) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{58} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{51} } func (x *BoundAPIGateway) GetMeta() map[string]string { @@ -5270,7 +4828,7 @@ type BoundAPIGatewayListener struct { func (x *BoundAPIGatewayListener) Reset() { *x = BoundAPIGatewayListener{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[59] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5283,7 +4841,7 @@ func (x *BoundAPIGatewayListener) String() string { func (*BoundAPIGatewayListener) ProtoMessage() {} func (x *BoundAPIGatewayListener) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[59] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5296,7 +4854,7 @@ func (x *BoundAPIGatewayListener) ProtoReflect() protoreflect.Message { // Deprecated: Use BoundAPIGatewayListener.ProtoReflect.Descriptor instead. func (*BoundAPIGatewayListener) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{59} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{52} } func (x *BoundAPIGatewayListener) GetName() string { @@ -5339,7 +4897,7 @@ type InlineCertificate struct { func (x *InlineCertificate) Reset() { *x = InlineCertificate{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[60] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5352,7 +4910,7 @@ func (x *InlineCertificate) String() string { func (*InlineCertificate) ProtoMessage() {} func (x *InlineCertificate) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[60] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5365,7 +4923,7 @@ func (x *InlineCertificate) ProtoReflect() protoreflect.Message { // Deprecated: Use InlineCertificate.ProtoReflect.Descriptor instead. func (*InlineCertificate) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{60} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{53} } func (x *InlineCertificate) GetMeta() map[string]string { @@ -5410,7 +4968,7 @@ type HTTPRoute struct { func (x *HTTPRoute) Reset() { *x = HTTPRoute{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[61] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5423,7 +4981,7 @@ func (x *HTTPRoute) String() string { func (*HTTPRoute) ProtoMessage() {} func (x *HTTPRoute) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[61] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5436,7 +4994,7 @@ func (x *HTTPRoute) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPRoute.ProtoReflect.Descriptor instead. func (*HTTPRoute) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{61} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{54} } func (x *HTTPRoute) GetMeta() map[string]string { @@ -5484,16 +5042,15 @@ type HTTPRouteRule struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Filters *HTTPFilters `protobuf:"bytes,1,opt,name=Filters,proto3" json:"Filters,omitempty"` - Matches []*HTTPMatch `protobuf:"bytes,2,rep,name=Matches,proto3" json:"Matches,omitempty"` - Services []*HTTPService `protobuf:"bytes,3,rep,name=Services,proto3" json:"Services,omitempty"` - ResponseFilters *HTTPResponseFilters `protobuf:"bytes,4,opt,name=ResponseFilters,proto3" json:"ResponseFilters,omitempty"` + Filters *HTTPFilters `protobuf:"bytes,1,opt,name=Filters,proto3" json:"Filters,omitempty"` + Matches []*HTTPMatch `protobuf:"bytes,2,rep,name=Matches,proto3" json:"Matches,omitempty"` + Services []*HTTPService `protobuf:"bytes,3,rep,name=Services,proto3" json:"Services,omitempty"` } func (x *HTTPRouteRule) Reset() { *x = HTTPRouteRule{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[62] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5506,7 +5063,7 @@ func (x *HTTPRouteRule) String() string { func (*HTTPRouteRule) ProtoMessage() {} func (x *HTTPRouteRule) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[62] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5519,7 +5076,7 @@ func (x *HTTPRouteRule) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPRouteRule.ProtoReflect.Descriptor instead. func (*HTTPRouteRule) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{62} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{55} } func (x *HTTPRouteRule) GetFilters() *HTTPFilters { @@ -5543,13 +5100,6 @@ func (x *HTTPRouteRule) GetServices() []*HTTPService { return nil } -func (x *HTTPRouteRule) GetResponseFilters() *HTTPResponseFilters { - if x != nil { - return x.ResponseFilters - } - return nil -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.HTTPMatch @@ -5570,7 +5120,7 @@ type HTTPMatch struct { func (x *HTTPMatch) Reset() { *x = HTTPMatch{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[63] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5583,7 +5133,7 @@ func (x *HTTPMatch) String() string { func (*HTTPMatch) ProtoMessage() {} func (x *HTTPMatch) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[63] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5596,7 +5146,7 @@ func (x *HTTPMatch) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPMatch.ProtoReflect.Descriptor instead. func (*HTTPMatch) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{63} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{56} } func (x *HTTPMatch) GetHeaders() []*HTTPHeaderMatch { @@ -5646,7 +5196,7 @@ type HTTPHeaderMatch struct { func (x *HTTPHeaderMatch) Reset() { *x = HTTPHeaderMatch{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[64] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5659,7 +5209,7 @@ func (x *HTTPHeaderMatch) String() string { func (*HTTPHeaderMatch) ProtoMessage() {} func (x *HTTPHeaderMatch) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[64] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5672,7 +5222,7 @@ func (x *HTTPHeaderMatch) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPHeaderMatch.ProtoReflect.Descriptor instead. func (*HTTPHeaderMatch) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{64} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{57} } func (x *HTTPHeaderMatch) GetMatch() HTTPHeaderMatchType { @@ -5714,7 +5264,7 @@ type HTTPPathMatch struct { func (x *HTTPPathMatch) Reset() { *x = HTTPPathMatch{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[65] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5727,7 +5277,7 @@ func (x *HTTPPathMatch) String() string { func (*HTTPPathMatch) ProtoMessage() {} func (x *HTTPPathMatch) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[65] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5740,7 +5290,7 @@ func (x *HTTPPathMatch) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPPathMatch.ProtoReflect.Descriptor instead. func (*HTTPPathMatch) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{65} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{58} } func (x *HTTPPathMatch) GetMatch() HTTPPathMatchType { @@ -5776,7 +5326,7 @@ type HTTPQueryMatch struct { func (x *HTTPQueryMatch) Reset() { *x = HTTPQueryMatch{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[66] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5789,7 +5339,7 @@ func (x *HTTPQueryMatch) String() string { func (*HTTPQueryMatch) ProtoMessage() {} func (x *HTTPQueryMatch) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[66] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5802,7 +5352,7 @@ func (x *HTTPQueryMatch) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPQueryMatch.ProtoReflect.Descriptor instead. func (*HTTPQueryMatch) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{66} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{59} } func (x *HTTPQueryMatch) GetMatch() HTTPQueryMatchType { @@ -5836,18 +5386,14 @@ type HTTPFilters struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Headers []*HTTPHeaderFilter `protobuf:"bytes,1,rep,name=Headers,proto3" json:"Headers,omitempty"` - URLRewrite *URLRewrite `protobuf:"bytes,2,opt,name=URLRewrite,proto3" json:"URLRewrite,omitempty"` - RetryFilter *RetryFilter `protobuf:"bytes,3,opt,name=RetryFilter,proto3" json:"RetryFilter,omitempty"` - TimeoutFilter *TimeoutFilter `protobuf:"bytes,4,opt,name=TimeoutFilter,proto3" json:"TimeoutFilter,omitempty"` - // mog: func-to=routeJWTFilterToStructs func-from=routeJWTFilterFromStructs - JWT *JWTFilter `protobuf:"bytes,5,opt,name=JWT,proto3" json:"JWT,omitempty"` + Headers []*HTTPHeaderFilter `protobuf:"bytes,1,rep,name=Headers,proto3" json:"Headers,omitempty"` + URLRewrite *URLRewrite `protobuf:"bytes,2,opt,name=URLRewrite,proto3" json:"URLRewrite,omitempty"` } func (x *HTTPFilters) Reset() { *x = HTTPFilters{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[67] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5860,7 +5406,7 @@ func (x *HTTPFilters) String() string { func (*HTTPFilters) ProtoMessage() {} func (x *HTTPFilters) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[67] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5873,7 +5419,7 @@ func (x *HTTPFilters) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPFilters.ProtoReflect.Descriptor instead. func (*HTTPFilters) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{67} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{60} } func (x *HTTPFilters) GetHeaders() []*HTTPHeaderFilter { @@ -5890,79 +5436,6 @@ func (x *HTTPFilters) GetURLRewrite() *URLRewrite { return nil } -func (x *HTTPFilters) GetRetryFilter() *RetryFilter { - if x != nil { - return x.RetryFilter - } - return nil -} - -func (x *HTTPFilters) GetTimeoutFilter() *TimeoutFilter { - if x != nil { - return x.TimeoutFilter - } - return nil -} - -func (x *HTTPFilters) GetJWT() *JWTFilter { - if x != nil { - return x.JWT - } - return nil -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.HTTPResponseFilters -// output=config_entry.gen.go -// name=Structs -type HTTPResponseFilters struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Headers []*HTTPHeaderFilter `protobuf:"bytes,1,rep,name=Headers,proto3" json:"Headers,omitempty"` -} - -func (x *HTTPResponseFilters) Reset() { - *x = HTTPResponseFilters{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[68] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *HTTPResponseFilters) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*HTTPResponseFilters) ProtoMessage() {} - -func (x *HTTPResponseFilters) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[68] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use HTTPResponseFilters.ProtoReflect.Descriptor instead. -func (*HTTPResponseFilters) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{68} -} - -func (x *HTTPResponseFilters) GetHeaders() []*HTTPHeaderFilter { - if x != nil { - return x.Headers - } - return nil -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.URLRewrite @@ -5979,7 +5452,7 @@ type URLRewrite struct { func (x *URLRewrite) Reset() { *x = URLRewrite{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[69] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5992,7 +5465,7 @@ func (x *URLRewrite) String() string { func (*URLRewrite) ProtoMessage() {} func (x *URLRewrite) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[69] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6005,7 +5478,7 @@ func (x *URLRewrite) ProtoReflect() protoreflect.Message { // Deprecated: Use URLRewrite.ProtoReflect.Descriptor instead. func (*URLRewrite) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{69} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{61} } func (x *URLRewrite) GetPath() string { @@ -6015,191 +5488,6 @@ func (x *URLRewrite) GetPath() string { return "" } -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.RetryFilter -// output=config_entry.gen.go -// name=Structs -type RetryFilter struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - NumRetries uint32 `protobuf:"varint,1,opt,name=NumRetries,proto3" json:"NumRetries,omitempty"` - RetryOn []string `protobuf:"bytes,2,rep,name=RetryOn,proto3" json:"RetryOn,omitempty"` - RetryOnStatusCodes []uint32 `protobuf:"varint,3,rep,packed,name=RetryOnStatusCodes,proto3" json:"RetryOnStatusCodes,omitempty"` - RetryOnConnectFailure bool `protobuf:"varint,4,opt,name=RetryOnConnectFailure,proto3" json:"RetryOnConnectFailure,omitempty"` -} - -func (x *RetryFilter) Reset() { - *x = RetryFilter{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[70] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RetryFilter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RetryFilter) ProtoMessage() {} - -func (x *RetryFilter) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[70] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RetryFilter.ProtoReflect.Descriptor instead. -func (*RetryFilter) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{70} -} - -func (x *RetryFilter) GetNumRetries() uint32 { - if x != nil { - return x.NumRetries - } - return 0 -} - -func (x *RetryFilter) GetRetryOn() []string { - if x != nil { - return x.RetryOn - } - return nil -} - -func (x *RetryFilter) GetRetryOnStatusCodes() []uint32 { - if x != nil { - return x.RetryOnStatusCodes - } - return nil -} - -func (x *RetryFilter) GetRetryOnConnectFailure() bool { - if x != nil { - return x.RetryOnConnectFailure - } - return false -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.TimeoutFilter -// output=config_entry.gen.go -// name=Structs -type TimeoutFilter struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // mog: func-to=structs.DurationFromProto func-from=structs.DurationToProto - RequestTimeout *durationpb.Duration `protobuf:"bytes,1,opt,name=RequestTimeout,proto3" json:"RequestTimeout,omitempty"` - // mog: func-to=structs.DurationFromProto func-from=structs.DurationToProto - IdleTimeout *durationpb.Duration `protobuf:"bytes,2,opt,name=IdleTimeout,proto3" json:"IdleTimeout,omitempty"` -} - -func (x *TimeoutFilter) Reset() { - *x = TimeoutFilter{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[71] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TimeoutFilter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TimeoutFilter) ProtoMessage() {} - -func (x *TimeoutFilter) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[71] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TimeoutFilter.ProtoReflect.Descriptor instead. -func (*TimeoutFilter) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{71} -} - -func (x *TimeoutFilter) GetRequestTimeout() *durationpb.Duration { - if x != nil { - return x.RequestTimeout - } - return nil -} - -func (x *TimeoutFilter) GetIdleTimeout() *durationpb.Duration { - if x != nil { - return x.IdleTimeout - } - return nil -} - -type JWTFilter struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Providers []*APIGatewayJWTProvider `protobuf:"bytes,1,rep,name=Providers,proto3" json:"Providers,omitempty"` -} - -func (x *JWTFilter) Reset() { - *x = JWTFilter{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[72] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *JWTFilter) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*JWTFilter) ProtoMessage() {} - -func (x *JWTFilter) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[72] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use JWTFilter.ProtoReflect.Descriptor instead. -func (*JWTFilter) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{72} -} - -func (x *JWTFilter) GetProviders() []*APIGatewayJWTProvider { - if x != nil { - return x.Providers - } - return nil -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.HTTPHeaderFilter @@ -6218,7 +5506,7 @@ type HTTPHeaderFilter struct { func (x *HTTPHeaderFilter) Reset() { *x = HTTPHeaderFilter{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[73] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6231,7 +5519,7 @@ func (x *HTTPHeaderFilter) String() string { func (*HTTPHeaderFilter) ProtoMessage() {} func (x *HTTPHeaderFilter) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[73] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6244,7 +5532,7 @@ func (x *HTTPHeaderFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPHeaderFilter.ProtoReflect.Descriptor instead. func (*HTTPHeaderFilter) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{73} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{62} } func (x *HTTPHeaderFilter) GetAdd() map[string]string { @@ -6283,14 +5571,13 @@ type HTTPService struct { Weight int32 `protobuf:"varint,2,opt,name=Weight,proto3" json:"Weight,omitempty"` Filters *HTTPFilters `protobuf:"bytes,3,opt,name=Filters,proto3" json:"Filters,omitempty"` // mog: func-to=enterpriseMetaToStructs func-from=enterpriseMetaFromStructs - EnterpriseMeta *pbcommon.EnterpriseMeta `protobuf:"bytes,4,opt,name=EnterpriseMeta,proto3" json:"EnterpriseMeta,omitempty"` - ResponseFilters *HTTPResponseFilters `protobuf:"bytes,5,opt,name=ResponseFilters,proto3" json:"ResponseFilters,omitempty"` + EnterpriseMeta *pbcommon.EnterpriseMeta `protobuf:"bytes,4,opt,name=EnterpriseMeta,proto3" json:"EnterpriseMeta,omitempty"` } func (x *HTTPService) Reset() { *x = HTTPService{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[74] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6303,7 +5590,7 @@ func (x *HTTPService) String() string { func (*HTTPService) ProtoMessage() {} func (x *HTTPService) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[74] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6316,7 +5603,7 @@ func (x *HTTPService) ProtoReflect() protoreflect.Message { // Deprecated: Use HTTPService.ProtoReflect.Descriptor instead. func (*HTTPService) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{74} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{63} } func (x *HTTPService) GetName() string { @@ -6347,13 +5634,6 @@ func (x *HTTPService) GetEnterpriseMeta() *pbcommon.EnterpriseMeta { return nil } -func (x *HTTPService) GetResponseFilters() *HTTPResponseFilters { - if x != nil { - return x.ResponseFilters - } - return nil -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.TCPRouteConfigEntry @@ -6374,7 +5654,7 @@ type TCPRoute struct { func (x *TCPRoute) Reset() { *x = TCPRoute{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[75] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6387,7 +5667,7 @@ func (x *TCPRoute) String() string { func (*TCPRoute) ProtoMessage() {} func (x *TCPRoute) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[75] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6400,7 +5680,7 @@ func (x *TCPRoute) ProtoReflect() protoreflect.Message { // Deprecated: Use TCPRoute.ProtoReflect.Descriptor instead. func (*TCPRoute) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{75} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{64} } func (x *TCPRoute) GetMeta() map[string]string { @@ -6449,7 +5729,7 @@ type TCPService struct { func (x *TCPService) Reset() { *x = TCPService{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[76] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6462,7 +5742,7 @@ func (x *TCPService) String() string { func (*TCPService) ProtoMessage() {} func (x *TCPService) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[76] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6475,7 +5755,7 @@ func (x *TCPService) ProtoReflect() protoreflect.Message { // Deprecated: Use TCPService.ProtoReflect.Descriptor instead. func (*TCPService) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{76} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{65} } func (x *TCPService) GetName() string { @@ -6515,7 +5795,7 @@ type SamenessGroup struct { func (x *SamenessGroup) Reset() { *x = SamenessGroup{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[77] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6528,7 +5808,7 @@ func (x *SamenessGroup) String() string { func (*SamenessGroup) ProtoMessage() {} func (x *SamenessGroup) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[77] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6541,7 +5821,7 @@ func (x *SamenessGroup) ProtoReflect() protoreflect.Message { // Deprecated: Use SamenessGroup.ProtoReflect.Descriptor instead. func (*SamenessGroup) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{77} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{66} } func (x *SamenessGroup) GetName() string { @@ -6603,7 +5883,7 @@ type SamenessGroupMember struct { func (x *SamenessGroupMember) Reset() { *x = SamenessGroupMember{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[78] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6616,7 +5896,7 @@ func (x *SamenessGroupMember) String() string { func (*SamenessGroupMember) ProtoMessage() {} func (x *SamenessGroupMember) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[78] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6629,7 +5909,7 @@ func (x *SamenessGroupMember) ProtoReflect() protoreflect.Message { // Deprecated: Use SamenessGroupMember.ProtoReflect.Descriptor instead. func (*SamenessGroupMember) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{78} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{67} } func (x *SamenessGroupMember) GetPartition() string { @@ -6671,7 +5951,7 @@ type JWTProvider struct { func (x *JWTProvider) Reset() { *x = JWTProvider{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[79] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6684,7 +5964,7 @@ func (x *JWTProvider) String() string { func (*JWTProvider) ProtoMessage() {} func (x *JWTProvider) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[79] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6697,7 +5977,7 @@ func (x *JWTProvider) ProtoReflect() protoreflect.Message { // Deprecated: Use JWTProvider.ProtoReflect.Descriptor instead. func (*JWTProvider) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{79} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{68} } func (x *JWTProvider) GetJSONWebKeySet() *JSONWebKeySet { @@ -6773,7 +6053,7 @@ type JSONWebKeySet struct { func (x *JSONWebKeySet) Reset() { *x = JSONWebKeySet{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[80] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6786,7 +6066,7 @@ func (x *JSONWebKeySet) String() string { func (*JSONWebKeySet) ProtoMessage() {} func (x *JSONWebKeySet) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[80] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6799,7 +6079,7 @@ func (x *JSONWebKeySet) ProtoReflect() protoreflect.Message { // Deprecated: Use JSONWebKeySet.ProtoReflect.Descriptor instead. func (*JSONWebKeySet) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{80} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{69} } func (x *JSONWebKeySet) GetLocal() *LocalJWKS { @@ -6833,7 +6113,7 @@ type LocalJWKS struct { func (x *LocalJWKS) Reset() { *x = LocalJWKS{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[81] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6846,7 +6126,7 @@ func (x *LocalJWKS) String() string { func (*LocalJWKS) ProtoMessage() {} func (x *LocalJWKS) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[81] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6859,7 +6139,7 @@ func (x *LocalJWKS) ProtoReflect() protoreflect.Message { // Deprecated: Use LocalJWKS.ProtoReflect.Descriptor instead. func (*LocalJWKS) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{81} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{70} } func (x *LocalJWKS) GetJWKS() string { @@ -6899,7 +6179,7 @@ type RemoteJWKS struct { func (x *RemoteJWKS) Reset() { *x = RemoteJWKS{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[82] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6912,7 +6192,7 @@ func (x *RemoteJWKS) String() string { func (*RemoteJWKS) ProtoMessage() {} func (x *RemoteJWKS) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[82] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[71] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6925,7 +6205,7 @@ func (x *RemoteJWKS) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoteJWKS.ProtoReflect.Descriptor instead. func (*RemoteJWKS) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{82} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{71} } func (x *RemoteJWKS) GetURI() string { @@ -6989,7 +6269,7 @@ type JWKSCluster struct { func (x *JWKSCluster) Reset() { *x = JWKSCluster{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[83] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7002,7 +6282,7 @@ func (x *JWKSCluster) String() string { func (*JWKSCluster) ProtoMessage() {} func (x *JWKSCluster) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[83] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[72] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7015,7 +6295,7 @@ func (x *JWKSCluster) ProtoReflect() protoreflect.Message { // Deprecated: Use JWKSCluster.ProtoReflect.Descriptor instead. func (*JWKSCluster) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{83} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{72} } func (x *JWKSCluster) GetDiscoveryType() string { @@ -7056,7 +6336,7 @@ type JWKSTLSCertificate struct { func (x *JWKSTLSCertificate) Reset() { *x = JWKSTLSCertificate{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[84] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7069,7 +6349,7 @@ func (x *JWKSTLSCertificate) String() string { func (*JWKSTLSCertificate) ProtoMessage() {} func (x *JWKSTLSCertificate) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[84] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[73] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7082,7 +6362,7 @@ func (x *JWKSTLSCertificate) ProtoReflect() protoreflect.Message { // Deprecated: Use JWKSTLSCertificate.ProtoReflect.Descriptor instead. func (*JWKSTLSCertificate) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{84} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{73} } func (x *JWKSTLSCertificate) GetCaCertificateProviderInstance() *JWKSTLSCertProviderInstance { @@ -7116,7 +6396,7 @@ type JWKSTLSCertProviderInstance struct { func (x *JWKSTLSCertProviderInstance) Reset() { *x = JWKSTLSCertProviderInstance{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[85] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7129,7 +6409,7 @@ func (x *JWKSTLSCertProviderInstance) String() string { func (*JWKSTLSCertProviderInstance) ProtoMessage() {} func (x *JWKSTLSCertProviderInstance) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[85] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[74] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7142,7 +6422,7 @@ func (x *JWKSTLSCertProviderInstance) ProtoReflect() protoreflect.Message { // Deprecated: Use JWKSTLSCertProviderInstance.ProtoReflect.Descriptor instead. func (*JWKSTLSCertProviderInstance) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{85} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{74} } func (x *JWKSTLSCertProviderInstance) GetInstanceName() string { @@ -7178,7 +6458,7 @@ type JWKSTLSCertTrustedCA struct { func (x *JWKSTLSCertTrustedCA) Reset() { *x = JWKSTLSCertTrustedCA{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[86] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7191,7 +6471,7 @@ func (x *JWKSTLSCertTrustedCA) String() string { func (*JWKSTLSCertTrustedCA) ProtoMessage() {} func (x *JWKSTLSCertTrustedCA) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[86] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7204,7 +6484,7 @@ func (x *JWKSTLSCertTrustedCA) ProtoReflect() protoreflect.Message { // Deprecated: Use JWKSTLSCertTrustedCA.ProtoReflect.Descriptor instead. func (*JWKSTLSCertTrustedCA) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{86} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{75} } func (x *JWKSTLSCertTrustedCA) GetFilename() string { @@ -7253,7 +6533,7 @@ type JWKSRetryPolicy struct { func (x *JWKSRetryPolicy) Reset() { *x = JWKSRetryPolicy{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[87] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7266,7 +6546,7 @@ func (x *JWKSRetryPolicy) String() string { func (*JWKSRetryPolicy) ProtoMessage() {} func (x *JWKSRetryPolicy) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[87] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7279,7 +6559,7 @@ func (x *JWKSRetryPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use JWKSRetryPolicy.ProtoReflect.Descriptor instead. func (*JWKSRetryPolicy) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{87} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{76} } func (x *JWKSRetryPolicy) GetNumRetries() int32 { @@ -7315,7 +6595,7 @@ type RetryPolicyBackOff struct { func (x *RetryPolicyBackOff) Reset() { *x = RetryPolicyBackOff{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[88] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7328,7 +6608,7 @@ func (x *RetryPolicyBackOff) String() string { func (*RetryPolicyBackOff) ProtoMessage() {} func (x *RetryPolicyBackOff) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[88] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7341,7 +6621,7 @@ func (x *RetryPolicyBackOff) ProtoReflect() protoreflect.Message { // Deprecated: Use RetryPolicyBackOff.ProtoReflect.Descriptor instead. func (*RetryPolicyBackOff) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{88} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{77} } func (x *RetryPolicyBackOff) GetBaseInterval() *durationpb.Duration { @@ -7376,7 +6656,7 @@ type JWTLocation struct { func (x *JWTLocation) Reset() { *x = JWTLocation{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[89] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7389,7 +6669,7 @@ func (x *JWTLocation) String() string { func (*JWTLocation) ProtoMessage() {} func (x *JWTLocation) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[89] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7402,7 +6682,7 @@ func (x *JWTLocation) ProtoReflect() protoreflect.Message { // Deprecated: Use JWTLocation.ProtoReflect.Descriptor instead. func (*JWTLocation) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{89} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{78} } func (x *JWTLocation) GetHeader() *JWTLocationHeader { @@ -7444,7 +6724,7 @@ type JWTLocationHeader struct { func (x *JWTLocationHeader) Reset() { *x = JWTLocationHeader{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[90] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7457,7 +6737,7 @@ func (x *JWTLocationHeader) String() string { func (*JWTLocationHeader) ProtoMessage() {} func (x *JWTLocationHeader) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[90] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7470,7 +6750,7 @@ func (x *JWTLocationHeader) ProtoReflect() protoreflect.Message { // Deprecated: Use JWTLocationHeader.ProtoReflect.Descriptor instead. func (*JWTLocationHeader) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{90} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{79} } func (x *JWTLocationHeader) GetName() string { @@ -7510,7 +6790,7 @@ type JWTLocationQueryParam struct { func (x *JWTLocationQueryParam) Reset() { *x = JWTLocationQueryParam{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[91] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7523,7 +6803,7 @@ func (x *JWTLocationQueryParam) String() string { func (*JWTLocationQueryParam) ProtoMessage() {} func (x *JWTLocationQueryParam) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[91] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[80] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7536,7 +6816,7 @@ func (x *JWTLocationQueryParam) ProtoReflect() protoreflect.Message { // Deprecated: Use JWTLocationQueryParam.ProtoReflect.Descriptor instead. func (*JWTLocationQueryParam) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{91} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{80} } func (x *JWTLocationQueryParam) GetName() string { @@ -7562,7 +6842,7 @@ type JWTLocationCookie struct { func (x *JWTLocationCookie) Reset() { *x = JWTLocationCookie{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[92] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7575,7 +6855,7 @@ func (x *JWTLocationCookie) String() string { func (*JWTLocationCookie) ProtoMessage() {} func (x *JWTLocationCookie) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[92] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[81] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7588,7 +6868,7 @@ func (x *JWTLocationCookie) ProtoReflect() protoreflect.Message { // Deprecated: Use JWTLocationCookie.ProtoReflect.Descriptor instead. func (*JWTLocationCookie) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{92} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{81} } func (x *JWTLocationCookie) GetName() string { @@ -7615,7 +6895,7 @@ type JWTForwardingConfig struct { func (x *JWTForwardingConfig) Reset() { *x = JWTForwardingConfig{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[93] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7628,7 +6908,7 @@ func (x *JWTForwardingConfig) String() string { func (*JWTForwardingConfig) ProtoMessage() {} func (x *JWTForwardingConfig) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[93] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[82] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7641,7 +6921,7 @@ func (x *JWTForwardingConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use JWTForwardingConfig.ProtoReflect.Descriptor instead. func (*JWTForwardingConfig) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{93} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{82} } func (x *JWTForwardingConfig) GetHeaderName() string { @@ -7675,7 +6955,7 @@ type JWTCacheConfig struct { func (x *JWTCacheConfig) Reset() { *x = JWTCacheConfig{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[94] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7688,7 +6968,7 @@ func (x *JWTCacheConfig) String() string { func (*JWTCacheConfig) ProtoMessage() {} func (x *JWTCacheConfig) ProtoReflect() protoreflect.Message { - mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[94] + mi := &file_private_pbconfigentry_config_entry_proto_msgTypes[83] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7701,7 +6981,7 @@ func (x *JWTCacheConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use JWTCacheConfig.ProtoReflect.Descriptor instead. func (*JWTCacheConfig) Descriptor() ([]byte, []int) { - return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{94} + return file_private_pbconfigentry_config_entry_proto_rawDescGZIP(), []int{83} } func (x *JWTCacheConfig) GetSize() int32 { @@ -8365,7 +7645,7 @@ var file_private_pbconfigentry_config_entry_proto_rawDesc = []byte{ 0x06, 0x53, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x49, - 0x6e, 0x76, 0x65, 0x72, 0x74, 0x22, 0xe5, 0x09, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x22, 0x92, 0x09, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x44, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, @@ -8418,900 +7698,761 @@ var file_private_pbconfigentry_config_entry_proto_rawDesc = []byte{ 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x51, 0x0a, 0x0a, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, - 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x0a, 0x52, 0x61, 0x74, 0x65, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x54, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x0d, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x5a, 0x0a, 0x0f, - 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x0d, 0x4d, 0x75, 0x74, 0x75, - 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, - 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0d, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, - 0x4d, 0x6f, 0x64, 0x65, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x74, 0x0a, - 0x16, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, - 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x0a, 0x14, 0x4f, 0x75, 0x74, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x44, - 0x69, 0x61, 0x6c, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0e, 0x44, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x6c, 0x79, 0x22, 0x5f, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4a, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, - 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, - 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x6f, 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x47, 0x0a, 0x05, - 0x50, 0x61, 0x74, 0x68, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x05, - 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, 0xb0, 0x01, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, - 0x50, 0x61, 0x74, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x50, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, - 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x50, 0x6f, - 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x28, - 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x73, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x50, 0x61, 0x72, 0x73, 0x65, 0x64, 0x46, - 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x22, 0xbf, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x09, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x4f, 0x76, - 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x51, 0x0a, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x8a, 0x05, 0x0a, 0x0e, 0x55, - 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, - 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x58, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, - 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, - 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, - 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x11, 0x45, - 0x6e, 0x76, 0x6f, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x53, 0x4f, 0x4e, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x4c, 0x69, 0x73, - 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x53, 0x4f, 0x4e, 0x12, 0x2a, 0x0a, 0x10, 0x45, 0x6e, 0x76, - 0x6f, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x10, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x4a, 0x53, 0x4f, 0x4e, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x4d, 0x0a, - 0x06, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, - 0x6d, 0x69, 0x74, 0x73, 0x52, 0x06, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x69, 0x0a, 0x12, - 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, - 0x63, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x2e, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x52, 0x12, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x5a, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x68, 0x47, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, + 0x6f, 0x6e, 0x73, 0x12, 0x54, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x0d, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x5a, 0x0a, 0x0f, 0x45, 0x6e, 0x76, + 0x6f, 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x0d, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, + 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x12, 0x3e, 0x0a, 0x1a, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x75, - 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1a, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, - 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, 0x72, 0x22, 0x9e, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x4d, 0x61, - 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x0e, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x4d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, - 0x4d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x15, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x9e, 0x02, 0x0a, 0x12, 0x50, 0x61, 0x73, - 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, - 0x35, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x61, 0x69, - 0x6c, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4d, 0x61, 0x78, - 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x17, 0x45, 0x6e, 0x66, 0x6f, - 0x72, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, - 0x35, 0x78, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x45, 0x6e, 0x66, 0x6f, 0x72, - 0x63, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, - 0x78, 0x78, 0x12, 0x2e, 0x0a, 0x12, 0x4d, 0x61, 0x78, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, - 0x4d, 0x61, 0x78, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x63, 0x65, - 0x6e, 0x74, 0x12, 0x45, 0x0a, 0x10, 0x42, 0x61, 0x73, 0x65, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x42, 0x61, 0x73, 0x65, 0x45, 0x6a, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x11, 0x44, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, - 0x0a, 0x09, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x09, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, - 0x22, 0x72, 0x0a, 0x0a, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x64, - 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x61, 0x74, 0x65, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4c, - 0x65, 0x76, 0x65, 0x6c, 0x22, 0xd0, 0x01, 0x0a, 0x17, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, - 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x2a, - 0x0a, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x4d, 0x61, 0x78, 0x42, 0x75, 0x72, - 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x4d, 0x61, 0x78, 0x42, 0x75, 0x72, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x06, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, - 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x1c, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x61, - 0x74, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x74, 0x68, - 0x45, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x74, - 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x61, 0x74, 0x68, 0x50, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x50, 0x61, 0x74, 0x68, - 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, - 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x74, 0x68, 0x52, - 0x65, 0x67, 0x65, 0x78, 0x12, 0x2c, 0x0a, 0x11, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, - 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x11, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x4d, 0x61, - 0x78, 0x42, 0x75, 0x72, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x4d, 0x61, 0x78, 0x42, 0x75, 0x72, 0x73, 0x74, 0x22, 0xb6, - 0x02, 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x4f, 0x0a, - 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4d, - 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x57, - 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x4c, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x37, - 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x50, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0x8b, 0x02, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, - 0x06, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x52, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x54, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x4c, 0x61, 0x73, 0x74, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x12, 0x4c, - 0x61, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, - 0x65, 0x22, 0xb4, 0x03, 0x0a, 0x12, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x5d, 0x0a, 0x08, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x53, 0x0a, 0x03, 0x54, - 0x4c, 0x53, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, + 0x64, 0x65, 0x52, 0x0d, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, + 0x65, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x74, 0x0a, 0x16, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x32, 0x0a, 0x14, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x14, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x44, 0x69, 0x61, 0x6c, + 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x44, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, + 0x22, 0x5f, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4a, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4d, 0x65, 0x73, 0x68, + 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x4d, 0x6f, 0x64, + 0x65, 0x22, 0x6f, 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x06, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x47, 0x0a, 0x05, 0x50, 0x61, 0x74, + 0x68, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x54, 0x4c, 0x53, - 0x12, 0x53, 0x0a, 0x08, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x52, 0x05, 0x50, 0x61, 0x74, + 0x68, 0x73, 0x22, 0xb0, 0x01, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, + 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x50, 0x6f, 0x72, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x28, 0x0a, 0x0f, 0x50, + 0x61, 0x72, 0x73, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x50, 0x61, 0x72, 0x73, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x22, 0xbf, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x53, 0x0a, 0x09, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, - 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, 0x4f, 0x76, 0x65, - 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x51, 0x0a, 0x07, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x4f, 0x76, 0x65, 0x72, 0x72, + 0x69, 0x64, 0x65, 0x73, 0x12, 0x51, 0x0a, 0x08, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, - 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, - 0x07, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0xde, 0x01, 0x0a, 0x1a, 0x41, 0x50, 0x49, - 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, 0x0c, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0c, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x69, 0x6e, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, - 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x69, 0x70, - 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x22, 0x65, 0x0a, 0x10, 0x41, 0x50, 0x49, - 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x51, 0x0a, - 0x03, 0x4a, 0x57, 0x54, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, + 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x55, + 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x08, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x8a, 0x05, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x58, + 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, + 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, + 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x11, 0x45, 0x6e, 0x76, 0x6f, + 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x11, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x65, 0x72, 0x4a, 0x53, 0x4f, 0x4e, 0x12, 0x2a, 0x0a, 0x10, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x53, + 0x4f, 0x4e, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x2a, + 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x4d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x4d, 0x0a, 0x06, 0x4c, 0x69, + 0x6d, 0x69, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4a, 0x57, 0x54, - 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x03, 0x4a, 0x57, 0x54, - 0x22, 0x76, 0x0a, 0x18, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4a, 0x57, - 0x54, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5a, 0x0a, 0x09, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x09, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x15, 0x41, 0x50, 0x49, - 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x69, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, - 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4a, - 0x57, 0x54, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6c, 0x61, 0x69, 0x6d, - 0x73, 0x22, 0x4a, 0x0a, 0x1e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4a, - 0x57, 0x54, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xb7, 0x01, - 0x0a, 0x11, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x53, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x58, 0x0a, - 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x72, 0x79, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x73, 0x52, 0x06, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x69, 0x0a, 0x12, 0x50, 0x61, 0x73, + 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x22, 0xfe, 0x01, 0x0a, 0x0f, 0x42, 0x6f, 0x75, 0x6e, - 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x54, 0x0a, 0x04, 0x4d, - 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x50, 0x61, + 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x52, 0x12, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x12, 0x5a, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, - 0x61, 0x12, 0x5c, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, - 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x1a, - 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdd, 0x01, 0x0a, 0x17, 0x42, 0x6f, 0x75, - 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5c, 0x0a, 0x0c, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0c, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x79, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x0b, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x12, 0x3e, 0x0a, 0x1a, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x75, 0x74, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x1a, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x75, 0x74, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x50, 0x65, 0x65, 0x72, 0x22, 0x9e, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x4d, 0x61, 0x78, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0e, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x2e, 0x0a, 0x12, 0x4d, 0x61, 0x78, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x4d, 0x61, 0x78, + 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, + 0x34, 0x0a, 0x15, 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x15, + 0x4d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x9e, 0x02, 0x0a, 0x12, 0x50, 0x61, 0x73, 0x73, 0x69, 0x76, + 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x08, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x4d, 0x61, 0x78, 0x46, 0x61, 0x69, + 0x6c, 0x75, 0x72, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x17, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x69, + 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, 0x78, 0x78, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x45, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, 0x78, 0x78, 0x12, + 0x2e, 0x0a, 0x12, 0x4d, 0x61, 0x78, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, + 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x4d, 0x61, 0x78, + 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x12, + 0x45, 0x0a, 0x10, 0x42, 0x61, 0x73, 0x65, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x42, 0x61, 0x73, 0x65, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x11, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xb6, 0x02, + 0x0a, 0x0a, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x4f, 0x0a, 0x04, + 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, + 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x57, 0x0a, + 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x52, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0xe6, 0x01, 0x0a, 0x11, 0x49, 0x6e, 0x6c, - 0x69, 0x6e, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x56, - 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x50, 0x72, - 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x99, 0x03, 0x0a, 0x09, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, - 0x4e, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, - 0x52, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x37, 0x0a, + 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x50, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x8b, 0x02, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x52, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x54, + 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x07, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x4a, 0x0a, 0x05, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, - 0x1c, 0x0a, 0x09, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x09, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x45, 0x0a, - 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdf, 0x02, - 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x12, - 0x4c, 0x0a, 0x07, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x73, 0x52, 0x07, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4a, 0x0a, - 0x07, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x07, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x08, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, - 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x64, 0x0a, 0x0f, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0f, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, - 0xc4, 0x02, 0x0a, 0x09, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, - 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, - 0x4e, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, - 0x48, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, + 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x4c, 0x61, 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x12, 0x4c, 0x61, + 0x73, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, + 0x22, 0x8c, 0x02, 0x0a, 0x12, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x48, + 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x48, + 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x5d, 0x0a, 0x08, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x4b, 0x0a, 0x05, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x53, 0x0a, 0x03, 0x54, 0x4c, + 0x53, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, + 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, 0x53, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x54, 0x4c, 0x53, 0x22, + 0xde, 0x01, 0x0a, 0x1a, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x54, 0x4c, + 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, + 0x0a, 0x0c, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0c, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, + 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x4d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, + 0x4d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x4d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, + 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0c, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, + 0x22, 0xb7, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x58, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x2e, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, - 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x22, 0x8d, 0x01, 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, 0x05, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, + 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, + 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x22, 0xfe, 0x01, 0x0a, 0x0f, 0x42, + 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x54, + 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, + 0x4d, 0x65, 0x74, 0x61, 0x12, 0x5c, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, + 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xdd, 0x01, 0x0a, 0x17, + 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x5c, 0x0a, 0x0c, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0c, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x06, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x75, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, - 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x4e, 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, - 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x8b, 0x01, - 0x0a, 0x0e, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x12, 0x4f, 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x52, 0x06, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x22, 0xe6, 0x01, 0x0a, 0x11, + 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x12, 0x56, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa9, 0x03, 0x0a, 0x0b, - 0x48, 0x54, 0x54, 0x50, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x51, 0x0a, 0x07, 0x48, - 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x51, - 0x0a, 0x0a, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x52, 0x4c, 0x52, 0x65, - 0x77, 0x72, 0x69, 0x74, 0x65, 0x52, 0x0a, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x12, 0x54, 0x0a, 0x0b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, - 0x65, 0x74, 0x72, 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0b, 0x52, 0x65, 0x74, 0x72, - 0x79, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, - 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x03, 0x4a, 0x57, 0x54, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x50, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x1a, 0x37, 0x0a, 0x09, 0x4d, + 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x99, 0x03, 0x0a, 0x09, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x12, 0x4e, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x52, 0x03, 0x4a, 0x57, 0x54, 0x22, 0x68, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x51, - 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x73, 0x22, 0x20, 0x0a, 0x0a, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, - 0x61, 0x74, 0x68, 0x22, 0xad, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x74, 0x72, - 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x65, 0x74, 0x72, 0x79, 0x4f, 0x6e, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x52, 0x65, 0x74, 0x72, 0x79, 0x4f, 0x6e, 0x12, 0x2e, 0x0a, - 0x12, 0x52, 0x65, 0x74, 0x72, 0x79, 0x4f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, - 0x64, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x12, 0x52, 0x65, 0x74, 0x72, 0x79, - 0x4f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x34, 0x0a, - 0x15, 0x52, 0x65, 0x74, 0x72, 0x79, 0x4f, 0x6e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x46, - 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x52, 0x65, - 0x74, 0x72, 0x79, 0x4f, 0x6e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x46, 0x61, 0x69, 0x6c, - 0x75, 0x72, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x0e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x49, 0x64, 0x6c, 0x65, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x49, 0x64, 0x6c, 0x65, 0x54, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x67, 0x0a, 0x09, 0x4a, 0x57, 0x54, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, + 0x74, 0x61, 0x12, 0x52, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x07, 0x50, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x4a, 0x0a, 0x05, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x50, - 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x52, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xc2, - 0x02, 0x0a, 0x10, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, + 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x12, 0x45, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x41, 0x64, 0x64, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x03, 0x41, 0x64, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, - 0x52, 0x0a, 0x03, 0x53, 0x65, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, + 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xf9, 0x01, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x75, + 0x6c, 0x65, 0x12, 0x4c, 0x0a, 0x07, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x52, 0x07, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, + 0x12, 0x4a, 0x0a, 0x07, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x07, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x08, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0xc4, 0x02, 0x0a, + 0x09, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, 0x07, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x4e, 0x0a, 0x06, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, - 0x53, 0x65, 0x74, 0x1a, 0x36, 0x0a, 0x08, 0x41, 0x64, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x36, 0x0a, 0x08, 0x53, - 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0xc7, 0x02, 0x0a, 0x0b, 0x48, 0x54, 0x54, 0x50, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x57, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x4c, 0x0a, 0x07, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x46, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x73, 0x52, 0x07, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x58, 0x0a, - 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x64, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0xfc, 0x02, - 0x0a, 0x08, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4d, 0x0a, 0x04, 0x4d, 0x65, - 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x2e, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x52, 0x0a, 0x07, 0x50, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x52, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x48, 0x0a, 0x04, + 0x50, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x52, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x4d, 0x0a, - 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x54, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x08, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x06, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7a, 0x0a, 0x0a, - 0x54, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x58, - 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x4b, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, + 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x22, 0x8d, 0x01, 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, - 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, - 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x22, 0xb4, 0x03, 0x0a, 0x0d, 0x53, 0x61, 0x6d, - 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, - 0x0a, 0x12, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, 0x6f, 0x72, 0x46, 0x61, 0x69, 0x6c, - 0x6f, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x44, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x46, 0x6f, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x22, - 0x0a, 0x0c, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x63, - 0x61, 0x6c, 0x12, 0x54, 0x0a, 0x07, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, + 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x75, 0x0a, 0x0d, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x4e, 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x61, 0x6d, 0x65, - 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x07, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x52, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, - 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x58, 0x0a, 0x0e, - 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, - 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, - 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x47, 0x0a, 0x13, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, 0x72, 0x22, 0xdd, 0x04, 0x0a, 0x0b, 0x4a, 0x57, 0x54, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x0d, 0x4a, 0x53, 0x4f, 0x4e, - 0x57, 0x65, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, - 0x65, 0x79, 0x53, 0x65, 0x74, 0x52, 0x0d, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, 0x65, - 0x79, 0x53, 0x65, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, - 0x41, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x09, 0x41, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x09, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x0a, - 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x46, 0x6f, 0x72, 0x77, - 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x46, 0x6f, - 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x57, 0x0a, 0x0b, 0x43, 0x61, 0x63, 0x68, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, - 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x50, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, + 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x8b, 0x01, 0x0a, 0x0e, 0x48, + 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x4f, 0x0a, + 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, + 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x0b, 0x48, 0x54, 0x54, + 0x50, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, 0x51, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x52, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x51, 0x0a, 0x0a, 0x55, + 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, - 0x65, 0x74, 0x61, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x6b, 0x65, 0x77, - 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x43, - 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x6b, 0x65, 0x77, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x1a, + 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x52, 0x0a, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x22, 0x20, + 0x0a, 0x0a, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, + 0x22, 0xc2, 0x02, 0x0a, 0x10, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x03, 0x41, 0x64, 0x64, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x41, 0x64, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x41, 0x64, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x12, 0x52, 0x0a, 0x03, 0x53, 0x65, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x03, 0x53, 0x65, 0x74, 0x1a, 0x36, 0x0a, 0x08, 0x41, 0x64, 0x64, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x36, 0x0a, + 0x08, 0x53, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe1, 0x01, 0x0a, 0x0b, 0x48, 0x54, 0x54, 0x50, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x57, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x57, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x12, 0x4c, 0x0a, 0x07, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x52, 0x07, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x12, + 0x58, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, + 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, + 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x22, 0xfc, 0x02, 0x0a, 0x08, 0x54, 0x43, + 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x4d, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x54, 0x43, 0x50, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x52, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x52, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x4d, 0x0a, 0x08, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x2e, 0x54, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x08, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa2, 0x01, 0x0a, 0x0d, 0x4a, 0x53, 0x4f, - 0x4e, 0x57, 0x65, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, 0x12, 0x46, 0x0a, 0x05, 0x4c, 0x6f, - 0x63, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x05, 0x4c, 0x6f, 0x63, - 0x61, 0x6c, 0x12, 0x49, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7a, 0x0a, 0x0a, 0x54, 0x43, 0x50, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x58, 0x0a, 0x0e, 0x45, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x22, 0x3b, 0x0a, - 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4a, 0x57, 0x4b, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x4a, 0x57, - 0x4b, 0x53, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4a, 0x57, 0x4b, 0x53, 0x12, 0x1a, - 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xed, 0x02, 0x0a, 0x0a, 0x52, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4a, 0x57, 0x4b, 0x53, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x49, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x52, 0x49, 0x12, 0x2a, 0x0a, 0x10, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, - 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x12, 0x3f, 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x79, 0x6e, - 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x12, 0x58, 0x0a, 0x0b, 0x52, 0x65, - 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x36, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, + 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, + 0x4d, 0x65, 0x74, 0x61, 0x22, 0xb4, 0x03, 0x0a, 0x0d, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, 0x6f, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x46, + 0x6f, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x12, 0x54, + 0x0a, 0x07, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x74, 0x72, - 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x12, 0x54, 0x0a, 0x0b, 0x4a, 0x57, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x12, 0x52, 0x0a, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x53, 0x61, 0x6d, 0x65, 0x6e, + 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x58, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, + 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x47, 0x0a, 0x13, 0x53, + 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x50, 0x65, 0x65, 0x72, 0x22, 0xdd, 0x04, 0x0a, 0x0b, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x0d, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, + 0x65, 0x79, 0x53, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x65, + 0x74, 0x52, 0x0d, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x49, 0x73, 0x73, 0x75, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x41, 0x75, 0x64, 0x69, + 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x41, 0x75, 0x64, + 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x09, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x4c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x77, + 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, + 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, + 0x64, 0x69, 0x6e, 0x67, 0x12, 0x57, 0x0a, 0x0b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x2e, 0x4a, 0x57, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x0b, 0x4a, - 0x57, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x22, 0xdb, 0x01, 0x0a, 0x0b, 0x4a, - 0x57, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x69, - 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x63, 0x0a, 0x0f, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x0b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x50, 0x0a, + 0x04, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4d, 0x65, 0x74, 0x61, 0x12, + 0x2a, 0x0a, 0x10, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x6b, 0x65, 0x77, 0x53, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x43, 0x6c, 0x6f, 0x63, 0x6b, + 0x53, 0x6b, 0x65, 0x77, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, + 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa2, 0x01, 0x0a, 0x0d, 0x4a, 0x53, 0x4f, 0x4e, 0x57, 0x65, 0x62, + 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, 0x12, 0x46, 0x0a, 0x05, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x05, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x12, 0x49, + 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4a, 0x57, 0x4b, + 0x53, 0x52, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x22, 0x3b, 0x0a, 0x09, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x4a, 0x57, 0x4b, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x4a, 0x57, 0x4b, 0x53, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4a, 0x57, 0x4b, 0x53, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, + 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, + 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xed, 0x02, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x4a, 0x57, 0x4b, 0x53, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x52, 0x49, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x55, 0x52, 0x49, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x4d, 0x73, 0x12, 0x3f, 0x0a, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x79, + 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x13, 0x46, 0x65, 0x74, 0x63, 0x68, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, + 0x6e, 0x6f, 0x75, 0x73, 0x6c, 0x79, 0x12, 0x58, 0x0a, 0x0b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x0b, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x12, 0x54, 0x0a, 0x0b, 0x4a, 0x57, 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, + 0x4b, 0x53, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x0b, 0x4a, 0x57, 0x4b, 0x53, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x22, 0xdb, 0x01, 0x0a, 0x0b, 0x4a, 0x57, 0x4b, 0x53, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x63, 0x0a, 0x0f, + 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, + 0x4b, 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x52, 0x0f, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x22, 0xfa, 0x01, 0x0a, 0x12, 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x88, 0x01, 0x0a, 0x1d, + 0x43, 0x61, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x4b, 0x53, + 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x1d, 0x43, 0x61, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x09, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x43, 0x41, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x2e, 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x52, 0x0f, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xfa, 0x01, 0x0a, 0x12, 0x4a, 0x57, 0x4b, - 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, - 0x88, 0x01, 0x0a, 0x1d, 0x43, 0x61, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x1d, 0x43, 0x61, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x59, 0x0a, 0x09, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x65, 0x64, 0x43, 0x41, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, + 0x79, 0x2e, 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x54, 0x72, 0x75, + 0x73, 0x74, 0x65, 0x64, 0x43, 0x41, 0x52, 0x09, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x43, + 0x41, 0x22, 0x6b, 0x0a, 0x1b, 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xaa, + 0x01, 0x0a, 0x14, 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x65, 0x64, 0x43, 0x41, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, + 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x49, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x49, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, + 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x9c, 0x01, 0x0a, 0x0f, + 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x1e, 0x0a, 0x0a, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0a, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, + 0x69, 0x0a, 0x12, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x61, + 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, + 0x61, 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x52, 0x12, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x42, 0x61, 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x22, 0x90, 0x01, 0x0a, 0x12, 0x52, + 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x61, 0x63, 0x6b, 0x4f, 0x66, + 0x66, 0x12, 0x3d, 0x0a, 0x0c, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0c, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x12, 0x3b, 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0b, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x8f, 0x02, + 0x0a, 0x0b, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, + 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, - 0x74, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x43, 0x41, 0x52, 0x09, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x65, 0x64, 0x43, 0x41, 0x22, 0x6b, 0x0a, 0x1b, 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, - 0x43, 0x65, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0xaa, 0x01, 0x0a, 0x14, 0x4a, 0x57, 0x4b, 0x53, 0x54, 0x4c, 0x53, 0x43, 0x65, - 0x72, 0x74, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x43, 0x41, 0x12, 0x1a, 0x0a, 0x08, 0x46, - 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, - 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, - 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, - 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x49, 0x6e, 0x6c, - 0x69, 0x6e, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, - 0x0b, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, - 0x9c, 0x01, 0x0a, 0x0f, 0x4a, 0x57, 0x4b, 0x53, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x74, 0x72, - 0x69, 0x65, 0x73, 0x12, 0x69, 0x0a, 0x12, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x42, 0x61, 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x42, 0x61, 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x52, 0x12, 0x52, 0x65, 0x74, 0x72, - 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x61, 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x22, 0x90, - 0x01, 0x0a, 0x12, 0x52, 0x65, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x61, - 0x63, 0x6b, 0x4f, 0x66, 0x66, 0x12, 0x3d, 0x0a, 0x0c, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x42, 0x61, 0x73, 0x65, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x4d, 0x61, 0x78, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, - 0x6c, 0x22, 0x8f, 0x02, 0x0a, 0x0b, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x50, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x12, 0x5c, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x12, 0x50, 0x0a, 0x06, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x52, 0x06, 0x43, 0x6f, 0x6f, - 0x6b, 0x69, 0x65, 0x22, 0x63, 0x0a, 0x11, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x18, - 0x0a, 0x07, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x22, 0x2b, 0x0a, 0x15, 0x4a, 0x57, 0x54, 0x4c, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, + 0x5c, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a, 0x11, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6f, - 0x0a, 0x13, 0x4a, 0x57, 0x54, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x17, 0x50, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x77, - 0x61, 0x72, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x17, 0x50, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x77, 0x61, - 0x72, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, - 0x24, 0x0a, 0x0e, 0x4a, 0x57, 0x54, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x12, 0x0a, 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x04, 0x53, 0x69, 0x7a, 0x65, 0x2a, 0xa9, 0x02, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0f, - 0x0a, 0x0b, 0x4b, 0x69, 0x6e, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, - 0x12, 0x0a, 0x0e, 0x4b, 0x69, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x4b, 0x69, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, - 0x4b, 0x69, 0x6e, 0x64, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x47, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x69, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x10, 0x04, 0x12, - 0x17, 0x0a, 0x13, 0x4b, 0x69, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x69, 0x6e, 0x64, - 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x10, 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x4b, 0x69, 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, - 0x74, 0x65, 0x77, 0x61, 0x79, 0x10, 0x07, 0x12, 0x17, 0x0a, 0x13, 0x4b, 0x69, 0x6e, 0x64, 0x42, - 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x10, 0x08, - 0x12, 0x11, 0x0a, 0x0d, 0x4b, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x10, 0x09, 0x12, 0x10, 0x0a, 0x0c, 0x4b, 0x69, 0x6e, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x10, 0x0a, 0x12, 0x15, 0x0a, 0x11, 0x4b, 0x69, 0x6e, 0x64, 0x53, 0x61, 0x6d, - 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x10, 0x0b, 0x12, 0x13, 0x0a, 0x0f, - 0x4b, 0x69, 0x6e, 0x64, 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x10, - 0x0c, 0x2a, 0x26, 0x0a, 0x0f, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x65, 0x6e, 0x79, 0x10, 0x00, 0x12, 0x09, - 0x0a, 0x05, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x10, 0x01, 0x2a, 0x21, 0x0a, 0x13, 0x49, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x10, 0x00, 0x2a, 0x50, 0x0a, 0x09, - 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, - 0x18, 0x0a, 0x14, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, - 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, 0x2a, 0x5f, - 0x0a, 0x0d, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x12, - 0x18, 0x0a, 0x14, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, - 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x75, 0x74, - 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, - 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, - 0x6f, 0x64, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x76, 0x65, 0x10, 0x02, 0x2a, - 0x7b, 0x0a, 0x0f, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, - 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x17, - 0x0a, 0x13, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, - 0x65, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x68, 0x47, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x10, - 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x10, 0x03, 0x2a, 0x4f, 0x0a, 0x1a, - 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, - 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x48, 0x54, - 0x54, 0x50, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x54, 0x43, 0x50, 0x10, 0x01, 0x2a, 0x92, 0x02, - 0x0a, 0x0f, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x12, 0x16, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x41, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x48, 0x54, 0x54, - 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x10, 0x02, - 0x12, 0x16, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x47, 0x65, 0x74, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x48, 0x65, 0x61, 0x64, 0x10, - 0x04, 0x12, 0x1a, 0x0a, 0x16, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x10, 0x05, 0x12, 0x18, 0x0a, - 0x14, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x50, 0x61, 0x74, 0x63, 0x68, 0x10, 0x06, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x50, 0x6f, 0x73, 0x74, 0x10, 0x07, - 0x12, 0x16, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x50, 0x75, 0x74, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x54, 0x54, 0x50, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x54, 0x72, 0x61, 0x63, 0x65, - 0x10, 0x09, 0x2a, 0xa7, 0x01, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x54, - 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x45, 0x78, 0x61, - 0x63, 0x74, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x10, 0x01, 0x12, - 0x1a, 0x0a, 0x16, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x24, 0x0a, 0x20, 0x48, - 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, + 0x6d, 0x52, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x50, 0x0a, + 0x06, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x52, 0x06, 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x22, + 0x63, 0x0a, 0x11, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x46, 0x6f, + 0x72, 0x77, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x46, 0x6f, 0x72, + 0x77, 0x61, 0x72, 0x64, 0x22, 0x2b, 0x0a, 0x15, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x12, 0x0a, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, + 0x65, 0x22, 0x27, 0x0a, 0x11, 0x4a, 0x57, 0x54, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6f, 0x0a, 0x13, 0x4a, 0x57, + 0x54, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x38, 0x0a, 0x17, 0x50, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x50, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x17, 0x50, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x24, 0x0a, 0x0e, 0x4a, + 0x57, 0x54, 0x43, 0x61, 0x63, 0x68, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, + 0x04, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x53, 0x69, 0x7a, + 0x65, 0x2a, 0xa9, 0x02, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x4b, 0x69, + 0x6e, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4b, + 0x69, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x10, 0x01, 0x12, + 0x17, 0x0a, 0x13, 0x4b, 0x69, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x69, 0x6e, 0x64, + 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x10, 0x03, + 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x69, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x10, 0x04, 0x12, 0x17, 0x0a, 0x13, 0x4b, + 0x69, 0x6e, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x73, 0x10, 0x05, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x69, 0x6e, 0x64, 0x49, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x10, 0x06, 0x12, + 0x12, 0x0a, 0x0e, 0x4b, 0x69, 0x6e, 0x64, 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x10, 0x07, 0x12, 0x17, 0x0a, 0x13, 0x4b, 0x69, 0x6e, 0x64, 0x42, 0x6f, 0x75, 0x6e, 0x64, + 0x41, 0x50, 0x49, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x10, 0x08, 0x12, 0x11, 0x0a, 0x0d, + 0x4b, 0x69, 0x6e, 0x64, 0x48, 0x54, 0x54, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x10, 0x09, 0x12, + 0x10, 0x0a, 0x0c, 0x4b, 0x69, 0x6e, 0x64, 0x54, 0x43, 0x50, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x10, + 0x0a, 0x12, 0x15, 0x0a, 0x11, 0x4b, 0x69, 0x6e, 0x64, 0x53, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, + 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x10, 0x0b, 0x12, 0x13, 0x0a, 0x0f, 0x4b, 0x69, 0x6e, 0x64, + 0x4a, 0x57, 0x54, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x10, 0x0c, 0x2a, 0x26, 0x0a, + 0x0f, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x08, 0x0a, 0x04, 0x44, 0x65, 0x6e, 0x79, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x6c, + 0x6c, 0x6f, 0x77, 0x10, 0x01, 0x2a, 0x21, 0x0a, 0x13, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x10, 0x00, 0x2a, 0x50, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x78, + 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, + 0x64, 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x50, + 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, + 0x64, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x10, 0x02, 0x2a, 0x5f, 0x0a, 0x0d, 0x4d, 0x75, + 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x4d, + 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, + 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x10, 0x01, 0x12, 0x1b, + 0x0a, 0x17, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x76, 0x65, 0x10, 0x02, 0x2a, 0x7b, 0x0a, 0x0f, 0x4d, + 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, + 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, + 0x65, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x65, + 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x4e, 0x6f, 0x6e, + 0x65, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, + 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x10, 0x02, 0x12, 0x19, 0x0a, + 0x15, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x6f, 0x64, 0x65, + 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x10, 0x03, 0x2a, 0x4f, 0x0a, 0x1a, 0x41, 0x50, 0x49, 0x47, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, + 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, + 0x12, 0x17, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x54, 0x43, 0x50, 0x10, 0x01, 0x2a, 0x92, 0x02, 0x0a, 0x0f, 0x48, 0x54, + 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x16, 0x0a, + 0x12, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x41, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x10, + 0x01, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, + 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x47, + 0x65, 0x74, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x48, 0x65, 0x61, 0x64, 0x10, 0x04, 0x12, 0x1a, 0x0a, + 0x16, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x54, 0x54, + 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x50, 0x61, 0x74, 0x63, + 0x68, 0x10, 0x06, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x50, 0x6f, 0x73, 0x74, 0x10, 0x07, 0x12, 0x16, 0x0a, 0x12, + 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x50, + 0x75, 0x74, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x54, 0x72, 0x61, 0x63, 0x65, 0x10, 0x09, 0x2a, 0xa7, + 0x01, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x10, 0x00, + 0x12, 0x19, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x48, + 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x24, 0x0a, 0x20, 0x48, 0x54, 0x54, 0x50, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, + 0x72, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x10, 0x03, 0x12, 0x19, 0x0a, + 0x15, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, + 0x53, 0x75, 0x66, 0x66, 0x69, 0x78, 0x10, 0x04, 0x2a, 0x68, 0x0a, 0x11, 0x48, 0x54, 0x54, 0x50, + 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, + 0x12, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x45, 0x78, + 0x61, 0x63, 0x74, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, + 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x10, 0x01, 0x12, 0x22, + 0x0a, 0x1e, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x10, 0x03, 0x2a, 0x6d, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x54, 0x54, 0x50, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x10, + 0x00, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, + 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x10, - 0x03, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, - 0x61, 0x74, 0x63, 0x68, 0x53, 0x75, 0x66, 0x66, 0x69, 0x78, 0x10, 0x04, 0x2a, 0x68, 0x0a, 0x11, - 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x16, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x48, 0x54, 0x54, - 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x48, 0x54, 0x54, 0x50, 0x50, 0x61, 0x74, 0x68, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x10, 0x03, 0x2a, 0x6d, 0x0a, 0x12, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, - 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x45, 0x78, - 0x61, 0x63, 0x74, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x10, 0x01, - 0x12, 0x23, 0x0a, 0x1f, 0x48, 0x54, 0x54, 0x50, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x65, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x10, 0x03, 0x42, 0xae, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x42, 0x10, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x2f, 0x70, 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x43, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0xca, - 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x5c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x28, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, - 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x03, 0x42, 0xae, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x42, + 0x10, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x70, + 0x62, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0xa2, 0x02, 0x04, 0x48, + 0x43, 0x49, 0x43, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0xca, 0x02, 0x25, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x28, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x65, 0x6e, 0x74, + 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -9327,7 +8468,7 @@ func file_private_pbconfigentry_config_entry_proto_rawDescGZIP() []byte { } var file_private_pbconfigentry_config_entry_proto_enumTypes = make([]protoimpl.EnumInfo, 11) -var file_private_pbconfigentry_config_entry_proto_msgTypes = make([]protoimpl.MessageInfo, 115) +var file_private_pbconfigentry_config_entry_proto_msgTypes = make([]protoimpl.MessageInfo, 104) var file_private_pbconfigentry_config_entry_proto_goTypes = []interface{}{ (Kind)(0), // 0: hashicorp.consul.internal.configentry.Kind (IntentionAction)(0), // 1: hashicorp.consul.internal.configentry.IntentionAction @@ -9385,112 +8526,101 @@ var file_private_pbconfigentry_config_entry_proto_goTypes = []interface{}{ (*UpstreamLimits)(nil), // 53: hashicorp.consul.internal.configentry.UpstreamLimits (*PassiveHealthCheck)(nil), // 54: hashicorp.consul.internal.configentry.PassiveHealthCheck (*DestinationConfig)(nil), // 55: hashicorp.consul.internal.configentry.DestinationConfig - (*RateLimits)(nil), // 56: hashicorp.consul.internal.configentry.RateLimits - (*InstanceLevelRateLimits)(nil), // 57: hashicorp.consul.internal.configentry.InstanceLevelRateLimits - (*InstanceLevelRouteRateLimits)(nil), // 58: hashicorp.consul.internal.configentry.InstanceLevelRouteRateLimits - (*APIGateway)(nil), // 59: hashicorp.consul.internal.configentry.APIGateway - (*Status)(nil), // 60: hashicorp.consul.internal.configentry.Status - (*Condition)(nil), // 61: hashicorp.consul.internal.configentry.Condition - (*APIGatewayListener)(nil), // 62: hashicorp.consul.internal.configentry.APIGatewayListener - (*APIGatewayTLSConfiguration)(nil), // 63: hashicorp.consul.internal.configentry.APIGatewayTLSConfiguration - (*APIGatewayPolicy)(nil), // 64: hashicorp.consul.internal.configentry.APIGatewayPolicy - (*APIGatewayJWTRequirement)(nil), // 65: hashicorp.consul.internal.configentry.APIGatewayJWTRequirement - (*APIGatewayJWTProvider)(nil), // 66: hashicorp.consul.internal.configentry.APIGatewayJWTProvider - (*APIGatewayJWTClaimVerification)(nil), // 67: hashicorp.consul.internal.configentry.APIGatewayJWTClaimVerification - (*ResourceReference)(nil), // 68: hashicorp.consul.internal.configentry.ResourceReference - (*BoundAPIGateway)(nil), // 69: hashicorp.consul.internal.configentry.BoundAPIGateway - (*BoundAPIGatewayListener)(nil), // 70: hashicorp.consul.internal.configentry.BoundAPIGatewayListener - (*InlineCertificate)(nil), // 71: hashicorp.consul.internal.configentry.InlineCertificate - (*HTTPRoute)(nil), // 72: hashicorp.consul.internal.configentry.HTTPRoute - (*HTTPRouteRule)(nil), // 73: hashicorp.consul.internal.configentry.HTTPRouteRule - (*HTTPMatch)(nil), // 74: hashicorp.consul.internal.configentry.HTTPMatch - (*HTTPHeaderMatch)(nil), // 75: hashicorp.consul.internal.configentry.HTTPHeaderMatch - (*HTTPPathMatch)(nil), // 76: hashicorp.consul.internal.configentry.HTTPPathMatch - (*HTTPQueryMatch)(nil), // 77: hashicorp.consul.internal.configentry.HTTPQueryMatch - (*HTTPFilters)(nil), // 78: hashicorp.consul.internal.configentry.HTTPFilters - (*HTTPResponseFilters)(nil), // 79: hashicorp.consul.internal.configentry.HTTPResponseFilters - (*URLRewrite)(nil), // 80: hashicorp.consul.internal.configentry.URLRewrite - (*RetryFilter)(nil), // 81: hashicorp.consul.internal.configentry.RetryFilter - (*TimeoutFilter)(nil), // 82: hashicorp.consul.internal.configentry.TimeoutFilter - (*JWTFilter)(nil), // 83: hashicorp.consul.internal.configentry.JWTFilter - (*HTTPHeaderFilter)(nil), // 84: hashicorp.consul.internal.configentry.HTTPHeaderFilter - (*HTTPService)(nil), // 85: hashicorp.consul.internal.configentry.HTTPService - (*TCPRoute)(nil), // 86: hashicorp.consul.internal.configentry.TCPRoute - (*TCPService)(nil), // 87: hashicorp.consul.internal.configentry.TCPService - (*SamenessGroup)(nil), // 88: hashicorp.consul.internal.configentry.SamenessGroup - (*SamenessGroupMember)(nil), // 89: hashicorp.consul.internal.configentry.SamenessGroupMember - (*JWTProvider)(nil), // 90: hashicorp.consul.internal.configentry.JWTProvider - (*JSONWebKeySet)(nil), // 91: hashicorp.consul.internal.configentry.JSONWebKeySet - (*LocalJWKS)(nil), // 92: hashicorp.consul.internal.configentry.LocalJWKS - (*RemoteJWKS)(nil), // 93: hashicorp.consul.internal.configentry.RemoteJWKS - (*JWKSCluster)(nil), // 94: hashicorp.consul.internal.configentry.JWKSCluster - (*JWKSTLSCertificate)(nil), // 95: hashicorp.consul.internal.configentry.JWKSTLSCertificate - (*JWKSTLSCertProviderInstance)(nil), // 96: hashicorp.consul.internal.configentry.JWKSTLSCertProviderInstance - (*JWKSTLSCertTrustedCA)(nil), // 97: hashicorp.consul.internal.configentry.JWKSTLSCertTrustedCA - (*JWKSRetryPolicy)(nil), // 98: hashicorp.consul.internal.configentry.JWKSRetryPolicy - (*RetryPolicyBackOff)(nil), // 99: hashicorp.consul.internal.configentry.RetryPolicyBackOff - (*JWTLocation)(nil), // 100: hashicorp.consul.internal.configentry.JWTLocation - (*JWTLocationHeader)(nil), // 101: hashicorp.consul.internal.configentry.JWTLocationHeader - (*JWTLocationQueryParam)(nil), // 102: hashicorp.consul.internal.configentry.JWTLocationQueryParam - (*JWTLocationCookie)(nil), // 103: hashicorp.consul.internal.configentry.JWTLocationCookie - (*JWTForwardingConfig)(nil), // 104: hashicorp.consul.internal.configentry.JWTForwardingConfig - (*JWTCacheConfig)(nil), // 105: hashicorp.consul.internal.configentry.JWTCacheConfig - nil, // 106: hashicorp.consul.internal.configentry.MeshConfig.MetaEntry - nil, // 107: hashicorp.consul.internal.configentry.ServiceResolver.SubsetsEntry - nil, // 108: hashicorp.consul.internal.configentry.ServiceResolver.FailoverEntry - nil, // 109: hashicorp.consul.internal.configentry.ServiceResolver.MetaEntry - nil, // 110: hashicorp.consul.internal.configentry.IngressGateway.MetaEntry - nil, // 111: hashicorp.consul.internal.configentry.IngressService.MetaEntry - nil, // 112: hashicorp.consul.internal.configentry.HTTPHeaderModifiers.AddEntry - nil, // 113: hashicorp.consul.internal.configentry.HTTPHeaderModifiers.SetEntry - nil, // 114: hashicorp.consul.internal.configentry.ServiceIntentions.MetaEntry - nil, // 115: hashicorp.consul.internal.configentry.SourceIntention.LegacyMetaEntry - nil, // 116: hashicorp.consul.internal.configentry.ServiceDefaults.MetaEntry - nil, // 117: hashicorp.consul.internal.configentry.APIGateway.MetaEntry - nil, // 118: hashicorp.consul.internal.configentry.BoundAPIGateway.MetaEntry - nil, // 119: hashicorp.consul.internal.configentry.InlineCertificate.MetaEntry - nil, // 120: hashicorp.consul.internal.configentry.HTTPRoute.MetaEntry - nil, // 121: hashicorp.consul.internal.configentry.HTTPHeaderFilter.AddEntry - nil, // 122: hashicorp.consul.internal.configentry.HTTPHeaderFilter.SetEntry - nil, // 123: hashicorp.consul.internal.configentry.TCPRoute.MetaEntry - nil, // 124: hashicorp.consul.internal.configentry.SamenessGroup.MetaEntry - nil, // 125: hashicorp.consul.internal.configentry.JWTProvider.MetaEntry - (*pbcommon.EnterpriseMeta)(nil), // 126: hashicorp.consul.internal.common.EnterpriseMeta - (*pbcommon.RaftIndex)(nil), // 127: hashicorp.consul.internal.common.RaftIndex - (*durationpb.Duration)(nil), // 128: google.protobuf.Duration - (*timestamppb.Timestamp)(nil), // 129: google.protobuf.Timestamp - (*pbcommon.EnvoyExtension)(nil), // 130: hashicorp.consul.internal.common.EnvoyExtension + (*APIGateway)(nil), // 56: hashicorp.consul.internal.configentry.APIGateway + (*Status)(nil), // 57: hashicorp.consul.internal.configentry.Status + (*Condition)(nil), // 58: hashicorp.consul.internal.configentry.Condition + (*APIGatewayListener)(nil), // 59: hashicorp.consul.internal.configentry.APIGatewayListener + (*APIGatewayTLSConfiguration)(nil), // 60: hashicorp.consul.internal.configentry.APIGatewayTLSConfiguration + (*ResourceReference)(nil), // 61: hashicorp.consul.internal.configentry.ResourceReference + (*BoundAPIGateway)(nil), // 62: hashicorp.consul.internal.configentry.BoundAPIGateway + (*BoundAPIGatewayListener)(nil), // 63: hashicorp.consul.internal.configentry.BoundAPIGatewayListener + (*InlineCertificate)(nil), // 64: hashicorp.consul.internal.configentry.InlineCertificate + (*HTTPRoute)(nil), // 65: hashicorp.consul.internal.configentry.HTTPRoute + (*HTTPRouteRule)(nil), // 66: hashicorp.consul.internal.configentry.HTTPRouteRule + (*HTTPMatch)(nil), // 67: hashicorp.consul.internal.configentry.HTTPMatch + (*HTTPHeaderMatch)(nil), // 68: hashicorp.consul.internal.configentry.HTTPHeaderMatch + (*HTTPPathMatch)(nil), // 69: hashicorp.consul.internal.configentry.HTTPPathMatch + (*HTTPQueryMatch)(nil), // 70: hashicorp.consul.internal.configentry.HTTPQueryMatch + (*HTTPFilters)(nil), // 71: hashicorp.consul.internal.configentry.HTTPFilters + (*URLRewrite)(nil), // 72: hashicorp.consul.internal.configentry.URLRewrite + (*HTTPHeaderFilter)(nil), // 73: hashicorp.consul.internal.configentry.HTTPHeaderFilter + (*HTTPService)(nil), // 74: hashicorp.consul.internal.configentry.HTTPService + (*TCPRoute)(nil), // 75: hashicorp.consul.internal.configentry.TCPRoute + (*TCPService)(nil), // 76: hashicorp.consul.internal.configentry.TCPService + (*SamenessGroup)(nil), // 77: hashicorp.consul.internal.configentry.SamenessGroup + (*SamenessGroupMember)(nil), // 78: hashicorp.consul.internal.configentry.SamenessGroupMember + (*JWTProvider)(nil), // 79: hashicorp.consul.internal.configentry.JWTProvider + (*JSONWebKeySet)(nil), // 80: hashicorp.consul.internal.configentry.JSONWebKeySet + (*LocalJWKS)(nil), // 81: hashicorp.consul.internal.configentry.LocalJWKS + (*RemoteJWKS)(nil), // 82: hashicorp.consul.internal.configentry.RemoteJWKS + (*JWKSCluster)(nil), // 83: hashicorp.consul.internal.configentry.JWKSCluster + (*JWKSTLSCertificate)(nil), // 84: hashicorp.consul.internal.configentry.JWKSTLSCertificate + (*JWKSTLSCertProviderInstance)(nil), // 85: hashicorp.consul.internal.configentry.JWKSTLSCertProviderInstance + (*JWKSTLSCertTrustedCA)(nil), // 86: hashicorp.consul.internal.configentry.JWKSTLSCertTrustedCA + (*JWKSRetryPolicy)(nil), // 87: hashicorp.consul.internal.configentry.JWKSRetryPolicy + (*RetryPolicyBackOff)(nil), // 88: hashicorp.consul.internal.configentry.RetryPolicyBackOff + (*JWTLocation)(nil), // 89: hashicorp.consul.internal.configentry.JWTLocation + (*JWTLocationHeader)(nil), // 90: hashicorp.consul.internal.configentry.JWTLocationHeader + (*JWTLocationQueryParam)(nil), // 91: hashicorp.consul.internal.configentry.JWTLocationQueryParam + (*JWTLocationCookie)(nil), // 92: hashicorp.consul.internal.configentry.JWTLocationCookie + (*JWTForwardingConfig)(nil), // 93: hashicorp.consul.internal.configentry.JWTForwardingConfig + (*JWTCacheConfig)(nil), // 94: hashicorp.consul.internal.configentry.JWTCacheConfig + nil, // 95: hashicorp.consul.internal.configentry.MeshConfig.MetaEntry + nil, // 96: hashicorp.consul.internal.configentry.ServiceResolver.SubsetsEntry + nil, // 97: hashicorp.consul.internal.configentry.ServiceResolver.FailoverEntry + nil, // 98: hashicorp.consul.internal.configentry.ServiceResolver.MetaEntry + nil, // 99: hashicorp.consul.internal.configentry.IngressGateway.MetaEntry + nil, // 100: hashicorp.consul.internal.configentry.IngressService.MetaEntry + nil, // 101: hashicorp.consul.internal.configentry.HTTPHeaderModifiers.AddEntry + nil, // 102: hashicorp.consul.internal.configentry.HTTPHeaderModifiers.SetEntry + nil, // 103: hashicorp.consul.internal.configentry.ServiceIntentions.MetaEntry + nil, // 104: hashicorp.consul.internal.configentry.SourceIntention.LegacyMetaEntry + nil, // 105: hashicorp.consul.internal.configentry.ServiceDefaults.MetaEntry + nil, // 106: hashicorp.consul.internal.configentry.APIGateway.MetaEntry + nil, // 107: hashicorp.consul.internal.configentry.BoundAPIGateway.MetaEntry + nil, // 108: hashicorp.consul.internal.configentry.InlineCertificate.MetaEntry + nil, // 109: hashicorp.consul.internal.configentry.HTTPRoute.MetaEntry + nil, // 110: hashicorp.consul.internal.configentry.HTTPHeaderFilter.AddEntry + nil, // 111: hashicorp.consul.internal.configentry.HTTPHeaderFilter.SetEntry + nil, // 112: hashicorp.consul.internal.configentry.TCPRoute.MetaEntry + nil, // 113: hashicorp.consul.internal.configentry.SamenessGroup.MetaEntry + nil, // 114: hashicorp.consul.internal.configentry.JWTProvider.MetaEntry + (*pbcommon.EnterpriseMeta)(nil), // 115: hashicorp.consul.internal.common.EnterpriseMeta + (*pbcommon.RaftIndex)(nil), // 116: hashicorp.consul.internal.common.RaftIndex + (*durationpb.Duration)(nil), // 117: google.protobuf.Duration + (*timestamppb.Timestamp)(nil), // 118: google.protobuf.Timestamp + (*pbcommon.EnvoyExtension)(nil), // 119: hashicorp.consul.internal.common.EnvoyExtension } var file_private_pbconfigentry_config_entry_proto_depIdxs = []int32{ 0, // 0: hashicorp.consul.internal.configentry.ConfigEntry.Kind:type_name -> hashicorp.consul.internal.configentry.Kind - 126, // 1: hashicorp.consul.internal.configentry.ConfigEntry.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta - 127, // 2: hashicorp.consul.internal.configentry.ConfigEntry.RaftIndex:type_name -> hashicorp.consul.internal.common.RaftIndex + 115, // 1: hashicorp.consul.internal.configentry.ConfigEntry.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta + 116, // 2: hashicorp.consul.internal.configentry.ConfigEntry.RaftIndex:type_name -> hashicorp.consul.internal.common.RaftIndex 12, // 3: hashicorp.consul.internal.configentry.ConfigEntry.MeshConfig:type_name -> hashicorp.consul.internal.configentry.MeshConfig 18, // 4: hashicorp.consul.internal.configentry.ConfigEntry.ServiceResolver:type_name -> hashicorp.consul.internal.configentry.ServiceResolver 30, // 5: hashicorp.consul.internal.configentry.ConfigEntry.IngressGateway:type_name -> hashicorp.consul.internal.configentry.IngressGateway 38, // 6: hashicorp.consul.internal.configentry.ConfigEntry.ServiceIntentions:type_name -> hashicorp.consul.internal.configentry.ServiceIntentions 46, // 7: hashicorp.consul.internal.configentry.ConfigEntry.ServiceDefaults:type_name -> hashicorp.consul.internal.configentry.ServiceDefaults - 59, // 8: hashicorp.consul.internal.configentry.ConfigEntry.APIGateway:type_name -> hashicorp.consul.internal.configentry.APIGateway - 69, // 9: hashicorp.consul.internal.configentry.ConfigEntry.BoundAPIGateway:type_name -> hashicorp.consul.internal.configentry.BoundAPIGateway - 86, // 10: hashicorp.consul.internal.configentry.ConfigEntry.TCPRoute:type_name -> hashicorp.consul.internal.configentry.TCPRoute - 72, // 11: hashicorp.consul.internal.configentry.ConfigEntry.HTTPRoute:type_name -> hashicorp.consul.internal.configentry.HTTPRoute - 71, // 12: hashicorp.consul.internal.configentry.ConfigEntry.InlineCertificate:type_name -> hashicorp.consul.internal.configentry.InlineCertificate - 88, // 13: hashicorp.consul.internal.configentry.ConfigEntry.SamenessGroup:type_name -> hashicorp.consul.internal.configentry.SamenessGroup - 90, // 14: hashicorp.consul.internal.configentry.ConfigEntry.JWTProvider:type_name -> hashicorp.consul.internal.configentry.JWTProvider + 56, // 8: hashicorp.consul.internal.configentry.ConfigEntry.APIGateway:type_name -> hashicorp.consul.internal.configentry.APIGateway + 62, // 9: hashicorp.consul.internal.configentry.ConfigEntry.BoundAPIGateway:type_name -> hashicorp.consul.internal.configentry.BoundAPIGateway + 75, // 10: hashicorp.consul.internal.configentry.ConfigEntry.TCPRoute:type_name -> hashicorp.consul.internal.configentry.TCPRoute + 65, // 11: hashicorp.consul.internal.configentry.ConfigEntry.HTTPRoute:type_name -> hashicorp.consul.internal.configentry.HTTPRoute + 64, // 12: hashicorp.consul.internal.configentry.ConfigEntry.InlineCertificate:type_name -> hashicorp.consul.internal.configentry.InlineCertificate + 77, // 13: hashicorp.consul.internal.configentry.ConfigEntry.SamenessGroup:type_name -> hashicorp.consul.internal.configentry.SamenessGroup + 79, // 14: hashicorp.consul.internal.configentry.ConfigEntry.JWTProvider:type_name -> hashicorp.consul.internal.configentry.JWTProvider 13, // 15: hashicorp.consul.internal.configentry.MeshConfig.TransparentProxy:type_name -> hashicorp.consul.internal.configentry.TransparentProxyMeshConfig 14, // 16: hashicorp.consul.internal.configentry.MeshConfig.TLS:type_name -> hashicorp.consul.internal.configentry.MeshTLSConfig 16, // 17: hashicorp.consul.internal.configentry.MeshConfig.HTTP:type_name -> hashicorp.consul.internal.configentry.MeshHTTPConfig - 106, // 18: hashicorp.consul.internal.configentry.MeshConfig.Meta:type_name -> hashicorp.consul.internal.configentry.MeshConfig.MetaEntry + 95, // 18: hashicorp.consul.internal.configentry.MeshConfig.Meta:type_name -> hashicorp.consul.internal.configentry.MeshConfig.MetaEntry 17, // 19: hashicorp.consul.internal.configentry.MeshConfig.Peering:type_name -> hashicorp.consul.internal.configentry.PeeringMeshConfig 15, // 20: hashicorp.consul.internal.configentry.MeshTLSConfig.Incoming:type_name -> hashicorp.consul.internal.configentry.MeshDirectionalTLSConfig 15, // 21: hashicorp.consul.internal.configentry.MeshTLSConfig.Outgoing:type_name -> hashicorp.consul.internal.configentry.MeshDirectionalTLSConfig - 107, // 22: hashicorp.consul.internal.configentry.ServiceResolver.Subsets:type_name -> hashicorp.consul.internal.configentry.ServiceResolver.SubsetsEntry + 96, // 22: hashicorp.consul.internal.configentry.ServiceResolver.Subsets:type_name -> hashicorp.consul.internal.configentry.ServiceResolver.SubsetsEntry 20, // 23: hashicorp.consul.internal.configentry.ServiceResolver.Redirect:type_name -> hashicorp.consul.internal.configentry.ServiceResolverRedirect - 108, // 24: hashicorp.consul.internal.configentry.ServiceResolver.Failover:type_name -> hashicorp.consul.internal.configentry.ServiceResolver.FailoverEntry - 128, // 25: hashicorp.consul.internal.configentry.ServiceResolver.ConnectTimeout:type_name -> google.protobuf.Duration + 97, // 24: hashicorp.consul.internal.configentry.ServiceResolver.Failover:type_name -> hashicorp.consul.internal.configentry.ServiceResolver.FailoverEntry + 117, // 25: hashicorp.consul.internal.configentry.ServiceResolver.ConnectTimeout:type_name -> google.protobuf.Duration 25, // 26: hashicorp.consul.internal.configentry.ServiceResolver.LoadBalancer:type_name -> hashicorp.consul.internal.configentry.LoadBalancer - 109, // 27: hashicorp.consul.internal.configentry.ServiceResolver.Meta:type_name -> hashicorp.consul.internal.configentry.ServiceResolver.MetaEntry - 128, // 28: hashicorp.consul.internal.configentry.ServiceResolver.RequestTimeout:type_name -> google.protobuf.Duration + 98, // 27: hashicorp.consul.internal.configentry.ServiceResolver.Meta:type_name -> hashicorp.consul.internal.configentry.ServiceResolver.MetaEntry + 117, // 28: hashicorp.consul.internal.configentry.ServiceResolver.RequestTimeout:type_name -> google.protobuf.Duration 23, // 29: hashicorp.consul.internal.configentry.ServiceResolver.PrioritizeByLocality:type_name -> hashicorp.consul.internal.configentry.ServiceResolverPrioritizeByLocality 24, // 30: hashicorp.consul.internal.configentry.ServiceResolverFailover.Targets:type_name -> hashicorp.consul.internal.configentry.ServiceResolverFailoverTarget 22, // 31: hashicorp.consul.internal.configentry.ServiceResolverFailover.Policy:type_name -> hashicorp.consul.internal.configentry.ServiceResolverFailoverPolicy @@ -9498,10 +8628,10 @@ var file_private_pbconfigentry_config_entry_proto_depIdxs = []int32{ 27, // 33: hashicorp.consul.internal.configentry.LoadBalancer.LeastRequestConfig:type_name -> hashicorp.consul.internal.configentry.LeastRequestConfig 28, // 34: hashicorp.consul.internal.configentry.LoadBalancer.HashPolicies:type_name -> hashicorp.consul.internal.configentry.HashPolicy 29, // 35: hashicorp.consul.internal.configentry.HashPolicy.CookieConfig:type_name -> hashicorp.consul.internal.configentry.CookieConfig - 128, // 36: hashicorp.consul.internal.configentry.CookieConfig.TTL:type_name -> google.protobuf.Duration + 117, // 36: hashicorp.consul.internal.configentry.CookieConfig.TTL:type_name -> google.protobuf.Duration 32, // 37: hashicorp.consul.internal.configentry.IngressGateway.TLS:type_name -> hashicorp.consul.internal.configentry.GatewayTLSConfig 34, // 38: hashicorp.consul.internal.configentry.IngressGateway.Listeners:type_name -> hashicorp.consul.internal.configentry.IngressListener - 110, // 39: hashicorp.consul.internal.configentry.IngressGateway.Meta:type_name -> hashicorp.consul.internal.configentry.IngressGateway.MetaEntry + 99, // 39: hashicorp.consul.internal.configentry.IngressGateway.Meta:type_name -> hashicorp.consul.internal.configentry.IngressGateway.MetaEntry 31, // 40: hashicorp.consul.internal.configentry.IngressGateway.Defaults:type_name -> hashicorp.consul.internal.configentry.IngressServiceConfig 54, // 41: hashicorp.consul.internal.configentry.IngressServiceConfig.PassiveHealthCheck:type_name -> hashicorp.consul.internal.configentry.PassiveHealthCheck 33, // 42: hashicorp.consul.internal.configentry.GatewayTLSConfig.SDS:type_name -> hashicorp.consul.internal.configentry.GatewayTLSSDSConfig @@ -9510,24 +8640,24 @@ var file_private_pbconfigentry_config_entry_proto_depIdxs = []int32{ 36, // 45: hashicorp.consul.internal.configentry.IngressService.TLS:type_name -> hashicorp.consul.internal.configentry.GatewayServiceTLSConfig 37, // 46: hashicorp.consul.internal.configentry.IngressService.RequestHeaders:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderModifiers 37, // 47: hashicorp.consul.internal.configentry.IngressService.ResponseHeaders:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderModifiers - 111, // 48: hashicorp.consul.internal.configentry.IngressService.Meta:type_name -> hashicorp.consul.internal.configentry.IngressService.MetaEntry - 126, // 49: hashicorp.consul.internal.configentry.IngressService.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta + 100, // 48: hashicorp.consul.internal.configentry.IngressService.Meta:type_name -> hashicorp.consul.internal.configentry.IngressService.MetaEntry + 115, // 49: hashicorp.consul.internal.configentry.IngressService.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta 54, // 50: hashicorp.consul.internal.configentry.IngressService.PassiveHealthCheck:type_name -> hashicorp.consul.internal.configentry.PassiveHealthCheck 33, // 51: hashicorp.consul.internal.configentry.GatewayServiceTLSConfig.SDS:type_name -> hashicorp.consul.internal.configentry.GatewayTLSSDSConfig - 112, // 52: hashicorp.consul.internal.configentry.HTTPHeaderModifiers.Add:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderModifiers.AddEntry - 113, // 53: hashicorp.consul.internal.configentry.HTTPHeaderModifiers.Set:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderModifiers.SetEntry + 101, // 52: hashicorp.consul.internal.configentry.HTTPHeaderModifiers.Add:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderModifiers.AddEntry + 102, // 53: hashicorp.consul.internal.configentry.HTTPHeaderModifiers.Set:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderModifiers.SetEntry 42, // 54: hashicorp.consul.internal.configentry.ServiceIntentions.Sources:type_name -> hashicorp.consul.internal.configentry.SourceIntention - 114, // 55: hashicorp.consul.internal.configentry.ServiceIntentions.Meta:type_name -> hashicorp.consul.internal.configentry.ServiceIntentions.MetaEntry + 103, // 55: hashicorp.consul.internal.configentry.ServiceIntentions.Meta:type_name -> hashicorp.consul.internal.configentry.ServiceIntentions.MetaEntry 39, // 56: hashicorp.consul.internal.configentry.ServiceIntentions.JWT:type_name -> hashicorp.consul.internal.configentry.IntentionJWTRequirement 40, // 57: hashicorp.consul.internal.configentry.IntentionJWTRequirement.Providers:type_name -> hashicorp.consul.internal.configentry.IntentionJWTProvider 41, // 58: hashicorp.consul.internal.configentry.IntentionJWTProvider.VerifyClaims:type_name -> hashicorp.consul.internal.configentry.IntentionJWTClaimVerification 1, // 59: hashicorp.consul.internal.configentry.SourceIntention.Action:type_name -> hashicorp.consul.internal.configentry.IntentionAction 43, // 60: hashicorp.consul.internal.configentry.SourceIntention.Permissions:type_name -> hashicorp.consul.internal.configentry.IntentionPermission 2, // 61: hashicorp.consul.internal.configentry.SourceIntention.Type:type_name -> hashicorp.consul.internal.configentry.IntentionSourceType - 115, // 62: hashicorp.consul.internal.configentry.SourceIntention.LegacyMeta:type_name -> hashicorp.consul.internal.configentry.SourceIntention.LegacyMetaEntry - 129, // 63: hashicorp.consul.internal.configentry.SourceIntention.LegacyCreateTime:type_name -> google.protobuf.Timestamp - 129, // 64: hashicorp.consul.internal.configentry.SourceIntention.LegacyUpdateTime:type_name -> google.protobuf.Timestamp - 126, // 65: hashicorp.consul.internal.configentry.SourceIntention.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta + 104, // 62: hashicorp.consul.internal.configentry.SourceIntention.LegacyMeta:type_name -> hashicorp.consul.internal.configentry.SourceIntention.LegacyMetaEntry + 118, // 63: hashicorp.consul.internal.configentry.SourceIntention.LegacyCreateTime:type_name -> google.protobuf.Timestamp + 118, // 64: hashicorp.consul.internal.configentry.SourceIntention.LegacyUpdateTime:type_name -> google.protobuf.Timestamp + 115, // 65: hashicorp.consul.internal.configentry.SourceIntention.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta 1, // 66: hashicorp.consul.internal.configentry.IntentionPermission.Action:type_name -> hashicorp.consul.internal.configentry.IntentionAction 44, // 67: hashicorp.consul.internal.configentry.IntentionPermission.HTTP:type_name -> hashicorp.consul.internal.configentry.IntentionHTTPPermission 39, // 68: hashicorp.consul.internal.configentry.IntentionPermission.JWT:type_name -> hashicorp.consul.internal.configentry.IntentionJWTRequirement @@ -9538,106 +8668,89 @@ var file_private_pbconfigentry_config_entry_proto_depIdxs = []int32{ 49, // 73: hashicorp.consul.internal.configentry.ServiceDefaults.Expose:type_name -> hashicorp.consul.internal.configentry.ExposeConfig 51, // 74: hashicorp.consul.internal.configentry.ServiceDefaults.UpstreamConfig:type_name -> hashicorp.consul.internal.configentry.UpstreamConfiguration 55, // 75: hashicorp.consul.internal.configentry.ServiceDefaults.Destination:type_name -> hashicorp.consul.internal.configentry.DestinationConfig - 56, // 76: hashicorp.consul.internal.configentry.ServiceDefaults.RateLimits:type_name -> hashicorp.consul.internal.configentry.RateLimits - 116, // 77: hashicorp.consul.internal.configentry.ServiceDefaults.Meta:type_name -> hashicorp.consul.internal.configentry.ServiceDefaults.MetaEntry - 130, // 78: hashicorp.consul.internal.configentry.ServiceDefaults.EnvoyExtensions:type_name -> hashicorp.consul.internal.common.EnvoyExtension - 4, // 79: hashicorp.consul.internal.configentry.ServiceDefaults.MutualTLSMode:type_name -> hashicorp.consul.internal.configentry.MutualTLSMode - 5, // 80: hashicorp.consul.internal.configentry.MeshGatewayConfig.Mode:type_name -> hashicorp.consul.internal.configentry.MeshGatewayMode - 50, // 81: hashicorp.consul.internal.configentry.ExposeConfig.Paths:type_name -> hashicorp.consul.internal.configentry.ExposePath - 52, // 82: hashicorp.consul.internal.configentry.UpstreamConfiguration.Overrides:type_name -> hashicorp.consul.internal.configentry.UpstreamConfig - 52, // 83: hashicorp.consul.internal.configentry.UpstreamConfiguration.Defaults:type_name -> hashicorp.consul.internal.configentry.UpstreamConfig - 126, // 84: hashicorp.consul.internal.configentry.UpstreamConfig.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta - 53, // 85: hashicorp.consul.internal.configentry.UpstreamConfig.Limits:type_name -> hashicorp.consul.internal.configentry.UpstreamLimits - 54, // 86: hashicorp.consul.internal.configentry.UpstreamConfig.PassiveHealthCheck:type_name -> hashicorp.consul.internal.configentry.PassiveHealthCheck - 48, // 87: hashicorp.consul.internal.configentry.UpstreamConfig.MeshGateway:type_name -> hashicorp.consul.internal.configentry.MeshGatewayConfig - 128, // 88: hashicorp.consul.internal.configentry.PassiveHealthCheck.Interval:type_name -> google.protobuf.Duration - 128, // 89: hashicorp.consul.internal.configentry.PassiveHealthCheck.BaseEjectionTime:type_name -> google.protobuf.Duration - 57, // 90: hashicorp.consul.internal.configentry.RateLimits.InstanceLevel:type_name -> hashicorp.consul.internal.configentry.InstanceLevelRateLimits - 58, // 91: hashicorp.consul.internal.configentry.InstanceLevelRateLimits.Routes:type_name -> hashicorp.consul.internal.configentry.InstanceLevelRouteRateLimits - 117, // 92: hashicorp.consul.internal.configentry.APIGateway.Meta:type_name -> hashicorp.consul.internal.configentry.APIGateway.MetaEntry - 62, // 93: hashicorp.consul.internal.configentry.APIGateway.Listeners:type_name -> hashicorp.consul.internal.configentry.APIGatewayListener - 60, // 94: hashicorp.consul.internal.configentry.APIGateway.Status:type_name -> hashicorp.consul.internal.configentry.Status - 61, // 95: hashicorp.consul.internal.configentry.Status.Conditions:type_name -> hashicorp.consul.internal.configentry.Condition - 68, // 96: hashicorp.consul.internal.configentry.Condition.Resource:type_name -> hashicorp.consul.internal.configentry.ResourceReference - 129, // 97: hashicorp.consul.internal.configentry.Condition.LastTransitionTime:type_name -> google.protobuf.Timestamp - 6, // 98: hashicorp.consul.internal.configentry.APIGatewayListener.Protocol:type_name -> hashicorp.consul.internal.configentry.APIGatewayListenerProtocol - 63, // 99: hashicorp.consul.internal.configentry.APIGatewayListener.TLS:type_name -> hashicorp.consul.internal.configentry.APIGatewayTLSConfiguration - 64, // 100: hashicorp.consul.internal.configentry.APIGatewayListener.Override:type_name -> hashicorp.consul.internal.configentry.APIGatewayPolicy - 64, // 101: hashicorp.consul.internal.configentry.APIGatewayListener.Default:type_name -> hashicorp.consul.internal.configentry.APIGatewayPolicy - 68, // 102: hashicorp.consul.internal.configentry.APIGatewayTLSConfiguration.Certificates:type_name -> hashicorp.consul.internal.configentry.ResourceReference - 65, // 103: hashicorp.consul.internal.configentry.APIGatewayPolicy.JWT:type_name -> hashicorp.consul.internal.configentry.APIGatewayJWTRequirement - 66, // 104: hashicorp.consul.internal.configentry.APIGatewayJWTRequirement.Providers:type_name -> hashicorp.consul.internal.configentry.APIGatewayJWTProvider - 67, // 105: hashicorp.consul.internal.configentry.APIGatewayJWTProvider.VerifyClaims:type_name -> hashicorp.consul.internal.configentry.APIGatewayJWTClaimVerification - 126, // 106: hashicorp.consul.internal.configentry.ResourceReference.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta - 118, // 107: hashicorp.consul.internal.configentry.BoundAPIGateway.Meta:type_name -> hashicorp.consul.internal.configentry.BoundAPIGateway.MetaEntry - 70, // 108: hashicorp.consul.internal.configentry.BoundAPIGateway.Listeners:type_name -> hashicorp.consul.internal.configentry.BoundAPIGatewayListener - 68, // 109: hashicorp.consul.internal.configentry.BoundAPIGatewayListener.Certificates:type_name -> hashicorp.consul.internal.configentry.ResourceReference - 68, // 110: hashicorp.consul.internal.configentry.BoundAPIGatewayListener.Routes:type_name -> hashicorp.consul.internal.configentry.ResourceReference - 119, // 111: hashicorp.consul.internal.configentry.InlineCertificate.Meta:type_name -> hashicorp.consul.internal.configentry.InlineCertificate.MetaEntry - 120, // 112: hashicorp.consul.internal.configentry.HTTPRoute.Meta:type_name -> hashicorp.consul.internal.configentry.HTTPRoute.MetaEntry - 68, // 113: hashicorp.consul.internal.configentry.HTTPRoute.Parents:type_name -> hashicorp.consul.internal.configentry.ResourceReference - 73, // 114: hashicorp.consul.internal.configentry.HTTPRoute.Rules:type_name -> hashicorp.consul.internal.configentry.HTTPRouteRule - 60, // 115: hashicorp.consul.internal.configentry.HTTPRoute.Status:type_name -> hashicorp.consul.internal.configentry.Status - 78, // 116: hashicorp.consul.internal.configentry.HTTPRouteRule.Filters:type_name -> hashicorp.consul.internal.configentry.HTTPFilters - 74, // 117: hashicorp.consul.internal.configentry.HTTPRouteRule.Matches:type_name -> hashicorp.consul.internal.configentry.HTTPMatch - 85, // 118: hashicorp.consul.internal.configentry.HTTPRouteRule.Services:type_name -> hashicorp.consul.internal.configentry.HTTPService - 79, // 119: hashicorp.consul.internal.configentry.HTTPRouteRule.ResponseFilters:type_name -> hashicorp.consul.internal.configentry.HTTPResponseFilters - 75, // 120: hashicorp.consul.internal.configentry.HTTPMatch.Headers:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderMatch - 7, // 121: hashicorp.consul.internal.configentry.HTTPMatch.Method:type_name -> hashicorp.consul.internal.configentry.HTTPMatchMethod - 76, // 122: hashicorp.consul.internal.configentry.HTTPMatch.Path:type_name -> hashicorp.consul.internal.configentry.HTTPPathMatch - 77, // 123: hashicorp.consul.internal.configentry.HTTPMatch.Query:type_name -> hashicorp.consul.internal.configentry.HTTPQueryMatch - 8, // 124: hashicorp.consul.internal.configentry.HTTPHeaderMatch.Match:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderMatchType - 9, // 125: hashicorp.consul.internal.configentry.HTTPPathMatch.Match:type_name -> hashicorp.consul.internal.configentry.HTTPPathMatchType - 10, // 126: hashicorp.consul.internal.configentry.HTTPQueryMatch.Match:type_name -> hashicorp.consul.internal.configentry.HTTPQueryMatchType - 84, // 127: hashicorp.consul.internal.configentry.HTTPFilters.Headers:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderFilter - 80, // 128: hashicorp.consul.internal.configentry.HTTPFilters.URLRewrite:type_name -> hashicorp.consul.internal.configentry.URLRewrite - 81, // 129: hashicorp.consul.internal.configentry.HTTPFilters.RetryFilter:type_name -> hashicorp.consul.internal.configentry.RetryFilter - 82, // 130: hashicorp.consul.internal.configentry.HTTPFilters.TimeoutFilter:type_name -> hashicorp.consul.internal.configentry.TimeoutFilter - 83, // 131: hashicorp.consul.internal.configentry.HTTPFilters.JWT:type_name -> hashicorp.consul.internal.configentry.JWTFilter - 84, // 132: hashicorp.consul.internal.configentry.HTTPResponseFilters.Headers:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderFilter - 128, // 133: hashicorp.consul.internal.configentry.TimeoutFilter.RequestTimeout:type_name -> google.protobuf.Duration - 128, // 134: hashicorp.consul.internal.configentry.TimeoutFilter.IdleTimeout:type_name -> google.protobuf.Duration - 66, // 135: hashicorp.consul.internal.configentry.JWTFilter.Providers:type_name -> hashicorp.consul.internal.configentry.APIGatewayJWTProvider - 121, // 136: hashicorp.consul.internal.configentry.HTTPHeaderFilter.Add:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderFilter.AddEntry - 122, // 137: hashicorp.consul.internal.configentry.HTTPHeaderFilter.Set:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderFilter.SetEntry - 78, // 138: hashicorp.consul.internal.configentry.HTTPService.Filters:type_name -> hashicorp.consul.internal.configentry.HTTPFilters - 126, // 139: hashicorp.consul.internal.configentry.HTTPService.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta - 79, // 140: hashicorp.consul.internal.configentry.HTTPService.ResponseFilters:type_name -> hashicorp.consul.internal.configentry.HTTPResponseFilters - 123, // 141: hashicorp.consul.internal.configentry.TCPRoute.Meta:type_name -> hashicorp.consul.internal.configentry.TCPRoute.MetaEntry - 68, // 142: hashicorp.consul.internal.configentry.TCPRoute.Parents:type_name -> hashicorp.consul.internal.configentry.ResourceReference - 87, // 143: hashicorp.consul.internal.configentry.TCPRoute.Services:type_name -> hashicorp.consul.internal.configentry.TCPService - 60, // 144: hashicorp.consul.internal.configentry.TCPRoute.Status:type_name -> hashicorp.consul.internal.configentry.Status - 126, // 145: hashicorp.consul.internal.configentry.TCPService.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta - 89, // 146: hashicorp.consul.internal.configentry.SamenessGroup.Members:type_name -> hashicorp.consul.internal.configentry.SamenessGroupMember - 124, // 147: hashicorp.consul.internal.configentry.SamenessGroup.Meta:type_name -> hashicorp.consul.internal.configentry.SamenessGroup.MetaEntry - 126, // 148: hashicorp.consul.internal.configentry.SamenessGroup.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta - 91, // 149: hashicorp.consul.internal.configentry.JWTProvider.JSONWebKeySet:type_name -> hashicorp.consul.internal.configentry.JSONWebKeySet - 100, // 150: hashicorp.consul.internal.configentry.JWTProvider.Locations:type_name -> hashicorp.consul.internal.configentry.JWTLocation - 104, // 151: hashicorp.consul.internal.configentry.JWTProvider.Forwarding:type_name -> hashicorp.consul.internal.configentry.JWTForwardingConfig - 105, // 152: hashicorp.consul.internal.configentry.JWTProvider.CacheConfig:type_name -> hashicorp.consul.internal.configentry.JWTCacheConfig - 125, // 153: hashicorp.consul.internal.configentry.JWTProvider.Meta:type_name -> hashicorp.consul.internal.configentry.JWTProvider.MetaEntry - 92, // 154: hashicorp.consul.internal.configentry.JSONWebKeySet.Local:type_name -> hashicorp.consul.internal.configentry.LocalJWKS - 93, // 155: hashicorp.consul.internal.configentry.JSONWebKeySet.Remote:type_name -> hashicorp.consul.internal.configentry.RemoteJWKS - 128, // 156: hashicorp.consul.internal.configentry.RemoteJWKS.CacheDuration:type_name -> google.protobuf.Duration - 98, // 157: hashicorp.consul.internal.configentry.RemoteJWKS.RetryPolicy:type_name -> hashicorp.consul.internal.configentry.JWKSRetryPolicy - 94, // 158: hashicorp.consul.internal.configentry.RemoteJWKS.JWKSCluster:type_name -> hashicorp.consul.internal.configentry.JWKSCluster - 95, // 159: hashicorp.consul.internal.configentry.JWKSCluster.TLSCertificates:type_name -> hashicorp.consul.internal.configentry.JWKSTLSCertificate - 128, // 160: hashicorp.consul.internal.configentry.JWKSCluster.ConnectTimeout:type_name -> google.protobuf.Duration - 96, // 161: hashicorp.consul.internal.configentry.JWKSTLSCertificate.CaCertificateProviderInstance:type_name -> hashicorp.consul.internal.configentry.JWKSTLSCertProviderInstance - 97, // 162: hashicorp.consul.internal.configentry.JWKSTLSCertificate.TrustedCA:type_name -> hashicorp.consul.internal.configentry.JWKSTLSCertTrustedCA - 99, // 163: hashicorp.consul.internal.configentry.JWKSRetryPolicy.RetryPolicyBackOff:type_name -> hashicorp.consul.internal.configentry.RetryPolicyBackOff - 128, // 164: hashicorp.consul.internal.configentry.RetryPolicyBackOff.BaseInterval:type_name -> google.protobuf.Duration - 128, // 165: hashicorp.consul.internal.configentry.RetryPolicyBackOff.MaxInterval:type_name -> google.protobuf.Duration - 101, // 166: hashicorp.consul.internal.configentry.JWTLocation.Header:type_name -> hashicorp.consul.internal.configentry.JWTLocationHeader - 102, // 167: hashicorp.consul.internal.configentry.JWTLocation.QueryParam:type_name -> hashicorp.consul.internal.configentry.JWTLocationQueryParam - 103, // 168: hashicorp.consul.internal.configentry.JWTLocation.Cookie:type_name -> hashicorp.consul.internal.configentry.JWTLocationCookie - 19, // 169: hashicorp.consul.internal.configentry.ServiceResolver.SubsetsEntry.value:type_name -> hashicorp.consul.internal.configentry.ServiceResolverSubset - 21, // 170: hashicorp.consul.internal.configentry.ServiceResolver.FailoverEntry.value:type_name -> hashicorp.consul.internal.configentry.ServiceResolverFailover - 171, // [171:171] is the sub-list for method output_type - 171, // [171:171] is the sub-list for method input_type - 171, // [171:171] is the sub-list for extension type_name - 171, // [171:171] is the sub-list for extension extendee - 0, // [0:171] is the sub-list for field type_name + 105, // 76: hashicorp.consul.internal.configentry.ServiceDefaults.Meta:type_name -> hashicorp.consul.internal.configentry.ServiceDefaults.MetaEntry + 119, // 77: hashicorp.consul.internal.configentry.ServiceDefaults.EnvoyExtensions:type_name -> hashicorp.consul.internal.common.EnvoyExtension + 4, // 78: hashicorp.consul.internal.configentry.ServiceDefaults.MutualTLSMode:type_name -> hashicorp.consul.internal.configentry.MutualTLSMode + 5, // 79: hashicorp.consul.internal.configentry.MeshGatewayConfig.Mode:type_name -> hashicorp.consul.internal.configentry.MeshGatewayMode + 50, // 80: hashicorp.consul.internal.configentry.ExposeConfig.Paths:type_name -> hashicorp.consul.internal.configentry.ExposePath + 52, // 81: hashicorp.consul.internal.configentry.UpstreamConfiguration.Overrides:type_name -> hashicorp.consul.internal.configentry.UpstreamConfig + 52, // 82: hashicorp.consul.internal.configentry.UpstreamConfiguration.Defaults:type_name -> hashicorp.consul.internal.configentry.UpstreamConfig + 115, // 83: hashicorp.consul.internal.configentry.UpstreamConfig.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta + 53, // 84: hashicorp.consul.internal.configentry.UpstreamConfig.Limits:type_name -> hashicorp.consul.internal.configentry.UpstreamLimits + 54, // 85: hashicorp.consul.internal.configentry.UpstreamConfig.PassiveHealthCheck:type_name -> hashicorp.consul.internal.configentry.PassiveHealthCheck + 48, // 86: hashicorp.consul.internal.configentry.UpstreamConfig.MeshGateway:type_name -> hashicorp.consul.internal.configentry.MeshGatewayConfig + 117, // 87: hashicorp.consul.internal.configentry.PassiveHealthCheck.Interval:type_name -> google.protobuf.Duration + 117, // 88: hashicorp.consul.internal.configentry.PassiveHealthCheck.BaseEjectionTime:type_name -> google.protobuf.Duration + 106, // 89: hashicorp.consul.internal.configentry.APIGateway.Meta:type_name -> hashicorp.consul.internal.configentry.APIGateway.MetaEntry + 59, // 90: hashicorp.consul.internal.configentry.APIGateway.Listeners:type_name -> hashicorp.consul.internal.configentry.APIGatewayListener + 57, // 91: hashicorp.consul.internal.configentry.APIGateway.Status:type_name -> hashicorp.consul.internal.configentry.Status + 58, // 92: hashicorp.consul.internal.configentry.Status.Conditions:type_name -> hashicorp.consul.internal.configentry.Condition + 61, // 93: hashicorp.consul.internal.configentry.Condition.Resource:type_name -> hashicorp.consul.internal.configentry.ResourceReference + 118, // 94: hashicorp.consul.internal.configentry.Condition.LastTransitionTime:type_name -> google.protobuf.Timestamp + 6, // 95: hashicorp.consul.internal.configentry.APIGatewayListener.Protocol:type_name -> hashicorp.consul.internal.configentry.APIGatewayListenerProtocol + 60, // 96: hashicorp.consul.internal.configentry.APIGatewayListener.TLS:type_name -> hashicorp.consul.internal.configentry.APIGatewayTLSConfiguration + 61, // 97: hashicorp.consul.internal.configentry.APIGatewayTLSConfiguration.Certificates:type_name -> hashicorp.consul.internal.configentry.ResourceReference + 115, // 98: hashicorp.consul.internal.configentry.ResourceReference.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta + 107, // 99: hashicorp.consul.internal.configentry.BoundAPIGateway.Meta:type_name -> hashicorp.consul.internal.configentry.BoundAPIGateway.MetaEntry + 63, // 100: hashicorp.consul.internal.configentry.BoundAPIGateway.Listeners:type_name -> hashicorp.consul.internal.configentry.BoundAPIGatewayListener + 61, // 101: hashicorp.consul.internal.configentry.BoundAPIGatewayListener.Certificates:type_name -> hashicorp.consul.internal.configentry.ResourceReference + 61, // 102: hashicorp.consul.internal.configentry.BoundAPIGatewayListener.Routes:type_name -> hashicorp.consul.internal.configentry.ResourceReference + 108, // 103: hashicorp.consul.internal.configentry.InlineCertificate.Meta:type_name -> hashicorp.consul.internal.configentry.InlineCertificate.MetaEntry + 109, // 104: hashicorp.consul.internal.configentry.HTTPRoute.Meta:type_name -> hashicorp.consul.internal.configentry.HTTPRoute.MetaEntry + 61, // 105: hashicorp.consul.internal.configentry.HTTPRoute.Parents:type_name -> hashicorp.consul.internal.configentry.ResourceReference + 66, // 106: hashicorp.consul.internal.configentry.HTTPRoute.Rules:type_name -> hashicorp.consul.internal.configentry.HTTPRouteRule + 57, // 107: hashicorp.consul.internal.configentry.HTTPRoute.Status:type_name -> hashicorp.consul.internal.configentry.Status + 71, // 108: hashicorp.consul.internal.configentry.HTTPRouteRule.Filters:type_name -> hashicorp.consul.internal.configentry.HTTPFilters + 67, // 109: hashicorp.consul.internal.configentry.HTTPRouteRule.Matches:type_name -> hashicorp.consul.internal.configentry.HTTPMatch + 74, // 110: hashicorp.consul.internal.configentry.HTTPRouteRule.Services:type_name -> hashicorp.consul.internal.configentry.HTTPService + 68, // 111: hashicorp.consul.internal.configentry.HTTPMatch.Headers:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderMatch + 7, // 112: hashicorp.consul.internal.configentry.HTTPMatch.Method:type_name -> hashicorp.consul.internal.configentry.HTTPMatchMethod + 69, // 113: hashicorp.consul.internal.configentry.HTTPMatch.Path:type_name -> hashicorp.consul.internal.configentry.HTTPPathMatch + 70, // 114: hashicorp.consul.internal.configentry.HTTPMatch.Query:type_name -> hashicorp.consul.internal.configentry.HTTPQueryMatch + 8, // 115: hashicorp.consul.internal.configentry.HTTPHeaderMatch.Match:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderMatchType + 9, // 116: hashicorp.consul.internal.configentry.HTTPPathMatch.Match:type_name -> hashicorp.consul.internal.configentry.HTTPPathMatchType + 10, // 117: hashicorp.consul.internal.configentry.HTTPQueryMatch.Match:type_name -> hashicorp.consul.internal.configentry.HTTPQueryMatchType + 73, // 118: hashicorp.consul.internal.configentry.HTTPFilters.Headers:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderFilter + 72, // 119: hashicorp.consul.internal.configentry.HTTPFilters.URLRewrite:type_name -> hashicorp.consul.internal.configentry.URLRewrite + 110, // 120: hashicorp.consul.internal.configentry.HTTPHeaderFilter.Add:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderFilter.AddEntry + 111, // 121: hashicorp.consul.internal.configentry.HTTPHeaderFilter.Set:type_name -> hashicorp.consul.internal.configentry.HTTPHeaderFilter.SetEntry + 71, // 122: hashicorp.consul.internal.configentry.HTTPService.Filters:type_name -> hashicorp.consul.internal.configentry.HTTPFilters + 115, // 123: hashicorp.consul.internal.configentry.HTTPService.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta + 112, // 124: hashicorp.consul.internal.configentry.TCPRoute.Meta:type_name -> hashicorp.consul.internal.configentry.TCPRoute.MetaEntry + 61, // 125: hashicorp.consul.internal.configentry.TCPRoute.Parents:type_name -> hashicorp.consul.internal.configentry.ResourceReference + 76, // 126: hashicorp.consul.internal.configentry.TCPRoute.Services:type_name -> hashicorp.consul.internal.configentry.TCPService + 57, // 127: hashicorp.consul.internal.configentry.TCPRoute.Status:type_name -> hashicorp.consul.internal.configentry.Status + 115, // 128: hashicorp.consul.internal.configentry.TCPService.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta + 78, // 129: hashicorp.consul.internal.configentry.SamenessGroup.Members:type_name -> hashicorp.consul.internal.configentry.SamenessGroupMember + 113, // 130: hashicorp.consul.internal.configentry.SamenessGroup.Meta:type_name -> hashicorp.consul.internal.configentry.SamenessGroup.MetaEntry + 115, // 131: hashicorp.consul.internal.configentry.SamenessGroup.EnterpriseMeta:type_name -> hashicorp.consul.internal.common.EnterpriseMeta + 80, // 132: hashicorp.consul.internal.configentry.JWTProvider.JSONWebKeySet:type_name -> hashicorp.consul.internal.configentry.JSONWebKeySet + 89, // 133: hashicorp.consul.internal.configentry.JWTProvider.Locations:type_name -> hashicorp.consul.internal.configentry.JWTLocation + 93, // 134: hashicorp.consul.internal.configentry.JWTProvider.Forwarding:type_name -> hashicorp.consul.internal.configentry.JWTForwardingConfig + 94, // 135: hashicorp.consul.internal.configentry.JWTProvider.CacheConfig:type_name -> hashicorp.consul.internal.configentry.JWTCacheConfig + 114, // 136: hashicorp.consul.internal.configentry.JWTProvider.Meta:type_name -> hashicorp.consul.internal.configentry.JWTProvider.MetaEntry + 81, // 137: hashicorp.consul.internal.configentry.JSONWebKeySet.Local:type_name -> hashicorp.consul.internal.configentry.LocalJWKS + 82, // 138: hashicorp.consul.internal.configentry.JSONWebKeySet.Remote:type_name -> hashicorp.consul.internal.configentry.RemoteJWKS + 117, // 139: hashicorp.consul.internal.configentry.RemoteJWKS.CacheDuration:type_name -> google.protobuf.Duration + 87, // 140: hashicorp.consul.internal.configentry.RemoteJWKS.RetryPolicy:type_name -> hashicorp.consul.internal.configentry.JWKSRetryPolicy + 83, // 141: hashicorp.consul.internal.configentry.RemoteJWKS.JWKSCluster:type_name -> hashicorp.consul.internal.configentry.JWKSCluster + 84, // 142: hashicorp.consul.internal.configentry.JWKSCluster.TLSCertificates:type_name -> hashicorp.consul.internal.configentry.JWKSTLSCertificate + 117, // 143: hashicorp.consul.internal.configentry.JWKSCluster.ConnectTimeout:type_name -> google.protobuf.Duration + 85, // 144: hashicorp.consul.internal.configentry.JWKSTLSCertificate.CaCertificateProviderInstance:type_name -> hashicorp.consul.internal.configentry.JWKSTLSCertProviderInstance + 86, // 145: hashicorp.consul.internal.configentry.JWKSTLSCertificate.TrustedCA:type_name -> hashicorp.consul.internal.configentry.JWKSTLSCertTrustedCA + 88, // 146: hashicorp.consul.internal.configentry.JWKSRetryPolicy.RetryPolicyBackOff:type_name -> hashicorp.consul.internal.configentry.RetryPolicyBackOff + 117, // 147: hashicorp.consul.internal.configentry.RetryPolicyBackOff.BaseInterval:type_name -> google.protobuf.Duration + 117, // 148: hashicorp.consul.internal.configentry.RetryPolicyBackOff.MaxInterval:type_name -> google.protobuf.Duration + 90, // 149: hashicorp.consul.internal.configentry.JWTLocation.Header:type_name -> hashicorp.consul.internal.configentry.JWTLocationHeader + 91, // 150: hashicorp.consul.internal.configentry.JWTLocation.QueryParam:type_name -> hashicorp.consul.internal.configentry.JWTLocationQueryParam + 92, // 151: hashicorp.consul.internal.configentry.JWTLocation.Cookie:type_name -> hashicorp.consul.internal.configentry.JWTLocationCookie + 19, // 152: hashicorp.consul.internal.configentry.ServiceResolver.SubsetsEntry.value:type_name -> hashicorp.consul.internal.configentry.ServiceResolverSubset + 21, // 153: hashicorp.consul.internal.configentry.ServiceResolver.FailoverEntry.value:type_name -> hashicorp.consul.internal.configentry.ServiceResolverFailover + 154, // [154:154] is the sub-list for method output_type + 154, // [154:154] is the sub-list for method input_type + 154, // [154:154] is the sub-list for extension type_name + 154, // [154:154] is the sub-list for extension extendee + 0, // [0:154] is the sub-list for field type_name } func init() { file_private_pbconfigentry_config_entry_proto_init() } @@ -10187,42 +9300,6 @@ func file_private_pbconfigentry_config_entry_proto_init() { } } file_private_pbconfigentry_config_entry_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RateLimits); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InstanceLevelRateLimits); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InstanceLevelRouteRateLimits); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*APIGateway); i { case 0: return &v.state @@ -10234,7 +9311,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Status); i { case 0: return &v.state @@ -10246,7 +9323,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Condition); i { case 0: return &v.state @@ -10258,7 +9335,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*APIGatewayListener); i { case 0: return &v.state @@ -10270,7 +9347,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*APIGatewayTLSConfiguration); i { case 0: return &v.state @@ -10282,55 +9359,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*APIGatewayPolicy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*APIGatewayJWTRequirement); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*APIGatewayJWTProvider); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*APIGatewayJWTClaimVerification); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ResourceReference); i { case 0: return &v.state @@ -10342,7 +9371,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BoundAPIGateway); i { case 0: return &v.state @@ -10354,7 +9383,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BoundAPIGatewayListener); i { case 0: return &v.state @@ -10366,7 +9395,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InlineCertificate); i { case 0: return &v.state @@ -10378,7 +9407,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPRoute); i { case 0: return &v.state @@ -10390,7 +9419,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPRouteRule); i { case 0: return &v.state @@ -10402,7 +9431,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPMatch); i { case 0: return &v.state @@ -10414,7 +9443,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPHeaderMatch); i { case 0: return &v.state @@ -10426,7 +9455,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPPathMatch); i { case 0: return &v.state @@ -10438,7 +9467,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPQueryMatch); i { case 0: return &v.state @@ -10450,7 +9479,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPFilters); i { case 0: return &v.state @@ -10462,19 +9491,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HTTPResponseFilters); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*URLRewrite); i { case 0: return &v.state @@ -10486,43 +9503,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RetryFilter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TimeoutFilter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*JWTFilter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbconfigentry_config_entry_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPHeaderFilter); i { case 0: return &v.state @@ -10534,7 +9515,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HTTPService); i { case 0: return &v.state @@ -10546,7 +9527,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TCPRoute); i { case 0: return &v.state @@ -10558,7 +9539,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*TCPService); i { case 0: return &v.state @@ -10570,7 +9551,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SamenessGroup); i { case 0: return &v.state @@ -10582,7 +9563,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SamenessGroupMember); i { case 0: return &v.state @@ -10594,7 +9575,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWTProvider); i { case 0: return &v.state @@ -10606,7 +9587,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JSONWebKeySet); i { case 0: return &v.state @@ -10618,7 +9599,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LocalJWKS); i { case 0: return &v.state @@ -10630,7 +9611,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RemoteJWKS); i { case 0: return &v.state @@ -10642,7 +9623,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWKSCluster); i { case 0: return &v.state @@ -10654,7 +9635,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWKSTLSCertificate); i { case 0: return &v.state @@ -10666,7 +9647,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWKSTLSCertProviderInstance); i { case 0: return &v.state @@ -10678,7 +9659,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWKSTLSCertTrustedCA); i { case 0: return &v.state @@ -10690,7 +9671,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWKSRetryPolicy); i { case 0: return &v.state @@ -10702,7 +9683,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[88].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RetryPolicyBackOff); i { case 0: return &v.state @@ -10714,7 +9695,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[89].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWTLocation); i { case 0: return &v.state @@ -10726,7 +9707,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[90].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWTLocationHeader); i { case 0: return &v.state @@ -10738,7 +9719,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[91].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWTLocationQueryParam); i { case 0: return &v.state @@ -10750,7 +9731,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWTLocationCookie); i { case 0: return &v.state @@ -10762,7 +9743,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[93].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWTForwardingConfig); i { case 0: return &v.state @@ -10774,7 +9755,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { return nil } } - file_private_pbconfigentry_config_entry_proto_msgTypes[94].Exporter = func(v interface{}, i int) interface{} { + file_private_pbconfigentry_config_entry_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JWTCacheConfig); i { case 0: return &v.state @@ -10807,7 +9788,7 @@ func file_private_pbconfigentry_config_entry_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_private_pbconfigentry_config_entry_proto_rawDesc, NumEnums: 11, - NumMessages: 115, + NumMessages: 104, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/private/pbconfigentry/config_entry.proto b/proto/private/pbconfigentry/config_entry.proto index b5143774eeb6b..5c675ec16c0cc 100644 --- a/proto/private/pbconfigentry/config_entry.proto +++ b/proto/private/pbconfigentry/config_entry.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; @@ -507,7 +507,6 @@ message ServiceDefaults { // mog: func-to=int func-from=int32 int32 LocalRequestTimeoutMs = 11; string BalanceInboundConnections = 12; - RateLimits RateLimits = 16; map Meta = 13; // mog: func-to=EnvoyExtensionsToStructs func-from=EnvoyExtensionsFromStructs repeated hashicorp.consul.internal.common.EnvoyExtension EnvoyExtensions = 14; @@ -653,43 +652,6 @@ message DestinationConfig { int32 Port = 2; } -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.RateLimits -// output=config_entry.gen.go -// name=Structs -message RateLimits { - InstanceLevelRateLimits InstanceLevel = 1; -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.InstanceLevelRateLimits -// output=config_entry.gen.go -// name=Structs -message InstanceLevelRateLimits { - // mog: func-to=int func-from=uint32 - uint32 RequestsPerSecond = 1; - // mog: func-to=int func-from=uint32 - uint32 RequestsMaxBurst = 2; - repeated InstanceLevelRouteRateLimits Routes = 3; -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.InstanceLevelRouteRateLimits -// output=config_entry.gen.go -// name=Structs -message InstanceLevelRouteRateLimits { - string PathExact = 1; - string PathPrefix = 2; - string PathRegex = 3; - // mog: func-to=int func-from=uint32 - uint32 RequestsPerSecond = 4; - // mog: func-to=int func-from=uint32 - uint32 RequestsMaxBurst = 5; -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.APIGatewayConfigEntry @@ -744,8 +706,6 @@ message APIGatewayListener { // mog: func-to=apiGatewayProtocolToStructs func-from=apiGatewayProtocolFromStructs APIGatewayListenerProtocol Protocol = 4; APIGatewayTLSConfiguration TLS = 5; - APIGatewayPolicy Override = 6; - APIGatewayPolicy Default = 7; } // mog annotation: @@ -763,30 +723,6 @@ message APIGatewayTLSConfiguration { repeated string CipherSuites = 4; } -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.APIGatewayPolicy -// output=config_entry.gen.go -// name=Structs -message APIGatewayPolicy { - // mog: func-to=gwJWTRequirementToStructs func-from=gwJWTRequirementFromStructs - APIGatewayJWTRequirement JWT = 1; -} - -message APIGatewayJWTRequirement { - repeated APIGatewayJWTProvider Providers = 1; -} - -message APIGatewayJWTProvider { - string Name = 1; - repeated APIGatewayJWTClaimVerification VerifyClaims = 2; -} - -message APIGatewayJWTClaimVerification { - repeated string Path = 1; - string Value = 2; -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.ResourceReference @@ -857,7 +793,6 @@ message HTTPRouteRule { HTTPFilters Filters = 1; repeated HTTPMatch Matches = 2; repeated HTTPService Services = 3; - HTTPResponseFilters ResponseFilters = 4; } // mog annotation: @@ -949,19 +884,6 @@ message HTTPQueryMatch { message HTTPFilters { repeated HTTPHeaderFilter Headers = 1; URLRewrite URLRewrite = 2; - RetryFilter RetryFilter = 3; - TimeoutFilter TimeoutFilter = 4; - // mog: func-to=routeJWTFilterToStructs func-from=routeJWTFilterFromStructs - JWTFilter JWT = 5; -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.HTTPResponseFilters -// output=config_entry.gen.go -// name=Structs -message HTTPResponseFilters { - repeated HTTPHeaderFilter Headers = 1; } // mog annotation: @@ -973,34 +895,6 @@ message URLRewrite { string Path = 1; } -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.RetryFilter -// output=config_entry.gen.go -// name=Structs -message RetryFilter { - uint32 NumRetries = 1; - repeated string RetryOn = 2; - repeated uint32 RetryOnStatusCodes = 3; - bool RetryOnConnectFailure = 4; -} - -// mog annotation: -// -// target=github.com/hashicorp/consul/agent/structs.TimeoutFilter -// output=config_entry.gen.go -// name=Structs -message TimeoutFilter { - // mog: func-to=structs.DurationFromProto func-from=structs.DurationToProto - google.protobuf.Duration RequestTimeout = 1; - // mog: func-to=structs.DurationFromProto func-from=structs.DurationToProto - google.protobuf.Duration IdleTimeout = 2; -} - -message JWTFilter { - repeated APIGatewayJWTProvider Providers = 1; -} - // mog annotation: // // target=github.com/hashicorp/consul/agent/structs.HTTPHeaderFilter @@ -1024,7 +918,6 @@ message HTTPService { HTTPFilters Filters = 3; // mog: func-to=enterpriseMetaToStructs func-from=enterpriseMetaFromStructs common.EnterpriseMeta EnterpriseMeta = 4; - HTTPResponseFilters ResponseFilters = 5; } // mog annotation: diff --git a/proto/private/pbconfigentry/config_entry_ce.go b/proto/private/pbconfigentry/config_entry_ce.go deleted file mode 100644 index acc395186c369..0000000000000 --- a/proto/private/pbconfigentry/config_entry_ce.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package pbconfigentry - -import "github.com/hashicorp/consul/agent/structs" - -func gwJWTRequirementToStructs(m *APIGatewayJWTRequirement) *structs.APIGatewayJWTRequirement { - return &structs.APIGatewayJWTRequirement{} -} - -func gwJWTRequirementFromStructs(*structs.APIGatewayJWTRequirement) *APIGatewayJWTRequirement { - return &APIGatewayJWTRequirement{} -} - -func routeJWTFilterToStructs(m *JWTFilter) *structs.JWTFilter { - return &structs.JWTFilter{} -} - -func routeJWTFilterFromStructs(*structs.JWTFilter) *JWTFilter { - return &JWTFilter{} -} diff --git a/proto/private/pbconnect/connect.gen.go b/proto/private/pbconnect/connect.gen.go index 5d961d54df082..abecd9b4cf4f4 100644 --- a/proto/private/pbconnect/connect.gen.go +++ b/proto/private/pbconnect/connect.gen.go @@ -89,8 +89,6 @@ func IssuedCertToStructsIssuedCert(s *IssuedCert, t *structs.IssuedCert) { t.SerialNumber = s.SerialNumber t.CertPEM = s.CertPEM t.PrivateKeyPEM = s.PrivateKeyPEM - t.WorkloadIdentity = s.WorkloadIdentity - t.WorkloadIdentityURI = s.WorkloadIdentityURI t.Service = s.Service t.ServiceURI = s.ServiceURI t.Agent = s.Agent @@ -110,8 +108,6 @@ func IssuedCertFromStructsIssuedCert(t *structs.IssuedCert, s *IssuedCert) { s.SerialNumber = t.SerialNumber s.CertPEM = t.CertPEM s.PrivateKeyPEM = t.PrivateKeyPEM - s.WorkloadIdentity = t.WorkloadIdentity - s.WorkloadIdentityURI = t.WorkloadIdentityURI s.Service = t.Service s.ServiceURI = t.ServiceURI s.Agent = t.Agent diff --git a/proto/private/pbconnect/connect.go b/proto/private/pbconnect/connect.go index 9c3ed9d7355e0..85f8a35b7d37b 100644 --- a/proto/private/pbconnect/connect.go +++ b/proto/private/pbconnect/connect.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbconnect diff --git a/proto/private/pbconnect/connect.pb.go b/proto/private/pbconnect/connect.pb.go index 72fce82238c97..278114b3b4aa9 100644 --- a/proto/private/pbconnect/connect.pb.go +++ b/proto/private/pbconnect/connect.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: @@ -383,10 +383,6 @@ type IssuedCert struct { // ServerURI is the URI value of a cert issued for a server agent. // The same URI is shared by all servers in a Consul datacenter. ServerURI string `protobuf:"bytes,14,opt,name=ServerURI,proto3" json:"ServerURI,omitempty"` - // WorkloadIdentity is the name of the workload identity for which the cert was issued. - WorkloadIdentity string `protobuf:"bytes,15,opt,name=WorkloadIdentity,proto3" json:"WorkloadIdentity,omitempty"` - // WorkloadIdentityURI is the cert URI value. - WorkloadIdentityURI string `protobuf:"bytes,16,opt,name=WorkloadIdentityURI,proto3" json:"WorkloadIdentityURI,omitempty"` // ValidAfter and ValidBefore are the validity periods for the // certificate. // mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto @@ -502,20 +498,6 @@ func (x *IssuedCert) GetServerURI() string { return "" } -func (x *IssuedCert) GetWorkloadIdentity() string { - if x != nil { - return x.WorkloadIdentity - } - return "" -} - -func (x *IssuedCert) GetWorkloadIdentityURI() string { - if x != nil { - return x.WorkloadIdentityURI - } - return "" -} - func (x *IssuedCert) GetValidAfter() *timestamppb.Timestamp { if x != nil { return x.ValidAfter @@ -610,7 +592,7 @@ var file_private_pbconnect_connect_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x52, 0x09, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xa5, 0x05, 0x0a, + 0x78, 0x52, 0x09, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xc7, 0x04, 0x0a, 0x0a, 0x49, 0x73, 0x73, 0x75, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, @@ -629,49 +611,43 @@ var file_private_pbconnect_connect_proto_rawDesc = []byte{ 0x18, 0x0a, 0x07, 0x4b, 0x69, 0x6e, 0x64, 0x55, 0x52, 0x49, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4b, 0x69, 0x6e, 0x64, 0x55, 0x52, 0x49, 0x12, 0x1c, 0x0a, 0x09, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x52, 0x49, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x55, 0x52, 0x49, 0x12, 0x2a, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x6c, - 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x12, 0x30, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x55, 0x52, 0x49, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x55, 0x52, 0x49, 0x12, 0x3a, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x41, 0x66, - 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x41, 0x66, 0x74, 0x65, - 0x72, 0x12, 0x3c, 0x0a, 0x0b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x0b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, - 0x58, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, - 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x65, 0x72, - 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, - 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x49, 0x0a, 0x09, 0x52, 0x61, 0x66, - 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x68, + 0x72, 0x76, 0x65, 0x72, 0x55, 0x52, 0x49, 0x12, 0x3a, 0x0a, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x41, 0x66, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x41, 0x66, + 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x0b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x12, 0x58, 0x0a, 0x0e, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, + 0x65, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0e, 0x45, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x49, 0x0a, 0x09, 0x52, + 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x09, 0x52, 0x61, 0x66, + 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x92, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x09, 0x52, 0x61, 0x66, 0x74, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x42, 0x92, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x42, 0x0c, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x62, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x43, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0xca, 0x02, - 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x42, 0x0c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x62, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x43, 0xaa, 0x02, 0x21, 0x48, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x5c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/proto/private/pbconnect/connect.proto b/proto/private/pbconnect/connect.proto index 4a6d08d220fd1..afd1a4e1a4dd6 100644 --- a/proto/private/pbconnect/connect.proto +++ b/proto/private/pbconnect/connect.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; @@ -172,11 +172,6 @@ message IssuedCert { // The same URI is shared by all servers in a Consul datacenter. string ServerURI = 14; - // WorkloadIdentity is the name of the workload identity for which the cert was issued. - string WorkloadIdentity = 15; - // WorkloadIdentityURI is the cert URI value. - string WorkloadIdentityURI = 16; - // ValidAfter and ValidBefore are the validity periods for the // certificate. // mog: func-to=structs.TimeFromProto func-from=structs.TimeToProto diff --git a/proto/private/pbdemo/v1/demo.pb.binary.go b/proto/private/pbdemo/v1/demo.pb.binary.go index 649e4c5fbb8fc..45a3c34e5536e 100644 --- a/proto/private/pbdemo/v1/demo.pb.binary.go +++ b/proto/private/pbdemo/v1/demo.pb.binary.go @@ -7,26 +7,6 @@ import ( "google.golang.org/protobuf/proto" ) -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Executive) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Executive) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *RecordLabel) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *RecordLabel) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - // MarshalBinary implements encoding.BinaryMarshaler func (msg *Artist) MarshalBinary() ([]byte, error) { return proto.Marshal(msg) @@ -46,13 +26,3 @@ func (msg *Album) MarshalBinary() ([]byte, error) { func (msg *Album) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *Concept) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *Concept) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto/private/pbdemo/v1/demo.pb.go b/proto/private/pbdemo/v1/demo.pb.go index cb3e2b8cd3ff2..9ee119d76f54d 100644 --- a/proto/private/pbdemo/v1/demo.pb.go +++ b/proto/private/pbdemo/v1/demo.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: @@ -105,111 +105,6 @@ func (Genre) EnumDescriptor() ([]byte, []int) { return file_private_pbdemo_v1_demo_proto_rawDescGZIP(), []int{0} } -// Cluster scoped resource. -type Executive struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Position string `protobuf:"bytes,1,opt,name=position,proto3" json:"position,omitempty"` -} - -func (x *Executive) Reset() { - *x = Executive{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Executive) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Executive) ProtoMessage() {} - -func (x *Executive) ProtoReflect() protoreflect.Message { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Executive.ProtoReflect.Descriptor instead. -func (*Executive) Descriptor() ([]byte, []int) { - return file_private_pbdemo_v1_demo_proto_rawDescGZIP(), []int{0} -} - -func (x *Executive) GetPosition() string { - if x != nil { - return x.Position - } - return "" -} - -// Partition scoped resource. -type RecordLabel struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` -} - -func (x *RecordLabel) Reset() { - *x = RecordLabel{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RecordLabel) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RecordLabel) ProtoMessage() {} - -func (x *RecordLabel) ProtoReflect() protoreflect.Message { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RecordLabel.ProtoReflect.Descriptor instead. -func (*RecordLabel) Descriptor() ([]byte, []int) { - return file_private_pbdemo_v1_demo_proto_rawDescGZIP(), []int{1} -} - -func (x *RecordLabel) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *RecordLabel) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -// Namespace scoped resource. type Artist struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -224,7 +119,7 @@ type Artist struct { func (x *Artist) Reset() { *x = Artist{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[2] + mi := &file_private_pbdemo_v1_demo_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -237,7 +132,7 @@ func (x *Artist) String() string { func (*Artist) ProtoMessage() {} func (x *Artist) ProtoReflect() protoreflect.Message { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[2] + mi := &file_private_pbdemo_v1_demo_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -250,7 +145,7 @@ func (x *Artist) ProtoReflect() protoreflect.Message { // Deprecated: Use Artist.ProtoReflect.Descriptor instead. func (*Artist) Descriptor() ([]byte, []int) { - return file_private_pbdemo_v1_demo_proto_rawDescGZIP(), []int{2} + return file_private_pbdemo_v1_demo_proto_rawDescGZIP(), []int{0} } func (x *Artist) GetName() string { @@ -286,16 +181,16 @@ type Album struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - YearOfRelease int32 `protobuf:"varint,2,opt,name=year_of_release,json=yearOfRelease,proto3" json:"year_of_release,omitempty"` - CriticallyAcclaimed bool `protobuf:"varint,3,opt,name=critically_acclaimed,json=criticallyAcclaimed,proto3" json:"critically_acclaimed,omitempty"` - Tracks []string `protobuf:"bytes,4,rep,name=tracks,proto3" json:"tracks,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + YearOfRelease int32 `protobuf:"varint,2,opt,name=year_of_release,json=yearOfRelease,proto3" json:"year_of_release,omitempty"` + CriticallyAclaimed bool `protobuf:"varint,3,opt,name=critically_aclaimed,json=criticallyAclaimed,proto3" json:"critically_aclaimed,omitempty"` + Tracks []string `protobuf:"bytes,4,rep,name=tracks,proto3" json:"tracks,omitempty"` } func (x *Album) Reset() { *x = Album{} if protoimpl.UnsafeEnabled { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[3] + mi := &file_private_pbdemo_v1_demo_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -308,7 +203,7 @@ func (x *Album) String() string { func (*Album) ProtoMessage() {} func (x *Album) ProtoReflect() protoreflect.Message { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[3] + mi := &file_private_pbdemo_v1_demo_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -321,7 +216,7 @@ func (x *Album) ProtoReflect() protoreflect.Message { // Deprecated: Use Album.ProtoReflect.Descriptor instead. func (*Album) Descriptor() ([]byte, []int) { - return file_private_pbdemo_v1_demo_proto_rawDescGZIP(), []int{3} + return file_private_pbdemo_v1_demo_proto_rawDescGZIP(), []int{1} } func (x *Album) GetName() string { @@ -338,9 +233,9 @@ func (x *Album) GetYearOfRelease() int32 { return 0 } -func (x *Album) GetCriticallyAcclaimed() bool { +func (x *Album) GetCriticallyAclaimed() bool { if x != nil { - return x.CriticallyAcclaimed + return x.CriticallyAclaimed } return false } @@ -352,44 +247,6 @@ func (x *Album) GetTracks() []string { return nil } -type Concept struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Concept) Reset() { - *x = Concept{} - if protoimpl.UnsafeEnabled { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Concept) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Concept) ProtoMessage() {} - -func (x *Concept) ProtoReflect() protoreflect.Message { - mi := &file_private_pbdemo_v1_demo_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Concept.ProtoReflect.Descriptor instead. -func (*Concept) Descriptor() ([]byte, []int) { - return file_private_pbdemo_v1_demo_proto_rawDescGZIP(), []int{4} -} - var File_private_pbdemo_v1_demo_proto protoreflect.FileDescriptor var file_private_pbdemo_v1_demo_proto_rawDesc = []byte{ @@ -397,66 +254,59 @@ var file_private_pbdemo_v1_demo_proto_rawDesc = []byte{ 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x76, - 0x31, 0x22, 0x27, 0x0a, 0x09, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x43, 0x0a, 0x0b, 0x52, 0x65, - 0x63, 0x6f, 0x72, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0xa3, 0x01, 0x0a, 0x06, 0x41, 0x72, 0x74, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x3e, 0x0a, 0x05, 0x67, 0x65, 0x6e, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x28, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x6d, 0x6f, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x72, 0x65, 0x52, 0x05, 0x67, 0x65, 0x6e, 0x72, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x05, 0x41, 0x6c, 0x62, 0x75, 0x6d, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x79, 0x65, 0x61, 0x72, 0x5f, 0x6f, 0x66, 0x5f, 0x72, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x79, 0x65, - 0x61, 0x72, 0x4f, 0x66, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x63, - 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x6c, 0x61, 0x69, - 0x6d, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x63, 0x72, 0x69, 0x74, 0x69, - 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x41, 0x63, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x12, 0x16, + 0x31, 0x22, 0xa3, 0x01, 0x0a, 0x06, 0x41, 0x72, 0x74, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x05, 0x67, 0x65, 0x6e, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x28, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, + 0x6d, 0x6f, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x72, 0x65, 0x52, 0x05, 0x67, 0x65, 0x6e, + 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x05, 0x41, 0x6c, 0x62, 0x75, + 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x79, 0x65, 0x61, 0x72, 0x5f, 0x6f, 0x66, + 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, + 0x79, 0x65, 0x61, 0x72, 0x4f, 0x66, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x2f, 0x0a, + 0x13, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x5f, 0x61, 0x63, 0x6c, 0x61, + 0x69, 0x6d, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x72, 0x69, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x41, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, - 0x74, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x22, 0x09, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x63, 0x65, 0x70, - 0x74, 0x2a, 0xe9, 0x01, 0x0a, 0x05, 0x47, 0x65, 0x6e, 0x72, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x47, - 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x4a, 0x41, 0x5a, 0x5a, - 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x46, 0x4f, 0x4c, 0x4b, - 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x50, 0x4f, 0x50, 0x10, - 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x4c, - 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x50, 0x55, 0x4e, 0x4b, - 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x42, 0x4c, 0x55, 0x45, - 0x53, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x52, 0x5f, 0x41, - 0x4e, 0x44, 0x5f, 0x42, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, - 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x52, 0x59, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x45, 0x4e, - 0x52, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x10, 0x09, 0x12, 0x0d, 0x0a, 0x09, 0x47, 0x45, - 0x4e, 0x52, 0x45, 0x5f, 0x53, 0x4b, 0x41, 0x10, 0x0a, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x45, 0x4e, - 0x52, 0x45, 0x5f, 0x48, 0x49, 0x50, 0x5f, 0x48, 0x4f, 0x50, 0x10, 0x0b, 0x12, 0x0f, 0x0a, 0x0b, - 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x49, 0x4e, 0x44, 0x49, 0x45, 0x10, 0x0c, 0x42, 0x97, 0x02, - 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x44, 0x65, 0x6d, 0x6f, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x2f, - 0x70, 0x62, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x76, 0x31, 0x3b, 0x64, 0x65, 0x6d, 0x6f, 0x76, 0x31, - 0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x44, 0xaa, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x44, 0x65, 0x6d, 0x6f, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x21, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x44, 0x65, 0x6d, 0x6f, 0x5c, 0x56, 0x31, 0xe2, - 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x44, 0x65, 0x6d, 0x6f, - 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x44, - 0x65, 0x6d, 0x6f, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x2a, 0xe9, 0x01, 0x0a, 0x05, 0x47, 0x65, 0x6e, 0x72, 0x65, + 0x12, 0x15, 0x0a, 0x11, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x47, 0x45, 0x4e, 0x52, 0x45, + 0x5f, 0x4a, 0x41, 0x5a, 0x5a, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x47, 0x45, 0x4e, 0x52, 0x45, + 0x5f, 0x46, 0x4f, 0x4c, 0x4b, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x47, 0x45, 0x4e, 0x52, 0x45, + 0x5f, 0x50, 0x4f, 0x50, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, + 0x4d, 0x45, 0x54, 0x41, 0x4c, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x47, 0x45, 0x4e, 0x52, 0x45, + 0x5f, 0x50, 0x55, 0x4e, 0x4b, 0x10, 0x05, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x45, 0x4e, 0x52, 0x45, + 0x5f, 0x42, 0x4c, 0x55, 0x45, 0x53, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x45, 0x4e, 0x52, + 0x45, 0x5f, 0x52, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x42, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x47, + 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x52, 0x59, 0x10, 0x08, 0x12, 0x0f, + 0x0a, 0x0b, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x10, 0x09, 0x12, + 0x0d, 0x0a, 0x09, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x53, 0x4b, 0x41, 0x10, 0x0a, 0x12, 0x11, + 0x0a, 0x0d, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x48, 0x49, 0x50, 0x5f, 0x48, 0x4f, 0x50, 0x10, + 0x0b, 0x12, 0x0f, 0x0a, 0x0b, 0x47, 0x45, 0x4e, 0x52, 0x45, 0x5f, 0x49, 0x4e, 0x44, 0x49, 0x45, + 0x10, 0x0c, 0x42, 0x97, 0x02, 0x0a, 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x44, 0x65, + 0x6d, 0x6f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x62, 0x64, 0x65, 0x6d, 0x6f, 0x2f, 0x76, 0x31, 0x3b, 0x64, + 0x65, 0x6d, 0x6f, 0x76, 0x31, 0xa2, 0x02, 0x04, 0x48, 0x43, 0x49, 0x44, 0xaa, 0x02, 0x21, 0x48, + 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x44, 0x65, 0x6d, 0x6f, 0x2e, 0x56, 0x31, + 0xca, 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, + 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x44, 0x65, 0x6d, + 0x6f, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x5c, 0x44, 0x65, 0x6d, 0x6f, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, + 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x3a, 0x3a, 0x44, 0x65, 0x6d, 0x6f, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -472,14 +322,11 @@ func file_private_pbdemo_v1_demo_proto_rawDescGZIP() []byte { } var file_private_pbdemo_v1_demo_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_private_pbdemo_v1_demo_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_private_pbdemo_v1_demo_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_private_pbdemo_v1_demo_proto_goTypes = []interface{}{ - (Genre)(0), // 0: hashicorp.consul.internal.demo.v1.Genre - (*Executive)(nil), // 1: hashicorp.consul.internal.demo.v1.Executive - (*RecordLabel)(nil), // 2: hashicorp.consul.internal.demo.v1.RecordLabel - (*Artist)(nil), // 3: hashicorp.consul.internal.demo.v1.Artist - (*Album)(nil), // 4: hashicorp.consul.internal.demo.v1.Album - (*Concept)(nil), // 5: hashicorp.consul.internal.demo.v1.Concept + (Genre)(0), // 0: hashicorp.consul.internal.demo.v1.Genre + (*Artist)(nil), // 1: hashicorp.consul.internal.demo.v1.Artist + (*Album)(nil), // 2: hashicorp.consul.internal.demo.v1.Album } var file_private_pbdemo_v1_demo_proto_depIdxs = []int32{ 0, // 0: hashicorp.consul.internal.demo.v1.Artist.genre:type_name -> hashicorp.consul.internal.demo.v1.Genre @@ -497,30 +344,6 @@ func file_private_pbdemo_v1_demo_proto_init() { } if !protoimpl.UnsafeEnabled { file_private_pbdemo_v1_demo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Executive); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbdemo_v1_demo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RecordLabel); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_private_pbdemo_v1_demo_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Artist); i { case 0: return &v.state @@ -532,7 +355,7 @@ func file_private_pbdemo_v1_demo_proto_init() { return nil } } - file_private_pbdemo_v1_demo_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_private_pbdemo_v1_demo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Album); i { case 0: return &v.state @@ -544,18 +367,6 @@ func file_private_pbdemo_v1_demo_proto_init() { return nil } } - file_private_pbdemo_v1_demo_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Concept); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } type x struct{} out := protoimpl.TypeBuilder{ @@ -563,7 +374,7 @@ func file_private_pbdemo_v1_demo_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_private_pbdemo_v1_demo_proto_rawDesc, NumEnums: 1, - NumMessages: 5, + NumMessages: 2, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/private/pbdemo/v1/demo.proto b/proto/private/pbdemo/v1/demo.proto index be2f393aafde3..60ce1d0a4f507 100644 --- a/proto/private/pbdemo/v1/demo.proto +++ b/proto/private/pbdemo/v1/demo.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; @@ -7,18 +7,6 @@ syntax = "proto3"; // Consul's generic storage APIs. package hashicorp.consul.internal.demo.v1; -// Cluster scoped resource. -message Executive { - string position = 1; -} - -// Partition scoped resource. -message RecordLabel { - string name = 1; - string description = 2; -} - -// Namespace scoped resource. message Artist { string name = 1; string description = 2; @@ -45,8 +33,6 @@ enum Genre { message Album { string name = 1; int32 year_of_release = 2; - bool critically_acclaimed = 3; + bool critically_aclaimed = 3; repeated string tracks = 4; } - -message Concept {} diff --git a/proto/private/pbdemo/v2/demo.pb.go b/proto/private/pbdemo/v2/demo.pb.go index a4c52a99d6a6c..2ffed20dcc6f5 100644 --- a/proto/private/pbdemo/v2/demo.pb.go +++ b/proto/private/pbdemo/v2/demo.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbdemo/v2/demo.proto b/proto/private/pbdemo/v2/demo.proto index 546cfe6972611..b208324801c12 100644 --- a/proto/private/pbdemo/v2/demo.proto +++ b/proto/private/pbdemo/v2/demo.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pboperator/operator.pb.go b/proto/private/pboperator/operator.pb.go index e7e457bc7389e..5f264c53937af 100644 --- a/proto/private/pboperator/operator.pb.go +++ b/proto/private/pboperator/operator.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pboperator/operator.proto b/proto/private/pboperator/operator.proto index 8669f03041fd9..4f8b99358d4e9 100644 --- a/proto/private/pboperator/operator.proto +++ b/proto/private/pboperator/operator.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbpeering/peering.go b/proto/private/pbpeering/peering.go index 5759061afce24..0fec964c46b1a 100644 --- a/proto/private/pbpeering/peering.go +++ b/proto/private/pbpeering/peering.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbpeering diff --git a/proto/private/pbpeering/peering.pb.go b/proto/private/pbpeering/peering.pb.go index a0c7bd21676d2..65a75ada268f5 100644 --- a/proto/private/pbpeering/peering.pb.go +++ b/proto/private/pbpeering/peering.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: @@ -324,7 +324,7 @@ type Peering struct { PeerCAPems []string `protobuf:"bytes,8,rep,name=PeerCAPems,proto3" json:"PeerCAPems,omitempty"` // PeerServerName is the name of the remote server as it relates to TLS. PeerServerName string `protobuf:"bytes,9,opt,name=PeerServerName,proto3" json:"PeerServerName,omitempty"` - // PeerServerAddresses contains all the connection addresses for the remote peer. + // PeerServerAddresses contains all the the connection addresses for the remote peer. PeerServerAddresses []string `protobuf:"bytes,10,rep,name=PeerServerAddresses,proto3" json:"PeerServerAddresses,omitempty"` // StreamStatus contains information computed on read based on the state of the stream. // diff --git a/proto/private/pbpeering/peering.proto b/proto/private/pbpeering/peering.proto index 02fddbf17fea4..098c8f6387d56 100644 --- a/proto/private/pbpeering/peering.proto +++ b/proto/private/pbpeering/peering.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; @@ -229,7 +229,7 @@ message Peering { // PeerServerName is the name of the remote server as it relates to TLS. string PeerServerName = 9; - // PeerServerAddresses contains all the connection addresses for the remote peer. + // PeerServerAddresses contains all the the connection addresses for the remote peer. repeated string PeerServerAddresses = 10; // StreamStatus contains information computed on read based on the state of the stream. diff --git a/proto/private/pbpeering/peering_ce.go b/proto/private/pbpeering/peering_ce.go index 30890d859106f..04d1107d02c83 100644 --- a/proto/private/pbpeering/peering_ce.go +++ b/proto/private/pbpeering/peering_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package pbpeering diff --git a/proto/private/pbpeerstream/convert.go b/proto/private/pbpeerstream/convert.go index d71dc5d3b15ff..27848e0e399e4 100644 --- a/proto/private/pbpeerstream/convert.go +++ b/proto/private/pbpeerstream/convert.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbpeerstream diff --git a/proto/private/pbpeerstream/peerstream.go b/proto/private/pbpeerstream/peerstream.go index 3dc6aa6093d83..85d44785d04e8 100644 --- a/proto/private/pbpeerstream/peerstream.go +++ b/proto/private/pbpeerstream/peerstream.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbpeerstream diff --git a/proto/private/pbpeerstream/peerstream.pb.go b/proto/private/pbpeerstream/peerstream.pb.go index aeb1bdb22082f..f20496642d30f 100644 --- a/proto/private/pbpeerstream/peerstream.pb.go +++ b/proto/private/pbpeerstream/peerstream.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbpeerstream/peerstream.proto b/proto/private/pbpeerstream/peerstream.proto index b46fcf2270dba..a66e823e049e1 100644 --- a/proto/private/pbpeerstream/peerstream.proto +++ b/proto/private/pbpeerstream/peerstream.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbpeerstream/types.go b/proto/private/pbpeerstream/types.go index bf2250c64dd9c..6b55bfb425665 100644 --- a/proto/private/pbpeerstream/types.go +++ b/proto/private/pbpeerstream/types.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbpeerstream diff --git a/proto/private/pbservice/convert.go b/proto/private/pbservice/convert.go index 8396ff7c649f2..973369f03dcde 100644 --- a/proto/private/pbservice/convert.go +++ b/proto/private/pbservice/convert.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbservice diff --git a/proto/private/pbservice/convert_ce.go b/proto/private/pbservice/convert_ce.go index 444e06134c501..938495b96b772 100644 --- a/proto/private/pbservice/convert_ce.go +++ b/proto/private/pbservice/convert_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package pbservice diff --git a/proto/private/pbservice/convert_ce_test.go b/proto/private/pbservice/convert_ce_test.go index 74da8e699b3be..2367f3e73aeba 100644 --- a/proto/private/pbservice/convert_ce_test.go +++ b/proto/private/pbservice/convert_ce_test.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package pbservice diff --git a/proto/private/pbservice/convert_test.go b/proto/private/pbservice/convert_test.go index 5b3c97680ef6d..0093a76dd9fb9 100644 --- a/proto/private/pbservice/convert_test.go +++ b/proto/private/pbservice/convert_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbservice diff --git a/proto/private/pbservice/healthcheck.pb.go b/proto/private/pbservice/healthcheck.pb.go index 0392fd77455be..524d95d6663d1 100644 --- a/proto/private/pbservice/healthcheck.pb.go +++ b/proto/private/pbservice/healthcheck.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbservice/healthcheck.proto b/proto/private/pbservice/healthcheck.proto index d75a7fc7c71bc..681cfae9754ee 100644 --- a/proto/private/pbservice/healthcheck.proto +++ b/proto/private/pbservice/healthcheck.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbservice/ids.go b/proto/private/pbservice/ids.go index bac74d6f7e805..8ab248c3e8d5b 100644 --- a/proto/private/pbservice/ids.go +++ b/proto/private/pbservice/ids.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbservice diff --git a/proto/private/pbservice/ids_test.go b/proto/private/pbservice/ids_test.go index 9477bb8d9bb72..9a56604ee8c1e 100644 --- a/proto/private/pbservice/ids_test.go +++ b/proto/private/pbservice/ids_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbservice diff --git a/proto/private/pbservice/node.pb.go b/proto/private/pbservice/node.pb.go index 3d562fe31f716..7b8fa6a3345b7 100644 --- a/proto/private/pbservice/node.pb.go +++ b/proto/private/pbservice/node.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbservice/node.proto b/proto/private/pbservice/node.proto index 6b81f0b6c06d3..85e82de7082ec 100644 --- a/proto/private/pbservice/node.proto +++ b/proto/private/pbservice/node.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbservice/service.pb.go b/proto/private/pbservice/service.pb.go index 871b6a04118cd..13826aa752eaa 100644 --- a/proto/private/pbservice/service.pb.go +++ b/proto/private/pbservice/service.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbservice/service.proto b/proto/private/pbservice/service.proto index b89f1717b17c1..4573a920a6eb8 100644 --- a/proto/private/pbservice/service.proto +++ b/proto/private/pbservice/service.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbstorage/raft.pb.go b/proto/private/pbstorage/raft.pb.go index 6efa5c8f8fb10..8ae22a6aba912 100644 --- a/proto/private/pbstorage/raft.pb.go +++ b/proto/private/pbstorage/raft.pb.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbstorage/raft.proto b/proto/private/pbstorage/raft.proto index ed7954a8690e5..1dbae409e28a3 100644 --- a/proto/private/pbstorage/raft.proto +++ b/proto/private/pbstorage/raft.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 syntax = "proto3"; diff --git a/proto/private/pbsubscribe/subscribe.go b/proto/private/pbsubscribe/subscribe.go index 918c3d298078b..53b7081245364 100644 --- a/proto/private/pbsubscribe/subscribe.go +++ b/proto/private/pbsubscribe/subscribe.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package pbsubscribe diff --git a/proto/private/pbsubscribe/subscribe.pb.go b/proto/private/pbsubscribe/subscribe.pb.go index 93dcf9c21c230..f71a855107c59 100644 --- a/proto/private/pbsubscribe/subscribe.pb.go +++ b/proto/private/pbsubscribe/subscribe.pb.go @@ -1,8 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // -//Package event provides a service for subscribing to state change events. +// Package event provides a service for subscribing to state change events. // Code generated by protoc-gen-go. DO NOT EDIT. // versions: diff --git a/proto/private/pbsubscribe/subscribe.proto b/proto/private/pbsubscribe/subscribe.proto index c327c92c7f024..37124b5d02770 100644 --- a/proto/private/pbsubscribe/subscribe.proto +++ b/proto/private/pbsubscribe/subscribe.proto @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 /* Package event provides a service for subscribing to state change events. diff --git a/proto/private/prototest/golden_json.go b/proto/private/prototest/golden_json.go deleted file mode 100644 index d6b68f523d01b..0000000000000 --- a/proto/private/prototest/golden_json.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package prototest - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/proto" -) - -// ProtoToJSON will encode a protobuf into a 2-space indented, deterministic, -// pretty form of JSON suitable for use in golden file output persistence. It -// does not aim to be performant. -func ProtoToJSON(t *testing.T, pb proto.Message) string { - t.Helper() - m := protojson.MarshalOptions{ - Indent: " ", - } - gotJSON, err := m.Marshal(pb) - require.NoError(t, err) - - // protojson format is non-determinstic, so scrub it through the - // determinstic json.Marshal so 'git diff' only shows real changes - // - // https://github.com/golang/protobuf/issues/1269 - var tmp map[string]any - require.NoError(t, json.Unmarshal(gotJSON, &tmp)) - - gotJSON, err = json.MarshalIndent(&tmp, "", " ") - require.NoError(t, err) - - return string(gotJSON) -} diff --git a/proto/private/prototest/testing.go b/proto/private/prototest/testing.go index 32839a78aa809..28341012afa6d 100644 --- a/proto/private/prototest/testing.go +++ b/proto/private/prototest/testing.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package prototest @@ -13,12 +13,12 @@ type TestingT interface { Fatalf(string, ...any) } -func AssertDeepEqual(t TestingT, exp, got interface{}, opts ...cmp.Option) { +func AssertDeepEqual(t TestingT, x, y interface{}, opts ...cmp.Option) { t.Helper() opts = append(opts, protocmp.Transform()) - if diff := cmp.Diff(exp, got, opts...); diff != "" { + if diff := cmp.Diff(x, y, opts...); diff != "" { t.Fatalf("assertion failed: values are not equal\n--- expected\n+++ actual\n%v", diff) } } @@ -32,7 +32,6 @@ func AssertDeepEqual(t TestingT, exp, got interface{}, opts ...cmp.Option) { func AssertElementsMatch[V any]( t TestingT, listX, listY []V, opts ...cmp.Option, ) { - t.Helper() diff := diffElements(listX, listY, opts...) if diff != "" { t.Fatalf("assertion failed: slices do not have matching elements\n--- expected\n+++ actual\n%v", diff) @@ -101,5 +100,5 @@ func AssertContainsElement[V any](t TestingT, list []V, element V, opts ...cmp.O } } - t.Fatalf("assertion failed: list does not contain element\n--- list\n%+v\n--- element: %+v", list, element) + t.Fatalf("assertion failed: list does not contain element\n--- list\n%#v\n--- element: %#v", list, element) } diff --git a/proto/private/prototest/testing_test.go b/proto/private/prototest/testing_test.go index 2ee383baa1da3..22c1848821ddc 100644 --- a/proto/private/prototest/testing_test.go +++ b/proto/private/prototest/testing_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package prototest import ( diff --git a/sdk/.copywrite.hcl b/sdk/.copywrite.hcl deleted file mode 100644 index 34d99ba25e12e..0000000000000 --- a/sdk/.copywrite.hcl +++ /dev/null @@ -1,8 +0,0 @@ -schema_version = 1 - -project { - license = "MPL-2.0" - copyright_year = 2023 - - header_ignore = [] -} diff --git a/sdk/LICENSE b/sdk/LICENSE deleted file mode 100644 index 7c5baa45e1c29..0000000000000 --- a/sdk/LICENSE +++ /dev/null @@ -1,365 +0,0 @@ -Copyright (c) 2020 HashiCorp, Inc. - -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. - - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. - diff --git a/sdk/freeport/ephemeral_darwin.go b/sdk/freeport/ephemeral_darwin.go index 18e6b012f3c7d..5ea57d1289c3b 100644 --- a/sdk/freeport/ephemeral_darwin.go +++ b/sdk/freeport/ephemeral_darwin.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build darwin +// +build darwin package freeport diff --git a/sdk/freeport/ephemeral_darwin_test.go b/sdk/freeport/ephemeral_darwin_test.go index 5f68890d6bb6d..22f5540560b2b 100644 --- a/sdk/freeport/ephemeral_darwin_test.go +++ b/sdk/freeport/ephemeral_darwin_test.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build darwin +// +build darwin package freeport diff --git a/sdk/freeport/ephemeral_fallback.go b/sdk/freeport/ephemeral_fallback.go index 94ba3fb3c0dfd..35d0216c551f7 100644 --- a/sdk/freeport/ephemeral_fallback.go +++ b/sdk/freeport/ephemeral_fallback.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build !linux && !darwin +// +build !linux,!darwin package freeport diff --git a/sdk/freeport/ephemeral_linux.go b/sdk/freeport/ephemeral_linux.go index ea7c133b5d4a0..69449ef8d06f7 100644 --- a/sdk/freeport/ephemeral_linux.go +++ b/sdk/freeport/ephemeral_linux.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build linux +// +build linux package freeport diff --git a/sdk/freeport/ephemeral_linux_test.go b/sdk/freeport/ephemeral_linux_test.go index aa3e2de53a6ee..f5ea7e86bf735 100644 --- a/sdk/freeport/ephemeral_linux_test.go +++ b/sdk/freeport/ephemeral_linux_test.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build linux +// +build linux package freeport diff --git a/sdk/freeport/systemlimit.go b/sdk/freeport/systemlimit.go index 8d71aa8acb939..1a4258689ce28 100644 --- a/sdk/freeport/systemlimit.go +++ b/sdk/freeport/systemlimit.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build !windows +// +build !windows package freeport diff --git a/sdk/freeport/systemlimit_windows.go b/sdk/freeport/systemlimit_windows.go index a01041ae3d63d..d51ed74ad0df3 100644 --- a/sdk/freeport/systemlimit_windows.go +++ b/sdk/freeport/systemlimit_windows.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build windows +// +build windows package freeport diff --git a/sdk/iptables/iptables.go b/sdk/iptables/iptables.go index 32f089a6c9a82..5b965a6322ac1 100644 --- a/sdk/iptables/iptables.go +++ b/sdk/iptables/iptables.go @@ -149,7 +149,7 @@ func Setup(cfg Config) error { // Redirect remaining outbound traffic to Envoy. cfg.IptablesProvider.AddRule("iptables", "-t", "nat", "-A", ProxyOutputChain, "-j", ProxyOutputRedirectChain) - // We are using "insert" (-I) instead of "append" (-A) so the provided rules take precedence over default ones. + // We are using "insert" (-I) instead of "append" (-A) so the the provided rules take precedence over default ones. for _, outboundPort := range cfg.ExcludeOutboundPorts { cfg.IptablesProvider.AddRule("iptables", "-t", "nat", "-I", ProxyOutputChain, "-p", "tcp", "--dport", outboundPort, "-j", "RETURN") } diff --git a/sdk/iptables/iptables_executor_linux.go b/sdk/iptables/iptables_executor_linux.go index ad954e82552c6..b152de47cc6af 100644 --- a/sdk/iptables/iptables_executor_linux.go +++ b/sdk/iptables/iptables_executor_linux.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build linux +// +build linux package iptables diff --git a/sdk/iptables/iptables_executor_unsupported.go b/sdk/iptables/iptables_executor_unsupported.go index cdf12237011e0..bc77ddb466de7 100644 --- a/sdk/iptables/iptables_executor_unsupported.go +++ b/sdk/iptables/iptables_executor_unsupported.go @@ -2,6 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //go:build !linux +// +build !linux package iptables diff --git a/sdk/testutil/context.go b/sdk/testutil/context.go index 47ff794c96c6d..257f205aa298e 100644 --- a/sdk/testutil/context.go +++ b/sdk/testutil/context.go @@ -5,14 +5,10 @@ package testutil import ( "context" + "testing" ) -type CleanerT interface { - Helper() - Cleanup(func()) -} - -func TestContext(t CleanerT) context.Context { +func TestContext(t *testing.T) context.Context { t.Helper() ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) diff --git a/sdk/testutil/io.go b/sdk/testutil/io.go index 7b446339728b4..518b4c81eefe6 100644 --- a/sdk/testutil/io.go +++ b/sdk/testutil/io.go @@ -10,7 +10,6 @@ import ( ) var noCleanup = strings.ToLower(os.Getenv("TEST_NOCLEANUP")) == "true" -var saveSnapshot = strings.ToLower(os.Getenv("TEST_SAVE_SNAPSHOT")) == "true" // TempDir creates a temporary directory within tmpdir with the name 'testname-name'. // If the directory cannot be created t.Fatal is called. diff --git a/sdk/testutil/retry/counter.go b/sdk/testutil/retry/counter.go deleted file mode 100644 index ffd509f1a4141..0000000000000 --- a/sdk/testutil/retry/counter.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package retry - -import "time" - -// Counter repeats an operation a given number of -// times and waits between subsequent operations. -type Counter struct { - Count int - Wait time.Duration - - count int -} - -func (r *Counter) Continue() bool { - if r.count == r.Count { - return false - } - if r.count > 0 { - time.Sleep(r.Wait) - } - r.count++ - return true -} diff --git a/sdk/testutil/retry/retry.go b/sdk/testutil/retry/retry.go index af468460d592a..ce0e4b6ecd2d6 100644 --- a/sdk/testutil/retry/retry.go +++ b/sdk/testutil/retry/retry.go @@ -53,8 +53,6 @@ type R struct { // and triggers t.FailNow() done bool output []string - - cleanups []func() } func (r *R) Logf(format string, args ...interface{}) { @@ -67,41 +65,6 @@ func (r *R) Log(args ...interface{}) { func (r *R) Helper() {} -// Cleanup register a function to be run to cleanup resources that -// were allocated during the retry attempt. These functions are executed -// after a retry attempt. If they panic, it will not stop further retry -// attempts but will be cause for the overall test failure. -func (r *R) Cleanup(fn func()) { - r.cleanups = append(r.cleanups, fn) -} - -func (r *R) runCleanup() { - - // Make sure that if a cleanup function panics, - // we still run the remaining cleanup functions. - defer func() { - err := recover() - if err != nil { - r.Stop(fmt.Errorf("error when performing test cleanup: %v", err)) - } - if len(r.cleanups) > 0 { - r.runCleanup() - } - }() - - for len(r.cleanups) > 0 { - var cleanup func() - if len(r.cleanups) > 0 { - last := len(r.cleanups) - 1 - cleanup = r.cleanups[last] - r.cleanups = r.cleanups[:last] - } - if cleanup != nil { - cleanup() - } - } -} - // runFailed is a sentinel value to indicate that the func itself // didn't panic, rather that `FailNow` was called. type runFailed struct{} @@ -227,7 +190,6 @@ func run(r Retryer, t Failer, f func(r *R)) { // run f(rr), but if recover yields a runFailed value, we know // FailNow was called. func() { - defer rr.runCleanup() defer func() { if p := recover(); p != nil && p != (runFailed{}) { panic(p) @@ -254,6 +216,22 @@ func DefaultFailer() *Timer { return &Timer{Timeout: 7 * time.Second, Wait: 25 * time.Millisecond} } +// ThirtySeconds repeats an operation for thirty seconds and waits 500ms in between. +// Best for known slower operations like waiting on eventually consistent state. +func ThirtySeconds() *Timer { + return &Timer{Timeout: 30 * time.Second, Wait: 500 * time.Millisecond} +} + +// TwoSeconds repeats an operation for two seconds and waits 25ms in between. +func TwoSeconds() *Timer { + return &Timer{Timeout: 2 * time.Second, Wait: 25 * time.Millisecond} +} + +// ThreeTimes repeats an operation three times and waits 25ms in between. +func ThreeTimes() *Counter { + return &Counter{Count: 3, Wait: 25 * time.Millisecond} +} + // Retryer provides an interface for repeating operations // until they succeed or an exit condition is met. type Retryer interface { @@ -261,3 +239,47 @@ type Retryer interface { // returns false to indicate retrying should stop. Continue() bool } + +// Counter repeats an operation a given number of +// times and waits between subsequent operations. +type Counter struct { + Count int + Wait time.Duration + + count int +} + +func (r *Counter) Continue() bool { + if r.count == r.Count { + return false + } + if r.count > 0 { + time.Sleep(r.Wait) + } + r.count++ + return true +} + +// Timer repeats an operation for a given amount +// of time and waits between subsequent operations. +type Timer struct { + Timeout time.Duration + Wait time.Duration + + // stop is the timeout deadline. + // TODO: Next()? + // Set on the first invocation of Next(). + stop time.Time +} + +func (r *Timer) Continue() bool { + if r.stop.IsZero() { + r.stop = time.Now().Add(r.Timeout) + return true + } + if time.Now().After(r.stop) { + return false + } + time.Sleep(r.Wait) + return true +} diff --git a/sdk/testutil/retry/retry_test.go b/sdk/testutil/retry/retry_test.go index 77bc2d4d9f96b..1f7eda7b31338 100644 --- a/sdk/testutil/retry/retry_test.go +++ b/sdk/testutil/retry/retry_test.go @@ -128,69 +128,6 @@ func TestRunWith(t *testing.T) { }) } -func TestCleanup(t *testing.T) { - t.Run("basic", func(t *testing.T) { - ft := &fakeT{} - cleanupsExecuted := 0 - RunWith(&Counter{Count: 2, Wait: time.Millisecond}, ft, func(r *R) { - r.Cleanup(func() { - cleanupsExecuted += 1 - }) - }) - - require.Equal(t, 0, ft.fails) - require.Equal(t, 1, cleanupsExecuted) - }) - t.Run("cleanup-panic-recovery", func(t *testing.T) { - ft := &fakeT{} - cleanupsExecuted := 0 - RunWith(&Counter{Count: 2, Wait: time.Millisecond}, ft, func(r *R) { - r.Cleanup(func() { - cleanupsExecuted += 1 - }) - - r.Cleanup(func() { - cleanupsExecuted += 1 - panic(fmt.Errorf("fake test error")) - }) - - r.Cleanup(func() { - cleanupsExecuted += 1 - }) - - // test is successful but should fail due to the cleanup panicing - }) - - require.Equal(t, 3, cleanupsExecuted) - require.Equal(t, 1, ft.fails) - require.Contains(t, ft.out[0], "fake test error") - }) - - t.Run("cleanup-per-retry", func(t *testing.T) { - ft := &fakeT{} - iter := 0 - cleanupsExecuted := 0 - RunWith(&Counter{Count: 3, Wait: time.Millisecond}, ft, func(r *R) { - if cleanupsExecuted != iter { - r.Stop(fmt.Errorf("cleanups not executed between retries")) - return - } - iter += 1 - - r.Cleanup(func() { - cleanupsExecuted += 1 - }) - - r.FailNow() - }) - - require.Equal(t, 3, cleanupsExecuted) - // ensure that r.Stop hadn't been called. If it was then we would - // have log output - require.Len(t, ft.out, 0) - }) -} - type fakeT struct { fails int out []string diff --git a/sdk/testutil/retry/timer.go b/sdk/testutil/retry/timer.go deleted file mode 100644 index be4f5e92f4072..0000000000000 --- a/sdk/testutil/retry/timer.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package retry - -import "time" - -// ThirtySeconds repeats an operation for thirty seconds and waits 500ms in between. -// Best for known slower operations like waiting on eventually consistent state. -func ThirtySeconds() *Timer { - return &Timer{Timeout: 30 * time.Second, Wait: 500 * time.Millisecond} -} - -// TwoSeconds repeats an operation for two seconds and waits 25ms in between. -func TwoSeconds() *Timer { - return &Timer{Timeout: 2 * time.Second, Wait: 25 * time.Millisecond} -} - -// ThreeTimes repeats an operation three times and waits 25ms in between. -func ThreeTimes() *Counter { - return &Counter{Count: 3, Wait: 25 * time.Millisecond} -} - -// Timer repeats an operation for a given amount -// of time and waits between subsequent operations. -type Timer struct { - Timeout time.Duration - Wait time.Duration - - // stop is the timeout deadline. - // TODO: Next()? - // Set on the first invocation of Next(). - stop time.Time -} - -func (r *Timer) Continue() bool { - if r.stop.IsZero() { - r.stop = time.Now().Add(r.Timeout) - return true - } - if time.Now().After(r.stop) { - return false - } - time.Sleep(r.Wait) - return true -} diff --git a/sdk/testutil/server.go b/sdk/testutil/server.go index a9da8f372725c..a20f95123aaba 100644 --- a/sdk/testutil/server.go +++ b/sdk/testutil/server.go @@ -26,6 +26,7 @@ import ( "os/exec" "path/filepath" "runtime" + "strconv" "strings" "syscall" "testing" @@ -85,11 +86,6 @@ type Locality struct { Zone string `json:"zone"` } -// TestAutopilotConfig contains the configuration for autopilot. -type TestAutopilotConfig struct { - ServerStabilizationTime string `json:"server_stabilization_time,omitempty"` -} - // TestServerConfig is the main server configuration struct. type TestServerConfig struct { NodeName string `json:"node_name"` @@ -127,7 +123,6 @@ type TestServerConfig struct { EnableDebug bool `json:"enable_debug,omitempty"` SkipLeaveOnInt bool `json:"skip_leave_on_interrupt"` Peering *TestPeeringConfig `json:"peering,omitempty"` - Autopilot *TestAutopilotConfig `json:"autopilot,omitempty"` ReadyTimeout time.Duration `json:"-"` StopTimeout time.Duration `json:"-"` Stdout io.Writer `json:"-"` @@ -136,7 +131,6 @@ type TestServerConfig struct { ReturnPorts func() `json:"-"` Audit *TestAuditConfig `json:"audit,omitempty"` Version string `json:"version,omitempty"` - Experiments []string `json:"experiments,omitempty"` } type TestACLs struct { @@ -176,16 +170,9 @@ type ServerConfigCallback func(c *TestServerConfig) // defaultServerConfig returns a new TestServerConfig struct // with all of the listen ports incremented by one. func defaultServerConfig(t TestingTB, consulVersion *version.Version) *TestServerConfig { - var nodeID string - var err error - - if id, ok := os.LookupEnv("TEST_NODE_ID"); ok { - nodeID = id - } else { - nodeID, err = uuid.GenerateUUID() - if err != nil { - panic(err) - } + nodeID, err := uuid.GenerateUUID() + if err != nil { + panic(err) } ports := freeport.GetN(t, 7) @@ -272,7 +259,6 @@ type TestServer struct { HTTPSAddr string LANAddr string WANAddr string - ServerAddr string GRPCAddr string GRPCTLSAddr string @@ -293,29 +279,14 @@ func NewTestServerConfigT(t TestingTB, cb ServerConfigCallback) (*TestServer, er "consul or skip this test") } - var tmpdir string - - if dir, ok := os.LookupEnv("TEST_TMP_DIR"); ok { - // NOTE(CTIA): using TEST_TMP_DIR may cause conflict when NewTestServerConfigT - // is called > 1 since two agent will uses the same directory - tmpdir = dir - if _, err := os.Stat(tmpdir); os.IsNotExist(err) { - if err = os.Mkdir(tmpdir, 0750); err != nil { - return nil, errors.Wrap(err, "failed to create tempdir from env TEST_TMP_DIR") - } - } else { - t.Logf("WARNING: using tempdir that already exists %s", tmpdir) - } - } else { - prefix := "consul" - if t != nil { - // Use test name for tmpdir if available - prefix = strings.Replace(t.Name(), "/", "_", -1) - } - tmpdir, err = os.MkdirTemp("", prefix) - if err != nil { - return nil, errors.Wrap(err, "failed to create tempdir") - } + prefix := "consul" + if t != nil { + // Use test name for tmpdir if available + prefix = strings.Replace(t.Name(), "/", "_", -1) + } + tmpdir, err := os.MkdirTemp("", prefix) + if err != nil { + return nil, errors.Wrap(err, "failed to create tempdir") } consulVersion, err := findConsulVersion() @@ -323,12 +294,8 @@ func NewTestServerConfigT(t TestingTB, cb ServerConfigCallback) (*TestServer, er return nil, err } - datadir := filepath.Join(tmpdir, "data") - if _, err := os.Stat(datadir); !os.IsNotExist(err) { - t.Logf("WARNING: using a data that already exists %s", datadir) - } cfg := defaultServerConfig(t, consulVersion) - cfg.DataDir = datadir + cfg.DataDir = filepath.Join(tmpdir, "data") if cb != nil { cb(cfg) } @@ -349,7 +316,6 @@ func NewTestServerConfigT(t TestingTB, cb ServerConfigCallback) (*TestServer, er // Start the server args := []string{"agent", "-config-file", configFile} args = append(args, cfg.Args...) - t.Logf("test cmd args: consul args: %s", args) cmd := exec.Command("consul", args...) cmd.Stdout = cfg.Stdout cmd.Stderr = cfg.Stderr @@ -377,7 +343,6 @@ func NewTestServerConfigT(t TestingTB, cb ServerConfigCallback) (*TestServer, er HTTPSAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.HTTPS), LANAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.SerfLan), WANAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.SerfWan), - ServerAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.Server), GRPCAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.GRPC), GRPCTLSAddr: fmt.Sprintf("127.0.0.1:%d", cfg.Ports.GRPCTLS), @@ -414,21 +379,6 @@ func (s *TestServer) Stop() error { } if s.cmd.Process != nil { - - if saveSnapshot { - fmt.Println("Saving snapshot") - // create a snapshot prior to upgrade test - args := []string{"snapshot", "save", "-http-addr", - fmt.Sprintf("http://%s", s.HTTPAddr), filepath.Join(s.tmpdir, "backup.snap")} - fmt.Printf("Saving snapshot: consul args: %s\n", args) - cmd := exec.Command("consul", args...) - cmd.Stdout = s.Config.Stdout - cmd.Stderr = s.Config.Stderr - if err := cmd.Run(); err != nil { - return errors.Wrap(err, "failed to save a snapshot") - } - } - if runtime.GOOS == "windows" { if err := s.cmd.Process.Kill(); err != nil { return errors.Wrap(err, "failed to kill consul server") @@ -491,13 +441,13 @@ func (s *TestServer) waitForAPI() error { return nil } -// WaitForLeader waits for the Consul server's HTTP API to become available, -// and then waits for a known leader to be observed to confirm leader election -// is done. +// waitForLeader waits for the Consul server's HTTP API to become +// available, and then waits for a known leader and an index of +// 2 or more to be observed to confirm leader election is done. func (s *TestServer) WaitForLeader(t testing.TB) { retry.Run(t, func(r *retry.R) { // Query the API and check the status code. - url := s.url("/v1/status/leader") + url := s.url("/v1/catalog/nodes") resp, err := s.privilegedGet(url) if err != nil { r.Fatalf("failed http get '%s': %v", url, err) @@ -507,59 +457,17 @@ func (s *TestServer) WaitForLeader(t testing.TB) { r.Fatalf("failed OK response: %v", err) } - var leader string - dec := json.NewDecoder(resp.Body) - if err := dec.Decode(&leader); err != nil { - r.Fatal(err) - } - - // Ensure we have a leader. - if leader == "" { - r.Fatal("no leader address") + // Ensure we have a leader and a node registration. + if leader := resp.Header.Get("X-Consul-KnownLeader"); leader != "true" { + r.Fatalf("Consul leader status: %#v", leader) } - }) -} - -// WaitForVoting waits for the Consul server to become a voter in the current raft -// configuration. You probably want to adjust the ServerStablizationTime autopilot -// configuration otherwise this could take 10 seconds. -func (s *TestServer) WaitForVoting(t testing.TB) { - // don't need to fully decode the response - type raftServer struct { - ID string - Voter bool - } - type raftCfgResponse struct { - Servers []raftServer - } - - retry.Run(t, func(r *retry.R) { - // Query the API and get the current raft configuration. - url := s.url("/v1/operator/raft/configuration") - resp, err := s.privilegedGet(url) + index, err := strconv.ParseInt(resp.Header.Get("X-Consul-Index"), 10, 64) if err != nil { - r.Fatalf("failed http get '%s': %v", url, err) + r.Fatalf("bad consul index: %v", err) } - defer resp.Body.Close() - if err := s.requireOK(resp); err != nil { - r.Fatalf("failed OK response: %v", err) - } - - var cfg raftCfgResponse - dec := json.NewDecoder(resp.Body) - if err := dec.Decode(&cfg); err != nil { - r.Fatal(err) - } - - for _, srv := range cfg.Servers { - if srv.ID == s.Config.NodeID { - if srv.Voter { - return - } - break - } + if index < 2 { + r.Fatal("consul index should be at least 2") } - r.Fatalf("Server is not voting: %#v", cfg.Servers) }) } diff --git a/sdk/testutil/testlog.go b/sdk/testutil/testlog.go index 1565509aa3d2c..f0d9b9823b304 100644 --- a/sdk/testutil/testlog.go +++ b/sdk/testutil/testlog.go @@ -17,14 +17,14 @@ import ( // be used by tests to set the log level of a hclog.Logger. Defaults to // hclog.Warn if the environment variable is unset, or if the value of the // environment variable can not be matched to a log level. -var TestLogLevel = TestLogLevelWithDefault(hclog.Warn) +var TestLogLevel = testLogLevel() -func TestLogLevelWithDefault(l hclog.Level) hclog.Level { +func testLogLevel() hclog.Level { level := hclog.LevelFromString(os.Getenv("TEST_LOG_LEVEL")) if level != hclog.NoLevel { return level } - return l + return hclog.Warn } func Logger(t TestingTB) hclog.InterceptLogger { diff --git a/sentinel/evaluator.go b/sentinel/evaluator.go index fd609fff90097..d37a82704e616 100644 --- a/sentinel/evaluator.go +++ b/sentinel/evaluator.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package sentinel diff --git a/sentinel/scope.go b/sentinel/scope.go index 4a6a87e146ab3..7f2fb5d721ef5 100644 --- a/sentinel/scope.go +++ b/sentinel/scope.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package sentinel diff --git a/sentinel/sentinel_ce.go b/sentinel/sentinel_ce.go index e2c4d7fcc7bc3..fc688bcb933ec 100644 --- a/sentinel/sentinel_ce.go +++ b/sentinel/sentinel_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package sentinel diff --git a/service_os/service.go b/service_os/service.go index 8a23c093475ae..cba71b23acf92 100644 --- a/service_os/service.go +++ b/service_os/service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package service_os diff --git a/service_os/service_windows.go b/service_os/service_windows.go index 65c84c21ebe34..0ff9f2e7c9688 100644 --- a/service_os/service_windows.go +++ b/service_os/service_windows.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build windows +// +build windows package service_os diff --git a/snapshot/archive.go b/snapshot/archive.go index 38aad441bf0ab..3560e0ac2319e 100644 --- a/snapshot/archive.go +++ b/snapshot/archive.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // The archive utilities manage the internal format of a snapshot, which is a // tar file with the following contents: diff --git a/snapshot/archive_test.go b/snapshot/archive_test.go index 74148b84e8f60..d7568edb80ce8 100644 --- a/snapshot/archive_test.go +++ b/snapshot/archive_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package snapshot diff --git a/snapshot/snapshot.go b/snapshot/snapshot.go index f09f8870e3253..a1deee9153dc4 100644 --- a/snapshot/snapshot.go +++ b/snapshot/snapshot.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // snapshot manages the interactions between Consul and Raft in order to take // and restore snapshots for disaster recovery. The internal format of a diff --git a/snapshot/snapshot_test.go b/snapshot/snapshot_test.go index 4e9701360dfa9..d59061e9eab61 100644 --- a/snapshot/snapshot_test.go +++ b/snapshot/snapshot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package snapshot diff --git a/test-integ/README.md b/test-integ/README.md deleted file mode 100644 index ebc611efa2bc0..0000000000000 --- a/test-integ/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# test-integ - -Go integration tests for consul. `/test/integration` also holds integration tests; they need migrating. \ No newline at end of file diff --git a/test-integ/connect/snapshot_test.go b/test-integ/connect/snapshot_test.go deleted file mode 100644 index 469562a160748..0000000000000 --- a/test-integ/connect/snapshot_test.go +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package connect - -import ( - "fmt" - "io" - "net/http" - "net/url" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" - "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" - "github.com/hashicorp/consul/testing/deployer/topology" -) - -// Test_Snapshot_Restore_Agentless verifies consul agent can continue -// to push envoy confgi after restoring from a snapshot. -// -// - This test is to detect server agent frozen after restoring from a snapshot -// (https://github.com/hashicorp/consul/pull/18636) -// -// - This bug only appeared in agentless mode -// -// Steps: -// 1. The test spins up a one-server cluster with static-server and static-client. -// 2. A snapshot is taken and the cluster is restored from the snapshot -// 3. A new static-server replaces the old one -// 4. At the end, we assert the static-client's upstream is updated with the -// new static-server -func Test_Snapshot_Restore_Agentless(t *testing.T) { - t.Parallel() - - staticServerSID := topology.NewServiceID("static-server", "default", "default") - staticClientSID := topology.NewServiceID("static-client", "default", "default") - - clu := &topology.Config{ - Images: utils.TargetImages(), - Networks: []*topology.Network{ - {Name: "dc1"}, - }, - Clusters: []*topology.Cluster{ - { - Name: "dc1", - Nodes: []*topology.Node{ - { - Kind: topology.NodeKindServer, - // NOTE: uncomment the following lines to trigger the agent frozen bug - // Images: topology.Images{ - // ConsulEnterprise: "hashicorp/consul-enterprise:1.16.1-ent", - // }, - Name: "dc1-server1", - Addresses: []*topology.Address{ - {Network: "dc1"}, - }, - }, - { - Kind: topology.NodeKindDataplane, - Name: "dc1-client1", - Services: []*topology.Service{ - { - ID: staticServerSID, - Image: "docker.mirror.hashicorp.services/fortio/fortio", - Port: 8080, - EnvoyAdminPort: 19000, - CheckTCP: "127.0.0.1:8080", - Command: []string{ - "server", - "-http-port", "8080", - "-redirect-port", "-disabled", - }, - }, - }, - }, - { - Kind: topology.NodeKindDataplane, - Name: "dc1-client2", - Services: []*topology.Service{ - { - ID: staticClientSID, - Image: "docker.mirror.hashicorp.services/fortio/fortio", - Port: 8080, - EnvoyAdminPort: 19000, - CheckTCP: "127.0.0.1:8080", - Command: []string{ - "server", - "-http-port", "8080", - "-redirect-port", "-disabled", - }, - Upstreams: []*topology.Upstream{ - { - ID: staticServerSID, - LocalPort: 5000, - }, - }, - }, - }, - }, - // Client3 for second static-server - { - Kind: topology.NodeKindDataplane, - Name: "dc1-client3", - Disabled: true, - Services: []*topology.Service{ - { - ID: staticServerSID, - Image: "docker.mirror.hashicorp.services/fortio/fortio", - Port: 8080, - EnvoyAdminPort: 19000, - CheckTCP: "127.0.0.1:8080", - Command: []string{ - "server", - "-http-port", "8080", - "-redirect-port", "-disabled", - }, - }, - }, - }, - }, - Enterprise: utils.IsEnterprise(), - InitialConfigEntries: []api.ConfigEntry{ - &api.ProxyConfigEntry{ - Kind: api.ProxyDefaults, - Name: "global", - Config: map[string]any{ - "protocol": "http", - }, - }, - &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: "static-server", - }, - &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: "static-server", - Sources: []*api.SourceIntention{ - { - Name: "static-client", - Action: api.IntentionActionAllow, - }, - }, - }, - }, - }, - }, - } - sp := sprawltest.Launch(t, clu) - - client, err := sp.HTTPClientForCluster("dc1") - require.NoError(t, err) - - staticClient := sp.Topology().Clusters["dc1"].ServiceByID( - topology.NewNodeID("dc1-client2", "default"), - staticClientSID, - ) - staticClientAddress := fmt.Sprintf("%s:%d", staticClient.Node.LocalAddress(), staticClient.Port) - - // The following url causes the static-client's fortio server to - // fetch the ?url= param (the upstream static-server in our case). - url := fmt.Sprintf("http://%s/fortio/fetch2?url=%s", staticClientAddress, - url.QueryEscape("http://localhost:5000"), - ) - - // We retry the first request until we get 200 OK since it may take a while - // for the server to be available. - // Use a custom retry.Timer since the default one usually times out too early. - retrySendRequest := func(isSuccess bool) { - t.Log("static-client sending requests to static-server...") - retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - resp, err := client.Post(url, "text/plain", nil) - require.NoError(r, err) - defer resp.Body.Close() - - if isSuccess { - require.Equal(r, http.StatusOK, resp.StatusCode) - } else { - require.NotEqual(r, http.StatusOK, resp.StatusCode) - } - body, err := io.ReadAll(resp.Body) - require.NoError(r, err) - fmt.Println("Body: ", string(body), resp.StatusCode) - }) - } - retrySendRequest(true) - t.Log("...ok, got 200 responses") - - t.Log("Take a snapshot of the cluster and restore ...") - err = sp.SnapshotSave("dc1") - require.NoError(t, err) - - // Shutdown existing static-server - cfg := sp.Config() - cluster := cfg.Cluster("dc1") - cluster.Nodes[1].Disabled = true // client 1 -- static-server - require.NoError(t, sp.Relaunch(cfg)) - retrySendRequest(false) - - // Add a new static-server - cfg = sp.Config() - cluster = cfg.Cluster("dc1") - cluster.Nodes[3].Disabled = false // client 3 -- static-server - require.NoError(t, sp.Relaunch(cfg)) - - // Ensure the static-client connected to static-server - retrySendRequest(true) -} diff --git a/test-integ/go.mod b/test-integ/go.mod deleted file mode 100644 index d0154d7a8f711..0000000000000 --- a/test-integ/go.mod +++ /dev/null @@ -1,248 +0,0 @@ -module github.com/hashicorp/consul/test-integ - -go 1.20 - -require ( - github.com/hashicorp/consul/api v1.24.0 - github.com/hashicorp/consul/sdk v0.14.1 - github.com/hashicorp/consul/test/integration/consul-container v0.0.0-20230628201853-bdf4fad7c5a5 - github.com/hashicorp/consul/testing/deployer v0.0.0-20230811171106-4a0afb5d1373 - github.com/hashicorp/go-cleanhttp v0.5.2 - github.com/itchyny/gojq v0.12.13 - github.com/mitchellh/copystructure v1.2.0 - github.com/stretchr/testify v1.8.4 -) - -require ( - cloud.google.com/go/compute v1.20.1 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.1 // indirect - dario.cat/mergo v1.0.0 // indirect - fortio.org/dflag v1.5.2 // indirect - fortio.org/fortio v1.54.0 // indirect - fortio.org/log v1.3.0 // indirect - fortio.org/sets v1.0.2 // indirect - fortio.org/version v1.0.2 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/DataDog/datadog-go v4.8.2+incompatible // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/agext/levenshtein v1.2.3 // indirect - github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 // indirect - github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect - github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e // indirect - github.com/armon/go-metrics v0.4.1 // indirect - github.com/armon/go-radix v1.0.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect - github.com/avast/retry-go v3.0.0+incompatible // indirect - github.com/aws/aws-sdk-go v1.44.289 // indirect - github.com/benbjohnson/immutable v0.4.0 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/boltdb/bolt v1.3.1 // indirect - github.com/cenkalti/backoff/v3 v3.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect - github.com/circonus-labs/circonusllhist v0.1.3 // indirect - github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect - github.com/containerd/containerd v1.7.3 // indirect - github.com/coreos/etcd v3.3.27+incompatible // indirect - github.com/coreos/go-oidc v2.1.0+incompatible // indirect - github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect - github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect - github.com/cpuguy83/dockercfg v0.3.1 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.5+incompatible // indirect - github.com/docker/go-connections v0.4.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.10.1 // indirect - github.com/envoyproxy/go-control-plane v0.11.1 // indirect - github.com/envoyproxy/protoc-gen-validate v1.0.1 // indirect - github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/fatih/color v1.14.1 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-jose/go-jose/v3 v3.0.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/loads v0.21.2 // indirect - github.com/go-openapi/runtime v0.25.0 // indirect - github.com/go-openapi/spec v0.20.8 // indirect - github.com/go-openapi/strfmt v0.21.3 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-openapi/validate v0.22.1 // indirect - github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/btree v1.0.1 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/s2a-go v0.1.4 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.11.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect - github.com/hashicorp/consul v1.16.1 // indirect - github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 // indirect - github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 // indirect - github.com/hashicorp/consul/envoyextensions v0.4.1 // indirect - github.com/hashicorp/consul/proto-public v0.4.1 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-bexpr v0.1.2 // indirect - github.com/hashicorp/go-connlimit v0.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-memdb v1.3.4 // indirect - github.com/hashicorp/go-msgpack v1.1.5 // indirect - github.com/hashicorp/go-msgpack/v2 v2.0.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.4.5 // indirect - github.com/hashicorp/go-raftchunking v0.7.0 // indirect - github.com/hashicorp/go-retryablehttp v0.6.7 // indirect - github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 // indirect - github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect - github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // 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-syslog v1.0.0 // indirect - github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/go-version v1.2.1 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hashicorp/hcl/v2 v2.16.2 // indirect - github.com/hashicorp/hcp-scada-provider v0.2.3 // indirect - github.com/hashicorp/hcp-sdk-go v0.61.0 // indirect - github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 // indirect - github.com/hashicorp/memberlist v0.5.0 // indirect - github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 // indirect - github.com/hashicorp/raft v1.5.0 // indirect - github.com/hashicorp/raft-autopilot v0.1.6 // indirect - github.com/hashicorp/raft-boltdb/v2 v2.2.2 // indirect - github.com/hashicorp/raft-wal v0.4.1 // indirect - github.com/hashicorp/serf v0.10.1 // indirect - github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 // indirect - github.com/hashicorp/vault/api v1.8.3 // indirect - github.com/hashicorp/vault/api/auth/gcp v0.3.0 // indirect - github.com/hashicorp/vault/sdk v0.7.0 // indirect - github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect - github.com/imdario/mergo v0.3.15 // indirect - github.com/itchyny/timefmt-go v0.1.5 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.50 // indirect - github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.14.0 // indirect - github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect - github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/mitchellh/pointerstructure v1.2.1 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moby/patternmatcher v0.5.0 // indirect - github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/term v0.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/morikuni/aec v1.0.0 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/oklog/run v1.0.0 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/oklog/ulid/v2 v2.1.0 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc4 // indirect - github.com/opencontainers/runc v1.1.8 // indirect - github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect - github.com/otiai10/copy v1.10.0 // indirect - github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pierrec/lz4 v2.6.1+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.39.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - github.com/rboyer/safeio v0.2.3 // indirect - github.com/ryanuber/go-glob v1.0.0 // indirect - github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect - github.com/segmentio/fasthash v1.0.3 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect - github.com/stretchr/objx v0.5.0 // indirect - github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 // indirect - github.com/testcontainers/testcontainers-go v0.22.0 // indirect - github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/zclconf/go-cty v1.12.1 // indirect - go.etcd.io/bbolt v1.3.7 // indirect - go.mongodb.org/mongo-driver v1.11.0 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/sdk v1.16.0 // indirect - go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.9.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect - google.golang.org/api v0.126.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect - google.golang.org/grpc v1.57.2 // indirect - google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.66.2 // indirect - gopkg.in/square/go-jose.v2 v2.5.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.26.2 // indirect - k8s.io/apimachinery v0.26.2 // indirect - k8s.io/client-go v0.26.2 // indirect - k8s.io/klog/v2 v2.90.1 // indirect - k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect - k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect -) - -replace ( - github.com/hashicorp/consul => ../ - github.com/hashicorp/consul/api => ../api - github.com/hashicorp/consul/envoyextensions => ../envoyextensions - github.com/hashicorp/consul/proto-public => ../proto-public - github.com/hashicorp/consul/sdk => ../sdk - github.com/hashicorp/consul/test/integration/consul-container => ../test/integration/consul-container - github.com/hashicorp/consul/testing/deployer => ../testing/deployer -) diff --git a/test-integ/go.sum b/test-integ/go.sum deleted file mode 100644 index aee362bf63c75..0000000000000 --- a/test-integ/go.sum +++ /dev/null @@ -1,1345 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= -cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -fortio.org/assert v1.1.4 h1:Za1RaG+OjsTMpQS3J3UCvTF6wc4+IOHCz+jAOU37Y4o= -fortio.org/dflag v1.5.2 h1:F9XVRj4Qr2IbJP7BMj7XZc9wB0Q/RZ61Ool+4YPVad8= -fortio.org/dflag v1.5.2/go.mod h1:ppb/A8u+KKg+qUUYZNYuvRnXuVb8IsdHb/XGzsmjkN8= -fortio.org/fortio v1.54.0 h1:2jn8yTd6hcIEoKY4CjI0lI6XxTWVxsMYF2bMiWOmv+Y= -fortio.org/fortio v1.54.0/go.mod h1:SRaZbikL31UoAkw0On2hwpvHrQ0rRVnsAz3UGVNvMRw= -fortio.org/log v1.3.0 h1:bESPvuQGKejw7rrx41Sg3GoF+tsrB7oC08PxBs5/AM0= -fortio.org/log v1.3.0/go.mod h1:u/8/2lyczXq52aT5Nw6reD+3cR6m/EbS2jBiIYhgiTU= -fortio.org/sets v1.0.2 h1:gSWZFg9rgzl1zJfI/93lDJKBFw8WZ3Uxe3oQ5uDM4T4= -fortio.org/sets v1.0.2/go.mod h1:xVjulHr0FhlmReSymI+AhDtQ4FgjiazQ3JmuNpYFMs8= -fortio.org/version v1.0.2 h1:8NwxdX58aoeKx7T5xAPO0xlUu1Hpk42nRz5s6e6eKZ0= -fortio.org/version v1.0.2/go.mod h1:2JQp9Ax+tm6QKiGuzR5nJY63kFeANcgrZ0osoQFDVm0= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= -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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/datadog-go v4.8.2+incompatible h1:qbcKSx29aBLD+5QLvlQZlGmRMF/FfGqFLFev/1TDzRo= -github.com/DataDog/datadog-go v4.8.2+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= -github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 h1:K4N91T1+RlSlx+t2dujeDviy4ehSGVjEltluDgmeHS4= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.156/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= -github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= -github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.44.289 h1:5CVEjiHFvdiVlKPBzv0rjG4zH/21W/onT18R5AH/qx0= -github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/benbjohnson/immutable v0.4.0 h1:CTqXbEerYso8YzVPxmWxh2gnoRQbbB9X1quUC8+vGZA= -github.com/benbjohnson/immutable v0.4.0/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= -github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= -github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= -github.com/coreos/etcd v3.3.27+incompatible h1:QIudLb9KeBsE5zyYxd1mjzRSkzLg9Wf9QlRwFgd6oTA= -github.com/coreos/etcd v3.3.27+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= -github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf h1:GOPo6vn/vTN+3IwZBvXX0y5doJfSC7My0cdzelyOCsQ= -github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= -github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= -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/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= -github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= -github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= -github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ= -github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= -github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= -github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= -github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= -github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -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-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= -github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= -github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= -github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= -github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= -github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= -github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE= -github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= -github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2 h1:AtvtonGEH/fZK0XPNNBdB6swgy7Iudfx88wzyIpwqJ8= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= -github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 h1:1ZEjnveDe20yFa6lSkfdQZm5BR/b271n0MsB5R2L3us= -github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706/go.mod h1:1Cs8FlmD1BfSQXJGcFLSV5FuIx1AbJP+EJGdxosoS2g= -github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 h1:wzWurXrxfSyG1PHskIZlfuXlTSCj1Tsyatp9DtaasuY= -github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69/go.mod h1:svUZZDvotY8zTODknUePc6mZ9pX8nN0ViGwWcUSOBEA= -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-bexpr v0.1.2 h1:ijMXI4qERbzxbCnkxmfUtwMyjrrk3y+Vt0MxojNCbBs= -github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-connlimit v0.3.0 h1:oAojHGjFxUTTTA8c5XXnDqWJ2HLuWbDiBPTpWvNzvqM= -github.com/hashicorp/go-connlimit v0.3.0/go.mod h1:OUj9FGL1tPIhl/2RCfzYHrIiWj+VVPGNyVPnUX8AqS0= -github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -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.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-kms-wrapping/entropy/v2 v2.0.0/go.mod h1:xvb32K2keAc+R8DSFG2IwDcydK9DBQE+fGA5fsw6hSk= -github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= -github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= -github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4= -github.com/hashicorp/go-msgpack/v2 v2.0.0 h1:c1fiLq1LNghmLOry1ipGhvLDi+/zEoaEP2JrE1oFJ9s= -github.com/hashicorp/go-msgpack/v2 v2.0.0/go.mod h1:JIxYkkFJRDDRSoWQBSh7s9QAVThq+82iWmUpmE4jKak= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= -github.com/hashicorp/go-plugin v1.4.5 h1:oTE/oQR4eghggRg8VY7PAz3dr++VwDNBGCcOfIvHpBo= -github.com/hashicorp/go-plugin v1.4.5/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= -github.com/hashicorp/go-raftchunking v0.7.0 h1:APNMnCXmTOhumkFv/GpJIbq7HteWF7EnGZ3875lRN0Y= -github.com/hashicorp/go-raftchunking v0.7.0/go.mod h1:Dg/eBOaJzE0jYKNwNLs5IA5j0OSmL5HoCUiMy3mDmrI= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.6.7 h1:8/CAEZt/+F7kR7GevNHulKkUjLht3CPmn7egmhieNKo= -github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= -github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= -github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= -github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= -github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= -github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= -github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-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.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/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/hcl/v2 v2.16.2 h1:mpkHZh/Tv+xet3sy3F9Ld4FyI2tUpWe9x3XtPx9f1a0= -github.com/hashicorp/hcl/v2 v2.16.2/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= -github.com/hashicorp/hcp-scada-provider v0.2.3 h1:AarYR+/Pcv+cMvPdAlb92uOBmZfEH6ny4+DT+4NY2VQ= -github.com/hashicorp/hcp-scada-provider v0.2.3/go.mod h1:ZFTgGwkzNv99PLQjTsulzaCplCzOTBh0IUQsPKzrQFo= -github.com/hashicorp/hcp-sdk-go v0.61.0 h1:x4hJ8SlLI5WCE8Uzcu4q5jfdOEz/hFxfUkhAdoFdzSg= -github.com/hashicorp/hcp-sdk-go v0.61.0/go.mod h1:xP7wmWAmdMxs/7+ovH3jZn+MCDhHRj50Rn+m7JIY3Ck= -github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 h1:n9J0rwVWXDpNd5iZnwY7w4WZyq53/rROeI7OVvLW8Ok= -github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= -github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= -github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 h1:kBpVVl1sl3MaSrs97e0+pDQhSrqJv9gVbSUrPpVfl1w= -github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0/go.mod h1:6pdNz0vo0mF0GvhwDG56O3N18qBrAz/XRIcfINfTbwo= -github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= -github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= -github.com/hashicorp/raft v1.3.11/go.mod h1:J8naEwc6XaaCfts7+28whSeRvCqTd6e20BlCU3LtEO4= -github.com/hashicorp/raft v1.5.0 h1:uNs9EfJ4FwiArZRxxfd/dQ5d33nV31/CdCHArH89hT8= -github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M= -github.com/hashicorp/raft-autopilot v0.1.6 h1:C1q3RNF2FfXNZfHWbvVAu0QixaQK8K5pX4O5lh+9z4I= -github.com/hashicorp/raft-autopilot v0.1.6/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw= -github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= -github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qRd6nFJYYS6Iqnc/8HcUmko2/2Gw8qTFEmxDLii6W5I= -github.com/hashicorp/raft-boltdb v0.0.0-20220329195025-15018e9b97e0 h1:CO8dBMLH6dvE1jTn/30ZZw3iuPsNfajshWoJTnVc5cc= -github.com/hashicorp/raft-boltdb/v2 v2.2.2 h1:rlkPtOllgIcKLxVT4nutqlTH2NRFn+tO1wwZk/4Dxqw= -github.com/hashicorp/raft-boltdb/v2 v2.2.2/go.mod h1:N8YgaZgNJLpZC+h+by7vDu5rzsRgONThTEeUS3zWbfY= -github.com/hashicorp/raft-wal v0.4.1 h1:aU8XZ6x8R9BAIB/83Z1dTDtXvDVmv9YVYeXxd/1QBSA= -github.com/hashicorp/raft-wal v0.4.1/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= -github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= -github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 h1:O6tNk0s/arubLUbLeCyaRs5xGo9VwmbQazISY/BfPK4= -github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0/go.mod h1:We3fJplmALwK1VpjwrLuXr/4QCQHYMdnXLHmLUU6Ntg= -github.com/hashicorp/vault/api v1.8.0/go.mod h1:uJrw6D3y9Rv7hhmS17JQC50jbPDAZdjZoTtrCCxxs7E= -github.com/hashicorp/vault/api v1.8.3 h1:cHQOLcMhBR+aVI0HzhPxO62w2+gJhIrKguQNONPzu6o= -github.com/hashicorp/vault/api v1.8.3/go.mod h1:4g/9lj9lmuJQMtT6CmVMHC5FW1yENaVv+Nv4ZfG8fAg= -github.com/hashicorp/vault/api/auth/gcp v0.3.0 h1:taum+3pCmOXnNgEKHlQbmgXmKw5daWHk7YJrLPP/w8g= -github.com/hashicorp/vault/api/auth/gcp v0.3.0/go.mod h1:gnNBFOASYUaFunedTHOzdir7vKcHL3skWBUzEn263bo= -github.com/hashicorp/vault/sdk v0.6.0/go.mod h1:+DRpzoXIdMvKc88R4qxr+edwy/RvH5QK8itmxLiDHLc= -github.com/hashicorp/vault/sdk v0.7.0 h1:2pQRO40R1etpKkia5fb4kjrdYMx3BHklPxl1pxpxDHg= -github.com/hashicorp/vault/sdk v0.7.0/go.mod h1:KyfArJkhooyba7gYCKSq8v66QdqJmnbAxtV/OX1+JTs= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU= -github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4= -github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= -github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= -github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= -github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU= -github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -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 v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= -github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= -github.com/moby/patternmatcher v0.5.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/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= -github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= -github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= -github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= -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-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= -github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.1.8 h1:zICRlc+C1XzivLc3nzE+cbJV4LIi8tib6YG0MqC6OqA= -github.com/opencontainers/runc v1.1.8/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= -github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU= -github.com/otiai10/copy v1.10.0 h1:znyI7l134wNg/wDktoVQPxPkgvhDfGCYUasey+h0rDQ= -github.com/otiai10/copy v1.10.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= -github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= -github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= -github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/rboyer/safeio v0.2.3 h1:gUybicx1kp8nuM4vO0GA5xTBX58/OBd8MQuErBfDxP8= -github.com/rboyer/safeio v0.2.3/go.mod h1:d7RMmt7utQBJZ4B7f0H/cU/EdZibQAU1Y8NWepK2dS8= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= -github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= -github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify 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= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI= -github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI= -github.com/testcontainers/testcontainers-go v0.22.0 h1:hOK4NzNu82VZcKEB1aP9LO1xYssVFMvlfeuDW9JMmV0= -github.com/testcontainers/testcontainers-go v0.22.0/go.mod h1:k0YiPa26xJCRUbUkYqy5rY6NGvSbVCeUBXCvucscBR4= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= -github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= -github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -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/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= -github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= -go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= -go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -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-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= -google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e h1:xIXmWJ303kJCuogpj0bHq+dcjcZHU+XFyc1I0Yl9cRg= -google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= -google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU= -google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= -google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= -google.golang.org/grpc v1.57.2 h1:uw37EN34aMFFXB2QPW7Tq6tdTbind1GpRxw5aOX3a5k= -google.golang.org/grpc v1.57.2/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.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.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= -k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= -k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= -k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= -k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= -k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= -k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/test-integ/peering_commontopo/README.md b/test-integ/peering_commontopo/README.md deleted file mode 100644 index 96466bb29b86f..0000000000000 --- a/test-integ/peering_commontopo/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# CONSUL PEERING COMMON TOPOLOGY TESTS - -These peering tests all use a `commonTopo` (read: "common topology") to enable sharing a deployment of a Consul. Sharing a deployment of Consul cuts down on setup time. - -To run these tests, you will need to have docker installed. Next, make sure that you have all the required consul containers built: - -``` -make test-compat-integ-setup -``` - -## Non-Shared CommonTopo Tests - -The tests in question are designed in a manner that modifies the topology. As a result, it is not possible to share the testing environment across these tests. - -## Shared CommonTopo Tests - -The tests in question are designed in a manner that does not modify the topology in any way that would interfere with other tests. As a result, it is possible to share the testing environment across these tests. - -To run all consul peering tests with no shared topology, run the following command: - -``` -cd /path/to/peering_commontopo -go test -timeout=10m -v -no-share-topo . -``` - -To run all peering tests with shared topology only: - -``` -cd /path/to/peering_commontopo -go test -timeout=10m -run '^TestSuitesOnSharedTopo' -v . -``` - -To run individual peering topology tests: - -``` -cd /path/to/peering_commontopo -go test -timeout=10m -run '^TestSuiteExample' -v -no-share-topo . -``` - -## Local Development and Testing - -If writing tests for peering with no shared topology, this recommendation does not apply. The following methods below not necessarily need to be implmented. For shared topology tests, all the methods in the `sharedTopoSuite` interface must be implemented. - -- `testName()` prepends the test suite name to each test in the test suite. -- `setup()` phase must ensure that any resources added to the topology cannot interfere with other tests. Principally by prefixing. -- `test()` phase must be "passive" and not mutate the topology in any way that would interfere with other tests. - -Common topology peering tests are defined in the [test-integ/peering_commontopo/](/test-integ/peering_commontopo/) directory and new peering integration tests should always be added to this location. Adding integration tests that does not modify the topology should always start by invoking - -```go -runShareableSuites(t, testSuiteExample) -``` - -else - -```go -func TestSuiteExample(t *testing.T) { - ct := NewCommonTopo(t) - s := &testSuiteExample{} - s.setup(t, ct) - ct.Launch(t) - s.test(t, ct) -} -``` - -Some of these tests *do* mutate in their `test()` phase, and while they use `commonTopo` for the purpose of code sharing, they are not included in the "shared topo" tests in `sharedtopology_test.go`. diff --git a/test-integ/peering_commontopo/ac1_basic_test.go b/test-integ/peering_commontopo/ac1_basic_test.go deleted file mode 100644 index 85aaee4e6b55b..0000000000000 --- a/test-integ/peering_commontopo/ac1_basic_test.go +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - "testing" - - "github.com/hashicorp/consul/testing/deployer/topology" - - "github.com/hashicorp/consul/api" -) - -type ac1BasicSuite struct { - // inputs - DC string - Peer string - - // test points - sidServerHTTP topology.ServiceID - sidServerTCP topology.ServiceID - nodeServerHTTP topology.NodeID - nodeServerTCP topology.NodeID - - // 1.1 - sidClientTCP topology.ServiceID - nodeClientTCP topology.NodeID - - // 1.2 - sidClientHTTP topology.ServiceID - nodeClientHTTP topology.NodeID - - upstreamHTTP *topology.Upstream - upstreamTCP *topology.Upstream -} - -var ac1BasicSuites []sharedTopoSuite = []sharedTopoSuite{ - &ac1BasicSuite{DC: "dc1", Peer: "dc2"}, - &ac1BasicSuite{DC: "dc2", Peer: "dc1"}, -} - -func TestAC1Basic(t *testing.T) { - runShareableSuites(t, ac1BasicSuites) -} - -func (s *ac1BasicSuite) testName() string { - return fmt.Sprintf("ac1 basic %s->%s", s.DC, s.Peer) -} - -// creates clients in s.DC and servers in s.Peer -func (s *ac1BasicSuite) setup(t *testing.T, ct *commonTopo) { - clu := ct.ClusterByDatacenter(t, s.DC) - peerClu := ct.ClusterByDatacenter(t, s.Peer) - - partition := "default" - peer := LocalPeerName(peerClu, "default") - cluPeerName := LocalPeerName(clu, "default") - const prefix = "ac1-" - - tcpServerSID := topology.ServiceID{ - Name: prefix + "server-tcp", - Partition: partition, - } - httpServerSID := topology.ServiceID{ - Name: prefix + "server-http", - Partition: partition, - } - upstreamHTTP := &topology.Upstream{ - ID: topology.ServiceID{ - Name: httpServerSID.Name, - Partition: partition, - }, - LocalPort: 5001, - Peer: peer, - } - upstreamTCP := &topology.Upstream{ - ID: topology.ServiceID{ - Name: tcpServerSID.Name, - Partition: partition, - }, - LocalPort: 5000, - Peer: peer, - } - - // Make clients which have server upstreams - setupClientServiceAndConfigs := func(protocol string) (serviceExt, *topology.Node) { - sid := topology.ServiceID{ - Name: prefix + "client-" + protocol, - Partition: partition, - } - svc := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - sid, - func(s *topology.Service) { - s.Upstreams = []*topology.Upstream{ - upstreamTCP, - upstreamHTTP, - } - }, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: sid.Name, - Partition: ConfigEntryPartition(sid.Partition), - Protocol: protocol, - UpstreamConfig: &api.UpstreamConfiguration{ - Defaults: &api.UpstreamConfig{ - MeshGateway: api.MeshGatewayConfig{ - Mode: api.MeshGatewayModeLocal, - }, - }, - }, - }, - } - - node := ct.AddServiceNode(clu, svc) - - return svc, node - } - tcpClient, tcpClientNode := setupClientServiceAndConfigs("tcp") - httpClient, httpClientNode := setupClientServiceAndConfigs("http") - - httpServer := serviceExt{ - Service: NewFortioServiceWithDefaults( - peerClu.Datacenter, - httpServerSID, - nil, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: httpServerSID.Name, - Partition: ConfigEntryPartition(httpServerSID.Partition), - Protocol: "http", - }, - Exports: []api.ServiceConsumer{{Peer: cluPeerName}}, - Intentions: &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: httpServerSID.Name, - Partition: ConfigEntryPartition(httpServerSID.Partition), - Sources: []*api.SourceIntention{ - { - Name: tcpClient.ID.Name, - Peer: cluPeerName, - Action: api.IntentionActionAllow, - }, - { - Name: httpClient.ID.Name, - Peer: cluPeerName, - Action: api.IntentionActionAllow, - }, - }, - }, - } - tcpServer := serviceExt{ - Service: NewFortioServiceWithDefaults( - peerClu.Datacenter, - tcpServerSID, - nil, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: tcpServerSID.Name, - Partition: ConfigEntryPartition(tcpServerSID.Partition), - Protocol: "tcp", - }, - Exports: []api.ServiceConsumer{{Peer: cluPeerName}}, - Intentions: &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: tcpServerSID.Name, - Partition: ConfigEntryPartition(tcpServerSID.Partition), - Sources: []*api.SourceIntention{ - { - Name: tcpClient.ID.Name, - Peer: cluPeerName, - Action: api.IntentionActionAllow, - }, - { - Name: httpClient.ID.Name, - Peer: cluPeerName, - Action: api.IntentionActionAllow, - }, - }, - }, - } - - httpServerNode := ct.AddServiceNode(peerClu, httpServer) - tcpServerNode := ct.AddServiceNode(peerClu, tcpServer) - - s.sidClientHTTP = httpClient.ID - s.nodeClientHTTP = httpClientNode.ID() - s.sidClientTCP = tcpClient.ID - s.nodeClientTCP = tcpClientNode.ID() - s.upstreamHTTP = upstreamHTTP - s.upstreamTCP = upstreamTCP - - // these are references in Peer - s.sidServerHTTP = httpServerSID - s.nodeServerHTTP = httpServerNode.ID() - s.sidServerTCP = tcpServerSID - s.nodeServerTCP = tcpServerNode.ID() -} - -// implements https://docs.google.com/document/d/1Fs3gNMhCqE4zVNMFcbzf02ZrB0kxxtJpI2h905oKhrs/edit#heading=h.wtzvyryyb56v -func (s *ac1BasicSuite) test(t *testing.T, ct *commonTopo) { - dc := ct.Sprawl.Topology().Clusters[s.DC] - peer := ct.Sprawl.Topology().Clusters[s.Peer] - ac := s - - // refresh this from Topology - svcClientTCP := dc.ServiceByID( - ac.nodeClientTCP, - ac.sidClientTCP, - ) - svcClientHTTP := dc.ServiceByID( - ac.nodeClientHTTP, - ac.sidClientHTTP, - ) - // our ac has the node/sid for server in the peer DC - svcServerHTTP := peer.ServiceByID( - ac.nodeServerHTTP, - ac.sidServerHTTP, - ) - svcServerTCP := peer.ServiceByID( - ac.nodeServerTCP, - ac.sidServerTCP, - ) - - // preconditions - // these could be done parallel with each other, but complexity - // probably not worth the speed boost - ct.Assert.HealthyWithPeer(t, dc.Name, svcServerHTTP.ID, LocalPeerName(peer, "default")) - ct.Assert.HealthyWithPeer(t, dc.Name, svcServerTCP.ID, LocalPeerName(peer, "default")) - ct.Assert.UpstreamEndpointHealthy(t, svcClientTCP, ac.upstreamTCP) - ct.Assert.UpstreamEndpointHealthy(t, svcClientTCP, ac.upstreamHTTP) - - tcs := []struct { - acSub int - proto string - svc *topology.Service - }{ - {1, "tcp", svcClientTCP}, - {2, "http", svcClientHTTP}, - } - for _, tc := range tcs { - tc := tc - t.Run(fmt.Sprintf("1.%d. %s in A can call HTTP upstream", tc.acSub, tc.proto), func(t *testing.T) { - t.Parallel() - ct.Assert.FortioFetch2HeaderEcho(t, tc.svc, ac.upstreamHTTP) - }) - t.Run(fmt.Sprintf("1.%d. %s in A can call TCP upstream", tc.acSub, tc.proto), func(t *testing.T) { - t.Parallel() - ct.Assert.FortioFetch2HeaderEcho(t, tc.svc, ac.upstreamTCP) - }) - t.Run(fmt.Sprintf("1.%d. via %s in A, FORTIO_NAME of HTTP upstream", tc.acSub, tc.proto), func(t *testing.T) { - t.Parallel() - ct.Assert.FortioFetch2FortioName(t, - tc.svc, - ac.upstreamHTTP, - peer.Name, - svcServerHTTP.ID, - ) - }) - t.Run(fmt.Sprintf("1.%d. via %s in A, FORTIO_NAME of TCP upstream", tc.acSub, tc.proto), func(t *testing.T) { - t.Parallel() - ct.Assert.FortioFetch2FortioName(t, - tc.svc, - ac.upstreamTCP, - peer.Name, - svcServerTCP.ID, - ) - }) - } -} diff --git a/test-integ/peering_commontopo/ac2_disco_chain_test.go b/test-integ/peering_commontopo/ac2_disco_chain_test.go deleted file mode 100644 index 448ab2840bfea..0000000000000 --- a/test-integ/peering_commontopo/ac2_disco_chain_test.go +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - "testing" - - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" -) - -type ac2DiscoChainSuite struct { - DC string - Peer string - - clientSID topology.ServiceID -} - -var ac2DiscoChainSuites []sharedTopoSuite = []sharedTopoSuite{ - &ac2DiscoChainSuite{DC: "dc1", Peer: "dc2"}, - &ac2DiscoChainSuite{DC: "dc2", Peer: "dc1"}, -} - -func TestAC2DiscoChain(t *testing.T) { - runShareableSuites(t, ac2DiscoChainSuites) -} - -func (s *ac2DiscoChainSuite) testName() string { - return fmt.Sprintf("ac2 disco chain %s->%s", s.DC, s.Peer) -} - -func (s *ac2DiscoChainSuite) setup(t *testing.T, ct *commonTopo) { - clu := ct.ClusterByDatacenter(t, s.DC) - peerClu := ct.ClusterByDatacenter(t, s.Peer) - partition := "default" - peer := LocalPeerName(peerClu, "default") - - // Make an HTTP server with discovery chain config entries - server := NewFortioServiceWithDefaults( - clu.Datacenter, - topology.ServiceID{ - Name: "ac2-disco-chain-svc", - Partition: partition, - }, - nil, - ) - ct.ExportService(clu, partition, - api.ExportedService{ - Name: server.ID.Name, - Consumers: []api.ServiceConsumer{ - { - Peer: peer, - }, - }, - }, - ) - - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", - }, - &api.ServiceSplitterConfigEntry{ - Kind: api.ServiceSplitter, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Splits: []api.ServiceSplit{ - { - Weight: 100.0, - ResponseHeaders: &api.HTTPHeaderModifiers{ - Add: map[string]string{ - "X-Split": "test", - }, - }, - }, - }, - }, - ) - ct.AddServiceNode(clu, serviceExt{Service: server}) - - // Define server as upstream for client - upstream := &topology.Upstream{ - ID: topology.ServiceID{ - Name: server.ID.Name, - Partition: partition, // TODO: iterate over all possible partitions - }, - // TODO: we need to expose this on 0.0.0.0 so we can check it - // through our forward proxy. not realistic IMO - LocalAddress: "0.0.0.0", - LocalPort: 5000, - Peer: peer, - } - - // Make client which will dial server - clientSID := topology.ServiceID{ - Name: "ac2-client", - Partition: partition, - } - client := NewFortioServiceWithDefaults( - clu.Datacenter, - clientSID, - func(s *topology.Service) { - s.Upstreams = []*topology.Upstream{ - upstream, - } - }, - ) - ct.ExportService(clu, partition, - api.ExportedService{ - Name: client.ID.Name, - Consumers: []api.ServiceConsumer{ - { - Peer: peer, - }, - }, - }, - ) - ct.AddServiceNode(clu, serviceExt{Service: client}) - - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: client.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", - UpstreamConfig: &api.UpstreamConfiguration{ - Defaults: &api.UpstreamConfig{ - MeshGateway: api.MeshGatewayConfig{ - Mode: api.MeshGatewayModeLocal, - }, - }, - }, - }, - ) - - // Add intention allowing client to call server - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Sources: []*api.SourceIntention{ - { - Name: client.ID.Name, - Peer: peer, - Action: api.IntentionActionAllow, - }, - }, - }, - ) - - s.clientSID = clientSID -} - -func (s *ac2DiscoChainSuite) test(t *testing.T, ct *commonTopo) { - dc := ct.Sprawl.Topology().Clusters[s.DC] - - svcs := dc.ServicesByID(s.clientSID) - require.Len(t, svcs, 1, "expected exactly one client in datacenter") - - client := svcs[0] - require.Len(t, client.Upstreams, 1, "expected exactly one upstream for client") - u := client.Upstreams[0] - - t.Run("peered upstream exists in catalog", func(t *testing.T) { - t.Parallel() - ct.Assert.CatalogServiceExists(t, s.DC, u.ID.Name, &api.QueryOptions{ - Peer: u.Peer, - }) - }) - - t.Run("peered upstream endpoint status is healthy", func(t *testing.T) { - t.Parallel() - ct.Assert.UpstreamEndpointStatus(t, client, peerClusterPrefix(u), "HEALTHY", 1) - }) - - t.Run("response contains header injected by splitter", func(t *testing.T) { - t.Parallel() - // TODO: not sure we should call u.LocalPort? it's not realistic from a security - // standpoint. prefer the fortio fetch2 stuff myself - ct.Assert.HTTPServiceEchoesResHeader(t, client, u.LocalPort, "", - map[string]string{ - "X-Split": "test", - }, - ) - }) -} - -// For reference see consul/xds/clusters.go: -// -// func (s *ResourceGenerator) getTargetClusterName -// -// and connect/sni.go -func peerClusterPrefix(u *topology.Upstream) string { - if u.Peer == "" { - panic("upstream is not from a peer") - } - u.ID.Normalize() - return u.ID.Name + "." + u.ID.Namespace + "." + u.Peer + ".external" -} diff --git a/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go b/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go deleted file mode 100644 index 586103c111272..0000000000000 --- a/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "encoding/json" - "fmt" - "net/http" - "net/url" - "testing" - "time" - - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/go-cleanhttp" - "github.com/itchyny/gojq" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" -) - -var ac3SvcDefaultsSuites []sharedTopoSuite = []sharedTopoSuite{ - &ac3SvcDefaultsSuite{DC: "dc1", Peer: "dc2"}, - &ac3SvcDefaultsSuite{DC: "dc2", Peer: "dc1"}, -} - -func TestAC3SvcDefaults(t *testing.T) { - runShareableSuites(t, ac3SvcDefaultsSuites) -} - -type ac3SvcDefaultsSuite struct { - // inputs - DC string - Peer string - - // test points - sidServer topology.ServiceID - nodeServer topology.NodeID - sidClient topology.ServiceID - nodeClient topology.NodeID - - upstream *topology.Upstream -} - -func (s *ac3SvcDefaultsSuite) testName() string { - return fmt.Sprintf("ac3 service defaults upstreams %s->%s", s.DC, s.Peer) -} - -// creates clients in s.DC and servers in s.Peer -func (s *ac3SvcDefaultsSuite) setup(t *testing.T, ct *commonTopo) { - clu := ct.ClusterByDatacenter(t, s.DC) - peerClu := ct.ClusterByDatacenter(t, s.Peer) - - partition := "default" - peer := LocalPeerName(peerClu, "default") - cluPeerName := LocalPeerName(clu, "default") - - serverSID := topology.ServiceID{ - Name: "ac3-server", - Partition: partition, - } - upstream := &topology.Upstream{ - ID: topology.ServiceID{ - Name: serverSID.Name, - Partition: partition, - }, - LocalPort: 5001, - Peer: peer, - } - - sid := topology.ServiceID{ - Name: "ac3-client", - Partition: partition, - } - client := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - sid, - func(s *topology.Service) { - s.Upstreams = []*topology.Upstream{ - upstream, - } - }, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: sid.Name, - Partition: ConfigEntryPartition(sid.Partition), - Protocol: "http", - UpstreamConfig: &api.UpstreamConfiguration{ - Overrides: []*api.UpstreamConfig{ - { - Name: upstream.ID.Name, - Namespace: upstream.ID.Namespace, - Peer: peer, - PassiveHealthCheck: &api.PassiveHealthCheck{ - MaxFailures: 1, - Interval: 10 * time.Minute, - }, - }, - }, - Defaults: &api.UpstreamConfig{ - MeshGateway: api.MeshGatewayConfig{ - Mode: api.MeshGatewayModeLocal, - }, - }, - }, - }, - } - - clientNode := ct.AddServiceNode(clu, client) - - server := serviceExt{ - Service: NewFortioServiceWithDefaults( - peerClu.Datacenter, - serverSID, - nil, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: serverSID.Name, - Partition: ConfigEntryPartition(serverSID.Partition), - Protocol: "http", - }, - Exports: []api.ServiceConsumer{{Peer: cluPeerName}}, - Intentions: &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: serverSID.Name, - Partition: ConfigEntryPartition(serverSID.Partition), - Sources: []*api.SourceIntention{ - { - Name: client.ID.Name, - Peer: cluPeerName, - Action: api.IntentionActionAllow, - }, - }, - }, - } - - serverNode := ct.AddServiceNode(peerClu, server) - - s.sidClient = client.ID - s.nodeClient = clientNode.ID() - s.upstream = upstream - - // these are references in Peer - s.sidServer = serverSID - s.nodeServer = serverNode.ID() -} - -// make two requests to upstream via client's fetch2 with status= -// the first time, it should return nonceStatus -// the second time, we expect the upstream to have been removed from the envoy cluster, -// and thereby get some other 5xx -func (s *ac3SvcDefaultsSuite) test(t *testing.T, ct *commonTopo) { - dc := ct.Sprawl.Topology().Clusters[s.DC] - peer := ct.Sprawl.Topology().Clusters[s.Peer] - - // refresh this from Topology - svcClient := dc.ServiceByID( - s.nodeClient, - s.sidClient, - ) - // our ac has the node/sid for server in the peer DC - svcServer := peer.ServiceByID( - s.nodeServer, - s.sidServer, - ) - - // preconditions - // these could be done parallel with each other, but complexity - // probably not worth the speed boost - ct.Assert.HealthyWithPeer(t, dc.Name, svcServer.ID, LocalPeerName(peer, "default")) - ct.Assert.UpstreamEndpointHealthy(t, svcClient, s.upstream) - // TODO: we need to let the upstream start serving properly before we do this. if it - // isn't ready and returns a 5xx (which it will do if it's not up yet!), it will stick - // in a down state for PassiveHealthCheck.Interval - time.Sleep(30 * time.Second) - ct.Assert.FortioFetch2HeaderEcho(t, svcClient, s.upstream) - - // TODO: use proxied HTTP client - client := cleanhttp.DefaultClient() - // TODO: what is default? namespace? partition? - clusterName := fmt.Sprintf("%s.default.%s.external", s.upstream.ID.Name, s.upstream.Peer) - nonceStatus := http.StatusInsufficientStorage - url507 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", svcClient.ExposedPort, - url.QueryEscape(fmt.Sprintf("http://localhost:%d/?status=%d", s.upstream.LocalPort, nonceStatus)), - ) - - // we only make this call once - req, err := http.NewRequest(http.MethodGet, url507, nil) - require.NoError(t, err) - res, err := client.Do(req) - require.NoError(t, err) - defer res.Body.Close() - require.Equal(t, nonceStatus, res.StatusCode) - - // this is a modified version of assertEnvoyUpstreamHealthy - envoyAddr := fmt.Sprintf("localhost:%d", svcClient.ExposedEnvoyAdminPort) - retry.RunWith(&retry.Timer{Timeout: 30 * time.Second, Wait: 500 * time.Millisecond}, t, func(r *retry.R) { - // BOOKMARK: avoid libassert, but we need to resurrect this method in asserter first - clusters, statusCode, err := libassert.GetEnvoyOutputWithClient(client, envoyAddr, "clusters", map[string]string{"format": "json"}) - if err != nil { - r.Fatal("could not fetch envoy clusters") - } - require.Equal(r, 200, statusCode) - - filter := fmt.Sprintf( - `.cluster_statuses[] - | select(.name|contains("%s")) - | [.host_statuses[].health_status.failed_outlier_check] - |.[0]`, - clusterName) - result, err := jqOne(clusters, filter) - require.NoErrorf(r, err, "could not found cluster name %q: %v \n%s", clusterName, err, clusters) - - resultAsBool, ok := result.(bool) - require.True(r, ok) - require.True(r, resultAsBool) - }) - - url200 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", svcClient.ExposedPort, - url.QueryEscape(fmt.Sprintf("http://localhost:%d/", s.upstream.LocalPort)), - ) - retry.RunWith(&retry.Timer{Timeout: time.Minute * 1, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - req, err := http.NewRequest(http.MethodGet, url200, nil) - require.NoError(r, err) - res, err := client.Do(req) - require.NoError(r, err) - defer res.Body.Close() - require.True(r, res.StatusCode >= 500 && res.StatusCode < 600 && res.StatusCode != nonceStatus) - }) -} - -// Executes the JQ filter against the given JSON string. -// Iff there is one result, return that. -func jqOne(config, filter string) (interface{}, error) { - query, err := gojq.Parse(filter) - if err != nil { - return nil, err - } - - var m interface{} - err = json.Unmarshal([]byte(config), &m) - if err != nil { - return nil, err - } - - iter := query.Run(m) - result := []interface{}{} - for { - v, ok := iter.Next() - if !ok { - break - } - if err, ok := v.(error); ok { - return nil, err - } - result = append(result, v) - } - if len(result) != 1 { - return nil, fmt.Errorf("required result of len 1, but is %d: %v", len(result), result) - } - return result[0], nil -} diff --git a/test-integ/peering_commontopo/ac4_proxy_defaults_test.go b/test-integ/peering_commontopo/ac4_proxy_defaults_test.go deleted file mode 100644 index c413820c6f2b7..0000000000000 --- a/test-integ/peering_commontopo/ac4_proxy_defaults_test.go +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - "net/http" - "net/url" - "testing" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/go-cleanhttp" - "github.com/stretchr/testify/require" -) - -type ac4ProxyDefaultsSuite struct { - DC string - Peer string - - nodeClient topology.NodeID - nodeServer topology.NodeID - - serverSID topology.ServiceID - clientSID topology.ServiceID - upstream *topology.Upstream -} - -var ac4ProxyDefaultsSuites []sharedTopoSuite = []sharedTopoSuite{ - &ac4ProxyDefaultsSuite{DC: "dc1", Peer: "dc2"}, - &ac4ProxyDefaultsSuite{DC: "dc2", Peer: "dc1"}, -} - -func TestAC4ProxyDefaults(t *testing.T) { - runShareableSuites(t, ac4ProxyDefaultsSuites) -} - -func (s *ac4ProxyDefaultsSuite) testName() string { - return fmt.Sprintf("ac4 proxy defaults %s->%s", s.DC, s.Peer) -} - -// creates clients in s.DC and servers in s.Peer -func (s *ac4ProxyDefaultsSuite) setup(t *testing.T, ct *commonTopo) { - clu := ct.ClusterByDatacenter(t, s.DC) - peerClu := ct.ClusterByDatacenter(t, s.Peer) - - partition := "default" - peer := LocalPeerName(peerClu, "default") - cluPeerName := LocalPeerName(clu, "default") - - serverSID := topology.ServiceID{ - Name: "ac4-server-http", - Partition: partition, - } - // Define server as upstream for client - upstream := &topology.Upstream{ - ID: serverSID, - LocalPort: 5000, - Peer: peer, - } - - // Make client which will dial server - clientSID := topology.ServiceID{ - Name: "ac4-http-client", - Partition: partition, - } - client := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - clientSID, - func(s *topology.Service) { - s.Upstreams = []*topology.Upstream{ - upstream, - } - }, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: clientSID.Name, - Partition: ConfigEntryPartition(clientSID.Partition), - Protocol: "http", - UpstreamConfig: &api.UpstreamConfiguration{ - Defaults: &api.UpstreamConfig{ - MeshGateway: api.MeshGatewayConfig{ - Mode: api.MeshGatewayModeLocal, - }, - }, - }, - }, - } - clientNode := ct.AddServiceNode(clu, client) - - server := serviceExt{ - Service: NewFortioServiceWithDefaults( - peerClu.Datacenter, - serverSID, - nil, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: serverSID.Name, - Partition: ConfigEntryPartition(serverSID.Partition), - Protocol: "http", - }, - Exports: []api.ServiceConsumer{{Peer: cluPeerName}}, - Intentions: &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: serverSID.Name, - Partition: ConfigEntryPartition(serverSID.Partition), - Sources: []*api.SourceIntention{ - { - Name: client.ID.Name, - Peer: cluPeerName, - Action: api.IntentionActionAllow, - }, - }, - }, - } - - peerClu.InitialConfigEntries = append(peerClu.InitialConfigEntries, - &api.ProxyConfigEntry{ - Kind: api.ProxyDefaults, - Name: api.ProxyConfigGlobal, - Partition: ConfigEntryPartition(server.ID.Partition), - Config: map[string]interface{}{ - "protocol": "http", - "local_request_timeout_ms": 500, - }, - MeshGateway: api.MeshGatewayConfig{ - Mode: api.MeshGatewayModeLocal, - }, - }, - ) - - serverNode := ct.AddServiceNode(peerClu, server) - - s.clientSID = clientSID - s.serverSID = serverSID - s.nodeServer = serverNode.ID() - s.nodeClient = clientNode.ID() - s.upstream = upstream -} - -func (s *ac4ProxyDefaultsSuite) test(t *testing.T, ct *commonTopo) { - var client *topology.Service - - dc := ct.Sprawl.Topology().Clusters[s.DC] - peer := ct.Sprawl.Topology().Clusters[s.Peer] - - clientSVC := dc.ServiceByID( - s.nodeClient, - s.clientSID, - ) - serverSVC := peer.ServiceByID( - s.nodeServer, - s.serverSID, - ) - - // preconditions check - ct.Assert.HealthyWithPeer(t, dc.Name, serverSVC.ID, LocalPeerName(peer, "default")) - ct.Assert.UpstreamEndpointHealthy(t, clientSVC, s.upstream) - ct.Assert.FortioFetch2HeaderEcho(t, clientSVC, s.upstream) - - t.Run("Validate services exist in catalog", func(t *testing.T) { - dcSvcs := dc.ServicesByID(s.clientSID) - require.Len(t, dcSvcs, 1, "expected exactly one client") - client = dcSvcs[0] - require.Len(t, client.Upstreams, 1, "expected exactly one upstream for client") - - server := dc.ServicesByID(s.serverSID) - require.Len(t, server, 1, "expected exactly one server") - require.Len(t, server[0].Upstreams, 0, "expected no upstream for server") - }) - - t.Run("peered upstream exists in catalog", func(t *testing.T) { - ct.Assert.CatalogServiceExists(t, s.DC, s.upstream.ID.Name, &api.QueryOptions{ - Peer: s.upstream.Peer, - }) - }) - - t.Run("HTTP service fails due to connection timeout", func(t *testing.T) { - url504 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", client.ExposedPort, - url.QueryEscape(fmt.Sprintf("http://localhost:%d/?delay=1000ms", s.upstream.LocalPort)), - ) - - url200 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", client.ExposedPort, - url.QueryEscape(fmt.Sprintf("http://localhost:%d/", s.upstream.LocalPort)), - ) - - // validate request timeout error where service has 1000ms response delay and - // proxy default is set to local_request_timeout_ms: 500ms - // return 504 - httpClient := cleanhttp.DefaultClient() - req, err := http.NewRequest(http.MethodGet, url504, nil) - require.NoError(t, err) - - res, err := httpClient.Do(req) - require.NoError(t, err) - - defer res.Body.Close() - require.Equal(t, http.StatusGatewayTimeout, res.StatusCode) - - // validate successful GET request where service has no response delay and - // proxy default is set to local_request_timeout_ms: 500ms - // return 200 - req, err = http.NewRequest(http.MethodGet, url200, nil) - require.NoError(t, err) - - res, err = httpClient.Do(req) - require.NoError(t, err) - - defer res.Body.Close() - require.Equal(t, http.StatusOK, res.StatusCode) - }) -} diff --git a/test-integ/peering_commontopo/ac5_1_no_svc_mesh_test.go b/test-integ/peering_commontopo/ac5_1_no_svc_mesh_test.go deleted file mode 100644 index d564261ed878e..0000000000000 --- a/test-integ/peering_commontopo/ac5_1_no_svc_mesh_test.go +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - - "testing" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" -) - -type ac5_1NoSvcMeshSuite struct { - DC string - Peer string - - serverSID topology.ServiceID - clientSID topology.ServiceID -} - -var ( - ac5_1NoSvcMeshSuites []sharedTopoSuite = []sharedTopoSuite{ - &ac5_1NoSvcMeshSuite{DC: "dc1", Peer: "dc2"}, - &ac5_1NoSvcMeshSuite{DC: "dc2", Peer: "dc1"}, - } -) - -func TestAC5ServiceMeshDisabledSuite(t *testing.T) { - runShareableSuites(t, ac5_1NoSvcMeshSuites) -} - -func (s *ac5_1NoSvcMeshSuite) testName() string { - return fmt.Sprintf("ac5.1 no service mesh %s->%s", s.DC, s.Peer) -} - -// creates clients in s.DC and servers in s.Peer -func (s *ac5_1NoSvcMeshSuite) setup(t *testing.T, ct *commonTopo) { - clu := ct.ClusterByDatacenter(t, s.DC) - peerClu := ct.ClusterByDatacenter(t, s.Peer) - - // TODO: handle all partitions - partition := "default" - peer := LocalPeerName(peerClu, partition) - - serverSID := topology.ServiceID{ - Name: "ac5-server-http", - Partition: partition, - } - - // Make client which will dial server - clientSID := topology.ServiceID{ - Name: "ac5-http-client", - Partition: partition, - } - - // disable service mesh for client in s.DC - client := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - clientSID, - func(s *topology.Service) { - s.EnvoyAdminPort = 0 - s.DisableServiceMesh = true - }, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: clientSID.Name, - Partition: ConfigEntryPartition(clientSID.Partition), - Protocol: "http", - }, - Exports: []api.ServiceConsumer{{Peer: peer}}, - } - ct.AddServiceNode(clu, client) - - server := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - serverSID, - nil, - ), - Exports: []api.ServiceConsumer{{Peer: peer}}, - } - - ct.AddServiceNode(clu, server) - - s.clientSID = clientSID - s.serverSID = serverSID -} - -func (s *ac5_1NoSvcMeshSuite) test(t *testing.T, ct *commonTopo) { - dc := ct.Sprawl.Topology().Clusters[s.DC] - peer := ct.Sprawl.Topology().Clusters[s.Peer] - cl := ct.APIClientForCluster(t, dc) - peerName := LocalPeerName(peer, "default") - - s.testServiceHealthInCatalog(t, ct, cl, peerName) - s.testProxyDisabledInDC2(t, cl, peerName) -} - -func (s *ac5_1NoSvcMeshSuite) testServiceHealthInCatalog(t *testing.T, _ *commonTopo, cl *api.Client, peer string) { - t.Run("validate service health in catalog", func(t *testing.T) { - libassert.CatalogServiceExists(t, cl, s.clientSID.Name, &api.QueryOptions{ - Peer: peer, - }) - require.NotEqual(t, s.serverSID.Name, s.Peer) - assertServiceHealth(t, cl, s.serverSID.Name, 1) - }) -} - -func (s *ac5_1NoSvcMeshSuite) testProxyDisabledInDC2(t *testing.T, cl *api.Client, peer string) { - t.Run("service mesh is disabled", func(t *testing.T) { - var ( - services map[string][]string - err error - expected = fmt.Sprintf("%s-sidecar-proxy", s.clientSID.Name) - ) - retry.Run(t, func(r *retry.R) { - services, _, err = cl.Catalog().Services(&api.QueryOptions{ - Peer: peer, - }) - require.NoError(r, err, "error reading service data") - require.Greater(r, len(services), 0, "did not find service(s) in catalog") - }) - require.NotContains(t, services, expected, fmt.Sprintf("error: should not create proxy for service: %s", services)) - }) -} diff --git a/test-integ/peering_commontopo/ac5_2_pq_failover_test.go b/test-integ/peering_commontopo/ac5_2_pq_failover_test.go deleted file mode 100644 index 3bf8c9be9ac8b..0000000000000 --- a/test-integ/peering_commontopo/ac5_2_pq_failover_test.go +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - "time" - - "testing" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" -) - -// 1. Setup: put health service instances in each of the 3 clusters and create the PQ in one of them -// 2. Execute the PQ: Validate that failover count == 0 and that the pq results come from the local cluster -// 3. Register a failing TTL health check with the agent managing the service instance in the local cluster -// 4. Execute the PQ: Validate that failover count == 1 and that the pq results come from the first failover target peer -// 5. Register a failing TTL health check with the agent managing the service instance in the first failover peer -// 6. Execute the PQ: Validate that failover count == 2 and that the pq results come from the second failover target -// 7. Delete failing health check from step 5 -// 8. Repeat step 4 -// 9. Delete failing health check from step 3 -// 10. Repeat step 2 -type ac5_2PQFailoverSuite struct { - clientSID topology.ServiceID - serverSID topology.ServiceID - nodeServer topology.NodeID -} - -var ac5_2Context = make(map[nodeKey]ac5_2PQFailoverSuite) - -func TestAC5PreparedQueryFailover(t *testing.T) { - ct := NewCommonTopo(t) - s := &ac5_2PQFailoverSuite{} - s.setup(t, ct) - ct.Launch(t) - s.test(t, ct) -} - -func (s *ac5_2PQFailoverSuite) setup(t *testing.T, ct *commonTopo) { - s.setupDC(ct, ct.DC1, ct.DC2) - s.setupDC(ct, ct.DC2, ct.DC1) - s.setupDC3(ct, ct.DC3, ct.DC1, ct.DC2) -} - -func (s *ac5_2PQFailoverSuite) setupDC(ct *commonTopo, clu, peerClu *topology.Cluster) { - // TODO: handle all partitions - partition := "default" - peer := LocalPeerName(peerClu, partition) - - serverSID := topology.ServiceID{ - Name: "ac5-server-http", - Partition: partition, - } - - clientSID := topology.ServiceID{ - Name: "ac5-client-http", - Partition: partition, - } - - client := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - clientSID, - func(s *topology.Service) { - s.EnvoyAdminPort = 0 - s.DisableServiceMesh = true - }, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: clientSID.Name, - Partition: ConfigEntryPartition(clientSID.Partition), - Protocol: "http", - }, - Exports: []api.ServiceConsumer{{Peer: peer}}, - } - - ct.AddServiceNode(clu, client) - - server := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - serverSID, - func(s *topology.Service) { - s.EnvoyAdminPort = 0 - s.DisableServiceMesh = true - }, - ), - Exports: []api.ServiceConsumer{{Peer: peer}}, - } - serverNode := ct.AddServiceNode(clu, server) - - ac5_2Context[nodeKey{clu.Datacenter, partition}] = ac5_2PQFailoverSuite{ - clientSID: clientSID, - serverSID: serverSID, - nodeServer: serverNode.ID(), - } -} - -func (s *ac5_2PQFailoverSuite) setupDC3(ct *commonTopo, clu, peer1, peer2 *topology.Cluster) { - var ( - peers []string - partition = "default" - ) - peers = append(peers, LocalPeerName(peer1, partition), LocalPeerName(peer2, partition)) - - serverSID := topology.ServiceID{ - Name: "ac5-server-http", - Partition: partition, - } - - clientSID := topology.ServiceID{ - Name: "ac5-client-http", - Partition: partition, - } - - // disable service mesh for client in DC3 - client := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - clientSID, - func(s *topology.Service) { - s.EnvoyAdminPort = 0 - s.DisableServiceMesh = true - }, - ), - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: clientSID.Name, - Partition: ConfigEntryPartition(clientSID.Partition), - Protocol: "http", - }, - Exports: func() []api.ServiceConsumer { - var consumers []api.ServiceConsumer - for _, peer := range peers { - consumers = append(consumers, api.ServiceConsumer{ - Peer: peer, - }) - } - return consumers - }(), - } - - ct.AddServiceNode(clu, client) - - server := serviceExt{ - Service: NewFortioServiceWithDefaults( - clu.Datacenter, - serverSID, - func(s *topology.Service) { - s.EnvoyAdminPort = 0 - s.DisableServiceMesh = true - }, - ), - Exports: func() []api.ServiceConsumer { - var consumers []api.ServiceConsumer - for _, peer := range peers { - consumers = append(consumers, api.ServiceConsumer{ - Peer: peer, - }) - } - return consumers - }(), - } - - serverNode := ct.AddServiceNode(clu, server) - - ac5_2Context[nodeKey{clu.Datacenter, partition}] = ac5_2PQFailoverSuite{ - clientSID: clientSID, - serverSID: serverSID, - nodeServer: serverNode.ID(), - } -} - -func (s *ac5_2PQFailoverSuite) createPreparedQuery(t *testing.T, ct *commonTopo, c *api.Client, serviceName, partition string) (*api.PreparedQueryDefinition, *api.PreparedQuery) { - var ( - peers []string - err error - ) - peers = append(peers, LocalPeerName(ct.DC2, partition), LocalPeerName(ct.DC3, partition)) - - def := &api.PreparedQueryDefinition{ - Name: "ac5-prepared-query", - Service: api.ServiceQuery{ - Service: serviceName, - Partition: ConfigEntryPartition(partition), - OnlyPassing: true, - Failover: api.QueryFailoverOptions{ - Targets: func() []api.QueryFailoverTarget { - var queryFailoverTargets []api.QueryFailoverTarget - for _, peer := range peers { - queryFailoverTargets = append(queryFailoverTargets, api.QueryFailoverTarget{ - Peer: peer, - }) - } - return queryFailoverTargets - }(), - }, - }, - } - - query := c.PreparedQuery() - def.ID, _, err = query.Create(def, nil) - require.NoError(t, err, "error creating prepared query in cluster") - - return def, query -} - -func (s *ac5_2PQFailoverSuite) test(t *testing.T, ct *commonTopo) { - partition := "default" - dc1 := ct.Sprawl.Topology().Clusters[ct.DC1.Name] - dc2 := ct.Sprawl.Topology().Clusters[ct.DC2.Name] - dc3 := ct.Sprawl.Topology().Clusters[ct.DC3.Name] - - type testcase struct { - cluster *topology.Cluster - peer *topology.Cluster - targetCluster *topology.Cluster - } - tcs := []testcase{ - { - cluster: dc1, - peer: dc2, - targetCluster: dc3, - }, - } - for _, tc := range tcs { - client := ct.APIClientForCluster(t, tc.cluster) - - t.Run(fmt.Sprintf("%#v", tc), func(t *testing.T) { - svc := ac5_2Context[nodeKey{tc.cluster.Name, partition}] - require.NotNil(t, svc.serverSID.Name, "expected service name to not be nil") - require.NotNil(t, svc.nodeServer, "expected node server to not be nil") - - assertServiceHealth(t, client, svc.serverSID.Name, 1) - def, _ := s.createPreparedQuery(t, ct, client, svc.serverSID.Name, partition) - s.testPreparedQueryZeroFailover(t, client, def, tc.cluster) - s.testPreparedQuerySingleFailover(t, ct, client, def, tc.cluster, tc.peer, partition) - s.testPreparedQueryTwoFailovers(t, ct, client, def, tc.cluster, tc.peer, tc.targetCluster, partition) - - // delete failing health check in peer cluster & validate single failover - s.testPQSingleFailover(t, ct, client, def, tc.cluster, tc.peer, partition) - // delete failing health check in cluster & validate zero failover - s.testPQZeroFailover(t, ct, client, def, tc.cluster, tc.peer, partition) - }) - } -} - -func (s *ac5_2PQFailoverSuite) testPreparedQueryZeroFailover(t *testing.T, cl *api.Client, def *api.PreparedQueryDefinition, cluster *topology.Cluster) { - t.Run(fmt.Sprintf("prepared query should not failover %s", cluster.Name), func(t *testing.T) { - - // Validate prepared query exists in cluster - queryDef, _, err := cl.PreparedQuery().Get(def.ID, nil) - require.NoError(t, err) - require.Len(t, queryDef, 1, "expected 1 prepared query") - require.Equal(t, 2, len(queryDef[0].Service.Failover.Targets), "expected 2 prepared query failover targets to dc2 and dc3") - - retry.RunWith(&retry.Timer{Timeout: 10 * time.Second, Wait: 500 * time.Millisecond}, t, func(r *retry.R) { - queryResult, _, err := cl.PreparedQuery().Execute(def.ID, nil) - require.NoError(r, err) - - // expected outcome should show 0 failover - require.Equal(r, 0, queryResult.Failovers, "expected 0 prepared query failover") - require.Equal(r, cluster.Name, queryResult.Nodes[0].Node.Datacenter, "pq results should come from the local cluster") - }) - }) -} - -func (s *ac5_2PQFailoverSuite) testPreparedQuerySingleFailover(t *testing.T, ct *commonTopo, cl *api.Client, def *api.PreparedQueryDefinition, cluster, peerClu *topology.Cluster, partition string) { - t.Run(fmt.Sprintf("prepared query with single failover %s", cluster.Name), func(t *testing.T) { - cfg := ct.Sprawl.Config() - svc := ac5_2Context[nodeKey{cluster.Name, partition}] - - nodeCfg := DisableNode(t, cfg, cluster.Name, svc.nodeServer) - require.NoError(t, ct.Sprawl.Relaunch(nodeCfg)) - - // assert server health status - assertServiceHealth(t, cl, svc.serverSID.Name, 0) - - // Validate prepared query exists in cluster - queryDef, _, err := cl.PreparedQuery().Get(def.ID, nil) - require.NoError(t, err) - require.Len(t, queryDef, 1, "expected 1 prepared query") - - pqFailoverTargets := queryDef[0].Service.Failover.Targets - require.Len(t, pqFailoverTargets, 2, "expected 2 prepared query failover targets to dc2 and dc3") - - retry.RunWith(&retry.Timer{Timeout: 10 * time.Second, Wait: 500 * time.Millisecond}, t, func(r *retry.R) { - queryResult, _, err := cl.PreparedQuery().Execute(def.ID, nil) - require.NoError(r, err) - - require.Equal(r, 1, queryResult.Failovers, "expected 1 prepared query failover") - require.Equal(r, peerClu.Name, queryResult.Nodes[0].Node.Datacenter, fmt.Sprintf("the pq results should originate from peer clu %s", peerClu.Name)) - require.Equal(r, pqFailoverTargets[0].Peer, queryResult.Nodes[0].Checks[0].PeerName, - fmt.Sprintf("pq results should come from the first failover target peer %s", pqFailoverTargets[0].Peer)) - }) - }) -} - -func (s *ac5_2PQFailoverSuite) testPreparedQueryTwoFailovers(t *testing.T, ct *commonTopo, cl *api.Client, def *api.PreparedQueryDefinition, cluster, peerClu, targetCluster *topology.Cluster, partition string) { - t.Run(fmt.Sprintf("prepared query with two failovers %s", cluster.Name), func(t *testing.T) { - cfg := ct.Sprawl.Config() - - svc := ac5_2Context[nodeKey{peerClu.Name, partition}] - - cfg = DisableNode(t, cfg, peerClu.Name, svc.nodeServer) - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - - // assert server health status - assertServiceHealth(t, cl, ac5_2Context[nodeKey{cluster.Name, partition}].serverSID.Name, 0) // cluster: failing - assertServiceHealth(t, cl, svc.serverSID.Name, 0) // peer cluster: failing - - queryDef, _, err := cl.PreparedQuery().Get(def.ID, nil) - require.NoError(t, err) - require.Len(t, queryDef, 1, "expected 1 prepared query") - - pqFailoverTargets := queryDef[0].Service.Failover.Targets - require.Len(t, pqFailoverTargets, 2, "expected 2 prepared query failover targets to dc2 and dc3") - - retry.RunWith(&retry.Timer{Timeout: 10 * time.Second, Wait: 500 * time.Millisecond}, t, func(r *retry.R) { - queryResult, _, err := cl.PreparedQuery().Execute(def.ID, nil) - require.NoError(r, err) - require.Equal(r, 2, queryResult.Failovers, "expected 2 prepared query failover") - - require.Equal(r, targetCluster.Name, queryResult.Nodes[0].Node.Datacenter, fmt.Sprintf("the pq results should originate from cluster %s", targetCluster.Name)) - require.Equal(r, pqFailoverTargets[1].Peer, queryResult.Nodes[0].Checks[0].PeerName, - fmt.Sprintf("pq results should come from the second failover target peer %s", pqFailoverTargets[1].Peer)) - }) - }) -} - -func (s *ac5_2PQFailoverSuite) testPQSingleFailover(t *testing.T, ct *commonTopo, cl *api.Client, def *api.PreparedQueryDefinition, cluster, peerClu *topology.Cluster, partition string) { - t.Run(fmt.Sprintf("delete failing health check in %s and validate single failover %s", peerClu.Name, cluster.Name), func(t *testing.T) { - cfg := ct.Sprawl.Config() - - svc := ac5_2Context[nodeKey{peerClu.Name, partition}] - - cfg = EnableNode(t, cfg, peerClu.Name, svc.nodeServer) - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - - queryDef, _, err := cl.PreparedQuery().Get(def.ID, nil) - require.NoError(t, err) - - pqFailoverTargets := queryDef[0].Service.Failover.Targets - require.Len(t, pqFailoverTargets, 2, "expected 2 prepared query failover targets to dc2 and dc3") - - retry.RunWith(&retry.Timer{Timeout: 10 * time.Second, Wait: 500 * time.Millisecond}, t, func(r *retry.R) { - queryResult, _, err := cl.PreparedQuery().Execute(def.ID, nil) - require.NoError(r, err) - require.Equal(r, 1, queryResult.Failovers, "expected 1 prepared query failover") - - require.Equal(r, peerClu.Name, queryResult.Nodes[0].Node.Datacenter, fmt.Sprintf("the pq results should originate from cluster %s", peerClu.Name)) - require.Equal(r, pqFailoverTargets[0].Peer, queryResult.Nodes[0].Checks[0].PeerName, - fmt.Sprintf("pq results should come from the second failover target peer %s", pqFailoverTargets[0].Peer)) - }) - }) -} - -func (s *ac5_2PQFailoverSuite) testPQZeroFailover(t *testing.T, ct *commonTopo, cl *api.Client, def *api.PreparedQueryDefinition, cluster, _ *topology.Cluster, partition string) { - t.Run(fmt.Sprintf("delete failing health check in %s and validate zero failover %s", cluster.Name, cluster.Name), func(t *testing.T) { - cfg := ct.Sprawl.Config() - - svc := ac5_2Context[nodeKey{cluster.Name, partition}] - - cfg = EnableNode(t, cfg, cluster.Name, svc.nodeServer) - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - - // assert server health status - assertServiceHealth(t, cl, ac5_2Context[nodeKey{cluster.Name, partition}].serverSID.Name, 1) // cluster: passing - assertServiceHealth(t, cl, svc.serverSID.Name, 1) // peer cluster: passing - - queryDef, _, err := cl.PreparedQuery().Get(def.ID, nil) - require.NoError(t, err) - - pqFailoverTargets := queryDef[0].Service.Failover.Targets - require.Len(t, pqFailoverTargets, 2, "expected 2 prepared query failover targets to dc2 and dc3") - - retry.RunWith(&retry.Timer{Timeout: 10 * time.Second, Wait: 500 * time.Millisecond}, t, func(r *retry.R) { - queryResult, _, err := cl.PreparedQuery().Execute(def.ID, nil) - require.NoError(r, err) - // expected outcome should show 0 failover - require.Equal(r, 0, queryResult.Failovers, "expected 0 prepared query failover") - require.Equal(r, cluster.Name, queryResult.Nodes[0].Node.Datacenter, "pq results should come from the local cluster") - }) - }) -} - -// assertServiceHealth checks that a service health status before running tests -func assertServiceHealth(t *testing.T, cl *api.Client, serverSVC string, count int) { - t.Helper() - t.Log("validate service health in catalog") - retry.RunWith(&retry.Timer{Timeout: time.Second * 20, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - svcs, _, err := cl.Health().Service( - serverSVC, - "", - true, - nil, - ) - require.NoError(r, err) - require.Equal(r, count, len(svcs)) - }) -} diff --git a/test-integ/peering_commontopo/ac6_failovers_test.go b/test-integ/peering_commontopo/ac6_failovers_test.go deleted file mode 100644 index fe3cd181b2032..0000000000000 --- a/test-integ/peering_commontopo/ac6_failovers_test.go +++ /dev/null @@ -1,432 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - "testing" - - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" -) - -// note: unlike other *Suite structs that are per-peering direction, -// this one is special and does all directions itself, because the -// setup is not exactly symmetrical -type ac6FailoversSuite struct { - ac6 map[nodeKey]ac6FailoversContext -} -type ac6FailoversContext struct { - clientSID topology.ServiceID - serverSID topology.ServiceID - - // used to remove the node and trigger failover - serverNode topology.NodeID -} -type nodeKey struct { - dc string - partition string -} - -// Note: this test cannot share topo -func TestAC6Failovers(t *testing.T) { - ct := NewCommonTopo(t) - s := &ac6FailoversSuite{} - s.setup(t, ct) - ct.Launch(t) - s.test(t, ct) -} - -func (s *ac6FailoversSuite) setup(t *testing.T, ct *commonTopo) { - // TODO: update setups to loop through a cluster's partitions+namespaces internally - s.setupAC6Failovers(ct, ct.DC1, ct.DC2) - s.setupAC6Failovers(ct, ct.DC2, ct.DC1) - s.setupAC6FailoversDC3(ct, ct.DC3, ct.DC1, ct.DC2) -} - -// dc1 is peered with dc2 and dc3. -// dc1 has an ac6-client in "default" and "part1" partitions (only default in CE). -// ac6-client has a single upstream ac6-failover-svc in its respective partition^. -// -// ac6-failover-svc has the following failovers: -// - peer-dc2-default -// - peer-dc2-part1 (not in CE) -// - peer-dc3-default -// -// This setup is mirrored from dc2->dc1 as well -// (both dcs have dc3 as the last failover target) -// -// ^NOTE: There are no cross-partition upstreams because MeshGatewayMode = local -// and failover information gets stripped out by the mesh gateways so we -// can't test failovers. -func (s *ac6FailoversSuite) setupAC6Failovers(ct *commonTopo, clu, peerClu *topology.Cluster) { - for _, part := range clu.Partitions { - partition := part.Name - - // There is a peering per partition in the peered cluster - var peers []string - for _, peerPart := range peerClu.Partitions { - peers = append(peers, LocalPeerName(peerClu, peerPart.Name)) - } - - // Make an HTTP server with various failover targets - serverSID := topology.ServiceID{ - Name: "ac6-failover-svc", - Partition: partition, - } - server := NewFortioServiceWithDefaults( - clu.Datacenter, - serverSID, - nil, - ) - // Export to all known peers - ct.ExportService(clu, partition, - api.ExportedService{ - Name: server.ID.Name, - Consumers: func() []api.ServiceConsumer { - var consumers []api.ServiceConsumer - for _, peer := range peers { - consumers = append(consumers, api.ServiceConsumer{ - Peer: peer, - }) - } - return consumers - }(), - }, - ) - serverNode := ct.AddServiceNode(clu, serviceExt{Service: server}) - - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", - }, - &api.ServiceResolverConfigEntry{ - Kind: api.ServiceResolver, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Failover: map[string]api.ServiceResolverFailover{ - "*": { - Targets: func() []api.ServiceResolverFailoverTarget { - // Make a failover target for every partition in the peer cluster - var targets []api.ServiceResolverFailoverTarget - for _, peer := range peers { - targets = append(targets, api.ServiceResolverFailoverTarget{ - Peer: peer, - }) - } - // Just hard code default partition for dc3, since the exhaustive - // testing will be done against dc2. - targets = append(targets, api.ServiceResolverFailoverTarget{ - Peer: "peer-dc3-default", - }) - return targets - }(), - }, - }, - }, - ) - - // Make client which will dial server - clientSID := topology.ServiceID{ - Name: "ac6-client", - Partition: partition, - } - client := NewFortioServiceWithDefaults( - clu.Datacenter, - clientSID, - func(s *topology.Service) { - // Upstream per partition - s.Upstreams = []*topology.Upstream{ - { - ID: topology.ServiceID{ - Name: server.ID.Name, - Partition: part.Name, - }, - LocalPort: 5000, - // exposed so we can hit it directly - // TODO: we shouldn't do this; it's not realistic - LocalAddress: "0.0.0.0", - }, - } - }, - ) - ct.ExportService(clu, partition, - api.ExportedService{ - Name: client.ID.Name, - Consumers: func() []api.ServiceConsumer { - var consumers []api.ServiceConsumer - // Export to each peer - for _, peer := range peers { - consumers = append(consumers, api.ServiceConsumer{ - Peer: peer, - }) - } - return consumers - }(), - }, - ) - ct.AddServiceNode(clu, serviceExt{Service: client}) - - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: client.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", - }, - ) - - // Add intention allowing local and peered clients to call server - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - // SourceIntention for local client and peered clients - Sources: func() []*api.SourceIntention { - ixns := []*api.SourceIntention{ - { - Name: client.ID.Name, - Partition: ConfigEntryPartition(part.Name), - Action: api.IntentionActionAllow, - }, - } - for _, peer := range peers { - ixns = append(ixns, &api.SourceIntention{ - Name: client.ID.Name, - Peer: peer, - Action: api.IntentionActionAllow, - }) - } - return ixns - }(), - }, - ) - if s.ac6 == nil { - s.ac6 = map[nodeKey]ac6FailoversContext{} - } - s.ac6[nodeKey{clu.Datacenter, partition}] = struct { - clientSID topology.ServiceID - serverSID topology.ServiceID - serverNode topology.NodeID - }{ - clientSID: clientSID, - serverSID: serverSID, - serverNode: serverNode.ID(), - } - } -} - -func (s *ac6FailoversSuite) setupAC6FailoversDC3(ct *commonTopo, clu, peer1, peer2 *topology.Cluster) { - var peers []string - for _, part := range peer1.Partitions { - peers = append(peers, LocalPeerName(peer1, part.Name)) - } - for _, part := range peer2.Partitions { - peers = append(peers, LocalPeerName(peer2, part.Name)) - } - - partition := "default" - - // Make an HTTP server - server := NewFortioServiceWithDefaults( - clu.Datacenter, - topology.ServiceID{ - Name: "ac6-failover-svc", - Partition: partition, - }, - nil, - ) - - ct.AddServiceNode(clu, serviceExt{ - Service: server, - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", - }, - Intentions: &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Sources: func() []*api.SourceIntention { - var ixns []*api.SourceIntention - for _, peer := range peers { - ixns = append(ixns, &api.SourceIntention{ - Name: "ac6-client", - Peer: peer, - Action: api.IntentionActionAllow, - }) - } - return ixns - }(), - }, - Exports: func() []api.ServiceConsumer { - var consumers []api.ServiceConsumer - for _, peer := range peers { - consumers = append(consumers, api.ServiceConsumer{ - Peer: peer, - }) - } - return consumers - }(), - }) -} - -func (s *ac6FailoversSuite) test(t *testing.T, ct *commonTopo) { - dc1 := ct.Sprawl.Topology().Clusters["dc1"] - dc2 := ct.Sprawl.Topology().Clusters["dc2"] - - type testcase struct { - name string - cluster *topology.Cluster - peer *topology.Cluster - partition string - } - tcs := []testcase{ - { - name: "dc1 default partition failovers", - cluster: dc1, - peer: dc2, // dc3 is hardcoded - partition: "default", - }, - { - name: "dc1 part1 partition failovers", - cluster: dc1, - peer: dc2, // dc3 is hardcoded - partition: "part1", - }, - { - name: "dc2 default partition failovers", - cluster: dc2, - peer: dc1, // dc3 is hardcoded - partition: "default", - }, - { - name: "dc2 part1 partition failovers", - cluster: dc2, - peer: dc1, // dc3 is hardcoded - partition: "part1", - }, - } - for _, tc := range tcs { - t.Run(tc.name, func(t *testing.T) { - // NOTE: *not parallel* because we mutate resources that are shared - // between test cases (disable/enable nodes) - if !utils.IsEnterprise() && tc.partition != "default" { - t.Skip("skipping enterprise test") - } - partition := tc.partition - clu := tc.cluster - peerClu := tc.peer - - svcs := clu.ServicesByID(s.ac6[nodeKey{clu.Datacenter, partition}].clientSID) - require.Len(t, svcs, 1, "expected exactly one client in datacenter") - - serverSID := s.ac6[nodeKey{clu.Datacenter, partition}].serverSID - serverSID.Normalize() - - client := svcs[0] - require.Len(t, client.Upstreams, 1, "expected one upstream for client") - - u := client.Upstreams[0] - ct.Assert.CatalogServiceExists(t, clu.Name, u.ID.Name, utils.CompatQueryOpts(&api.QueryOptions{ - Partition: u.ID.Partition, - })) - - t.Cleanup(func() { - cfg := ct.Sprawl.Config() - for _, part := range clu.Partitions { - EnableNode(t, cfg, clu.Name, s.ac6[nodeKey{clu.Datacenter, part.Name}].serverNode) - } - for _, part := range peerClu.Partitions { - EnableNode(t, cfg, peerClu.Name, s.ac6[nodeKey{peerClu.Datacenter, part.Name}].serverNode) - } - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - }) - - fmt.Println("### preconditions") - // TODO: deduce this number, instead of hard-coding - nFailoverTargets := 4 - // in CE, we don't have failover targets for non-default partitions - if !utils.IsEnterprise() { - nFailoverTargets = 3 - } - for i := 0; i < nFailoverTargets; i++ { - ct.Assert.UpstreamEndpointStatus(t, client, fmt.Sprintf("failover-target~%d~%s", i, clusterPrefix(u, clu.Datacenter)), "HEALTHY", 1) - } - - ct.Assert.FortioFetch2FortioName(t, client, u, clu.Name, serverSID) - - if t.Failed() { - t.Fatalf("failed preconditions") - } - - fmt.Println("### Failover to peer target") - cfg := ct.Sprawl.Config() - DisableNode(t, cfg, clu.Name, s.ac6[nodeKey{clu.Datacenter, partition}].serverNode) - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - // Clusters for imported services rely on outlier detection for - // failovers, NOT eds_health_status. This means that killing the - // node above does not actually make the envoy cluster UNHEALTHY - // so we do not assert for it. - expectUID := topology.ServiceID{ - Name: u.ID.Name, - Partition: "default", - } - expectUID.Normalize() - ct.Assert.FortioFetch2FortioName(t, client, u, peerClu.Name, expectUID) - - if utils.IsEnterprise() { - fmt.Println("### Failover to peer target in non-default partition") - cfg = ct.Sprawl.Config() - DisableNode(t, cfg, clu.Name, s.ac6[nodeKey{clu.Datacenter, partition}].serverNode) - DisableNode(t, cfg, peerClu.Name, s.ac6[nodeKey{peerClu.Datacenter, "default"}].serverNode) - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - // Retry until outlier_detection deems the cluster - // unhealthy and fails over to peer part1. - expectUID = topology.ServiceID{ - Name: u.ID.Name, - Partition: "part1", - } - expectUID.Normalize() - ct.Assert.FortioFetch2FortioName(t, client, u, peerClu.Name, expectUID) - } - - fmt.Println("### Failover to dc3 peer target") - cfg = ct.Sprawl.Config() - DisableNode(t, cfg, clu.Name, s.ac6[nodeKey{clu.Datacenter, partition}].serverNode) - // Disable all partitions for peer - for _, part := range peerClu.Partitions { - DisableNode(t, cfg, peerClu.Name, s.ac6[nodeKey{peerClu.Datacenter, part.Name}].serverNode) - } - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - // This will retry until outlier_detection deems the cluster - // unhealthy and fails over to dc3. - expectUID = topology.ServiceID{ - Name: u.ID.Name, - Partition: "default", - } - expectUID.Normalize() - ct.Assert.FortioFetch2FortioName(t, client, u, "dc3", expectUID) - }) - } -} - -func clusterPrefix(u *topology.Upstream, dc string) string { - u.ID.Normalize() - switch u.ID.Partition { - case "default": - return fmt.Sprintf("%s.%s.%s.internal", u.ID.Name, u.ID.Namespace, dc) - default: - return fmt.Sprintf("%s.%s.%s.%s.internal-v1", u.ID.Name, u.ID.Namespace, u.ID.Partition, dc) - } -} diff --git a/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go b/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go deleted file mode 100644 index 4973cb6d04877..0000000000000 --- a/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - "strings" - "testing" - - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" -) - -// TestRotateGW ensures that peered services continue to be able to talk to their -// upstreams during a mesh gateway rotation -// NOTE: because suiteRotateGW needs to mutate the topo, we actually *DO NOT* share a topo - -type suiteRotateGW struct { - DC string - Peer string - - sidServer topology.ServiceID - nodeServer topology.NodeID - - sidClient topology.ServiceID - nodeClient topology.NodeID - - upstream *topology.Upstream - - newMGWNodeName string -} - -func TestRotateGW(t *testing.T) { - suites := []*suiteRotateGW{ - {DC: "dc1", Peer: "dc2"}, - {DC: "dc2", Peer: "dc1"}, - } - ct := NewCommonTopo(t) - for _, s := range suites { - s.setup(t, ct) - } - ct.Launch(t) - for _, s := range suites { - s := s - t.Run(fmt.Sprintf("%s->%s", s.DC, s.Peer), func(t *testing.T) { - // no t.Parallel() due to Relaunch - s.test(t, ct) - }) - } -} - -func (s *suiteRotateGW) setup(t *testing.T, ct *commonTopo) { - const prefix = "ac7-1-" - - clu := ct.ClusterByDatacenter(t, s.DC) - peerClu := ct.ClusterByDatacenter(t, s.Peer) - partition := "default" - peer := LocalPeerName(peerClu, "default") - cluPeerName := LocalPeerName(clu, "default") - - server := NewFortioServiceWithDefaults( - peerClu.Datacenter, - topology.ServiceID{ - Name: prefix + "server-http", - Partition: partition, - }, - nil, - ) - - // Make clients which have server upstreams - upstream := &topology.Upstream{ - ID: topology.ServiceID{ - Name: server.ID.Name, - Partition: partition, - }, - // TODO: we shouldn't need this, need to investigate - LocalAddress: "0.0.0.0", - LocalPort: 5001, - Peer: peer, - } - // create client in us - client := NewFortioServiceWithDefaults( - clu.Datacenter, - topology.ServiceID{ - Name: prefix + "client", - Partition: partition, - }, - func(s *topology.Service) { - s.Upstreams = []*topology.Upstream{ - upstream, - } - }, - ) - clientNode := ct.AddServiceNode(clu, serviceExt{Service: client, - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: client.ID.Name, - Partition: ConfigEntryPartition(client.ID.Partition), - Protocol: "http", - UpstreamConfig: &api.UpstreamConfiguration{ - Defaults: &api.UpstreamConfig{ - MeshGateway: api.MeshGatewayConfig{ - Mode: api.MeshGatewayModeLocal, - }, - }, - }, - }, - }) - // actually to be used by the other pairing - serverNode := ct.AddServiceNode(peerClu, serviceExt{ - Service: server, - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", - }, - Exports: []api.ServiceConsumer{{Peer: cluPeerName}}, - Intentions: &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Sources: []*api.SourceIntention{ - { - Name: client.ID.Name, - Peer: cluPeerName, - Action: api.IntentionActionAllow, - }, - }, - }, - }) - - s.sidClient = client.ID - s.nodeClient = clientNode.ID() - s.upstream = upstream - s.sidServer = server.ID - s.nodeServer = serverNode.ID() - - // add a second mesh gateway "new" - s.newMGWNodeName = fmt.Sprintf("new-%s-default-mgw", clu.Name) - nodeKind := topology.NodeKindClient - if clu.Datacenter == agentlessDC { - nodeKind = topology.NodeKindDataplane - } - clu.Nodes = append(clu.Nodes, newTopologyMeshGatewaySet( - nodeKind, - "default", - s.newMGWNodeName, - 1, - []string{clu.Datacenter, "wan"}, - func(i int, node *topology.Node) { - node.Disabled = true - }, - )...) -} - -func (s *suiteRotateGW) test(t *testing.T, ct *commonTopo) { - dc := ct.Sprawl.Topology().Clusters[s.DC] - peer := ct.Sprawl.Topology().Clusters[s.Peer] - - svcHTTPServer := peer.ServiceByID( - s.nodeServer, - s.sidServer, - ) - svcHTTPClient := dc.ServiceByID( - s.nodeClient, - s.sidClient, - ) - ct.Assert.HealthyWithPeer(t, dc.Name, svcHTTPServer.ID, LocalPeerName(peer, "default")) - - ct.Assert.FortioFetch2HeaderEcho(t, svcHTTPClient, s.upstream) - - t.Log("relaunching with new gateways") - cfg := ct.Sprawl.Config() - for _, n := range dc.Nodes { - if strings.HasPrefix(n.Name, s.newMGWNodeName) { - n.Disabled = false - } - } - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - ct.Assert.FortioFetch2HeaderEcho(t, svcHTTPClient, s.upstream) - - t.Log("relaunching without old gateways") - cfg = ct.Sprawl.Config() - for _, n := range dc.Nodes { - if strings.HasPrefix(n.Name, fmt.Sprintf("%s-default-mgw", dc.Name)) { - n.Disabled = true - } - } - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - ct.Assert.FortioFetch2HeaderEcho(t, svcHTTPClient, s.upstream) -} diff --git a/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go b/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go deleted file mode 100644 index a5684ebbc0242..0000000000000 --- a/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - "testing" - "time" - - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/mitchellh/copystructure" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" -) - -// TestAC7_2RotateLeader ensures that after a leader rotation, information continues to replicate to peers -// NOTE: because suiteRotateLeader needs to mutate the topo, we actually *DO NOT* share a topo -type ac7_2RotateLeaderSuite struct { - DC string - Peer string - - sidServer topology.ServiceID - nodeServer topology.NodeID - - sidClient topology.ServiceID - nodeClient topology.NodeID - - upstream *topology.Upstream -} - -func TestAC7_2RotateLeader(t *testing.T) { - suites := []*ac7_2RotateLeaderSuite{ - {DC: "dc1", Peer: "dc2"}, - {DC: "dc2", Peer: "dc1"}, - } - ct := NewCommonTopo(t) - for _, s := range suites { - s.setup(t, ct) - } - ct.Launch(t) - for _, s := range suites { - s := s - t.Run(fmt.Sprintf("%s->%s", s.DC, s.Peer), func(t *testing.T) { - // no t.Parallel() due to Relaunch - s.test(t, ct) - }) - } -} - -// makes client in clu, server in peerClu -func (s *ac7_2RotateLeaderSuite) setup(t *testing.T, ct *commonTopo) { - const prefix = "ac7-2-" - - clu := ct.ClusterByDatacenter(t, s.DC) - peerClu := ct.ClusterByDatacenter(t, s.Peer) - partition := "default" - peer := LocalPeerName(peerClu, "default") - cluPeerName := LocalPeerName(clu, "default") - - server := NewFortioServiceWithDefaults( - peerClu.Datacenter, - topology.ServiceID{ - Name: prefix + "server-http", - Partition: partition, - }, - nil, - ) - - // Make clients which have server upstreams - upstream := &topology.Upstream{ - ID: topology.ServiceID{ - Name: server.ID.Name, - Partition: partition, - }, - LocalPort: 5001, - Peer: peer, - } - // create client in us - client := NewFortioServiceWithDefaults( - clu.Datacenter, - topology.ServiceID{ - Name: prefix + "client", - Partition: partition, - }, - func(s *topology.Service) { - s.Upstreams = []*topology.Upstream{ - upstream, - } - }, - ) - clientNode := ct.AddServiceNode(clu, serviceExt{Service: client, - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: client.ID.Name, - Partition: ConfigEntryPartition(client.ID.Partition), - Protocol: "http", - UpstreamConfig: &api.UpstreamConfiguration{ - Defaults: &api.UpstreamConfig{ - MeshGateway: api.MeshGatewayConfig{ - Mode: api.MeshGatewayModeLocal, - }, - }, - }, - }, - }) - // actually to be used by the other pairing - serverNode := ct.AddServiceNode(peerClu, serviceExt{ - Service: server, - Config: &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", - }, - Exports: []api.ServiceConsumer{{Peer: cluPeerName}}, - Intentions: &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Sources: []*api.SourceIntention{ - { - Name: client.ID.Name, - Peer: cluPeerName, - Action: api.IntentionActionAllow, - }, - }, - }, - }) - - s.sidClient = client.ID - s.nodeClient = clientNode.ID() - s.upstream = upstream - s.sidServer = server.ID - s.nodeServer = serverNode.ID() -} - -func (s *ac7_2RotateLeaderSuite) test(t *testing.T, ct *commonTopo) { - dc := ct.Sprawl.Topology().Clusters[s.DC] - peer := ct.Sprawl.Topology().Clusters[s.Peer] - clDC := ct.APIClientForCluster(t, dc) - clPeer := ct.APIClientForCluster(t, peer) - - svcServer := peer.ServiceByID(s.nodeServer, s.sidServer) - svcClient := dc.ServiceByID(s.nodeClient, s.sidClient) - ct.Assert.HealthyWithPeer(t, dc.Name, svcServer.ID, LocalPeerName(peer, "default")) - - ct.Assert.FortioFetch2HeaderEcho(t, svcClient, s.upstream) - - // force leader election - rotateLeader(t, clDC) - rotateLeader(t, clPeer) - - // unexport httpServer - ce, _, err := clPeer.ConfigEntries().Get(api.ExportedServices, s.sidServer.Partition, nil) - require.NoError(t, err) - // ceAsES = config entry as ExportedServicesConfigEntry - ceAsES := ce.(*api.ExportedServicesConfigEntry) - origCE, err := copystructure.Copy(ceAsES) - require.NoError(t, err) - found := 0 - foundI := 0 - for i, svc := range ceAsES.Services { - if svc.Name == s.sidServer.Name && svc.Namespace == utils.DefaultToEmpty(s.sidServer.Namespace) { - found += 1 - foundI = i - } - } - require.Equal(t, found, 1) - // remove found entry - ceAsES.Services = append(ceAsES.Services[:foundI], ceAsES.Services[foundI+1:]...) - _, _, err = clPeer.ConfigEntries().Set(ceAsES, nil) - require.NoError(t, err) - t.Cleanup(func() { - //restore for next pairing - _, _, err = clPeer.ConfigEntries().Set(origCE.(*api.ExportedServicesConfigEntry), nil) - require.NoError(t, err) - }) - - // expect health entry in for peer to disappear - retry.RunWith(&retry.Timer{Timeout: time.Minute, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - svcs, _, err := clDC.Health().Service(s.sidServer.Name, "", true, utils.CompatQueryOpts(&api.QueryOptions{ - Partition: s.sidServer.Partition, - Namespace: s.sidServer.Namespace, - Peer: LocalPeerName(peer, "default"), - })) - require.NoError(r, err) - assert.Equal(r, len(svcs), 0, "health entry for imported service gone") - }) -} - -func rotateLeader(t *testing.T, cl *api.Client) { - t.Helper() - oldLeader := findLeader(t, cl) - _, err := cl.Operator().RaftLeaderTransfer("", nil) - require.NoError(t, err) - retry.RunWith(&retry.Timer{Timeout: 30 * time.Second, Wait: time.Second}, t, func(r *retry.R) { - newLeader := findLeader(r, cl) - require.NotEqual(r, oldLeader.ID, newLeader.ID) - }) -} - -func findLeader(t require.TestingT, cl *api.Client) *api.RaftServer { - raftConfig, err := cl.Operator().RaftGetConfiguration(nil) - require.NoError(t, err) - var leader *api.RaftServer - for _, svr := range raftConfig.Servers { - if svr.Leader { - leader = svr - } - } - require.NotNil(t, leader) - return leader -} diff --git a/test-integ/peering_commontopo/asserter.go b/test-integ/peering_commontopo/asserter.go deleted file mode 100644 index b5aa71ebae45f..0000000000000 --- a/test-integ/peering_commontopo/asserter.go +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "fmt" - "io" - "net/http" - "net/url" - "regexp" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/testing/deployer/topology" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" -) - -// asserter is a utility to help in reducing boilerplate in invoking test -// assertions against consul-topology Sprawl components. -// -// The methods should largely take in *topology.Service instances in lieu of -// ip/ports if there is only one port that makes sense for the assertion (such -// as use of the envoy admin port 19000). -// -// If it's up to the test (like picking an upstream) leave port as an argument -// but still take the service and use that to grab the local ip from the -// topology.Node. -type asserter struct { - sp sprawlLite -} - -// *sprawl.Sprawl satisfies this. We don't need anything else. -type sprawlLite interface { - HTTPClientForCluster(clusterName string) (*http.Client, error) - APIClientForNode(clusterName string, nid topology.NodeID, token string) (*api.Client, error) - APIClientForCluster(clusterName string, token string) (*api.Client, error) - Topology() *topology.Topology -} - -// newAsserter creates a new assertion helper for the provided sprawl. -func newAsserter(sp sprawlLite) *asserter { - return &asserter{ - sp: sp, - } -} - -func (a *asserter) mustGetHTTPClient(t *testing.T, cluster string) *http.Client { - client, err := a.httpClientFor(cluster) - require.NoError(t, err) - return client -} - -func (a *asserter) mustGetAPIClient(t *testing.T, cluster string) *api.Client { - clu := a.sp.Topology().Clusters[cluster] - cl, err := a.sp.APIClientForCluster(clu.Name, "") - require.NoError(t, err) - return cl -} - -// httpClientFor returns a pre-configured http.Client that proxies requests -// through the embedded squid instance in each LAN. -// -// Use this in methods below to magically pick the right proxied http client -// given the home of each node being checked. -func (a *asserter) httpClientFor(cluster string) (*http.Client, error) { - client, err := a.sp.HTTPClientForCluster(cluster) - if err != nil { - return nil, err - } - return client, nil -} - -// UpstreamEndpointStatus validates that proxy was configured with provided clusterName in the healthStatus -// -// Exposes libassert.UpstreamEndpointStatus for use against a Sprawl. -// -// NOTE: this doesn't take a port b/c you always want to use the envoy admin port. -func (a *asserter) UpstreamEndpointStatus( - t *testing.T, - service *topology.Service, - clusterName string, - healthStatus string, - count int, -) { - t.Helper() - node := service.Node - ip := node.LocalAddress() - port := service.EnvoyAdminPort - addr := fmt.Sprintf("%s:%d", ip, port) - - client := a.mustGetHTTPClient(t, node.Cluster) - libassert.AssertUpstreamEndpointStatusWithClient(t, client, addr, clusterName, healthStatus, count) -} - -// HTTPServiceEchoes verifies that a post to the given ip/port combination -// returns the data in the response body. Optional path can be provided to -// differentiate requests. -// -// Exposes libassert.HTTPServiceEchoes for use against a Sprawl. -// -// NOTE: this takes a port b/c you may want to reach this via your choice of upstream. -func (a *asserter) HTTPServiceEchoes( - t *testing.T, - service *topology.Service, - port int, - path string, -) { - t.Helper() - require.True(t, port > 0) - - node := service.Node - ip := node.LocalAddress() - addr := fmt.Sprintf("%s:%d", ip, port) - - client := a.mustGetHTTPClient(t, node.Cluster) - libassert.HTTPServiceEchoesWithClient(t, client, addr, path) -} - -// HTTPServiceEchoesResHeader verifies that a post to the given ip/port combination -// returns the data in the response body with expected response headers. -// Optional path can be provided to differentiate requests. -// -// Exposes libassert.HTTPServiceEchoes for use against a Sprawl. -// -// NOTE: this takes a port b/c you may want to reach this via your choice of upstream. -func (a *asserter) HTTPServiceEchoesResHeader( - t *testing.T, - service *topology.Service, - port int, - path string, - expectedResHeader map[string]string, -) { - t.Helper() - require.True(t, port > 0) - - node := service.Node - ip := node.LocalAddress() - addr := fmt.Sprintf("%s:%d", ip, port) - - client := a.mustGetHTTPClient(t, node.Cluster) - libassert.HTTPServiceEchoesResHeaderWithClient(t, client, addr, path, expectedResHeader) -} - -func (a *asserter) HTTPStatus( - t *testing.T, - service *topology.Service, - port int, - status int, -) { - t.Helper() - require.True(t, port > 0) - - node := service.Node - ip := node.LocalAddress() - addr := fmt.Sprintf("%s:%d", ip, port) - - client := a.mustGetHTTPClient(t, node.Cluster) - - url := "http://" + addr - - retry.RunWith(&retry.Timer{Timeout: 30 * time.Second, Wait: 500 * time.Millisecond}, t, func(r *retry.R) { - resp, err := client.Get(url) - if err != nil { - r.Fatalf("could not make request to %q: %v", url, err) - } - defer resp.Body.Close() - if resp.StatusCode != status { - r.Fatalf("expected status %d, got %d", status, resp.StatusCode) - } - }) -} - -// asserts that the service sid in cluster and exported by peer localPeerName is passing health checks, -func (a *asserter) HealthyWithPeer(t *testing.T, cluster string, sid topology.ServiceID, peerName string) { - t.Helper() - cl := a.mustGetAPIClient(t, cluster) - retry.RunWith(&retry.Timer{Timeout: time.Minute * 1, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - svcs, _, err := cl.Health().Service( - sid.Name, - "", - true, - utils.CompatQueryOpts(&api.QueryOptions{ - Partition: sid.Partition, - Namespace: sid.Namespace, - Peer: peerName, - }), - ) - require.NoError(r, err) - assert.GreaterOrEqual(r, len(svcs), 1) - }) -} - -func (a *asserter) UpstreamEndpointHealthy(t *testing.T, svc *topology.Service, upstream *topology.Upstream) { - t.Helper() - node := svc.Node - ip := node.LocalAddress() - port := svc.EnvoyAdminPort - addr := fmt.Sprintf("%s:%d", ip, port) - - client := a.mustGetHTTPClient(t, node.Cluster) - libassert.AssertUpstreamEndpointStatusWithClient(t, - client, - addr, - // TODO: what is default? namespace? partition? - fmt.Sprintf("%s.default.%s.external", upstream.ID.Name, upstream.Peer), - "HEALTHY", - 1, - ) -} - -// does a fortio /fetch2 to the given fortio service, targetting the given upstream. Returns -// the body, and response with response.Body already Closed. -// -// We treat 400, 503, and 504s as retryable errors -func (a *asserter) fortioFetch2Upstream(t *testing.T, fortioSvc *topology.Service, upstream *topology.Upstream, path string) (body []byte, res *http.Response) { - t.Helper() - - // TODO: fortioSvc.ID.Normalize()? or should that be up to the caller? - - node := fortioSvc.Node - client := a.mustGetHTTPClient(t, node.Cluster) - urlbase := fmt.Sprintf("%s:%d", node.LocalAddress(), fortioSvc.Port) - - url := fmt.Sprintf("http://%s/fortio/fetch2?url=%s", urlbase, - url.QueryEscape(fmt.Sprintf("http://localhost:%d/%s", upstream.LocalPort, path)), - ) - - req, err := http.NewRequest(http.MethodPost, url, nil) - require.NoError(t, err) - retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - res, err = client.Do(req) - require.NoError(r, err) - defer res.Body.Close() - // not sure when these happen, suspect it's when the mesh gateway in the peer is not yet ready - require.NotEqual(r, http.StatusServiceUnavailable, res.StatusCode) - require.NotEqual(r, http.StatusGatewayTimeout, res.StatusCode) - // not sure when this happens, suspect it's when envoy hasn't configured the local upstream yet - require.NotEqual(r, http.StatusBadRequest, res.StatusCode) - body, err = io.ReadAll(res.Body) - require.NoError(r, err) - }) - - return body, res -} - -// uses the /fortio/fetch2 endpoint to do a header echo check against an -// upstream fortio -func (a *asserter) FortioFetch2HeaderEcho(t *testing.T, fortioSvc *topology.Service, upstream *topology.Upstream) { - const kPassphrase = "x-passphrase" - const passphrase = "hello" - path := (fmt.Sprintf("/?header=%s:%s", kPassphrase, passphrase)) - - retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - _, res := a.fortioFetch2Upstream(t, fortioSvc, upstream, path) - require.Equal(t, http.StatusOK, res.StatusCode) - v := res.Header.Get(kPassphrase) - require.Equal(t, passphrase, v) - }) -} - -// similar to libassert.AssertFortioName, -// uses the /fortio/fetch2 endpoint to hit the debug endpoint on the upstream, -// and assert that the FORTIO_NAME == name -func (a *asserter) FortioFetch2FortioName(t *testing.T, fortioSvc *topology.Service, upstream *topology.Upstream, clusterName string, sid topology.ServiceID) { - t.Helper() - - var fortioNameRE = regexp.MustCompile(("\nFORTIO_NAME=(.+)\n")) - path := "/debug?env=dump" - - retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - body, res := a.fortioFetch2Upstream(t, fortioSvc, upstream, path) - require.Equal(t, http.StatusOK, res.StatusCode) - - // TODO: not sure we should retry these? - m := fortioNameRE.FindStringSubmatch(string(body)) - require.GreaterOrEqual(r, len(m), 2) - // TODO: dedupe from NewFortioService - require.Equal(r, fmt.Sprintf("%s::%s", clusterName, sid.String()), m[1]) - }) -} - -// CatalogServiceExists is the same as libassert.CatalogServiceExists, except that it uses -// a proxied API client -func (a *asserter) CatalogServiceExists(t *testing.T, cluster string, svc string, opts *api.QueryOptions) { - t.Helper() - cl := a.mustGetAPIClient(t, cluster) - libassert.CatalogServiceExists(t, cl, svc, opts) -} diff --git a/test-integ/peering_commontopo/commontopo.go b/test-integ/peering_commontopo/commontopo.go deleted file mode 100644 index e43456b231bce..0000000000000 --- a/test-integ/peering_commontopo/commontopo.go +++ /dev/null @@ -1,625 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "bytes" - "context" - "fmt" - "strconv" - "testing" - "text/tabwriter" - "time" - - "github.com/hashicorp/consul/testing/deployer/sprawl" - "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" -) - -// commonTopo helps create a shareable topology configured to represent -// the common denominator between tests. -// -// Use NewCommonTopo to create. -// -// Compatible suites should implement sharedTopoSuite. -// -// Style: -// - avoid referencing components using strings, prefer IDs like Service ID, etc. -// - avoid passing addresses and ports, etc. Instead, look up components in sprawl.Topology -// by ID to find a concrete type, then pass that to helper functions that know which port to use -// - minimize the surface area of information passed between setup and test code (via members) -// to those that are strictly necessary -type commonTopo struct { - // - Cfg *topology.Config - // shortcuts to corresponding entry in Cfg - DC1 *topology.Cluster - DC2 *topology.Cluster - DC3 *topology.Cluster - - // set after Launch. Should be considered read-only - Sprawl *sprawl.Sprawl - Assert *asserter - - // track per-DC services to prevent duplicates - services map[string]map[topology.ServiceID]struct{} -} - -const agentlessDC = "dc2" - -func NewCommonTopo(t *testing.T) *commonTopo { - t.Helper() - - ct := commonTopo{} - - const nServers = 3 - - // Make 3-server clusters in dc1 and dc2 - // For simplicity, the Name and Datacenter of the clusters are the same. - // dc1 and dc2 should be symmetric. - dc1 := clusterWithJustServers("dc1", nServers) - ct.DC1 = dc1 - dc2 := clusterWithJustServers("dc2", nServers) - ct.DC2 = dc2 - // dc3 is a failover cluster for both dc1 and dc2 - dc3 := clusterWithJustServers("dc3", 1) - // dc3 is only used for certain failover scenarios and does not need tenancies - dc3.Partitions = []*topology.Partition{{Name: "default"}} - ct.DC3 = dc3 - - injectTenancies(dc1) - injectTenancies(dc2) - // dc3 is only used for certain failover scenarios and does not need tenancies - dc3.Partitions = []*topology.Partition{{Name: "default"}} - - ct.services = map[string]map[topology.ServiceID]struct{}{} - for _, dc := range []*topology.Cluster{dc1, dc2, dc3} { - ct.services[dc.Datacenter] = map[topology.ServiceID]struct{}{} - } - - peerings := addPeerings(dc1, dc2) - peerings = append(peerings, addPeerings(dc1, dc3)...) - peerings = append(peerings, addPeerings(dc2, dc3)...) - - addMeshGateways(dc1) - addMeshGateways(dc2) - addMeshGateways(dc3) - - setupGlobals(dc1) - setupGlobals(dc2) - setupGlobals(dc3) - - // Build final configuration - ct.Cfg = &topology.Config{ - Images: utils.TargetImages(), - Networks: []*topology.Network{ - {Name: dc1.Datacenter}, // "dc1" LAN - {Name: dc2.Datacenter}, // "dc2" LAN - {Name: dc3.Datacenter}, // "dc3" LAN - {Name: "wan", Type: "wan"}, - }, - Clusters: []*topology.Cluster{ - dc1, - dc2, - dc3, - }, - Peerings: peerings, - } - return &ct -} - -// calls sprawltest.Launch followed by s.postLaunchChecks -func (ct *commonTopo) Launch(t *testing.T) { - if ct.Sprawl != nil { - t.Fatalf("Launch must only be called once") - } - ct.Sprawl = sprawltest.Launch(t, ct.Cfg) - - ct.Assert = newAsserter(ct.Sprawl) - ct.postLaunchChecks(t) -} - -// tests that use Relaunch might want to call this again afterwards -func (ct *commonTopo) postLaunchChecks(t *testing.T) { - t.Logf("TESTING RELATIONSHIPS: \n%s", - renderRelationships(computeRelationships(ct.Sprawl.Topology())), - ) - - // check that exports line up as expected - for _, clu := range ct.Sprawl.Topology().Clusters { - // expected exports per peer - type key struct { - peer string - partition string - namespace string - } - eepp := map[key]int{} - for _, e := range clu.InitialConfigEntries { - if e.GetKind() == api.ExportedServices { - asExport := e.(*api.ExportedServicesConfigEntry) - // do we care about the partition? - for _, svc := range asExport.Services { - for _, con := range svc.Consumers { - // do we care about con.Partition? - // TODO: surely there is code to normalize this - partition := asExport.Partition - if partition == "" { - partition = "default" - } - namespace := svc.Namespace - if namespace == "" { - namespace = "default" - } - eepp[key{peer: con.Peer, partition: partition, namespace: namespace}] += 1 - } - } - } - } - cl := ct.APIClientForCluster(t, clu) - // TODO: these could probably be done in parallel - for k, v := range eepp { - retry.RunWith(&retry.Timer{Timeout: 30 * time.Second, Wait: 500 * time.Millisecond}, t, func(r *retry.R) { - peering, _, err := cl.Peerings().Read(context.Background(), k.peer, utils.CompatQueryOpts(&api.QueryOptions{ - Partition: k.partition, - Namespace: k.namespace, - })) - require.Nil(r, err, "reading peering data") - require.NotNilf(r, peering, "peering not found %q", k.peer) - assert.Len(r, peering.StreamStatus.ExportedServices, v, "peering exported services") - }) - } - } - - if t.Failed() { - t.Fatal("failing fast: post-Launch assertions failed") - } -} - -// PeerName is how you'd address a remote dc+partition locally -// as your peer name. -func LocalPeerName(clu *topology.Cluster, partition string) string { - return fmt.Sprintf("peer-%s-%s", clu.Datacenter, partition) -} - -// TODO: move these to topology -// TODO: alternatively, delete it: we only use it in one place, to bundle up args -type serviceExt struct { - *topology.Service - - Exports []api.ServiceConsumer - Config *api.ServiceConfigEntry - Intentions *api.ServiceIntentionsConfigEntry -} - -func (ct *commonTopo) AddServiceNode(clu *topology.Cluster, svc serviceExt) *topology.Node { - clusterName := clu.Name - if _, ok := ct.services[clusterName][svc.ID]; ok { - panic(fmt.Sprintf("duplicate service %q in cluster %q", svc.ID, clusterName)) - } - ct.services[clusterName][svc.ID] = struct{}{} - - // TODO: inline - serviceHostnameString := func(dc string, id topology.ServiceID) string { - n := id.Name - // prepend - and - if they are not default/empty - // avoids hostname limit of 63 chars in most cases - // TODO: this obviously isn't scalable - if id.Namespace != "default" && id.Namespace != "" { - n = id.Namespace + "-" + n - } - if id.Partition != "default" && id.Partition != "" { - n = id.Partition + "-" + n - } - n = dc + "-" + n - // TODO: experimentally, when this is larger than 63, docker can't start - // the host. confirmed by internet rumor https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27763 - if len(n) > 63 { - panic(fmt.Sprintf("docker hostname must not be longer than 63 chars: %q", n)) - } - return n - } - - nodeKind := topology.NodeKindClient - // TODO: bug in deployer somewhere; it should guard against a KindDataplane node with - // DisableServiceMesh services on it; dataplane is only for service-mesh - if !svc.DisableServiceMesh && clu.Datacenter == agentlessDC { - nodeKind = topology.NodeKindDataplane - } - - node := &topology.Node{ - Kind: nodeKind, - Name: serviceHostnameString(clu.Datacenter, svc.ID), - Partition: svc.ID.Partition, - Addresses: []*topology.Address{ - {Network: clu.Datacenter}, - }, - Services: []*topology.Service{ - svc.Service, - }, - Cluster: clusterName, - } - clu.Nodes = append(clu.Nodes, node) - - // Export if necessary - if len(svc.Exports) > 0 { - ct.ExportService(clu, svc.ID.Partition, api.ExportedService{ - Name: svc.ID.Name, - Namespace: svc.ID.Namespace, - Consumers: svc.Exports, - }) - } - - // Add any config entries - if svc.Config != nil { - clu.InitialConfigEntries = append(clu.InitialConfigEntries, svc.Config) - } - if svc.Intentions != nil { - clu.InitialConfigEntries = append(clu.InitialConfigEntries, svc.Intentions) - } - - return node -} - -func (ct *commonTopo) APIClientForCluster(t *testing.T, clu *topology.Cluster) *api.Client { - cl, err := ct.Sprawl.APIClientForCluster(clu.Name, "") - require.NoError(t, err) - return cl -} - -// ExportService looks for an existing ExportedServicesConfigEntry for the given partition -// and inserts svcs. If none is found, it inserts a new ExportedServicesConfigEntry. -func (ct *commonTopo) ExportService(clu *topology.Cluster, partition string, svcs ...api.ExportedService) { - var found bool - for _, ce := range clu.InitialConfigEntries { - // We check Name because it must be "default" in CE whereas Partition will be "". - if ce.GetKind() == api.ExportedServices && ce.GetName() == partition { - found = true - e := ce.(*api.ExportedServicesConfigEntry) - e.Services = append(e.Services, svcs...) - } - } - if !found { - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ExportedServicesConfigEntry{ - Name: partition, // this NEEDs to be "default" in CE - Partition: ConfigEntryPartition(partition), - Services: svcs, - }, - ) - } -} - -func (ct *commonTopo) ClusterByDatacenter(t *testing.T, name string) *topology.Cluster { - t.Helper() - - for _, clu := range ct.Cfg.Clusters { - if clu.Datacenter == name { - return clu - } - } - t.Fatalf("cluster %q not found", name) - return nil -} - -// Since CE config entries do not contain the partition field, -// this func converts default partition to empty string. -func ConfigEntryPartition(p string) string { - if p == "default" { - return "" // make this CE friendly - } - return p -} - -// disableNode is a no-op if the node is already disabled. -func DisableNode(t *testing.T, cfg *topology.Config, clusterName string, nid topology.NodeID) *topology.Config { - nodes := cfg.Cluster(clusterName).Nodes - var found bool - for _, n := range nodes { - if n.ID() == nid { - found = true - if n.Disabled { - return cfg - } - t.Logf("disabling node %s in cluster %s", nid.String(), clusterName) - n.Disabled = true - break - } - } - require.True(t, found, "expected to find nodeID %q in cluster %q", nid.String(), clusterName) - return cfg -} - -// enableNode is a no-op if the node is already enabled. -func EnableNode(t *testing.T, cfg *topology.Config, clusterName string, nid topology.NodeID) *topology.Config { - nodes := cfg.Cluster(clusterName).Nodes - var found bool - for _, n := range nodes { - if n.ID() == nid { - found = true - if !n.Disabled { - return cfg - } - t.Logf("enabling node %s in cluster %s", nid.String(), clusterName) - n.Disabled = false - break - } - } - require.True(t, found, "expected to find nodeID %q in cluster %q", nid.String(), clusterName) - return cfg -} - -func setupGlobals(clu *topology.Cluster) { - for _, part := range clu.Partitions { - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ProxyConfigEntry{ - Name: api.ProxyConfigGlobal, - Kind: api.ProxyDefaults, - Partition: ConfigEntryPartition(part.Name), - MeshGateway: api.MeshGatewayConfig{ - // Although we define service-defaults for most upstreams in - // this test suite, failover tests require a global mode - // because the default for peered targets is MeshGatewayModeRemote. - Mode: api.MeshGatewayModeLocal, - }, - }, - &api.MeshConfigEntry{ - Peering: &api.PeeringMeshConfig{ - PeerThroughMeshGateways: true, - }, - }, - ) - } -} - -// addMeshGateways adds a mesh gateway for every partition in the cluster. -// Assumes that the LAN network name is equal to datacenter name. -func addMeshGateways(c *topology.Cluster) { - nodeKind := topology.NodeKindClient - if c.Datacenter == agentlessDC { - nodeKind = topology.NodeKindDataplane - } - for _, p := range c.Partitions { - c.Nodes = topology.MergeSlices(c.Nodes, newTopologyMeshGatewaySet( - nodeKind, - p.Name, - fmt.Sprintf("%s-%s-mgw", c.Name, p.Name), - 1, - []string{c.Datacenter, "wan"}, - nil, - )) - } -} - -func clusterWithJustServers(name string, numServers int) *topology.Cluster { - return &topology.Cluster{ - Enterprise: utils.IsEnterprise(), - Name: name, - Datacenter: name, - Nodes: newTopologyServerSet( - name+"-server", - numServers, - []string{name}, - nil, - ), - } -} - -func addPeerings(acc *topology.Cluster, dial *topology.Cluster) []*topology.Peering { - peerings := []*topology.Peering{} - for _, accPart := range acc.Partitions { - for _, dialPart := range dial.Partitions { - peerings = append(peerings, &topology.Peering{ - Accepting: topology.PeerCluster{ - Name: acc.Datacenter, - Partition: accPart.Name, - PeerName: LocalPeerName(dial, dialPart.Name), - }, - Dialing: topology.PeerCluster{ - Name: dial.Datacenter, - Partition: dialPart.Name, - PeerName: LocalPeerName(acc, accPart.Name), - }, - }) - } - } - return peerings -} - -func injectTenancies(clu *topology.Cluster) { - if !utils.IsEnterprise() { - clu.Partitions = []*topology.Partition{ - { - Name: "default", - Namespaces: []string{ - "default", - }, - }, - } - return - } - - for _, part := range []string{"default", "part1"} { - clu.Partitions = append(clu.Partitions, - &topology.Partition{ - Name: part, - Namespaces: []string{ - "default", - "ns1", - }, - }, - ) - } -} - -func newTopologyServerSet( - namePrefix string, - num int, - networks []string, - mutateFn func(i int, node *topology.Node), -) []*topology.Node { - var out []*topology.Node - for i := 1; i <= num; i++ { - name := namePrefix + strconv.Itoa(i) - - node := &topology.Node{ - Kind: topology.NodeKindServer, - Name: name, - } - for _, net := range networks { - node.Addresses = append(node.Addresses, &topology.Address{Network: net}) - } - - if mutateFn != nil { - mutateFn(i, node) - } - - out = append(out, node) - } - return out -} - -func newTopologyMeshGatewaySet( - nodeKind topology.NodeKind, - partition string, - namePrefix string, - num int, - networks []string, - mutateFn func(i int, node *topology.Node), -) []*topology.Node { - var out []*topology.Node - for i := 1; i <= num; i++ { - name := namePrefix + strconv.Itoa(i) - - node := &topology.Node{ - Kind: nodeKind, - Partition: partition, - Name: name, - Services: []*topology.Service{{ - ID: topology.ServiceID{Name: "mesh-gateway"}, - Port: 8443, - EnvoyAdminPort: 19000, - IsMeshGateway: true, - }}, - } - for _, net := range networks { - node.Addresses = append(node.Addresses, &topology.Address{Network: net}) - } - - if mutateFn != nil { - mutateFn(i, node) - } - - out = append(out, node) - } - return out -} - -const HashicorpDockerProxy = "docker.mirror.hashicorp.services" - -func NewFortioServiceWithDefaults( - cluster string, - sid topology.ServiceID, - mut func(s *topology.Service), -) *topology.Service { - const ( - httpPort = 8080 - grpcPort = 8079 - adminPort = 19000 - ) - sid.Normalize() - - svc := &topology.Service{ - ID: sid, - Image: HashicorpDockerProxy + "/fortio/fortio", - Port: httpPort, - EnvoyAdminPort: adminPort, - CheckTCP: "127.0.0.1:" + strconv.Itoa(httpPort), - Env: []string{ - "FORTIO_NAME=" + cluster + "::" + sid.String(), - }, - Command: []string{ - "server", - "-http-port", strconv.Itoa(httpPort), - "-grpc-port", strconv.Itoa(grpcPort), - "-redirect-port", "-disabled", - }, - } - if mut != nil { - mut(svc) - } - return svc -} - -// computeRelationships will analyze a full topology and generate all of the -// downstream/upstream information for all of them. -func computeRelationships(topo *topology.Topology) []Relationship { - var out []Relationship - for _, cluster := range topo.Clusters { - for _, n := range cluster.Nodes { - for _, s := range n.Services { - for _, u := range s.Upstreams { - out = append(out, Relationship{ - Caller: s, - Upstream: u, - }) - } - } - } - } - return out -} - -// renderRelationships will take the output of ComputeRelationships and display -// it in tabular form. -func renderRelationships(ships []Relationship) string { - var buf bytes.Buffer - w := tabwriter.NewWriter(&buf, 0, 0, 3, ' ', tabwriter.Debug) - fmt.Fprintf(w, "DOWN\tnode\tservice\tport\tUP\tservice\t\n") - for _, r := range ships { - fmt.Fprintf(w, - "%s\t%s\t%s\t%d\t%s\t%s\t\n", - r.downCluster(), - r.Caller.Node.ID().String(), - r.Caller.ID.String(), - r.Upstream.LocalPort, - r.upCluster(), - r.Upstream.ID.String(), - ) - } - fmt.Fprintf(w, "\t\t\t\t\t\t\n") - - w.Flush() - return buf.String() -} - -type Relationship struct { - Caller *topology.Service - Upstream *topology.Upstream -} - -func (r Relationship) String() string { - return fmt.Sprintf( - "%s on %s in %s via :%d => %s in %s", - r.Caller.ID.String(), - r.Caller.Node.ID().String(), - r.downCluster(), - r.Upstream.LocalPort, - r.Upstream.ID.String(), - r.upCluster(), - ) -} - -func (r Relationship) downCluster() string { - return r.Caller.Node.Cluster -} - -func (r Relationship) upCluster() string { - return r.Upstream.Cluster -} diff --git a/test-integ/peering_commontopo/sharedtopology_test.go b/test-integ/peering_commontopo/sharedtopology_test.go deleted file mode 100644 index f51b05e41ef78..0000000000000 --- a/test-integ/peering_commontopo/sharedtopology_test.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package peering - -import ( - "flag" - "testing" -) - -// Tests that use commonTopo should implement sharedTopoSuite. -// -// Tests that use commonTopo are either cooperative or non-cooperative. Non-cooperative -// uses of commonTopo include is anything that may interfere with other tests, namely -// mutations, such as: -// - any calls to commonTopo.Relaunch; this is generally disruptive to other tests -// - stopping or disabling nodes -// - ... -// -// Cooperative tests should just call testFuncMayReuseCommonTopo() to ensure they -// are run in the correct `sharetopo` mode. They should also ensure they are included -// in the commonTopoSuites slice in TestSuitesOnSharedTopo. -type sharedTopoSuite interface { - testName() string - setup(*testing.T, *commonTopo) - test(*testing.T, *commonTopo) -} - -var flagNoShareTopo = flag.Bool("no-share-topo", false, "do not share topology; run each test in its own isolated topology") - -func runShareableSuites(t *testing.T, suites []sharedTopoSuite) { - t.Helper() - if !*flagNoShareTopo { - names := []string{} - for _, s := range suites { - names = append(names, s.testName()) - } - t.Skipf(`Will run as part of "TestSuitesOnSharedTopo": %v`, names) - } - ct := NewCommonTopo(t) - for _, s := range suites { - s.setup(t, ct) - } - ct.Launch(t) - for _, s := range suites { - s := s - t.Run(s.testName(), func(t *testing.T) { - t.Parallel() - s.test(t, ct) - }) - } -} - -// Tests that can share topo must implement sharedTopoSuite and be appended to the sharedTopoSuites -// slice inside -func TestSuitesOnSharedTopo(t *testing.T) { - if *flagNoShareTopo { - t.Skip(`shared topo suites disabled by -no-share-topo`) - } - ct := NewCommonTopo(t) - - sharedTopoSuites := []sharedTopoSuite{} - sharedTopoSuites = append(sharedTopoSuites, ac1BasicSuites...) - sharedTopoSuites = append(sharedTopoSuites, ac2DiscoChainSuites...) - sharedTopoSuites = append(sharedTopoSuites, ac3SvcDefaultsSuites...) - sharedTopoSuites = append(sharedTopoSuites, ac4ProxyDefaultsSuites...) - sharedTopoSuites = append(sharedTopoSuites, ac5_1NoSvcMeshSuites...) - - for _, s := range sharedTopoSuites { - s.setup(t, ct) - } - ct.Launch(t) - for _, s := range sharedTopoSuites { - s := s - t.Run(s.testName(), func(t *testing.T) { - t.Parallel() - s.test(t, ct) - }) - } -} - -func TestCommonTopologySetup(t *testing.T) { - ct := NewCommonTopo(t) - ct.Launch(t) -} diff --git a/test/bin/cluster.bash b/test/bin/cluster.bash index a6bc7d336f11f..8b856c4a2c9a9 100755 --- a/test/bin/cluster.bash +++ b/test/bin/cluster.bash @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # # Script for bringing up an N node consul cluster diff --git a/test/ca/generate.sh b/test/ca/generate.sh index 7159431f4c490..897071dda8a0b 100755 --- a/test/ca/generate.sh +++ b/test/ca/generate.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -e diff --git a/test/client_certs/generate.sh b/test/client_certs/generate.sh index f5c645d7bbb76..e93f568dcb126 100755 --- a/test/client_certs/generate.sh +++ b/test/client_certs/generate.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/hostname/generate.sh b/test/hostname/generate.sh index 8e43dbee4e8a5..61febd2a36751 100755 --- a/test/hostname/generate.sh +++ b/test/hostname/generate.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/Dockerfile-consul-envoy-windows b/test/integration/connect/envoy/Dockerfile-consul-envoy-windows deleted file mode 100644 index b760fd5754f7d..0000000000000 --- a/test/integration/connect/envoy/Dockerfile-consul-envoy-windows +++ /dev/null @@ -1,12 +0,0 @@ -# From Consul Version 1.13.3 / 1.12.6 / 1.11.11 -ARG VERSION=1.16.0-dev -# From Envoy version 1.23.1 / 1.21.5 / 1.20.7 -ARG ENVOY_VERSION - -FROM docker.mirror.hashicorp.services/windows/envoy-windows:v${ENVOY_VERSION} as envoy -FROM windows/consul:${VERSION} - -# Copy envoy.exe from FROM windows/envoy-windows:${ENVOY_VERSION} -COPY --from=envoy ["C:/Program Files/envoy/", "C:/envoy/"] - -RUN SETX /M path "%PATH%;C:\envoy;" \ No newline at end of file diff --git a/test/integration/connect/envoy/Dockerfile-tcpdump-windows b/test/integration/connect/envoy/Dockerfile-tcpdump-windows deleted file mode 100644 index cbf5041630b99..0000000000000 --- a/test/integration/connect/envoy/Dockerfile-tcpdump-windows +++ /dev/null @@ -1,7 +0,0 @@ -FROM mcr.microsoft.com/windows/servercore:ltsc2019 - -COPY ["tcpdump.exe", "C:/Program Files/"] - -ENTRYPOINT ["C:/Program Files/tcpdump.exe"] - -# docker.exe build -t envoy-tcpdump -f Dockerfile-tcpdump-windows . diff --git a/test/integration/connect/envoy/Dockerfile-test-sds-server-windows b/test/integration/connect/envoy/Dockerfile-test-sds-server-windows deleted file mode 100644 index fc5e45b88d355..0000000000000 --- a/test/integration/connect/envoy/Dockerfile-test-sds-server-windows +++ /dev/null @@ -1,8 +0,0 @@ -FROM docker.mirror.hashicorp.services/windows/golang:1809 - -WORKDIR /go/src -COPY ./ . - -RUN go build -v -o test-sds-server.exe sds.go - -CMD ["test-sds-server.exe"] diff --git a/test/integration/connect/envoy/README.md b/test/integration/connect/envoy/README.md index ef358e7a2b44a..a97acc710a953 100644 --- a/test/integration/connect/envoy/README.md +++ b/test/integration/connect/envoy/README.md @@ -52,7 +52,6 @@ Where `case-basic` can be replaced by any directory name from this directory. * When tests fail in CI, logs and additional debugging data are available in the artifacts of the test run. * You can re-run the tests locally by running `make test-envoy-integ GO_TEST_FLAGS="-run TestEnvoy/"` where `` is replaced with the name of the directory, e.g. `case-basic`. -* You can override the envoy version by specifying `ENVOY_VERSION=` eg. `ENVOY_VERSION=1.27.0 make test-envoy-integ`. * Locally, all the logs of the failed test will be available in `workdir` in this directory. * You can run with `DEBUG=1` to print out all the commands being run, e.g. `DEBUG=1 make test-envoy-integ GO_TEST_FLAGS="-run TestEnvoy/case-basic"`. * If you want to prevent the Docker containers from being spun down after test failure, add a `sleep 9999` to the `verify.bats` test case that's failing. diff --git a/test/integration/connect/envoy/WINDOWS-TEST.md b/test/integration/connect/envoy/WINDOWS-TEST.md deleted file mode 100644 index d9217f7a385a9..0000000000000 --- a/test/integration/connect/envoy/WINDOWS-TEST.md +++ /dev/null @@ -1,40 +0,0 @@ -# Envoy Integration Tests on Windows - -## Index - -- [About](#about) -- [Pre-built core images](#pre-built-core-images) -- [Test images](#integration-test-images) -- [Run Tests](#run-tests) - -## About - -This file is the entrypoint to understand how to execute Envoy integration tests on Windows as well as to understand the differences between Linux tests and Windows tests. Below you can find a list of relevant documentation that has been written while working on supporting the Envoy integration tests on Windows. - -- [Windows Testing Architecture](test/integration/connect/envoy/docs/windows-testing-architecture.md): On this file you will find why the testing architecture on Windows differs from Linux's. -- [Build Images](build-support-windows/BUILD-IMAGES.md): Here you will find how to build the images required for executing the tests. -- [Windows Troubleshooting](test/integration/connect/envoy/WindowsTroubleshooting.md): This file lists, among other things everything we needed to change/adapt for the existing tests to run in Windows containers. - -## Pre-built core images - -Before running the integration tests, you must pre-build the core images that the tests require to be ran on the Windows environment. Make sure to check out the `BUILD-IMAGES` file [here](build-support-windows/BUILD-IMAGES.md) for this purpose. - -## Integration test images - -During the execution of the integration tests, several images are built based-on the pre-built core images. To get more information about these and how to run them independently, please check out the `docker.windows` file [here](test/integration/connect/envoy/docker.windows.md). - -## Run tests - -To run all the integration tests, you need to execute next command - -```shell -go test -v -timeout=30s -tags integration ./test/integration/connect/envoy -run="TestEnvoy" -win=true -``` - -To run a single test case, the name should be specified. For instance, to run the `case-badauthz` test, you need to execute next command - -```shell -go test -v -timeout=30m -tags integration ./test/integration/connect/envoy -run="TestEnvoy/case-badauthz" -win=true -``` - -> :warning: Note that the flag `-win=true` must be specified as shown in the above commands. This flag is very important because the same allows to indicate that the tests will be executed on the Windows environment. When executing the Envoy integration tests the **End of Line Sequence** of every related file and or script will be automatically changed from **LF to CRLF**. diff --git a/test/integration/connect/envoy/case-api-gateway-http-hostnames/capture.sh b/test/integration/connect/envoy/case-api-gateway-http-hostnames/capture.sh index 92123f3f4c077..13eb01ba5f824 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-hostnames/capture.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-hostnames/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 api-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-api-gateway-http-hostnames/service_gateway.hcl b/test/integration/connect/envoy/case-api-gateway-http-hostnames/service_gateway.hcl index 1d0d5fffe26bf..c0af862f92e32 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-hostnames/service_gateway.hcl +++ b/test/integration/connect/envoy/case-api-gateway-http-hostnames/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "api-gateway" diff --git a/test/integration/connect/envoy/case-api-gateway-http-hostnames/setup.sh b/test/integration/connect/envoy/case-api-gateway-http-hostnames/setup.sh index 3b3db83268911..754e461f847ed 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-hostnames/setup.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-hostnames/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-api-gateway-http-hostnames/vars.sh b/test/integration/connect/envoy/case-api-gateway-http-hostnames/vars.sh index 1456b6a5ad024..87f668072e221 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-hostnames/vars.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-hostnames/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES api-gateway-primary" diff --git a/test/integration/connect/envoy/case-api-gateway-http-simple/capture.sh b/test/integration/connect/envoy/case-api-gateway-http-simple/capture.sh index 92123f3f4c077..13eb01ba5f824 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-simple/capture.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-simple/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 api-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-api-gateway-http-simple/service_gateway.hcl b/test/integration/connect/envoy/case-api-gateway-http-simple/service_gateway.hcl index 1d0d5fffe26bf..c0af862f92e32 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-simple/service_gateway.hcl +++ b/test/integration/connect/envoy/case-api-gateway-http-simple/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "api-gateway" diff --git a/test/integration/connect/envoy/case-api-gateway-http-simple/setup.sh b/test/integration/connect/envoy/case-api-gateway-http-simple/setup.sh index e25e92ba0011c..350eea0c5fde1 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-simple/setup.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-simple/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-api-gateway-http-simple/vars.sh b/test/integration/connect/envoy/case-api-gateway-http-simple/vars.sh index 1456b6a5ad024..87f668072e221 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-simple/vars.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-simple/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES api-gateway-primary" diff --git a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/capture.sh b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/capture.sh index 92123f3f4c077..13eb01ba5f824 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/capture.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 api-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/service_gateway.hcl b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/service_gateway.hcl index 1d0d5fffe26bf..c0af862f92e32 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/service_gateway.hcl +++ b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "api-gateway" diff --git a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/service_s3.hcl b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/service_s3.hcl index b41ec0349862a..3b11b245d4fde 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/service_s3.hcl +++ b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s3" diff --git a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/setup.sh b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/setup.sh index 622df90c297a7..da74ff07c1237 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/setup.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/vars.sh b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/vars.sh index 1456b6a5ad024..87f668072e221 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/vars.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-splitter-targets/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES api-gateway-primary" diff --git a/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/capture.sh b/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/capture.sh index 92123f3f4c077..13eb01ba5f824 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/capture.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 api-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/service_gateway.hcl b/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/service_gateway.hcl index 1d0d5fffe26bf..c0af862f92e32 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/service_gateway.hcl +++ b/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "api-gateway" diff --git a/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/setup.sh b/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/setup.sh index 23076cd00e281..bb058d96fd75a 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/setup.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/vars.sh b/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/vars.sh index 1456b6a5ad024..87f668072e221 100644 --- a/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/vars.sh +++ b/test/integration/connect/envoy/case-api-gateway-http-tls-overlapping-hosts/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES api-gateway-primary" diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/capture.sh b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/capture.sh index 92123f3f4c077..13eb01ba5f824 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/capture.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 api-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/service_gateway.hcl b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/service_gateway.hcl index 1d0d5fffe26bf..c0af862f92e32 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/service_gateway.hcl +++ b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "api-gateway" diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/setup.sh b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/setup.sh index a4529b6772edc..35d01c8bb9318 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/setup.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/vars.sh b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/vars.sh index 1456b6a5ad024..87f668072e221 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/vars.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-conflicted/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES api-gateway-primary" diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-simple/capture.sh b/test/integration/connect/envoy/case-api-gateway-tcp-simple/capture.sh index 92123f3f4c077..13eb01ba5f824 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-simple/capture.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-simple/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 api-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-simple/service_gateway.hcl b/test/integration/connect/envoy/case-api-gateway-tcp-simple/service_gateway.hcl index 1d0d5fffe26bf..c0af862f92e32 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-simple/service_gateway.hcl +++ b/test/integration/connect/envoy/case-api-gateway-tcp-simple/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "api-gateway" diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-simple/setup.sh b/test/integration/connect/envoy/case-api-gateway-tcp-simple/setup.sh index 152e0772104e5..82504d09f5093 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-simple/setup.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-simple/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-simple/vars.sh b/test/integration/connect/envoy/case-api-gateway-tcp-simple/vars.sh index 1456b6a5ad024..87f668072e221 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-simple/vars.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-simple/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES api-gateway-primary" diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/capture.sh b/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/capture.sh index 92123f3f4c077..13eb01ba5f824 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/capture.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 api-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/service_gateway.hcl b/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/service_gateway.hcl index 1d0d5fffe26bf..c0af862f92e32 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/service_gateway.hcl +++ b/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "api-gateway" diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/setup.sh b/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/setup.sh index ca9568e348846..a4be961ebb5bb 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/setup.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/vars.sh b/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/vars.sh index 1456b6a5ad024..87f668072e221 100644 --- a/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/vars.sh +++ b/test/integration/connect/envoy/case-api-gateway-tcp-tls-overlapping-hosts/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES api-gateway-primary" diff --git a/test/integration/connect/envoy/case-badauthz/capture.sh b/test/integration/connect/envoy/case-badauthz/capture.sh index c6b9e36ed1df1..94c0278ce256c 100644 --- a/test/integration/connect/envoy/case-badauthz/capture.sh +++ b/test/integration/connect/envoy/case-badauthz/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 || true diff --git a/test/integration/connect/envoy/case-badauthz/setup.sh b/test/integration/connect/envoy/case-badauthz/setup.sh index 1aa0962cf6fb1..6bd91b1f4e66f 100644 --- a/test/integration/connect/envoy/case-badauthz/setup.sh +++ b/test/integration/connect/envoy/case-badauthz/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-basic/capture.sh b/test/integration/connect/envoy/case-basic/capture.sh index 14dc00afc65b8..5268305f8ff6c 100644 --- a/test/integration/connect/envoy/case-basic/capture.sh +++ b/test/integration/connect/envoy/case-basic/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-basic/setup.sh b/test/integration/connect/envoy/case-basic/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-basic/setup.sh +++ b/test/integration/connect/envoy/case-basic/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-centralconf/capture.sh b/test/integration/connect/envoy/case-centralconf/capture.sh index 8bc4413d09f9e..21ebba78787be 100644 --- a/test/integration/connect/envoy/case-centralconf/capture.sh +++ b/test/integration/connect/envoy/case-centralconf/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-centralconf/service_s1.hcl b/test/integration/connect/envoy/case-centralconf/service_s1.hcl index 54c6ac6501b40..6eaca129855b9 100644 --- a/test/integration/connect/envoy/case-centralconf/service_s1.hcl +++ b/test/integration/connect/envoy/case-centralconf/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-centralconf/service_s2.hcl b/test/integration/connect/envoy/case-centralconf/service_s2.hcl index 1a89f855944da..dfb92edce6368 100644 --- a/test/integration/connect/envoy/case-centralconf/service_s2.hcl +++ b/test/integration/connect/envoy/case-centralconf/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-centralconf/setup.sh b/test/integration/connect/envoy/case-centralconf/setup.sh index 934ea006fddbb..10038488c8c23 100644 --- a/test/integration/connect/envoy/case-centralconf/setup.sh +++ b/test/integration/connect/envoy/case-centralconf/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/base.hcl b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/base.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_s1.hcl b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_s1.hcl index b065abc9055e2..11acde14f4270 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in this peer diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_s2.hcl b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_s2.hcl index 90d2315f4d2c9..42252eb82f686 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/setup.sh index af71eccb8e188..917d0ba6c125f 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/bind.hcl b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/bind.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/capture.sh b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/capture.sh index 0921d3c32a0e9..e1b411ab95176 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/capture.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/base.hcl b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/base.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/service_s1.hcl b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/service_s1.hcl index 63dfc2994f3de..c9da404077ffe 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/service_s2.hcl b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/service_s2.hcl index 90d2315f4d2c9..42252eb82f686 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/setup.sh index d84fe0a869918..830ecb23b73cd 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/vars.sh index 41b95915331d4..9d1f5c977a9bc 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-cluster-peering-failover/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy s2 s2-sidecar-proxy s2-alpha s2-sidecar-proxy-alpha gateway-alpha tcpdump-primary tcpdump-alpha" diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/bind.hcl b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/bind.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/capture.sh b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/capture.sh index 0ee4884a15215..93352a5228b92 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/capture.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/primary/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/primary/setup.sh index 8b24664564cb7..e9a9055ab6a55 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/primary/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/join.hcl b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/join.hcl index f0bd3fbd4ac7e..0f63220d549fe 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/join.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/join.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 retry_join_wan = ["consul-primary-server"] diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/service_gateway.hcl b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/service_gateway.hcl index 4f91a740182af..8c2315b9ae360 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/service_s1.hcl b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/service_s1.hcl index 8b4d4a83a42d4..06af757cd68e7 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # we don't want an s1 service in the secondary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/setup.sh index ed13954a1f5e6..1af35392b9c26 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/secondary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/vars.sh index 11e14176e3892..e33bd22ca6184 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-none/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/bind.hcl b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/bind.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/capture.sh b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/capture.sh index 0ee4884a15215..93352a5228b92 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/capture.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/primary/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/primary/setup.sh index 25a7c173f08bb..33a1a035c53ac 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/primary/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/join.hcl b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/join.hcl index f0bd3fbd4ac7e..0f63220d549fe 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/join.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/join.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 retry_join_wan = ["consul-primary-server"] diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/service_gateway.hcl b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/service_gateway.hcl index 4f91a740182af..8c2315b9ae360 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/service_s1.hcl b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/service_s1.hcl index 8b4d4a83a42d4..06af757cd68e7 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # we don't want an s1 service in the secondary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/setup.sh index ed13954a1f5e6..1af35392b9c26 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/secondary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/vars.sh index 11e14176e3892..e33bd22ca6184 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-dc-failover-gateways-remote/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/service_s2-v1.hcl b/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/service_s2-v1.hcl index b96b473cf4fbf..9dd3cb782fd3f 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/service_s2-v1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/service_s2-v1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v1" diff --git a/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/service_s2-v2.hcl b/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/service_s2-v2.hcl index d642e71fa31b1..451f835e86881 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/service_s2-v2.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/service_s2-v2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v2" diff --git a/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/setup.sh index 043dd7f7fc66b..20dd92172327f 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/vars.sh index 358c95541fda3..50c5f8f67f9b0 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-defaultsubset/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-resolver-features/capture.sh b/test/integration/connect/envoy/case-cfg-resolver-features/capture.sh index b1782df01e27c..39878041c3672 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-features/capture.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-features/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cfg-resolver-features/service_s2-v1.hcl b/test/integration/connect/envoy/case-cfg-resolver-features/service_s2-v1.hcl index b96b473cf4fbf..9dd3cb782fd3f 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-features/service_s2-v1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-features/service_s2-v1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v1" diff --git a/test/integration/connect/envoy/case-cfg-resolver-features/service_s2-v2.hcl b/test/integration/connect/envoy/case-cfg-resolver-features/service_s2-v2.hcl index d642e71fa31b1..451f835e86881 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-features/service_s2-v2.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-features/service_s2-v2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v2" diff --git a/test/integration/connect/envoy/case-cfg-resolver-features/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-features/setup.sh index 2e3078edc872c..c3f2fa3a1d4f5 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-features/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-features/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-features/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-features/vars.sh index 358c95541fda3..50c5f8f67f9b0 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-features/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-features/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/service_s2-v1.hcl b/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/service_s2-v1.hcl index d45b1462723f4..551db8a322a9a 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/service_s2-v1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/service_s2-v1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v1" diff --git a/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/setup.sh index 606cadd8f1fb3..229247da4f512 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/vars.sh index aab3c8c39ea5b..9f9b54a8e9ebd 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-subset-onlypassing/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3-v1.hcl b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3-v1.hcl index d9a050a16f653..af20754d254de 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3-v1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3-v1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s3-v1" diff --git a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3-v2.hcl b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3-v2.hcl index 19e2c7cac1506..22a40609e19e8 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3-v2.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3-v2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s3-v2" diff --git a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3.hcl b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3.hcl index 973e69b01c89a..82db490a879b9 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s3" diff --git a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/setup.sh index 7d02158a6325c..e1fb33c3dca3e 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/vars.sh index a9a2bcd57188d..f76eb49ceb2db 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-subset-redirect/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3-v1.hcl b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3-v1.hcl index d9a050a16f653..af20754d254de 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3-v1.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3-v1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s3-v1" diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3-v2.hcl b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3-v2.hcl index 19e2c7cac1506..22a40609e19e8 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3-v2.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3-v2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s3-v2" diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3.hcl b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3.hcl index 973e69b01c89a..82db490a879b9 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s3" diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/setup.sh index eae9bd4feaf13..b4472fd8a207c 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/vars.sh index a9a2bcd57188d..f76eb49ceb2db 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-failover/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-failover/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/service_s3.hcl b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/service_s3.hcl index 94e31c3df895d..59209aab121c1 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/service_s3.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s3" diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/setup.sh index 097f1fa756663..640e1519ea473 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/vars.sh index 63c854f959c9e..bbc811fa66db5 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-http/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES s3 s3-sidecar-proxy" diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/service_s3.hcl b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/service_s3.hcl index 94e31c3df895d..59209aab121c1 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/service_s3.hcl +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s3" diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/setup.sh b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/setup.sh index fd106032bf2e9..9ce5a82f75468 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/setup.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/vars.sh b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/vars.sh index 63c854f959c9e..bbc811fa66db5 100644 --- a/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/vars.sh +++ b/test/integration/connect/envoy/case-cfg-resolver-svc-redirect-tcp/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES s3 s3-sidecar-proxy" diff --git a/test/integration/connect/envoy/case-cfg-router-features/capture.sh b/test/integration/connect/envoy/case-cfg-router-features/capture.sh index b1782df01e27c..39878041c3672 100644 --- a/test/integration/connect/envoy/case-cfg-router-features/capture.sh +++ b/test/integration/connect/envoy/case-cfg-router-features/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cfg-router-features/service_s2-v1.hcl b/test/integration/connect/envoy/case-cfg-router-features/service_s2-v1.hcl index b96b473cf4fbf..9dd3cb782fd3f 100644 --- a/test/integration/connect/envoy/case-cfg-router-features/service_s2-v1.hcl +++ b/test/integration/connect/envoy/case-cfg-router-features/service_s2-v1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v1" diff --git a/test/integration/connect/envoy/case-cfg-router-features/service_s2-v2.hcl b/test/integration/connect/envoy/case-cfg-router-features/service_s2-v2.hcl index d642e71fa31b1..451f835e86881 100644 --- a/test/integration/connect/envoy/case-cfg-router-features/service_s2-v2.hcl +++ b/test/integration/connect/envoy/case-cfg-router-features/service_s2-v2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v2" diff --git a/test/integration/connect/envoy/case-cfg-router-features/setup.sh b/test/integration/connect/envoy/case-cfg-router-features/setup.sh index 577b3512b4fe3..247bc00c33beb 100644 --- a/test/integration/connect/envoy/case-cfg-router-features/setup.sh +++ b/test/integration/connect/envoy/case-cfg-router-features/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-router-features/vars.sh b/test/integration/connect/envoy/case-cfg-router-features/vars.sh index 358c95541fda3..50c5f8f67f9b0 100644 --- a/test/integration/connect/envoy/case-cfg-router-features/vars.sh +++ b/test/integration/connect/envoy/case-cfg-router-features/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/base.hcl b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/base.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_s1.hcl b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_s1.hcl index b065abc9055e2..11acde14f4270 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in this peer diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_s2.hcl b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_s2.hcl index 26b5f481f377a..6666a63ba257e 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/setup.sh b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/setup.sh index 99c4eb46f2186..5aabbbbee0e5d 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/bind.hcl b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/bind.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/capture.sh b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/capture.sh index 0921d3c32a0e9..e1b411ab95176 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/capture.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/base.hcl b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/base.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/service_s1.hcl b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/service_s1.hcl index d50d8cb04979c..70caaaebc900b 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/service_s2.hcl b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/service_s2.hcl index 26b5f481f377a..6666a63ba257e 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/setup.sh b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/setup.sh index 9b274b375f874..8bc36b6d02299 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/setup.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/vars.sh b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/vars.sh index 7c231bcfad68f..17f98153dd14d 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/vars.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-cluster-peering/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy s2 s2-sidecar-proxy s2-alpha s2-sidecar-proxy-alpha gateway-alpha" diff --git a/test/integration/connect/envoy/case-cfg-splitter-features/capture.sh b/test/integration/connect/envoy/case-cfg-splitter-features/capture.sh index b1782df01e27c..39878041c3672 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-features/capture.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-features/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cfg-splitter-features/service_s2-v1.hcl b/test/integration/connect/envoy/case-cfg-splitter-features/service_s2-v1.hcl index b96b473cf4fbf..9dd3cb782fd3f 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-features/service_s2-v1.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-features/service_s2-v1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v1" diff --git a/test/integration/connect/envoy/case-cfg-splitter-features/service_s2-v2.hcl b/test/integration/connect/envoy/case-cfg-splitter-features/service_s2-v2.hcl index d642e71fa31b1..451f835e86881 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-features/service_s2-v2.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-features/service_s2-v2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v2" diff --git a/test/integration/connect/envoy/case-cfg-splitter-features/setup.sh b/test/integration/connect/envoy/case-cfg-splitter-features/setup.sh index 311799fccfbc1..68c8ac0a6cb4f 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-features/setup.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-features/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-splitter-features/vars.sh b/test/integration/connect/envoy/case-cfg-splitter-features/vars.sh index 358c95541fda3..50c5f8f67f9b0 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-features/vars.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-features/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES=" diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/base.hcl b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/base.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_s1.hcl b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_s1.hcl index ca196db64f0f4..976e0e993d4d5 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_s2.hcl b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_s2.hcl index 26b5f481f377a..6666a63ba257e 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/setup.sh b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/setup.sh index 47127ab03d482..8c24708aebe2b 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/bind.hcl b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/bind.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/capture.sh b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/capture.sh index 965f136de6822..a3dd69ed05b86 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/capture.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/base.hcl b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/base.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/service_ingress.hcl b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/service_ingress.hcl index a1324f7f83799..fbb1d402f9869 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/service_ingress.hcl +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/service_ingress.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/setup.sh b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/setup.sh index ed0da099d6527..d69a26f1d89c6 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/setup.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/vars.sh b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/vars.sh index e5b080741aa26..2a2aa6fb1e9c6 100644 --- a/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/vars.sh +++ b/test/integration/connect/envoy/case-cfg-splitter-peering-ingress-gateways/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy s1-alpha s1-sidecar-proxy-alpha s2-alpha s2-sidecar-proxy-alpha gateway-alpha ingress-gateway-primary" diff --git a/test/integration/connect/envoy/case-consul-exec/setup.sh b/test/integration/connect/envoy/case-consul-exec/setup.sh index 7e869b53f17ad..fe3505623b54e 100644 --- a/test/integration/connect/envoy/case-consul-exec/setup.sh +++ b/test/integration/connect/envoy/case-consul-exec/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-consul-exec/vars.sh b/test/integration/connect/envoy/case-consul-exec/vars.sh index 81ee777414571..4af0cb775d386 100644 --- a/test/integration/connect/envoy/case-consul-exec/vars.sh +++ b/test/integration/connect/envoy/case-consul-exec/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # Bring up s1 and it's proxy as well because the check that it has a cert causes diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/base.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/base.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_s1.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_s1.hcl index b065abc9055e2..11acde14f4270 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in this peer diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_s2.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_s2.hcl index 90d2315f4d2c9..42252eb82f686 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/setup.sh b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/setup.sh index ca05659843d7c..a7fb502a28159 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/bind.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/bind.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/capture.sh b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/capture.sh index b4316246f3ab6..8168b3de6416e 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/capture.sh +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19001 mesh-gateway primary || true diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/base.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/base.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_gateway.hcl index a6b33968ad020..9ea00427e9e7d 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_s1.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_s1.hcl index b3230f6dcfa1f..b8bd0f20be465 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_s2.hcl b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/setup.sh b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/setup.sh index d107c44ea6f39..cf57a59db8739 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/setup.sh +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/vars.sh b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/vars.sh index 93ac3281f1286..475b7f2312782 100644 --- a/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/vars.sh +++ b/test/integration/connect/envoy/case-cross-peer-control-plane-mgw/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy gateway-primary s2-alpha s2-sidecar-proxy-alpha gateway-alpha" diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/base.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/base.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s1.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s1.hcl index b065abc9055e2..11acde14f4270 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in this peer diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s2.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s2.hcl index 90d2315f4d2c9..42252eb82f686 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s3.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s3.hcl index 94e31c3df895d..59209aab121c1 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s3.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s3" diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/setup.sh b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/setup.sh index 00ab68e36144c..e852ef7d3d26c 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers-http-router/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/bind.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/bind.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/capture.sh b/test/integration/connect/envoy/case-cross-peers-http-router/capture.sh index be4068fd193b2..bcea1e921c6d1 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/capture.sh +++ b/test/integration/connect/envoy/case-cross-peers-http-router/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/primary/base.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/primary/base.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_gateway.hcl index a6b33968ad020..9ea00427e9e7d 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_s1.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_s1.hcl index ec6c29b8e158c..026636c814f75 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_s2.hcl b/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http-router/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/primary/setup.sh b/test/integration/connect/envoy/case-cross-peers-http-router/primary/setup.sh index 47c9eff11432a..2a06124a7d60c 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/primary/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers-http-router/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peers-http-router/vars.sh b/test/integration/connect/envoy/case-cross-peers-http-router/vars.sh index b11c21c524075..44ed49bb79619 100644 --- a/test/integration/connect/envoy/case-cross-peers-http-router/vars.sh +++ b/test/integration/connect/envoy/case-cross-peers-http-router/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy gateway-primary s2-alpha s2-sidecar-proxy-alpha s3-alpha s3-sidecar-proxy-alpha gateway-alpha tcpdump-primary tcpdump-alpha" diff --git a/test/integration/connect/envoy/case-cross-peers-http/alpha/base.hcl b/test/integration/connect/envoy/case-cross-peers-http/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/alpha/base.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-cross-peers-http/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peers-http/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peers-http/alpha/service_s1.hcl b/test/integration/connect/envoy/case-cross-peers-http/alpha/service_s1.hcl index b065abc9055e2..11acde14f4270 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/alpha/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in this peer diff --git a/test/integration/connect/envoy/case-cross-peers-http/alpha/service_s2.hcl b/test/integration/connect/envoy/case-cross-peers-http/alpha/service_s2.hcl index 90d2315f4d2c9..42252eb82f686 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cross-peers-http/alpha/setup.sh b/test/integration/connect/envoy/case-cross-peers-http/alpha/setup.sh index 267d9403dba71..f7ac96c41a7ad 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers-http/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peers-http/bind.hcl b/test/integration/connect/envoy/case-cross-peers-http/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/bind.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peers-http/capture.sh b/test/integration/connect/envoy/case-cross-peers-http/capture.sh index 3e81bd44657f4..62c8c60d702c1 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/capture.sh +++ b/test/integration/connect/envoy/case-cross-peers-http/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cross-peers-http/primary/base.hcl b/test/integration/connect/envoy/case-cross-peers-http/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/primary/base.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-cross-peers-http/primary/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peers-http/primary/service_gateway.hcl index a6b33968ad020..9ea00427e9e7d 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/primary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/primary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peers-http/primary/service_s1.hcl b/test/integration/connect/envoy/case-cross-peers-http/primary/service_s1.hcl index ec6c29b8e158c..026636c814f75 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-cross-peers-http/primary/service_s2.hcl b/test/integration/connect/envoy/case-cross-peers-http/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peers-http/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peers-http/primary/setup.sh b/test/integration/connect/envoy/case-cross-peers-http/primary/setup.sh index 7c5ac5fdb8ba9..997bb504f62d4 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/primary/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers-http/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peers-http/vars.sh b/test/integration/connect/envoy/case-cross-peers-http/vars.sh index d999e45dd263e..0c1c07b28b9c3 100644 --- a/test/integration/connect/envoy/case-cross-peers-http/vars.sh +++ b/test/integration/connect/envoy/case-cross-peers-http/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy gateway-primary s2-alpha s2-sidecar-proxy-alpha gateway-alpha tcpdump-primary tcpdump-alpha" diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/base.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/base.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s1.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s1.hcl index b065abc9055e2..11acde14f4270 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in this peer diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s2.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s2.hcl index 90d2315f4d2c9..42252eb82f686 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s3.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s3.hcl index 94e31c3df895d..59209aab121c1 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s3.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s3" diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/setup.sh b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/setup.sh index 3cc1a2eb2de8d..6574ecf873a6f 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/bind.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/bind.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/capture.sh b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/capture.sh index be4068fd193b2..bcea1e921c6d1 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/capture.sh +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/base.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/base.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_gateway.hcl index a6b33968ad020..9ea00427e9e7d 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_s1.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_s1.hcl index ec6c29b8e158c..026636c814f75 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_s2.hcl b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/setup.sh b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/setup.sh index d72b0798f5d8f..ad70bad80a866 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/vars.sh b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/vars.sh index b11c21c524075..44ed49bb79619 100644 --- a/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/vars.sh +++ b/test/integration/connect/envoy/case-cross-peers-resolver-redirect-tcp/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy gateway-primary s2-alpha s2-sidecar-proxy-alpha s3-alpha s3-sidecar-proxy-alpha gateway-alpha tcpdump-primary tcpdump-alpha" diff --git a/test/integration/connect/envoy/case-cross-peers/alpha/base.hcl b/test/integration/connect/envoy/case-cross-peers/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-cross-peers/alpha/base.hcl +++ b/test/integration/connect/envoy/case-cross-peers/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-cross-peers/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peers/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-cross-peers/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peers/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peers/alpha/service_s1.hcl b/test/integration/connect/envoy/case-cross-peers/alpha/service_s1.hcl index b065abc9055e2..11acde14f4270 100644 --- a/test/integration/connect/envoy/case-cross-peers/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peers/alpha/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in this peer diff --git a/test/integration/connect/envoy/case-cross-peers/alpha/service_s2.hcl b/test/integration/connect/envoy/case-cross-peers/alpha/service_s2.hcl index 90d2315f4d2c9..42252eb82f686 100644 --- a/test/integration/connect/envoy/case-cross-peers/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peers/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-cross-peers/alpha/setup.sh b/test/integration/connect/envoy/case-cross-peers/alpha/setup.sh index f5fd3d003aa68..afaa580684a7a 100644 --- a/test/integration/connect/envoy/case-cross-peers/alpha/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peers/bind.hcl b/test/integration/connect/envoy/case-cross-peers/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-cross-peers/bind.hcl +++ b/test/integration/connect/envoy/case-cross-peers/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peers/capture.sh b/test/integration/connect/envoy/case-cross-peers/capture.sh index 3e81bd44657f4..62c8c60d702c1 100644 --- a/test/integration/connect/envoy/case-cross-peers/capture.sh +++ b/test/integration/connect/envoy/case-cross-peers/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-cross-peers/primary/base.hcl b/test/integration/connect/envoy/case-cross-peers/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-cross-peers/primary/base.hcl +++ b/test/integration/connect/envoy/case-cross-peers/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-cross-peers/primary/service_gateway.hcl b/test/integration/connect/envoy/case-cross-peers/primary/service_gateway.hcl index a6b33968ad020..9ea00427e9e7d 100644 --- a/test/integration/connect/envoy/case-cross-peers/primary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-cross-peers/primary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-cross-peers/primary/service_s1.hcl b/test/integration/connect/envoy/case-cross-peers/primary/service_s1.hcl index b3230f6dcfa1f..b8bd0f20be465 100644 --- a/test/integration/connect/envoy/case-cross-peers/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-cross-peers/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-cross-peers/primary/service_s2.hcl b/test/integration/connect/envoy/case-cross-peers/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-cross-peers/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-cross-peers/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-cross-peers/primary/setup.sh b/test/integration/connect/envoy/case-cross-peers/primary/setup.sh index d72b0798f5d8f..ad70bad80a866 100644 --- a/test/integration/connect/envoy/case-cross-peers/primary/setup.sh +++ b/test/integration/connect/envoy/case-cross-peers/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-cross-peers/vars.sh b/test/integration/connect/envoy/case-cross-peers/vars.sh index d999e45dd263e..0c1c07b28b9c3 100644 --- a/test/integration/connect/envoy/case-cross-peers/vars.sh +++ b/test/integration/connect/envoy/case-cross-peers/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy gateway-primary s2-alpha s2-sidecar-proxy-alpha gateway-alpha tcpdump-primary tcpdump-alpha" diff --git a/test/integration/connect/envoy/case-dogstatsd-udp/service_s1.hcl b/test/integration/connect/envoy/case-dogstatsd-udp/service_s1.hcl index a4e91f3aa41b4..a75675751d525 100644 --- a/test/integration/connect/envoy/case-dogstatsd-udp/service_s1.hcl +++ b/test/integration/connect/envoy/case-dogstatsd-udp/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-dogstatsd-udp/setup.sh b/test/integration/connect/envoy/case-dogstatsd-udp/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-dogstatsd-udp/setup.sh +++ b/test/integration/connect/envoy/case-dogstatsd-udp/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-dogstatsd-udp/vars.sh b/test/integration/connect/envoy/case-dogstatsd-udp/vars.sh index 7fa5a238ce933..c599f12e8232d 100644 --- a/test/integration/connect/envoy/case-dogstatsd-udp/vars.sh +++ b/test/integration/connect/envoy/case-dogstatsd-udp/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES fake-statsd" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-dogstatsd-udp/verify.bats b/test/integration/connect/envoy/case-dogstatsd-udp/verify.bats index dfc238ad6d9de..55b0ad76849c3 100644 --- a/test/integration/connect/envoy/case-dogstatsd-udp/verify.bats +++ b/test/integration/connect/envoy/case-dogstatsd-udp/verify.bats @@ -24,11 +24,14 @@ load helpers } @test "s1 proxy should be sending metrics to statsd" { - run retry_default must_match_in_statsd_logs '^envoy\.' primary + run retry_default cat /workdir/primary/statsd/statsd.log - echo "METRICS: $output" + echo "METRICS:" + echo "$output" + echo "COUNT: $(echo "$output" | grep -Ec '^envoy\.')" - [ "$status" == 0 ] + [ "$status" == 0 ] + [ $(echo $output | grep -Ec '^envoy\.') -gt "0" ] } @test "s1 proxy should be sending dogstatsd tagged metrics" { diff --git a/test/integration/connect/envoy/case-expose-checks/capture.sh b/test/integration/connect/envoy/case-expose-checks/capture.sh index c6b9e36ed1df1..94c0278ce256c 100644 --- a/test/integration/connect/envoy/case-expose-checks/capture.sh +++ b/test/integration/connect/envoy/case-expose-checks/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 || true diff --git a/test/integration/connect/envoy/case-expose-checks/service_s1.hcl b/test/integration/connect/envoy/case-expose-checks/service_s1.hcl index b2b685c08abec..9a883739e4fa3 100644 --- a/test/integration/connect/envoy/case-expose-checks/service_s1.hcl +++ b/test/integration/connect/envoy/case-expose-checks/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-expose-checks/service_s2.hcl b/test/integration/connect/envoy/case-expose-checks/service_s2.hcl index f5cb3fb0374c4..b09d152fc5f0f 100644 --- a/test/integration/connect/envoy/case-expose-checks/service_s2.hcl +++ b/test/integration/connect/envoy/case-expose-checks/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-expose-checks/setup.sh b/test/integration/connect/envoy/case-expose-checks/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-expose-checks/setup.sh +++ b/test/integration/connect/envoy/case-expose-checks/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-gateway-without-services/bind.hcl b/test/integration/connect/envoy/case-gateway-without-services/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-gateway-without-services/bind.hcl +++ b/test/integration/connect/envoy/case-gateway-without-services/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-gateway-without-services/capture.sh b/test/integration/connect/envoy/case-gateway-without-services/capture.sh index ad74026c7ace2..fc5238fb6d6b2 100644 --- a/test/integration/connect/envoy/case-gateway-without-services/capture.sh +++ b/test/integration/connect/envoy/case-gateway-without-services/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 mesh-gateway primary || true diff --git a/test/integration/connect/envoy/case-gateway-without-services/service_gateway.hcl b/test/integration/connect/envoy/case-gateway-without-services/service_gateway.hcl index 2026fb2a94b84..446a2698e595b 100644 --- a/test/integration/connect/envoy/case-gateway-without-services/service_gateway.hcl +++ b/test/integration/connect/envoy/case-gateway-without-services/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-gateway-without-services/service_s1.hcl b/test/integration/connect/envoy/case-gateway-without-services/service_s1.hcl index 0891eebceb9c9..f74a67a5aef0c 100644 --- a/test/integration/connect/envoy/case-gateway-without-services/service_s1.hcl +++ b/test/integration/connect/envoy/case-gateway-without-services/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service diff --git a/test/integration/connect/envoy/case-gateway-without-services/service_s2.hcl b/test/integration/connect/envoy/case-gateway-without-services/service_s2.hcl index ca644bb3ffa22..1f3f2edd47893 100644 --- a/test/integration/connect/envoy/case-gateway-without-services/service_s2.hcl +++ b/test/integration/connect/envoy/case-gateway-without-services/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service diff --git a/test/integration/connect/envoy/case-gateway-without-services/setup.sh b/test/integration/connect/envoy/case-gateway-without-services/setup.sh index 6e4f5d8ee9bf9..002ef312bc34b 100644 --- a/test/integration/connect/envoy/case-gateway-without-services/setup.sh +++ b/test/integration/connect/envoy/case-gateway-without-services/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-gateway-without-services/vars.sh b/test/integration/connect/envoy/case-gateway-without-services/vars.sh index 21ab024ab5375..2d42d0baf5d3d 100644 --- a/test/integration/connect/envoy/case-gateway-without-services/vars.sh +++ b/test/integration/connect/envoy/case-gateway-without-services/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="gateway-primary" diff --git a/test/integration/connect/envoy/case-gateways-local/bind.hcl b/test/integration/connect/envoy/case-gateways-local/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-gateways-local/bind.hcl +++ b/test/integration/connect/envoy/case-gateways-local/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-gateways-local/capture.sh b/test/integration/connect/envoy/case-gateways-local/capture.sh index f4727b52c72ad..f7ca8e9586481 100644 --- a/test/integration/connect/envoy/case-gateways-local/capture.sh +++ b/test/integration/connect/envoy/case-gateways-local/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-gateways-local/primary/service_gateway.hcl b/test/integration/connect/envoy/case-gateways-local/primary/service_gateway.hcl index 2026fb2a94b84..446a2698e595b 100644 --- a/test/integration/connect/envoy/case-gateways-local/primary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-gateways-local/primary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-gateways-local/primary/service_s1.hcl b/test/integration/connect/envoy/case-gateways-local/primary/service_s1.hcl index 75fa1acc0e7e3..a759b590b07c2 100644 --- a/test/integration/connect/envoy/case-gateways-local/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-gateways-local/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-gateways-local/primary/service_s2.hcl b/test/integration/connect/envoy/case-gateways-local/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-gateways-local/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-gateways-local/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-gateways-local/primary/setup.sh b/test/integration/connect/envoy/case-gateways-local/primary/setup.sh index 29720753ba515..a8bfb7c9ffe5d 100644 --- a/test/integration/connect/envoy/case-gateways-local/primary/setup.sh +++ b/test/integration/connect/envoy/case-gateways-local/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-gateways-local/secondary/join.hcl b/test/integration/connect/envoy/case-gateways-local/secondary/join.hcl index f0bd3fbd4ac7e..0f63220d549fe 100644 --- a/test/integration/connect/envoy/case-gateways-local/secondary/join.hcl +++ b/test/integration/connect/envoy/case-gateways-local/secondary/join.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 retry_join_wan = ["consul-primary-server"] diff --git a/test/integration/connect/envoy/case-gateways-local/secondary/service_gateway.hcl b/test/integration/connect/envoy/case-gateways-local/secondary/service_gateway.hcl index 4f91a740182af..8c2315b9ae360 100644 --- a/test/integration/connect/envoy/case-gateways-local/secondary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-gateways-local/secondary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-gateways-local/secondary/service_s1.hcl b/test/integration/connect/envoy/case-gateways-local/secondary/service_s1.hcl index 8b4d4a83a42d4..06af757cd68e7 100644 --- a/test/integration/connect/envoy/case-gateways-local/secondary/service_s1.hcl +++ b/test/integration/connect/envoy/case-gateways-local/secondary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # we don't want an s1 service in the secondary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-gateways-local/secondary/setup.sh b/test/integration/connect/envoy/case-gateways-local/secondary/setup.sh index ede2b4c4b9f70..938135c9f4ff3 100644 --- a/test/integration/connect/envoy/case-gateways-local/secondary/setup.sh +++ b/test/integration/connect/envoy/case-gateways-local/secondary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail @@ -9,4 +9,4 @@ register_services secondary gen_envoy_bootstrap s2 19001 secondary gen_envoy_bootstrap mesh-gateway 19003 secondary true -retry_default docker_consul secondary curl -s "http://localhost:8500/v1/catalog/service/consul?dc=primary" > /dev/null +retry_default docker_consul secondary curl -s "http://localhost:8500/v1/catalog/service/consul?dc=primary" >/dev/null diff --git a/test/integration/connect/envoy/case-gateways-local/vars.sh b/test/integration/connect/envoy/case-gateways-local/vars.sh index d9a319933f8da..c5ab45789beba 100644 --- a/test/integration/connect/envoy/case-gateways-local/vars.sh +++ b/test/integration/connect/envoy/case-gateways-local/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy gateway-primary s2-secondary s2-sidecar-proxy-secondary gateway-secondary" diff --git a/test/integration/connect/envoy/case-gateways-remote/bind.hcl b/test/integration/connect/envoy/case-gateways-remote/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-gateways-remote/bind.hcl +++ b/test/integration/connect/envoy/case-gateways-remote/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-gateways-remote/capture.sh b/test/integration/connect/envoy/case-gateways-remote/capture.sh index f4727b52c72ad..f7ca8e9586481 100644 --- a/test/integration/connect/envoy/case-gateways-remote/capture.sh +++ b/test/integration/connect/envoy/case-gateways-remote/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-gateways-remote/primary/service_s1.hcl b/test/integration/connect/envoy/case-gateways-remote/primary/service_s1.hcl index 4cb4fbc41d1e3..789717ee52297 100644 --- a/test/integration/connect/envoy/case-gateways-remote/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-gateways-remote/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-gateways-remote/primary/service_s2.hcl b/test/integration/connect/envoy/case-gateways-remote/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-gateways-remote/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-gateways-remote/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-gateways-remote/primary/setup.sh b/test/integration/connect/envoy/case-gateways-remote/primary/setup.sh index 6dd0f0622bd36..f79f346477e47 100644 --- a/test/integration/connect/envoy/case-gateways-remote/primary/setup.sh +++ b/test/integration/connect/envoy/case-gateways-remote/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-gateways-remote/secondary/join.hcl b/test/integration/connect/envoy/case-gateways-remote/secondary/join.hcl index f0bd3fbd4ac7e..0f63220d549fe 100644 --- a/test/integration/connect/envoy/case-gateways-remote/secondary/join.hcl +++ b/test/integration/connect/envoy/case-gateways-remote/secondary/join.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 retry_join_wan = ["consul-primary-server"] diff --git a/test/integration/connect/envoy/case-gateways-remote/secondary/service_gateway.hcl b/test/integration/connect/envoy/case-gateways-remote/secondary/service_gateway.hcl index 4f91a740182af..8c2315b9ae360 100644 --- a/test/integration/connect/envoy/case-gateways-remote/secondary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-gateways-remote/secondary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-gateways-remote/secondary/service_s1.hcl b/test/integration/connect/envoy/case-gateways-remote/secondary/service_s1.hcl index 8b4d4a83a42d4..06af757cd68e7 100644 --- a/test/integration/connect/envoy/case-gateways-remote/secondary/service_s1.hcl +++ b/test/integration/connect/envoy/case-gateways-remote/secondary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # we don't want an s1 service in the secondary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-gateways-remote/secondary/setup.sh b/test/integration/connect/envoy/case-gateways-remote/secondary/setup.sh index 43a4c713cee91..938135c9f4ff3 100644 --- a/test/integration/connect/envoy/case-gateways-remote/secondary/setup.sh +++ b/test/integration/connect/envoy/case-gateways-remote/secondary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-gateways-remote/vars.sh b/test/integration/connect/envoy/case-gateways-remote/vars.sh index d9a319933f8da..c5ab45789beba 100644 --- a/test/integration/connect/envoy/case-gateways-remote/vars.sh +++ b/test/integration/connect/envoy/case-gateways-remote/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy gateway-primary s2-secondary s2-sidecar-proxy-secondary gateway-secondary" diff --git a/test/integration/connect/envoy/case-grpc/service_s1.hcl b/test/integration/connect/envoy/case-grpc/service_s1.hcl index 7d7814800c4d7..b22ba221fa1df 100644 --- a/test/integration/connect/envoy/case-grpc/service_s1.hcl +++ b/test/integration/connect/envoy/case-grpc/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" @@ -20,7 +20,7 @@ services { protocol = "grpc" envoy_dogstatsd_url = "udp://127.0.0.1:8125" envoy_stats_tags = ["foo=bar"] - envoy_stats_flush_interval = "5s" + envoy_stats_flush_interval = "1s" } } } diff --git a/test/integration/connect/envoy/case-grpc/service_s2.hcl b/test/integration/connect/envoy/case-grpc/service_s2.hcl index aaebecf627320..f7d7a267343d3 100644 --- a/test/integration/connect/envoy/case-grpc/service_s2.hcl +++ b/test/integration/connect/envoy/case-grpc/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-grpc/setup.sh b/test/integration/connect/envoy/case-grpc/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-grpc/setup.sh +++ b/test/integration/connect/envoy/case-grpc/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-grpc/vars.sh b/test/integration/connect/envoy/case-grpc/vars.sh index 7fa5a238ce933..c599f12e8232d 100644 --- a/test/integration/connect/envoy/case-grpc/vars.sh +++ b/test/integration/connect/envoy/case-grpc/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES fake-statsd" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-grpc/verify.bats b/test/integration/connect/envoy/case-grpc/verify.bats index fc7ca15b5b94a..422258a0c0ef7 100644 --- a/test/integration/connect/envoy/case-grpc/verify.bats +++ b/test/integration/connect/envoy/case-grpc/verify.bats @@ -43,7 +43,7 @@ load helpers metrics_query='envoy.cluster.grpc.PingServer.total.*[#,]local_cluster:s1(,|$)' fi - run retry_long must_match_in_statsd_logs "${metrics_query}" + run retry_default must_match_in_statsd_logs "${metrics_query}" echo "OUTPUT: $output" [ "$status" == 0 ] diff --git a/test/integration/connect/envoy/case-http-badauthz/capture.sh b/test/integration/connect/envoy/case-http-badauthz/capture.sh index c6b9e36ed1df1..94c0278ce256c 100644 --- a/test/integration/connect/envoy/case-http-badauthz/capture.sh +++ b/test/integration/connect/envoy/case-http-badauthz/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 || true diff --git a/test/integration/connect/envoy/case-http-badauthz/service_s1.hcl b/test/integration/connect/envoy/case-http-badauthz/service_s1.hcl index 25d2c1e380f26..96f67dcf40999 100644 --- a/test/integration/connect/envoy/case-http-badauthz/service_s1.hcl +++ b/test/integration/connect/envoy/case-http-badauthz/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-http-badauthz/service_s2.hcl b/test/integration/connect/envoy/case-http-badauthz/service_s2.hcl index fb857d005ee91..4b6632beb8365 100644 --- a/test/integration/connect/envoy/case-http-badauthz/service_s2.hcl +++ b/test/integration/connect/envoy/case-http-badauthz/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-http-badauthz/setup.sh b/test/integration/connect/envoy/case-http-badauthz/setup.sh index d15f836e65847..6bd91b1f4e66f 100644 --- a/test/integration/connect/envoy/case-http-badauthz/setup.sh +++ b/test/integration/connect/envoy/case-http-badauthz/setup.sh @@ -1,14 +1,14 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail -register_services primary - # Setup deny intention setup_upsert_l4_intention s1 s2 deny +register_services primary + gen_envoy_bootstrap s1 19000 primary gen_envoy_bootstrap s2 19001 primary diff --git a/test/integration/connect/envoy/case-http/capture.sh b/test/integration/connect/envoy/case-http/capture.sh index 14dc00afc65b8..5268305f8ff6c 100644 --- a/test/integration/connect/envoy/case-http/capture.sh +++ b/test/integration/connect/envoy/case-http/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-http/service_s1.hcl b/test/integration/connect/envoy/case-http/service_s1.hcl index 42a62acfb9f68..0c3f594fbc7d1 100644 --- a/test/integration/connect/envoy/case-http/service_s1.hcl +++ b/test/integration/connect/envoy/case-http/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-http/service_s2.hcl b/test/integration/connect/envoy/case-http/service_s2.hcl index fb857d005ee91..4b6632beb8365 100644 --- a/test/integration/connect/envoy/case-http/service_s2.hcl +++ b/test/integration/connect/envoy/case-http/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-http/setup.sh b/test/integration/connect/envoy/case-http/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-http/setup.sh +++ b/test/integration/connect/envoy/case-http/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-grpc/capture.sh b/test/integration/connect/envoy/case-ingress-gateway-grpc/capture.sh index 4214ba8274aaa..1c244823aba8b 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-grpc/capture.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-grpc/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true diff --git a/test/integration/connect/envoy/case-ingress-gateway-grpc/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-gateway-grpc/service_gateway.hcl index a1324f7f83799..fbb1d402f9869 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-grpc/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-grpc/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-ingress-gateway-grpc/service_s1.hcl b/test/integration/connect/envoy/case-ingress-gateway-grpc/service_s1.hcl index f525d48868ced..ff23e6fea3a0d 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-grpc/service_s1.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-grpc/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-ingress-gateway-grpc/setup.sh b/test/integration/connect/envoy/case-ingress-gateway-grpc/setup.sh index 387d079e3bd2a..40e2802f02ccf 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-grpc/setup.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-grpc/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-grpc/vars.sh b/test/integration/connect/envoy/case-ingress-gateway-grpc/vars.sh index 8b34fe36ef2a3..32dc504c49ce0 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-grpc/vars.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-grpc/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES ingress-gateway-primary" diff --git a/test/integration/connect/envoy/case-ingress-gateway-http/capture.sh b/test/integration/connect/envoy/case-ingress-gateway-http/capture.sh index c2b55d229a591..ab02875e61359 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-http/capture.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-http/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-gateway-http/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-gateway-http/service_gateway.hcl index a1324f7f83799..fbb1d402f9869 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-http/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-http/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-ingress-gateway-http/setup.sh b/test/integration/connect/envoy/case-ingress-gateway-http/setup.sh index 33d06b516c725..03f2184e6d067 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-http/setup.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-http/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-http/vars.sh b/test/integration/connect/envoy/case-ingress-gateway-http/vars.sh index 8b34fe36ef2a3..32dc504c49ce0 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-http/vars.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-http/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES ingress-gateway-primary" diff --git a/test/integration/connect/envoy/case-ingress-gateway-multiple-services/capture.sh b/test/integration/connect/envoy/case-ingress-gateway-multiple-services/capture.sh index c2b55d229a591..ab02875e61359 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-multiple-services/capture.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-multiple-services/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-gateway-multiple-services/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-gateway-multiple-services/service_gateway.hcl index a1324f7f83799..fbb1d402f9869 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-multiple-services/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-multiple-services/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-ingress-gateway-multiple-services/setup.sh b/test/integration/connect/envoy/case-ingress-gateway-multiple-services/setup.sh index 858d2f9ce53a2..f80e42cb73325 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-multiple-services/setup.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-multiple-services/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-multiple-services/vars.sh b/test/integration/connect/envoy/case-ingress-gateway-multiple-services/vars.sh index 8b34fe36ef2a3..32dc504c49ce0 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-multiple-services/vars.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-multiple-services/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES ingress-gateway-primary" diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/base.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/base.hcl index 8cd6db14878a7..899e81705a4cf 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/base.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "alpha" log_level = "trace" diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_gateway.hcl index 640b9b6ce753f..82ddd559eb3a5 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_s1.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_s1.hcl index b065abc9055e2..11acde14f4270 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_s1.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in this peer diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_s2.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_s2.hcl index 26b5f481f377a..6666a63ba257e 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_s2.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/setup.sh b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/setup.sh index 99c4eb46f2186..5aabbbbee0e5d 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/setup.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/alpha/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/bind.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/bind.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/capture.sh b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/capture.sh index ca10f2773107a..20ad858ecdb60 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/capture.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/base.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/base.hcl index 55c268b37e784..189b8e0ccf722 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/base.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 peering { enabled = true diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_ingress.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_ingress.hcl index a1324f7f83799..fbb1d402f9869 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_ingress.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_ingress.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_s1.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_s1.hcl index 18be60cdbf96a..85f8da9740029 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't need an s1 because requests go through the gateway and not a sidecar. \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_s2.hcl b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_s2.hcl index 26b5f481f377a..6666a63ba257e 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/setup.sh b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/setup.sh index b4a8dd736feec..58f12866948f2 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/setup.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/vars.sh b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/vars.sh index 8f9ac12cb1e3d..08bfe96a9d3b3 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-peering-failover/vars.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-peering-failover/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s2 s2-sidecar-proxy s2-alpha s2-sidecar-proxy-alpha gateway-alpha ingress-gateway-primary" diff --git a/test/integration/connect/envoy/case-ingress-gateway-sds/capture.sh b/test/integration/connect/envoy/case-ingress-gateway-sds/capture.sh index c2b55d229a591..ab02875e61359 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-sds/capture.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-sds/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-gateway-sds/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-gateway-sds/service_gateway.hcl index 1ffa476e6ff98..176a66f1afef1 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-sds/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-sds/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-ingress-gateway-sds/setup.sh b/test/integration/connect/envoy/case-ingress-gateway-sds/setup.sh index fbef09b014cf2..fb98b05aad30a 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-sds/setup.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-sds/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-sds/vars.sh b/test/integration/connect/envoy/case-ingress-gateway-sds/vars.sh index 6bbbcfd6fe52d..0c98c8fe04507 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-sds/vars.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-sds/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES ingress-gateway-primary test-sds-server" diff --git a/test/integration/connect/envoy/case-ingress-gateway-simple/capture.sh b/test/integration/connect/envoy/case-ingress-gateway-simple/capture.sh index c2b55d229a591..ab02875e61359 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-simple/capture.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-simple/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-gateway-simple/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-gateway-simple/service_gateway.hcl index a1324f7f83799..fbb1d402f9869 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-simple/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-simple/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-ingress-gateway-simple/setup.sh b/test/integration/connect/envoy/case-ingress-gateway-simple/setup.sh index aaaa4d91cb4de..8bcd42aa5075f 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-simple/setup.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-simple/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-simple/vars.sh b/test/integration/connect/envoy/case-ingress-gateway-simple/vars.sh index 8b34fe36ef2a3..32dc504c49ce0 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-simple/vars.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-simple/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES ingress-gateway-primary" diff --git a/test/integration/connect/envoy/case-ingress-gateway-tls/capture.sh b/test/integration/connect/envoy/case-ingress-gateway-tls/capture.sh index c2b55d229a591..ab02875e61359 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-tls/capture.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-tls/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-gateway-tls/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-gateway-tls/service_gateway.hcl index a1324f7f83799..fbb1d402f9869 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-tls/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-gateway-tls/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-ingress-gateway-tls/setup.sh b/test/integration/connect/envoy/case-ingress-gateway-tls/setup.sh index a485eeaa5b29f..accafeb7353ee 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-tls/setup.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-tls/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-ingress-gateway-tls/vars.sh b/test/integration/connect/envoy/case-ingress-gateway-tls/vars.sh index 8b34fe36ef2a3..32dc504c49ce0 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-tls/vars.sh +++ b/test/integration/connect/envoy/case-ingress-gateway-tls/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES ingress-gateway-primary" diff --git a/test/integration/connect/envoy/case-ingress-gateway-tls/verify.bats b/test/integration/connect/envoy/case-ingress-gateway-tls/verify.bats index 92a158e51b6a5..61eaaf97ccdf8 100644 --- a/test/integration/connect/envoy/case-ingress-gateway-tls/verify.bats +++ b/test/integration/connect/envoy/case-ingress-gateway-tls/verify.bats @@ -19,7 +19,7 @@ load helpers } @test "ingress-gateway should have healthy endpoints for s1" { - assert_upstream_has_endpoints_in_status 127.0.0.1:20000 s1 HEALTHY 1 + assert_upstream_has_endpoints_in_status 127.0.0.1:20000 s1 HEALTHY 1 } @test "should be able to connect to s1 through the TLS-enabled ingress port" { @@ -29,8 +29,8 @@ load helpers run retry_default curl --cacert <(get_ca_root) -s -f -d hello \ --resolve s1.ingress.consul:9998:127.0.0.1 \ https://s1.ingress.consul:9998 - [ "$status" -eq 0 ] - [[ "$output" == *"hello"* ]] + [ "$status" -eq 0 ] + [[ "$output" == *"hello"* ]] } @test "should be able to connect to s1 through the TLS-enabled ingress port using the custom host" { @@ -38,6 +38,6 @@ load helpers run retry_default curl --cacert <(get_ca_root) -s -f -d hello \ --resolve test.example.com:9999:127.0.0.1 \ https://test.example.com:9999 - [ "$status" -eq 0 ] - [[ "$output" == *"hello"* ]] + [ "$status" -eq 0 ] + [[ "$output" == *"hello"* ]] } diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/bind.hcl b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/bind.hcl +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/capture.sh b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/capture.sh index 3bbc13144aa27..556a296756f0a 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/capture.sh +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 ingress-gateway primary || true diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_gateway.hcl index 2026fb2a94b84..446a2698e595b 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_ingress.hcl b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_ingress.hcl index a1324f7f83799..fbb1d402f9869 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_ingress.hcl +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_ingress.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "ingress-gateway" diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_s1.hcl b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_s1.hcl index e6f778e5c811d..b9772c7da8627 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service in the primary dc diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_s2.hcl b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/setup.sh b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/setup.sh index f7e31ac0db5a4..72025d4f8efed 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/setup.sh +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/join.hcl b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/join.hcl index f0bd3fbd4ac7e..0f63220d549fe 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/join.hcl +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/join.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 retry_join_wan = ["consul-primary-server"] diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/service_gateway.hcl b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/service_gateway.hcl index 4f91a740182af..8c2315b9ae360 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/setup.sh b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/setup.sh index 59f303a5eafde..a012c03b9e969 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/setup.sh +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/secondary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/vars.sh b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/vars.sh index 85c791704a871..8d492ea3af8dc 100644 --- a/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/vars.sh +++ b/test/integration/connect/envoy/case-ingress-mesh-gateways-resolver/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="gateway-primary s1-secondary s1-sidecar-proxy-secondary s2-secondary s2-sidecar-proxy-secondary gateway-secondary ingress-gateway-primary" diff --git a/test/integration/connect/envoy/case-l7-intentions/acl.hcl b/test/integration/connect/envoy/case-l7-intentions/acl.hcl index 3d80d4f69420b..41e2b1995359c 100644 --- a/test/integration/connect/envoy/case-l7-intentions/acl.hcl +++ b/test/integration/connect/envoy/case-l7-intentions/acl.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 acl { default_policy = "deny" diff --git a/test/integration/connect/envoy/case-l7-intentions/capture.sh b/test/integration/connect/envoy/case-l7-intentions/capture.sh index d588be9381ea0..c93e4c6cea95e 100644 --- a/test/integration/connect/envoy/case-l7-intentions/capture.sh +++ b/test/integration/connect/envoy/case-l7-intentions/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-l7-intentions/setup.sh b/test/integration/connect/envoy/case-l7-intentions/setup.sh index 6946ce3263a9a..705eac06255be 100644 --- a/test/integration/connect/envoy/case-l7-intentions/setup.sh +++ b/test/integration/connect/envoy/case-l7-intentions/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-lua/capture.sh b/test/integration/connect/envoy/case-lua/capture.sh index 14dc00afc65b8..5268305f8ff6c 100644 --- a/test/integration/connect/envoy/case-lua/capture.sh +++ b/test/integration/connect/envoy/case-lua/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-lua/service_s1.hcl b/test/integration/connect/envoy/case-lua/service_s1.hcl index 54c6ac6501b40..6eaca129855b9 100644 --- a/test/integration/connect/envoy/case-lua/service_s1.hcl +++ b/test/integration/connect/envoy/case-lua/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-lua/service_s2.hcl b/test/integration/connect/envoy/case-lua/service_s2.hcl index a167379776625..c01f4b2fefe59 100644 --- a/test/integration/connect/envoy/case-lua/service_s2.hcl +++ b/test/integration/connect/envoy/case-lua/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-lua/setup.sh b/test/integration/connect/envoy/case-lua/setup.sh index 56a668c0ac061..e6b7e3eca3dd2 100644 --- a/test/integration/connect/envoy/case-lua/setup.sh +++ b/test/integration/connect/envoy/case-lua/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-lua/vars.sh b/test/integration/connect/envoy/case-lua/vars.sh index ac0664606f93b..091a358e13dfd 100644 --- a/test/integration/connect/envoy/case-lua/vars.sh +++ b/test/integration/connect/envoy/case-lua/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy s2 s2-sidecar-proxy" diff --git a/test/integration/connect/envoy/case-mesh-to-lambda/capture.sh b/test/integration/connect/envoy/case-mesh-to-lambda/capture.sh index b64ad4d05a9c1..3c3c6a928a0ca 100644 --- a/test/integration/connect/envoy/case-mesh-to-lambda/capture.sh +++ b/test/integration/connect/envoy/case-mesh-to-lambda/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-mesh-to-lambda/service_gateway.hcl b/test/integration/connect/envoy/case-mesh-to-lambda/service_gateway.hcl index 63c212da3ace6..e1b3ea8a8fdeb 100644 --- a/test/integration/connect/envoy/case-mesh-to-lambda/service_gateway.hcl +++ b/test/integration/connect/envoy/case-mesh-to-lambda/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "terminating-gateway" diff --git a/test/integration/connect/envoy/case-mesh-to-lambda/service_s1.hcl b/test/integration/connect/envoy/case-mesh-to-lambda/service_s1.hcl index 11e8328a82fac..9bc567caa0a9c 100644 --- a/test/integration/connect/envoy/case-mesh-to-lambda/service_s1.hcl +++ b/test/integration/connect/envoy/case-mesh-to-lambda/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-mesh-to-lambda/setup.sh b/test/integration/connect/envoy/case-mesh-to-lambda/setup.sh index 406914e3cf5a9..359fbd863fc47 100644 --- a/test/integration/connect/envoy/case-mesh-to-lambda/setup.sh +++ b/test/integration/connect/envoy/case-mesh-to-lambda/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-mesh-to-lambda/vars.sh b/test/integration/connect/envoy/case-mesh-to-lambda/vars.sh index 8643eead0d266..fbe042a40b479 100644 --- a/test/integration/connect/envoy/case-mesh-to-lambda/vars.sh +++ b/test/integration/connect/envoy/case-mesh-to-lambda/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # Ensure that the environment variables required to configure and invoke the Lambda function are present, otherwise skip. diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/bind.hcl b/test/integration/connect/envoy/case-multidc-rsa-ca/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/bind.hcl +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/ca_config.hcl b/test/integration/connect/envoy/case-multidc-rsa-ca/ca_config.hcl index 0f8d98ac6be52..e5db7ec1b8855 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/ca_config.hcl +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/ca_config.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 connect { enabled = true diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/capture.sh b/test/integration/connect/envoy/case-multidc-rsa-ca/capture.sh index daf25ad574959..170c0e3cdfb66 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/capture.sh +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/primary/service_s1.hcl b/test/integration/connect/envoy/case-multidc-rsa-ca/primary/service_s1.hcl index b4eb4b1f04fd7..e4f73b127142f 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/primary/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/primary/service_s2.hcl b/test/integration/connect/envoy/case-multidc-rsa-ca/primary/service_s2.hcl index d0f6294f72802..acd65faf3d612 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service in the primary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/primary/setup.sh b/test/integration/connect/envoy/case-multidc-rsa-ca/primary/setup.sh index de07522f12f73..efbac1091d621 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/primary/setup.sh +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/join.hcl b/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/join.hcl index f0bd3fbd4ac7e..0f63220d549fe 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/join.hcl +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/join.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 retry_join_wan = ["consul-primary-server"] diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/service_s1.hcl b/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/service_s1.hcl index 8b4d4a83a42d4..06af757cd68e7 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/service_s1.hcl +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # we don't want an s1 service in the secondary dc \ No newline at end of file diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/setup.sh b/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/setup.sh index 712cdd5e79456..17d9cecd2a027 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/setup.sh +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/secondary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-multidc-rsa-ca/vars.sh b/test/integration/connect/envoy/case-multidc-rsa-ca/vars.sh index 7bf4a264a204f..f49887ddcdfa5 100644 --- a/test/integration/connect/envoy/case-multidc-rsa-ca/vars.sh +++ b/test/integration/connect/envoy/case-multidc-rsa-ca/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy s2-secondary s2-sidecar-proxy-secondary" diff --git a/test/integration/connect/envoy/case-prometheus/capture.sh b/test/integration/connect/envoy/case-prometheus/capture.sh index 8bc4413d09f9e..21ebba78787be 100644 --- a/test/integration/connect/envoy/case-prometheus/capture.sh +++ b/test/integration/connect/envoy/case-prometheus/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-prometheus/service_s1.hcl b/test/integration/connect/envoy/case-prometheus/service_s1.hcl index 4ac588d9a2a09..d318f786c1079 100644 --- a/test/integration/connect/envoy/case-prometheus/service_s1.hcl +++ b/test/integration/connect/envoy/case-prometheus/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-prometheus/service_s2.hcl b/test/integration/connect/envoy/case-prometheus/service_s2.hcl index fb857d005ee91..4b6632beb8365 100644 --- a/test/integration/connect/envoy/case-prometheus/service_s2.hcl +++ b/test/integration/connect/envoy/case-prometheus/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-prometheus/setup.sh b/test/integration/connect/envoy/case-prometheus/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-prometheus/setup.sh +++ b/test/integration/connect/envoy/case-prometheus/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-property-override/capture.sh b/test/integration/connect/envoy/case-property-override/capture.sh index bc1ac2dcf172e..88f1dd6465f25 100644 --- a/test/integration/connect/envoy/case-property-override/capture.sh +++ b/test/integration/connect/envoy/case-property-override/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-property-override/service_s1.hcl b/test/integration/connect/envoy/case-property-override/service_s1.hcl index a1f811b527429..6bacecf916171 100644 --- a/test/integration/connect/envoy/case-property-override/service_s1.hcl +++ b/test/integration/connect/envoy/case-property-override/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-property-override/service_s2.hcl b/test/integration/connect/envoy/case-property-override/service_s2.hcl index a167379776625..c01f4b2fefe59 100644 --- a/test/integration/connect/envoy/case-property-override/service_s2.hcl +++ b/test/integration/connect/envoy/case-property-override/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-property-override/service_s3.hcl b/test/integration/connect/envoy/case-property-override/service_s3.hcl index 4e5c7cb78e03a..d616906e4c678 100644 --- a/test/integration/connect/envoy/case-property-override/service_s3.hcl +++ b/test/integration/connect/envoy/case-property-override/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s3" diff --git a/test/integration/connect/envoy/case-property-override/setup.sh b/test/integration/connect/envoy/case-property-override/setup.sh index dd82af3487d8e..744055f94966f 100644 --- a/test/integration/connect/envoy/case-property-override/setup.sh +++ b/test/integration/connect/envoy/case-property-override/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-property-override/vars.sh b/test/integration/connect/envoy/case-property-override/vars.sh index 172824ba73d10..358866872a137 100644 --- a/test/integration/connect/envoy/case-property-override/vars.sh +++ b/test/integration/connect/envoy/case-property-override/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy s2 s2-sidecar-proxy s3 s3-sidecar-proxy" diff --git a/test/integration/connect/envoy/case-stats-proxy/service_s1.hcl b/test/integration/connect/envoy/case-stats-proxy/service_s1.hcl index 3be3803cb4882..25d959520cfe5 100644 --- a/test/integration/connect/envoy/case-stats-proxy/service_s1.hcl +++ b/test/integration/connect/envoy/case-stats-proxy/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-stats-proxy/service_s2.hcl b/test/integration/connect/envoy/case-stats-proxy/service_s2.hcl index fb857d005ee91..4b6632beb8365 100644 --- a/test/integration/connect/envoy/case-stats-proxy/service_s2.hcl +++ b/test/integration/connect/envoy/case-stats-proxy/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-stats-proxy/setup.sh b/test/integration/connect/envoy/case-stats-proxy/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-stats-proxy/setup.sh +++ b/test/integration/connect/envoy/case-stats-proxy/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-stats-proxy/verify.bats b/test/integration/connect/envoy/case-stats-proxy/verify.bats index a200a5a313671..2d02010dc1851 100644 --- a/test/integration/connect/envoy/case-stats-proxy/verify.bats +++ b/test/integration/connect/envoy/case-stats-proxy/verify.bats @@ -40,7 +40,7 @@ load helpers must_match_in_stats_proxy_response localhost:1239 \ 'stats' '^http.envoy_metrics.downstream_rq_active' - # Response should include the local cluster request. + # Response should include the the local cluster request. retry_default \ must_match_in_stats_proxy_response localhost:1239 \ 'stats' 'cluster.local_agent.upstream_rq_active' diff --git a/test/integration/connect/envoy/case-statsd-udp/service_s1.hcl b/test/integration/connect/envoy/case-statsd-udp/service_s1.hcl index a416ce25a0ce0..2748dc59b0843 100644 --- a/test/integration/connect/envoy/case-statsd-udp/service_s1.hcl +++ b/test/integration/connect/envoy/case-statsd-udp/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-statsd-udp/setup.sh b/test/integration/connect/envoy/case-statsd-udp/setup.sh index 883c78e1eb7f5..66e5af830037c 100644 --- a/test/integration/connect/envoy/case-statsd-udp/setup.sh +++ b/test/integration/connect/envoy/case-statsd-udp/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-statsd-udp/vars.sh b/test/integration/connect/envoy/case-statsd-udp/vars.sh index 7fa5a238ce933..c599f12e8232d 100644 --- a/test/integration/connect/envoy/case-statsd-udp/vars.sh +++ b/test/integration/connect/envoy/case-statsd-udp/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES fake-statsd" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-terminating-gateway-hostnames/capture.sh b/test/integration/connect/envoy/case-terminating-gateway-hostnames/capture.sh index f5515165d799d..fbfd74951abf1 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-hostnames/capture.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-hostnames/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 terminating-gateway primary || true diff --git a/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_gateway.hcl b/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_gateway.hcl index 63c212da3ace6..e1b3ea8a8fdeb 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_gateway.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "terminating-gateway" diff --git a/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_s1.hcl b/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_s1.hcl index da98b2729cbf1..a0f80d75676c5 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_s1.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_s4.hcl b/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_s4.hcl index 3fba0f792ebd8..ce8a7bbcf67ae 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_s4.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-hostnames/service_s4.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s4" diff --git a/test/integration/connect/envoy/case-terminating-gateway-hostnames/setup.sh b/test/integration/connect/envoy/case-terminating-gateway-hostnames/setup.sh index 919f9cfd1e9a2..bca191d6d11df 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-hostnames/setup.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-hostnames/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-terminating-gateway-hostnames/vars.sh b/test/integration/connect/envoy/case-terminating-gateway-hostnames/vars.sh index a86dca2e7e31a..e4e3560ceea56 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-hostnames/vars.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-hostnames/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # There is no sidecar proxy for s2, since the terminating gateway acts as the proxy diff --git a/test/integration/connect/envoy/case-terminating-gateway-simple/service_gateway.hcl b/test/integration/connect/envoy/case-terminating-gateway-simple/service_gateway.hcl index 63c212da3ace6..e1b3ea8a8fdeb 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-simple/service_gateway.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-simple/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "terminating-gateway" diff --git a/test/integration/connect/envoy/case-terminating-gateway-simple/setup.sh b/test/integration/connect/envoy/case-terminating-gateway-simple/setup.sh index f8638925a4a17..c4d33d8fe1df8 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-simple/setup.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-simple/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-terminating-gateway-simple/vars.sh b/test/integration/connect/envoy/case-terminating-gateway-simple/vars.sh index 02ed45703c1e2..12cb3aa9ae1f9 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-simple/vars.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-simple/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # There is no sidecar proxy for s2, since the terminating gateway acts as the proxy diff --git a/test/integration/connect/envoy/case-terminating-gateway-subsets/capture.sh b/test/integration/connect/envoy/case-terminating-gateway-subsets/capture.sh index 8a28a10f3a6df..30d597a96aa5c 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-subsets/capture.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-subsets/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:20000 terminating-gateway primary || true diff --git a/test/integration/connect/envoy/case-terminating-gateway-subsets/service_gateway.hcl b/test/integration/connect/envoy/case-terminating-gateway-subsets/service_gateway.hcl index f294b64e6966a..b9af6a07093d4 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-subsets/service_gateway.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-subsets/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "terminating-gateway" diff --git a/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s2-v1.hcl b/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s2-v1.hcl index 2191385000f66..4812ba8db3907 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s2-v1.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s2-v1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v1" diff --git a/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s2-v2.hcl b/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s2-v2.hcl index cc7df98777ebd..aa8f453a17e62 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s2-v2.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s2-v2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s2-v2" diff --git a/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s3.hcl b/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s3.hcl index 3269b33a8117f..30b3f9e6658b0 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s3.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-subsets/service_s3.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { id = "s3" diff --git a/test/integration/connect/envoy/case-terminating-gateway-subsets/setup.sh b/test/integration/connect/envoy/case-terminating-gateway-subsets/setup.sh index ec38097fd2735..63e0708aca594 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-subsets/setup.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-subsets/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -euo pipefail diff --git a/test/integration/connect/envoy/case-terminating-gateway-subsets/vars.sh b/test/integration/connect/envoy/case-terminating-gateway-subsets/vars.sh index e6d96721e4c50..0dd7176570f20 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-subsets/vars.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-subsets/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # There is no sidecar proxy for s2-v1, since the terminating gateway acts as the proxy diff --git a/test/integration/connect/envoy/case-terminating-gateway-without-services/bind.hcl b/test/integration/connect/envoy/case-terminating-gateway-without-services/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-without-services/bind.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-without-services/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-terminating-gateway-without-services/service_gateway.hcl b/test/integration/connect/envoy/case-terminating-gateway-without-services/service_gateway.hcl index fee3bb25b00b0..4f784aab291b4 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-without-services/service_gateway.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-without-services/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "terminating-gateway" diff --git a/test/integration/connect/envoy/case-terminating-gateway-without-services/service_s1.hcl b/test/integration/connect/envoy/case-terminating-gateway-without-services/service_s1.hcl index 0891eebceb9c9..f74a67a5aef0c 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-without-services/service_s1.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-without-services/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service diff --git a/test/integration/connect/envoy/case-terminating-gateway-without-services/service_s2.hcl b/test/integration/connect/envoy/case-terminating-gateway-without-services/service_s2.hcl index ca644bb3ffa22..1f3f2edd47893 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-without-services/service_s2.hcl +++ b/test/integration/connect/envoy/case-terminating-gateway-without-services/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service diff --git a/test/integration/connect/envoy/case-terminating-gateway-without-services/setup.sh b/test/integration/connect/envoy/case-terminating-gateway-without-services/setup.sh index 91f82633b3d51..4192820bd514c 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-without-services/setup.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-without-services/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-terminating-gateway-without-services/vars.sh b/test/integration/connect/envoy/case-terminating-gateway-without-services/vars.sh index a8d23fead535d..d6e7573ffff2c 100644 --- a/test/integration/connect/envoy/case-terminating-gateway-without-services/vars.sh +++ b/test/integration/connect/envoy/case-terminating-gateway-without-services/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="terminating-gateway-primary" diff --git a/test/integration/connect/envoy/case-upstream-config/service_s1.hcl b/test/integration/connect/envoy/case-upstream-config/service_s1.hcl index 3bfcb906db70f..6d3da674ed968 100644 --- a/test/integration/connect/envoy/case-upstream-config/service_s1.hcl +++ b/test/integration/connect/envoy/case-upstream-config/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-upstream-config/service_s2.hcl b/test/integration/connect/envoy/case-upstream-config/service_s2.hcl index a167379776625..c01f4b2fefe59 100644 --- a/test/integration/connect/envoy/case-upstream-config/service_s2.hcl +++ b/test/integration/connect/envoy/case-upstream-config/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-upstream-config/setup.sh b/test/integration/connect/envoy/case-upstream-config/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-upstream-config/setup.sh +++ b/test/integration/connect/envoy/case-upstream-config/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-wanfed-gw/bind.hcl b/test/integration/connect/envoy/case-wanfed-gw/bind.hcl index e54caa47a4922..057e0e727f66a 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/bind.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/bind.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 bind_addr = "0.0.0.0" advertise_addr = "{{ GetInterfaceIP \"eth0\" }}" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-wanfed-gw/capture.sh b/test/integration/connect/envoy/case-wanfed-gw/capture.sh index 5c24811d11722..17a53a4320405 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/capture.sh +++ b/test/integration/connect/envoy/case-wanfed-gw/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 mesh-gateway primary || true diff --git a/test/integration/connect/envoy/case-wanfed-gw/global-setup-windows.sh b/test/integration/connect/envoy/case-wanfed-gw/global-setup-windows.sh deleted file mode 100644 index 080d5abf94f1d..0000000000000 --- a/test/integration/connect/envoy/case-wanfed-gw/global-setup-windows.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - - -# initialize the outputs for each dc -for dc in primary secondary; do - rm -rf "workdir/${dc}/tls" - mkdir -p "workdir/${dc}/tls" -done - -container="consul-envoy-integ-tls-init--${CASE_NAME}" - -scriptlet=" -mkdir /out ; -cd /out ; -consul tls ca create ; -consul tls cert create -dc=primary -server -node=pri ; -consul tls cert create -dc=secondary -server -node=sec ; -" - -docker.exe rm -f "$container" &>/dev/null || true -docker.exe run -i --net=none --name="$container" windows/consul:local bash -c "${scriptlet}" - -# primary -for f in \ - consul-agent-ca.pem \ - primary-server-consul-0-key.pem \ - primary-server-consul-0.pem \ - ; do - docker.exe cp "${container}:C:\\Program Files\\Git\\out\\$f" workdir/primary/tls -done - -# secondary -for f in \ - consul-agent-ca.pem \ - secondary-server-consul-0-key.pem \ - secondary-server-consul-0.pem \ - ; do - docker.exe cp "${container}:C:\\Program Files\\Git\\out\\$f" workdir/secondary/tls -done - -# Private keys have 600 perms but tests are run as another user -chmod 666 workdir/primary/tls/primary-server-consul-0-key.pem -chmod 666 workdir/secondary/tls/secondary-server-consul-0-key.pem - -docker.exe rm -f "$container" >/dev/null || true \ No newline at end of file diff --git a/test/integration/connect/envoy/case-wanfed-gw/global-setup.sh b/test/integration/connect/envoy/case-wanfed-gw/global-setup.sh index 0e21aef6893ad..50625daf07878 100755 --- a/test/integration/connect/envoy/case-wanfed-gw/global-setup.sh +++ b/test/integration/connect/envoy/case-wanfed-gw/global-setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # initialize the outputs for each dc diff --git a/test/integration/connect/envoy/case-wanfed-gw/primary/common.hcl b/test/integration/connect/envoy/case-wanfed-gw/primary/common.hcl index 06ad70b29aaf7..d30c465429cca 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/primary/common.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/primary/common.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 tls { internal_rpc { diff --git a/test/integration/connect/envoy/case-wanfed-gw/primary/server.hcl b/test/integration/connect/envoy/case-wanfed-gw/primary/server.hcl index e694d94c441eb..ee2d77e48637d 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/primary/server.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/primary/server.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 node_name = "pri" connect { diff --git a/test/integration/connect/envoy/case-wanfed-gw/primary/service_gateway.hcl b/test/integration/connect/envoy/case-wanfed-gw/primary/service_gateway.hcl index 0a33536b9c8dd..31c8747b9308c 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/primary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/primary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-wanfed-gw/primary/service_s1.hcl b/test/integration/connect/envoy/case-wanfed-gw/primary/service_s1.hcl index 0891eebceb9c9..f74a67a5aef0c 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/primary/service_s1.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/primary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service diff --git a/test/integration/connect/envoy/case-wanfed-gw/primary/service_s2.hcl b/test/integration/connect/envoy/case-wanfed-gw/primary/service_s2.hcl index ca644bb3ffa22..1f3f2edd47893 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/primary/service_s2.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/primary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service diff --git a/test/integration/connect/envoy/case-wanfed-gw/primary/setup.sh b/test/integration/connect/envoy/case-wanfed-gw/primary/setup.sh index 11d5abf14d595..f39cf66dd0097 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/primary/setup.sh +++ b/test/integration/connect/envoy/case-wanfed-gw/primary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-wanfed-gw/secondary/common.hcl b/test/integration/connect/envoy/case-wanfed-gw/secondary/common.hcl index 6b76d377d8210..570fa9d0594e0 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/secondary/common.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/secondary/common.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 tls { internal_rpc { diff --git a/test/integration/connect/envoy/case-wanfed-gw/secondary/server.hcl b/test/integration/connect/envoy/case-wanfed-gw/secondary/server.hcl index 027174bf632d7..6265b917445e7 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/secondary/server.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/secondary/server.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 node_name = "sec" connect { diff --git a/test/integration/connect/envoy/case-wanfed-gw/secondary/service_gateway.hcl b/test/integration/connect/envoy/case-wanfed-gw/secondary/service_gateway.hcl index bba04fd97146f..c010c4d4e4a25 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/secondary/service_gateway.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/secondary/service_gateway.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "mesh-gateway" diff --git a/test/integration/connect/envoy/case-wanfed-gw/secondary/service_s1.hcl b/test/integration/connect/envoy/case-wanfed-gw/secondary/service_s1.hcl index 0891eebceb9c9..f74a67a5aef0c 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/secondary/service_s1.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/secondary/service_s1.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s1 service diff --git a/test/integration/connect/envoy/case-wanfed-gw/secondary/service_s2.hcl b/test/integration/connect/envoy/case-wanfed-gw/secondary/service_s2.hcl index ca644bb3ffa22..1f3f2edd47893 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/secondary/service_s2.hcl +++ b/test/integration/connect/envoy/case-wanfed-gw/secondary/service_s2.hcl @@ -1,4 +1,4 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 # We don't want an s2 service diff --git a/test/integration/connect/envoy/case-wanfed-gw/secondary/setup.sh b/test/integration/connect/envoy/case-wanfed-gw/secondary/setup.sh index 0f4313108c8ce..ef5032115a59d 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/secondary/setup.sh +++ b/test/integration/connect/envoy/case-wanfed-gw/secondary/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-wanfed-gw/vars.sh b/test/integration/connect/envoy/case-wanfed-gw/vars.sh index 4de3b552dcf83..79007fcfe8d27 100644 --- a/test/integration/connect/envoy/case-wanfed-gw/vars.sh +++ b/test/integration/connect/envoy/case-wanfed-gw/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="gateway-primary gateway-secondary" diff --git a/test/integration/connect/envoy/case-wasm/capture.sh b/test/integration/connect/envoy/case-wasm/capture.sh index 14dc00afc65b8..5268305f8ff6c 100644 --- a/test/integration/connect/envoy/case-wasm/capture.sh +++ b/test/integration/connect/envoy/case-wasm/capture.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 snapshot_envoy_admin localhost:19000 s1 primary || true diff --git a/test/integration/connect/envoy/case-wasm/service_s1.hcl b/test/integration/connect/envoy/case-wasm/service_s1.hcl index 54c6ac6501b40..6eaca129855b9 100644 --- a/test/integration/connect/envoy/case-wasm/service_s1.hcl +++ b/test/integration/connect/envoy/case-wasm/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-wasm/service_s2.hcl b/test/integration/connect/envoy/case-wasm/service_s2.hcl index a167379776625..c01f4b2fefe59 100644 --- a/test/integration/connect/envoy/case-wasm/service_s2.hcl +++ b/test/integration/connect/envoy/case-wasm/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-wasm/setup.sh b/test/integration/connect/envoy/case-wasm/setup.sh index 54ab4d4c72ce4..d491aa92fc1db 100644 --- a/test/integration/connect/envoy/case-wasm/setup.sh +++ b/test/integration/connect/envoy/case-wasm/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-wasm/vars.sh b/test/integration/connect/envoy/case-wasm/vars.sh index ac0664606f93b..091a358e13dfd 100644 --- a/test/integration/connect/envoy/case-wasm/vars.sh +++ b/test/integration/connect/envoy/case-wasm/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="s1 s1-sidecar-proxy s2 s2-sidecar-proxy" diff --git a/test/integration/connect/envoy/case-zipkin/service_s1.hcl b/test/integration/connect/envoy/case-zipkin/service_s1.hcl index 5f6935fedfbfe..7adcedd7db9e0 100644 --- a/test/integration/connect/envoy/case-zipkin/service_s1.hcl +++ b/test/integration/connect/envoy/case-zipkin/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/case-zipkin/service_s2.hcl b/test/integration/connect/envoy/case-zipkin/service_s2.hcl index 21b8f859b8f23..a537840dff690 100644 --- a/test/integration/connect/envoy/case-zipkin/service_s2.hcl +++ b/test/integration/connect/envoy/case-zipkin/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/case-zipkin/setup.sh b/test/integration/connect/envoy/case-zipkin/setup.sh index 3fb3ade6c5fbb..b88cc90129682 100644 --- a/test/integration/connect/envoy/case-zipkin/setup.sh +++ b/test/integration/connect/envoy/case-zipkin/setup.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/case-zipkin/vars.sh b/test/integration/connect/envoy/case-zipkin/vars.sh index 7f4fb54ac6d79..c4221f8b1aca8 100644 --- a/test/integration/connect/envoy/case-zipkin/vars.sh +++ b/test/integration/connect/envoy/case-zipkin/vars.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export REQUIRED_SERVICES="$DEFAULT_REQUIRED_SERVICES jaeger" \ No newline at end of file diff --git a/test/integration/connect/envoy/case-zipkin/verify.bats b/test/integration/connect/envoy/case-zipkin/verify.bats index 509345689069c..d771d523639a4 100644 --- a/test/integration/connect/envoy/case-zipkin/verify.bats +++ b/test/integration/connect/envoy/case-zipkin/verify.bats @@ -35,17 +35,14 @@ load helpers # Send traced request through upstream. Debug echoes headers back which we can # use to get the traceID generated (no way to force one I can find with Envoy # currently?) - # Fixed from /Debug -> /debug. Reason: /Debug return null - run curl -s -f -H 'x-client-trace-id:test-sentinel' localhost:5000/debug -m 5 + run curl -s -f -H 'x-client-trace-id:test-sentinel' localhost:5000/Debug echo "OUTPUT $output" [ "$status" == "0" ] # Get the traceID from the output - # Replaced grep by jq to filter the TraceId. - # Reason: Grep did not filter and return the entire raw string and the test was failing - TRACEID=$(echo $output | jq -rR 'split("X-B3-Traceid: ") | last' | cut -c -16) + TRACEID=$(echo $output | grep 'X-B3-Traceid:' | cut -c 15-) # Get the trace from Jaeger. Won't bother parsing it just seeing it show up # there is enough to know that the tracing config worked. diff --git a/test/integration/connect/envoy/consul-base-cfg/base.hcl b/test/integration/connect/envoy/consul-base-cfg/base.hcl index 941f68aa26f6a..49116ea6e9b0e 100644 --- a/test/integration/connect/envoy/consul-base-cfg/base.hcl +++ b/test/integration/connect/envoy/consul-base-cfg/base.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 primary_datacenter = "primary" log_level = "trace" \ No newline at end of file diff --git a/test/integration/connect/envoy/consul-base-cfg/service_s1.hcl b/test/integration/connect/envoy/consul-base-cfg/service_s1.hcl index b2b685c08abec..9a883739e4fa3 100644 --- a/test/integration/connect/envoy/consul-base-cfg/service_s1.hcl +++ b/test/integration/connect/envoy/consul-base-cfg/service_s1.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s1" diff --git a/test/integration/connect/envoy/consul-base-cfg/service_s2.hcl b/test/integration/connect/envoy/consul-base-cfg/service_s2.hcl index 73d7798297812..0869e74f24068 100644 --- a/test/integration/connect/envoy/consul-base-cfg/service_s2.hcl +++ b/test/integration/connect/envoy/consul-base-cfg/service_s2.hcl @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 services { name = "s2" diff --git a/test/integration/connect/envoy/defaults.sh b/test/integration/connect/envoy/defaults.sh index f92c2cfb1fa9f..ad428e49eaf5f 100644 --- a/test/integration/connect/envoy/defaults.sh +++ b/test/integration/connect/envoy/defaults.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 export DEFAULT_REQUIRED_SERVICES="s1 s1-sidecar-proxy s2 s2-sidecar-proxy" diff --git a/test/integration/connect/envoy/docker-windows.md b/test/integration/connect/envoy/docker-windows.md deleted file mode 100644 index a9f2bbcaca1ca..0000000000000 --- a/test/integration/connect/envoy/docker-windows.md +++ /dev/null @@ -1,42 +0,0 @@ -# Docker Files for Windows Integration Tests - -## Index - -- [About](#about-this-file) -- [Pre-requisites](#pre-requisites) -- [Dockerfile-test-sds-server-windows](#dockerfile-test-sds-server-windows) - -## About this File - -In this file you will find which Dockerfiles are needed to run the Envoy integration tests on Windows, as well as information on how to run each of these files individually for testing purposes. - -## Pre-requisites - -After building and running the images and containers, you need to have pre-built the base images used by these Dockerfiles. See [pre-built images required in Windows](../../../../build-support-windows/BUILD-IMAGES.md) - -## Dockerfile-test-sds-server-windows - -This file sole purpose is to build the test-sds-server executable using Go. To do so, we use an official [golang image](https://hub.docker.com/_/golang/) provided in docker hub with Windows nano server. -To build this image you need to run the following command on your terminal: - -```shell -docker build -t test-sds-server -f Dockerfile-test-sds-server-windows test-sds-server -``` - -This is the same command used in run-tests.sh - -You can test the built file by running the following command: - -```shell -docker run --rm -p 1234:1234 --name test-sds-server test-sds-server -``` - -If everything works properly you should get the following output: - -```shell -20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] Loaded cert from file: name=ca-root -20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] Loaded cert from file: name=foo.example.com -20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] Loaded cert from file: name=wildcard.ingress.consul -20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] Loaded cert from file: name=www.example.com -20XX-XX-XXTXX:XX:XX.XXX-XXX [INFO] ==> SDS listening: addr=0.0.0.0:1234 -``` diff --git a/test/integration/connect/envoy/docs/img/linux-arch.png b/test/integration/connect/envoy/docs/img/linux-arch.png deleted file mode 100644 index 710b83b24570baad3e673b71d2c59c8e8018edd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63964 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 #@kZ!sf*w33Y#gk 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�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 diff --git a/test/integration/connect/envoy/docs/img/windows-linux-arch.png b/test/integration/connect/envoy/docs/img/windows-linux-arch.png deleted file mode 100644 index d1c05533e51f21a971153bbcfff5ae81714bbae9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61475 zcmeFZbyQSw`!9+C3P_hAk|GUCHwrTXgT%lL9U|S`Wq>pY5=t}FFm!iFcgc`~(hVZr zXM?_Z&i$>s&boizS&QZ1?7ip7&y!z*loe(0aHw!FFfj1sWI-wz7?{);7&lk$-UR+9 zCZix5_~(YBii{LSK|l2>@XKw}=L*j;Fp48^&kQhu-?8mvH61Z9@LR5aZgkipjW95_ ztK>k>VQzXG=iYh7njSL&{B(C;zwAjAO%;Cf^5aKtx+g_11DY`dS)QB)+|~)a8>T$J z!gi1EvDFO~g`ZzRY7ai+m{rSQht9p^AiU2IN2qo0ScZbctY(oYn9*5G$`aCMz`nVl zhIf}4#g*3Oyw`D{bW7AWzkZ;YDN?|2oNw;53t5VIi8F~(zll-Ph$;oUU4i2wN^^#$Xs2f+5z3R|>gp!8JGs^KK zrKGS!iRIt@`t{3B22`GqR^eZxYB@c^Uo2Q0l-&O*L_0dtzB(5reVI^NS{n6~QKGph zh@k7A5BkE6%1p{L1#v4qJk2cIFmKb2@`(D{Hf97WuUSQb<>HC9)$U713hWSS57#`} z$N4L6m&9s>NXAHv$I?)f|C93z9rMjXeaSie(O=Cb=L zNY#Ta{ByVc*tNuM$SQ57gRwg4e3yjlSfRSOylLUfuGDi$cQfNMC?$kFVgfdV=N+Sr zGwP1NjY!2TDS};jN?0dyRj9?iZ#w#dx8hH>KuJ%tTZ@9e&2b^OaV(L3f|={E@%E#6 zED80s)X?Q13w>2>9D?d!S-h)GWUj%3U1i?Ru?rLJG{hDziH^0Ki>d_IDt@B26uhR) z5ra{17gHrNQ~qxL%T9rySV#pW6W1Vb+lsj)6RS6=@E+XXBaTdWAKR2@nxcT=w&N$l zk0nkJrkhDDMo$Kmm{5+lZsJN7(?cKP@Gh7oqB~Vu5}D>m=0)BrntKFB-@UyC)|neM zAY^`SZ2dT%qNj6wnfcyt>@G%nE^iv%;0llaZord)S1LjmChtrtx3eeR^OzV-ET+P! zCc}1Ls#A)c&nVDHPMHk5GOawL-k46xk9&|;fbigxyxi)<3t5O<^(tBfVp1(Kwa~9M zp*GhIM>4L(CkB+@$>p#mGRS8e5wRq)AjasE*?VLuL<}twCaJe|Sd=%2hZqHY9wH8q zEXm;YM8BvAUP7MnY;};~+$1>o7gMZ#Rj@$EVu)UVBataF(^jXa1SVkmXb~i`4xXOhKt>H|Lp%Z z5R&e?71>gsD0fZM=ey@2Yajh%;q-U?VVaAat#GDl>7W?5Tgw#;&&eWG5Yw0=59OwJNnFI1>?U@p@JAb}ih5(`UdwyZz(TFY~16#5kmFCI& zT87pEF}6+8=#3FE?Ce3=w6A{mM&5MdG(XhbqHB>byrn4;|9~!$r5Ucu z74N>PNXjI^I1_~oW&bU$Rr*sQ;EY9xrtNg7pk^D%@50AlkQMleM7{9~1B!%yyN(~A zt$B!!LsuSYCdjV{``kt6kzM?B7wWsAzsy-l`A1=LwMcTXhS<6A)Z>^}{YK9jm}Ax| zh;bvoLBya|Djdmb&1olo&W22%c+$Q}?Hj8%2Q{xcjKi|uhV+sID3U_KPG=BG^F$WN z+3J88H(}RnR%nu>C}9fcVRkxL2b8oXWNQ)R2!7O#w#^D$1NDj8_La^e?fCBYAemCA z8&&C;p^?1^*JHWbdx)=(m#=~v1_rE`483DEMw@C4c4!kIe$p2(KyUl*qaea#vO3Sn zo|T9P9X-;sr>qv`KkB1!PR@X`C?fIK1@|~h%^g>(`lTx@w+At3J$P8iv79Lijdm;1 zv3sjVSCGS{3?pI?n~|<|-_07Z7F*))`!wO_K>N)$PX?*ypqg@Zf|s zEFlh0ylPD!aX-IA88iZgdrceNXLi&s@5~^KEX}{<5k7wu7}j1bHTz51yp-LZHIgi{ zRY|U%R0`j88EUvvMyP)Au{7vTMKj#bs)xWNiGjLrn@0%DryG=|!?!z}#6k_<=D^>d ztX(KIofTAb(0>hU_2fd=(%Z+*tqH1voXO@sjWb{+5YK;gOAJG*bJ_=gG%geFe<2o# z&n$6#Z2ho)X$B7Jng0_bt|iBCJJc_LFSIQK6w=%srFPH!k@xGTBube6;Akr&>NaVE z5AX2$NR-|fvw|PVeKOYY4+$g`V|##ykGF&@`l6R0!Wmsu1nc3^sIrpfsDz-w!BuvA z>1z$tA{K~p93k)~)Yt#CKt(ZPiIN#dMw*gK2+U5>ui#VoJd7hJ4ixdyIaW&*cC^1Di30D0AFR|ZggNDlS@rqd z@(I@G-(s-cZNE>jBquN@vXI(zw>7=9Q(&9W)b&SAFzrX(e*#5)VR#J#38H^5Jqe7k zTP`IEB0H{0Kx!=nLx%4)hP{Rie>3_MuipfN5tFhoS&|PwBePWaqCXggg2Em1X`~-% zJL6(X%^=;xBJoLM^6=6+V^>{A(bNV{cBXKfXfJNEi1WA8!-=RIr6eE0-X z{RUZaSnzlgOEEeIQ9UmLwF&xIpU4i~bcO5}Tg1Q-?8CyYWpW3NJPyPcxdOQRlbQ&N zjJs{?TV+{+M^4WgaE|>}_D)o4m>ga|NY8^jS-%%o2TFVydFKUd$*0}0 zQf<4(wUTE*&e(sxi=zt%QR9bkg7NnoJ?|l?Dscbi69@M}{8kiy3EX%ZXfe+9mz;4! zLUfVtV`dbsn46uQU8+q=a&qjWad?%+72S4BSC@)DLMbUKj>PxQ&d!!wj@kTZuzs)i zQBbtee*T5rBnFUgIB*X83EIwZ*DKpE18G}IN=n=a zjTzU*Z$l^KO&D~j`oX>ZhA1p_w9;dM=+GGKU<*k$ z+^(W*4a%@rt~LFElhH^Qn5=2L^qA#XLCnbheGQmAbe*4ls*`O;oR+TQ(|Jn%T?+ts1@T?rzaljW9**aY3d%Y9AkgYeZ3iKx?Cr@SvF0~B=E#i{a z+l|CA_M-~qVMbn=8$V_iF1tgR2%v*l3P$NF)$c7{cGcEVOKes^8EvO)7Ipk%K5zPm zv|_^L9U7w_94HP-00#cQX)YM7(<3%Rp@+%wBZ6 zL;6WvxgQYgdDVlS|px zL$4FL$=G%ytpdFJ{pV5}&U^P|Q2j@xG(*XHA8!vN#Tjgc^|IkDWACx2Qm-a*N(ZZMd%E*TaPY$|TI6O{H5ezDmp#cr8Ma>Yu4LAVoatXCa2#`qybRm%I=0Y{gOf`BrM zG=#)o8Wa3nUyDgA;I8L^zaWoVaEu)IGb;ykLFVr#ymim86tVXgx7?hth8$dtZU{J1 z=p=az^%57z7TQ0a9w`Fs+{~JfQ8Dt@#9(gv7WBRl8$p_G?gwmr+;W-15boHIUuu=H z$DW13a=gNfSUvScXLmn&Pd?*>XjvDc|oiTBNMyEYSNMW)Rn>}8#<1c(YBVzFYyvwBRRa^jyA+g=R(F7=xtNg0Sl@7&T_r7lmW=&N7 ztv|uq-zhXwB2=}Czvw+o5`3rdS(r*!IklUZST@+CFK5Rz z;l2xl*34vKXdgnK+`%QL6v33=8(g6uJ=klJ&6KE^W!W{>xven%3|5l=d&3T0-bS$w zLAa5W4+={{l0 z`;LLyocSxbW?H3o7bEu{?qHGW1yTi%QXJIEGUP_4JSx)r)}omc9$V{VA=@A&HGIz( zCuUKWA>5-eRc`yrW36mIKc$k&gsC8y*24Qg#1#G52xMx})!;z2)y?Ue2`Cw40!BNi zIV`7&<{341Kvq4g(nQk8y#%-BsF$L4Tvf0*UubtK3i^u{Kc(T%HN#rNN#R^#?lj~!%B0*qdfRv zktph^Vx&!3f6!cmTN=iuBo5opcPJ@FZlf3X%ff%s^#YNRA6_T(6Xg2j>`t1SbTYW7 zkQ651cqc4I1Gbs>S=d6_NoF6_&SE*uVnlcP+0cF_lo_tW5$Q>)KI*99W_#ELG{a z6}!3lYX%JzmEbu*(9h>N($rX~I16DqBnj|z-juS=5)Lb#0lHz%fl$R%l6(w>t;kS* zUHKPM*^{~?ia9kEN3V^62=(aR2#qjNLj(C2Dc0ag?bPUQgOLPuNs-{IxiL+ zeg^SMc0O3pvEfXhaP5Y2hw~`cAb3qFj-*)BWdqp3;$*yni_*`#OP&I}HtD@V_M53@ z=PiZv8B!v25wv%Obv9x3ymbzzYjc2_vFex1O66iEF8<-9hWM>ycuwZdYuX*b1qBY) zkCReM=s$(t{@kr4W%PcqcxO-P!g`6>jSaa@)z9>4q2u)nq+Yf<8m^(&Z5^aPXV18x zKlE#KvO|czzr2B1-Gat7+oLXr%a5llp2wjeSO;YG8^$Yx7FI8;ewBzYi_p67gQCef zsG^oK&h477I3~WWu9vq0Lr;Wikv$yAZLYR%U_hhqUB2yu)wOc(m<5sK`ji)lHVpR7 z>3;MT)GKfGB*YcTv?Pstp((Nng|Lj}!(&4h4%kzXoL8af02Ac=;#Az&yfjYmE!oWX z3LBkU*1wGzot5VttIRs!h)IQEwQtb$CHFCrcjwt2P^q48rAVy%>{`Zr-!g3FuUkqd zx1hSSGLO+MWRx9_jN6K2x^#631C^l}Za$r+32g|i@*{I)(tF^fz5|M@0Coq8H;A2Y z7H@tmED6wnvDanGbAM!w+{xq`uV?C+WT@zoL zsa3U}X4c6n6Wz__DTq@+ucGPYscH##O0fEmtmrUe_VPSP`o!-XEf~tYA_7UlR3;W^ z@g{dC9?nUA(b;#i>=l{n6{Q-Tx54}I8dB;h>#;B!g#dO)D*DgrB~@ zLja*R`RAPz-cU}wJP0q7Ars8Y8#>JvQ8>~YxTZE*o%)ZWm*O z>za$J@M4hUqiCj*M{MIENVNwUx$;II5Fz4>C~eJSmEbh6Gryg%kdVtSje~-#nMu*( z9vewE?2(W`jqe|_kg;6wU_Mm(==joA3CG8@|HX7Jr=&Ty!G(A=s+G6Jv;$aNkxwl{a%IL<4h|{o)N>JPfS){s9`G zn7`*6O?fxLXkt@_>8%G5RmjvJDO!qkw4FRrkrXH3H%!RVBv+H73{i1s`9%(gYrd8= znK}mx*{V&QxDy51Aj`>rGv6@b5Z@VfgWB1i+- zK%Y6yc4weT1(_Q4Mp^UJE5><_c6L@L*Rp#5b&2Mc+h^C7qK$*}sAu(e!`iIPx?z%~ zF;Os~n~y`;g{fG^K&%uwD-5V~N~s&n0_!ov2aLuE`wS?GGC(FhfK1f5zpM(~@t|A> zM3W#9Tc3NQ=~Yqno%=LP(@!{R&ykOmxup#4A8^nCTJtl`U?C)ivGlN&X?BlGcy>lr zy#`8e^4@mVK93eTax_F!2F48#T&yT_B8>TP`5Cui();&@-#SWM`7!R_6F9_ZX{meg z!MKt(2AD^fao9*Rsb;d3ZbZlTRpXdCQyFwYb0=7GqX%;*cpNj4E>nIm8@YJ*T)v9j zeuPMNtxWaAkSL}WxV#g5K;@kAUm|ZWt{z+3`1$kMRGfCDP0XV=53!))_x@!~SnC5X zyQ)AcrAA`;yiA(%Yt&tA^{5j3sb0`r3_`0@VqGtColLEtA;f~HFIjxKVRW(?6QNaA z6(q3z(83FwlK>I_{(bsiA;A((cXu6aU%!mg9a9q$7KZNj_xF?9OzUv9<9u(s@!`&& z?=Itr9t_po_d~b>Yv2Wc))3}fJRR;G6kD`Cg6t$31^CISa%*cZp?pui22I&3p0vL0_fei zZ2l&CPBDR#ot=&H&KbB<^A%`+kq53BXtIs!4LV>Du4!B$;8*M&vWTqW6wk_48i`WUyim+5YDM*iqQxpaZE0$uYpp& zv)V8AMu#2qJi>7Y7S9+5zM^7qx$g0lHx3JG&$9H#9Tm;;4)BPkw%RJHx&5tW$`}R4 zTO`euMaJhd@ukDfI6R9m<9V)7?IAHb+-H^cd@1E*M>2mU;%p`5Zo-z#HZVca;~ZL- ztUVNkOgw~cM)c&+l@ zv}P<6jAR)d=dGw3<#QFIige*?u%mzuw#7Ws^(g@D1T775ec)+D-`NtsOh_=HC|;?< z!Ohl|6%)(`diof*5gu2FVwM~`c#mv*k!9z-dU3x;;`^M+gF-Z6Q=FLCU0;Y{k9nrnd{bM8JUBODJ7X#jxAC+u!XXvpr$4K zn>F2fBqkqwn(Mkg=Mg%|3?FY_Wn0-h>wkwAj}YlsNyLMb>MA=Q(3O}Twr#o!Df)}f zRe;s_r14|S5>|5X-NS>U^}MN*43!ABSTIC;0IzCQo%r@m)z^Fiq9G(6;NJ{P6w8+5 z1`zp(ux_n&E!&>z=HDEKn6N=O3zHRx8Izi^VG2FUv7njAIYGA&ZvP?(a7Xi3?k<@Y z?{60&MwiK3c<|v?l_*&Q3fBbV!V(;0-Z|gtO*%sK6%I=8mH`dkS4l+WAqcGiz6=!( z%uGdVLfLs%-I{(L{*U$bIaRG`;4C;IWzOUbG`99s86v?jL?-uivJq@vCf3>Pd4o9R zK)+l+znrDqrH>C>j=yf5``TH?z?rw1>|o=f=3F?>&;;IJT}u8FvRK;69obYN7+x;{ zWJ01nV$f--m{2hh5r<%V5B!iLmU39;UWQ7ZRM?{ezU&fG{8`kqk(e&TB*Q2NA$qtt zxVteX|4dXo-D!4iB4&!PAaT(HZN=Z-C!koEEL*$rt^wmN;Nw?WTplk1=%6N$pm)SZ zUn{Zozf*@Y zMTJ!^lB>1J;_5-I1z4KC)@>`U&q(#*G09JXT~SOQr;Qig@0GIB zw`_Uyqz%$08RdOOu#%)rCx$oortbJOw#=^N32Og&g+7ox_2IDqqE zg%Z2Ll=hC6993nhg(II(iC=R;4FkxTv{Dnan}$`DAOgi%u{-fkcam_VUG{g@iFVh5 zscYhk_H5dZu@Ryfh5o87skpNYSzyPCt7rhvL1tv}Wy3Oy6#O4mhTL^`L4d6u_bhQl zSbuSxmi?4e*{x+-?dGz$6~Jy7c*(83lS68RApeJ4e!TzTlbe!%&Xlyh?F z7kpFU4US4?3s>?EGkg$#Q@@J!)_LUWGlo2Hxvp)#lZgv|@SP@y45Zj!$mm~#<71)vapb~YDvAv>yli2#c)5SW-8C&{f z!GwzbMX7vJ_aCO|A`3Hp^k)8THrTv9SkYnVrszj@&(gQJT9g7wWvGs|B4bcX&?YA< zZ-HPXJ)~O16x%;xlVW$cMca9yQ0cVvhsgJwQ0i`Lqv~_DeX{)QHb6)0hkU$+Nz|v# zK-%gOTWqtHA23gO^x;=W9S{c}efGz!D0Aw<`g{w(#J@%}MS&*vTzmG5QSyZOk=ib! zF(pfzh-x8@Htkwq$0X!%cbLO$u{F~uHtDn4zQ)6nF`^+i#jWgy-?m@#K$7hJD!dDs zjeZ+z3ttcVRYt0xXPlas>TxEVi&gL2eR2?WM#>!gEOEHM3JJQXnPAKPG+)HY&Z|CK zl+q>RIU=Ti^F5NL<1G?vT=PYBwPd5$49!53pr2nEd-nqK8b&@HD&PiCXBh+FRPgnRbyirAnSm^@+04{cU+mVzY`Y79+oYG%5Lr4Z`aVc;(k|Qv#lAWtj)OD43=Z=gw9ZIm{r79z8xkO{m zMOZjwDpg|15h(fIa6Q@na778`6%|9vZ;><9DkD+;TIK%eq{ao-ye%m~$OSysr<*O$ zrzK{;sPwFEj73mPXxbo+A-MZ}`tQQ%CoTohSQ7svWRetgVyYc8X@%5&XX)$W)E&i$ z7n8nD%5bDr;+?cSRNhV(_JhpMUZ}hBh&3UKp~UL|#P>`Sr{_gXO{!gN=g`XhR@2`+ z_6<;ymh=a%nQ}0ogoWCj00sgU5}o7s({6f{uc^ic?h(dD5?j`Xu#BxTL>s)QKA_t- z!?wtHq^n#w+9f6666I{t&I7-}--74D+guIb@m~%7W%z!@zvv6Gu5zc!0W^b6l(+hs zA_9lPUZb-&zuT1c!Tn0j8xuY5um$AJp-G)>#eXE#|0iOcax!xk62V!ZByxL0;pM%L z?iG>VPvg__?3nTdq|4(8KSJa5biYGSt-95-Z*wu|B;8bWwT!vH8Okw_bp#jSrNx9# zZ=?pIbi3g~;PHf(e&V+I%n|h_tlwF7Xo^~RQ@KnSB;~lO3Euf^)@=5Fl1#_TyOK<( zebg_G-J5a^gw7SA(Gc1XxzC0;Zo<2v^;+-N;6unsmNCpEb_ek6Hxryz&JKz6RB&Et zXvnzs2n~zHfRq3m7s6snU03aOMwM)$xZsPoqXN;LUeJea>?o{zy^?39wlT`@`ox=l z{qGh->^AB~?uTziBpBr$<)T=b;Z)@Vbv+rrO7{n(Rrl2| zXSZPwJn-?ub%n~RefN&07AtTt-oN<+_Q22>aJQ7}B4_+|Oyb3W&+5AV88gAe-x}}= zovv$7Zy+~(qnjG_&F5L)l8SZ_@HEeG&UbcphK7c^y5zdX zv241Ioc32&SHFIJTcb9Y@YY@MUM)AuP~{F}Z|`tHOAXeMqHrH9-|ivy`P{MNoxTZB z)_>pnp}p}~#2jdBori(}emXv1MG!9KF7uWpA3n8twuq zncLh^coHpH88%ozv3QRa<-46k;1n%us>Qzxq>C35Lq6mzvs-j1b;BG>^`QYOKY)e% z--bleFB`YdL-ddH8{rHXMNH%0w~1oCW-O!|WjT+m-?xeA^)2Q6H?zcf+q~)Jg;LxjjB#SCtwSKWS{ket7ZLgW-ZjZ+b`S3> zAo5vodBoOm4V?G1*lzukMUW9VtQTT|AVyP-OTBfo$RB&6JlgvWvs(pHFxfe-X)xca znU<}y$c#3iYfcEBO8Az(5eO9oYU>lt_kh~PX$JHzwW+>c&NN;wqpqogNKHa9xyav` zCS%_U-;(KF`S|TBf7CWD>N^J(Kwsa=u8(%{Szcad+IC=eb#Op{Y;juhG;|l+g~i2V-s(+DP4&R{Cmd{jf!<6F1vDw$9;;b}bt_uAlvCA_vxWgJM@U5@ zA}lbN8=C8wyB1yWhHI<$uEx_Er*yeBG^TIo`u_D>EQ`(0s5CTH6|)B*_MG z?d%25T4Uk`>L!{9JQ3$X9xYM`F3HF)H! z%hW&RKOk9_!BY+%_LlPNb0Uu3nyZMs4L|AjhI$&2h^XNk7ryD#;!D7;9M$BV+OGE= zbXs|%ho*7v3&IclzBJgy(}_7Bh5g_Nl#@dvPd*?)MtKO{k3EXg87XU5tHQmigjHde zYm#S45avQVubmVzj;+a}{(F2EF+xf(83dG%`*Az()4QJBtUG#eGBT9buKZh_bd^Mw z=#@1cf0Fm3bM2+@w`}qUTib!=$;hodJ)ZZ-rIno(Fw8N}@oeB?en8D(G61~4@B3>f z@hIg|@Di8lqTTiqmF_#Ad0Bm{@kIObPNwAHV&eufV&J@zg8k?c*pUItT=x7p(qG@7 zXuPET?t5A=d>NvB$)0^$we#ZwZFRO=c@d@8a^!nRa1p0?XfO}>=Vg6*+finU&+haX zt)%;c8Fk8K_vPaUmwlSN61$m=AHyzpfoBPgwfim$US_3_U4HdNs%K(Y`QH#YoT)e8 zjpmQ4P=)L%%8vu

14)qEBYug{x@|1<~i`Wi5!U4HrBmPMSmIc6?UM1O2{P!}mg0 zjZa>*XM=;nni1jtSWy-j3fU*p76Yqj%fOVeA&i7Zd($eGJH^g}@3D4G)rPcGZVxo1 zKSIU97tKvZa0z|lYOu6)lfUGVt_4Bl)Dj4-G1p_5!c;4ltmfO#^VKz>)s*k0x)*vZGM0;`6X)Q-?Trb@f1QDXOCB@Qh&wgB>jE$&!Byui(+g?txAL?^N z675WI`y%`>uuR|d)q`RCeCP+Q&a6Ulhb8%~uH>kV{mW?HJQ6DDafA&M#leJv1%*bh z!8qEk{gw7|V`lqoL;r$Z@^`wgR2=ARM9H^q*sU9Wa_z*^l6l6ZN8+68a$mqiv=>ht zN5A+kt6%E59lfPJl7+{SE&aI2)DI%1O*t?0fv);)N}fM}d#uw3@D#Les&9Es^DluO z`mS|cmJO%liIAa~6#X60{7fI}@fRl}IINej1i|GZ?D9;g16lhpsciYx7^I6R+&^99 z?9^1`mdFndBi&twK7Kb9AT1ef@}6jrU(U7A``~E@87yQ*MsrL#a`bYWeiX zQWIL86WM|;WTRhZWfJPB_m?x{re~bZL%sS>PQ<@6V(OrRvGSQSL>`!wHz3>9c(Xf% z6HOmSb0KEb4~#WlBrRf0dT06(A~xau*TKc?f80fU#+yfhQqxtOM~R|5}M#?63#=`26tWCz|07Gs7us6f>?nQjdEJ60mC&FJ2Z+y zRAxPyt>bI%O5_B>55uMt;5IXuSTVG|L4r7Jsb=N+by00$#hr;Vvi5>`6HB8cD*MeG zTOkOx82g$8ilJ0U%C$tF=ErVY8`<=8FWU45tuO+*q_rY~@X0b9jcx&7s z$O>4HzREmk#V-z2946hSSt8}dLd7T9Zz^g%!AAsDYL^HjDy29O8C&qp*i3@5;x^u~DOC51W~7$%+Arx<4v9^jnn@^` zI-jK$tqaX+xJkXmY?8RXJ6{Nr@_@sfDrhU~$6Y(iU2SZMc($=2H$nPvLiA3!^p?M4 zt|N=Q`DtV1GaoVY4)g-(A(pZ7xpVS8AZP(jx|R zR%Yz+m%m_N17W7;5QhZ2Rt@>KLZ|e-D3h<6K`ziuy;H_p5@g3xg-!qT$*U~C=P&R0 z50TF#wES&A-WnIIJwt?<2Fl(C+6F_g59Cd=*~4oh9LmxzF2ZLTLVI;n-UgmQ)Y-fN(A2CJ2A-yVWq|uUcpW(Tx@wDD$yLoQ@wC1QPWjcx0DpFjk zc@8)gL72Avodo9WeLrB)Uo(w+v`IuAzI)axBvuA7PIn>-GcR}Ij&Cys%a3VU#|M=X zZz8lbVryZJ7##n?{(tAV;#ESxLO~zLnGrRnv&MySvAXxo@6cSc9Eygb9 zEwQmJx%>}I~9ni z9mVuXsQ#>;i=BPejLwirO@+;qT`ta#mbFDEGMF^PuMtz6yOI%?ic!4KL`Xf1D15D4 zWA72Ft;D++OD$pgk$VLL+41v341^Z(B)sRP;-d(3hB3HYu^g{;j+?4i8lEd+D9PmD zRksw-r49J>zbm<)$L*`ZtU9)0Pb0^{8EoP=Kj6c`!Fjyi8sC?=ADlAxade(T*Vb}u z;}`{%6mTwaPOB?L7nf&6yx6qRwX_m44@k)s+!N7-2}z=hYez?iFCrR1`z)6#^1pU$ z#~I#RZ!w`WlBQS5l1~EjvWmKj!*^jKq~w4d-N%^ z-?oK88%I75<_-rFhiUF>eiGDPAyL70PH9pLtF+RWy49n7*MYxK1nn}#HZq;F62iII z4K>WyX2M}wvfM0Pkbhihk&sfq{0{D{V3o=heH7IyXU3z{Rrqg>z`!-1@FVb6)@WaV z{|{ga5zv$jd<0+0=h zJGwB0fA{iyE%+}L;6SIR4D#8F_vNP_k$@-1q2oxk(%y+LPNnOGMU z8xd-><+#Q>7b5hxuo9xs`jOe zBdxDAd@gPy9hp29hgs%>>ESE<8QNtC;{Q8+Aw(-QeM6Ixp)|I*FRbMg?H6~Z>_;IU~T7mkx0hptck!2)KN!EtbGsRQ3AA&Z=`!A zU>w~2J6ZobdLaEXr#>M@7dGttKJr0s^ttNOE&_UK`1e-pyFVSJE5we8+e(flZ2I|M zBwlsMfTwKNU5*~nto`-}y31BuH$DUaEu}x_BY=*W#1$MQY&ZB^Zq@=B;Z=ua$2;rc zf6(-|Lk5W4Bid_8o_3kL{MEmS;}Bo>-BhJ*T;~N)=w3Cs0Fr+Ao^Bl_!*GFN3ei9I z2Bs;{zzGWKEERR5@CaAev9u+66y861H9SvQ^CZ}g{tq_#fL#>_PC=XR%8($At}O6& z);U412nEHTRgJ(k%(`Eb%kp<$J@^;r{(LBu+pnL`g9Xa1eP^o5xg z(TEf=HljCQfoZ&<>5}fyl2iE^_xLZ)7oxnj8yE+;f3o2pUWfZizB@<9h2oXbWfh?u zk@97a+EHe#>;C<7!Z1tHXnVB^vhJiq1KZ3FVv*ck*8TNhhg+bG2kgtla@96^LZl_3 zCM+MuLnC_ z;mYTf0G36-Rz9@6y20popXG_pY8nS073&veqXH{bm0grU(H z@(yaiKn=_;m&2uQy&xvz@9I3$PAPc*)fE5(MQ(Wn*KiGS3PWM;3-;t#2xej?TFIdB zQ|TG*YffjI$HA3zDkjOu*gLaDy{|RNAA+6r5^wSIA9k|DpKpt)0;{e#0{itX}L(XvqVx^jts zZ}{@syBaSzB@Sbhu6!9V!%3X`{_<;Zgot)~vej3g{?0tM&(01^FoyMXCzfnOCfJ?|#e z+~$q4P+`q)l1!ZtU^=E!=IpJuvjQt{rG_yZumT%JSH=>$`V7YXGqX1PDpHb5=2QfS zCn>u^^X;O4Z$ZkokkOxUCwWLR>kLWghstmDOo~mma*y2wjz*8ujd_Ad8cAo+ZYc#K`rxi7ffnrH9eCUJth&hXas{z{;Bc%CX>gL zKc|AB6ThC|kK_<*(Ofs@y@BINGRM-!x#!q-p6PRtqnou^0{jof@ja!Ne%*vx*Ex14 z@G_R_D2t-96dqTaCKpqiq+rxy0i(qa6zJ*2Jsh(yVKJJpT$>0p^L%nUjWA%q`%mit zV4=9V#bTTRIAWe={oJakY$BK=vm-oha)$N$_fK6_$9JVnerq!DN(xW55=c`gSMGiy zfihs!0swy1K^=D+ikClXM+(>949i}0O?m)|arE>$w^LVp4)eNobf1REH&?zDgglI7uNq3kO;~enRB?Dl)_u2NJIBzh|N2`42 znt$JOZLjOt{$EcjZE0zF|Nhphg~SD({8I?@e0cgBF>qew&Bayd2ex*xc1#;Nvx(3} zr0HjAB|y@*4g~c7B8US8OvR5B`I}fIzu^PS0~4p~pXYP)KRjZZxUK}#I}hCFyL?^= zG2*yVDhvG;B@y04=&=G_RrC@dLndc+U@TQJIdO(uEkS1gR%Ku`PQqtE&06#i4DgdB z3?T6kR7>$|P=jI`lu_jKbCdx%BO%6C=J z{%b&k6!}E)l4JxlVk{GJS8~0g;3s!EaI=T$A-LQH*bQRhaT%H5KxJbfs03~zs79|s z-r z$Q+$#j(Bmb2-riD3$P-aPbK|BP1gNGMcGAJa#?d37a0z&Xz>@Yl}sswzBalg_S@*0 zfa8u%25N`^0dLLpO9VZL{+t4<&1>lnE>adcDJZfdi<#IeRkS=^Wd?E|GY0pDJ`)-G zEPG(O>>jEDYrM`r012EJ`huOw6JHFEK+rW~463qTA1+9X%eTy8$x7^41B_Gn?fB>@ zBA>fVWvKM;g350mi*@oeJ|xtHXS<}V{KUC#4bm{h-_p&x0qAGvs4IQv{G`(D!g3(y z>aQW}wQhy1DWk}uBGcFuI>#UydS;8yLFLW)h???qi#n^D%v|K?A*`oLwzX?3BU>c( z8gJ3^CWPp85Q!W~dm&Q}9^h8MHoRN)AIEgjhsjr|%}p4=&82*_5A||lMdRTHaSj>> znzsUc3P8>-mJYACI$uK{c58O>D9ZOs!MO1N3FtKX=<+W71d_ZJ*-zbkmm0WGyxor% zb%(zcgF-QVGVcNF!z3FGNOBbHbe8xFtBR#;ruy*6>ymV>EwjgE!Vw&qxB)R5{CTV> z$Cf>d(+y?T*(dVGvnBXF63tQuV~bA^9?pblLol&c@X6jDOm!#`I8<9F4=9-R5lV75 zGa~NpwK((wE$DM{Pzr%^xSe#-83F^sY{FDHYAo_tI8J;d6@2)jx(8Qq-l{o-tCNHm z>S)cHXl9-SE-yM0uqXCI1g@czl zyYl+k+=19XYWRpaY58#;9!`AYGk{;#0Digux;{5G7)cM_cWt;>IFvl_jPTvk&EUTc zJcF*IH05@k^LlKvhd8ifEi7yw3jl)HmUta+11+29*}@QzdjlyF;2b0^Ar`cN|zn*37#x+8}f87H>2@Cj}1xvFVKTw7Gjavgg>-?8O z68`}UVmZJr_e#>HM2^p;>CEv#l5LFD=PR7&h#Caunx>|vII@PPr)a=fAGet{o?&08 z0B1B(T`QPSk>6ec&_$Gyl8>-`^qbcLIH=(M-P3LPV#-zC2z0%|?qTW%4NLq09N)f1 z38QG=oc;b&+pynBSE#wklYzY0@}yyVsJYPkYg-R6Z_1%+H5)3N!AN87a1vb1{fc`9`2)r(CE)H zU0}J<{r+Kgsyz)wBO#Z!ltDuUV5pokmREeiSmdi&%-8nRI@cwNwB-K(xn(H_7O6?uP`6u z^(-CunJM1|o8jS86Gw`EkFy(L4L%@Py?b>99 zn=hyHMjt-&M)wLrXvW}7@}mbiKG3-?0Y!r}mMGRzL<1s*ygNRdZB<77D6SMnQlsG6@Mjc1K zVQ<9CartP%?LtclnE10W7Kum%t5I^}f~0+u2EDh#Zcd7*Var$weN7tm&wfnG>4z^9 znpBcZOI(65t?3~g#4ugfY<1InchV9IZsWV3iQqv@sKvE9@dw!(;E5;kXUW;Gzc7+; z^wvt?H}z&+olOd6i4J87>5|c)QMqPhzzSsiuSmw<)(Sk#)HWx_nj>sAVKgnR25JXk z^?u!q`)W`8LEVY32!(Wkwx0Wb4Un`L%1OzButjT8wzn&|3|GvG~7HCb&XbY5ULD0-(6XGvi$JU(Dg~;P=KTUh3;}xlw&@B=Dw*2muj20xRF~Ud9^jtF z<599|UR*AE%ABHQzqrP51{YF)gL3~@&d#Y>p+H(>>Y4-O8*AT=HivNROud(Uxisz| zI)d1Y(?WVAy=VP)U+fJSrtn6T;-PfcPc1wu{Id%a+uQtykpiAL+>S%AJrJ<#Tw1&K z$GiUf-rRxv**Jg|8DNf1grEPX6pxLh&u-M#2upC*$}A^sxy@GYF;WHKWu(MGF_a1v z$BxE<>=q2!EViVngZY|N)(ij%3qE?p7ObHg1-vIl5x~kL?V+usH8EPBH9oDFj_`u9k&bc#c*SeuPd{|2L2L4|g-_!TVCV`v~SKI3Y+ zS^W_)(^~3j_Y@SO$1&}?0@Q80c%&UdKeVDZN7{EkJBb2NO7NP^XPjt9BOLN?X9H>f z#{~EOE}xANI9@!BoIW4{m`434S{PdDP}No7LFlQET@d-n^W|Y^QdCaOSJDmDSxqO! z*p4|CtI^4DBQho_F36mC`)(n?$@55+&G?Db>vCl2e6LmquNC~LcMBjCxnNhpY_4KH z*W7Zm(b`+fHU(kEfo5YY>MQK%4%qTV{Cz07cY(15jNS}v04)e*WYE4gy_!eQRgz z1vC}K3P8K0R3vR~i-o^~H!4X}N!3K}(MPAnF-1sI6&sDexS?qZtfV6sK4X|7E)l7! zjARyKO3qoA&!>;LL)^~WW1@4zpX7nD^odE$zH1+gIYs(l`aH#KTzuae8!rvqn1{B% z7zc{+sfh{k+ib>iNL-zH_!W5nX4qqYy*O5!rJ%XXSZ z_W14VKQk5=aKpq|5 z(+{hqG*IxV@|D-Psj3`V2^Y~qob^rMB>LojZ%a<>2%dpS1f~e0^ z=2-;FLSKA{iW-&J$bOLs(+dhsL0V~7s$bC1v;0JE7_SG@pBiVT_J}eD>b;aE;h~E? z*Yw-fJ{b1$Q|ZZ4H%qI7T$;7+|GEJ=dDnx_4jgoIDSPW+{)Wwkl_`}(A6F{RB-;B_ z2UK-CdHU)&+~@bJr<_0p3L@hVK{21X<+80&1uI8=^+*W4KV!p3e992r1!XiaBm{m$ zt~Xh6=oJ)taY?vkcI3^Nu)~*A1ndYYAk3+hE_XaUST3_5R z8#hx7(vZ*{0jHCJ$^LS{?S>c>#o${M^_)ds;;MX5>)`VTo*@Cujs`%b9-#d?{vXj8 zUuHam{6Y7CqQ~+5csTG+hUx3;14(9;!3X7sua?SIutqyF?Eeb(XM@pYwu}9XGTSkK z0@(&=kNhhcx<7*!9M0I`v)nJvyr(-7mf-)V9giA=tPDsRz;l#R9VSv0aY+LXfflUF z!YNP|0I#LqTR3|pN5`{hD%99O}~syq*(A<4idJQa51g z4@hX$i)|NiX@G$TFex6Vc~$AEFj*4ystg>47xTy z0=}*E&jo*w*Z{IxFhEOl8HYy!@nYgkj9e~vp*&_I{#>|1m#3#EXfohLnWv7w7k5&= z|3hRk{@x}y$R_L%7k~m?T{S-dJ5j)jN$`jq{F|*J0a)iNdV>W*!;RztMU^FJtc>q{ zd2qiGM@;+!T;72hIbhJV!Cy%ndJ=b+_#OYVP?yH0u_U&)aHkJT;qi;#iB<6##KfKe+@W(K6-Df5`|kI>`>P%q z!cEn9V2)c$JYP9VxZg5I`V!17S2g{}yIxl(VLj|*Zxo^>@)WmE>z9w=Nv4Kc`(cA{+tO1Wm&=M{#f~84B|#_b;PgRNPFms&PyPK?g`9w8VlTlTc(yNQ(9r>&=)+o50{rElBc?SD z;$P?il*kT1TRHoyIE=9t_0N*vl6Rry_*noOl{;8cj2`NVp(C`8{tc>vfYa6vS1His zx&OEoj23?Q@S%W!z-LQm=T-47@C1CE-9VS3E9QU)p(m3jBiEp$-^1+Y^`l;gOXn_LRz0D6r_fs!R>mRjC zvEo`f)#Tem*f${x4c`Fp69vAI6XHbkpkt;R1VYwYC+=B@)GilCdN-FbC(n$vAvt0t zA!$M?*vwEj9;G2jwY0vl*Br1@Q;wA)cZ-X^ho(|(Z*&64`wN=<5vm8YgR!G4pRSD@ zW9}#+a%@#mkvQrrCj>mkW_e$BMhY6Zf@MzLJ30Kh(s6 zKE>BiP($UTk)F=@U~p+a7x!XR&@L-D?qbE-hg|CI=oX=7n%`g0RAu1-4-HHhNUK%PX=zrBZ9u6hy>&>~Se&-d5 zau{_!vMU-m`{0Sh+fTNoS8z`(n292ofcv&oap-dO;apI4ljFcC_9q_CoZD_xWK=c6rq6wrv49M0DH;i`Dh%TSl ztQ=JPO%g>TyMY2TT>%5nteZ@q5`-P?Rh7?;NYgaylz{rq`4yh@nxg~Ya2*auX_ zsH5jHqo8rWm#2R_MMwCzOrQ)DzsKdxpI-)lH{$c5jNJ>Fe`-G*SQ1y=1r2ghRi;}2 z-TmrG0k;we@jD|5K`$WsH8gmi?dw}u z&RbV~zyZGUt34n`w_Q7c2hHECf&&NZ>s=#pnZ3+D!M_8FT0I!u{E`(0=?VsM;aa& zk!y!my|e_;&aj4)U|;b>oTbVJ$Z$up9AEhYrjT~h!VzyM11k1XIsu=#OIhu$^eH+b zK|bBjnS%T1$7YsG*DB{NT&q3Bk?(*kHlO`u4X*J9*i#_khaMBfx36HqB{h2VV*zUU1xZ2EhWy{`*{Y%KQt=;q3`*d^S-Ybvcs#)r{7LB-0DdCXmDe;5T*Tw z&qIt018cXxE=d%b1XW2HK2K!eO$v`Tp7_%x0ee9^1L6>&a?HVDq}x_`23ekhG;Kwa z!$0j3aZcbA+8rAQNZp6eX5mA5RBA@=%}w(fKJXZ;z9&u3hB_s+gm;*RMf9bTV$)ha z`lB!V0&nY}Msf`S*6efFd(Bu2TOMGWrCOc$syp5x7h6IvovXA~x|kO{xBA(#<27l>A$oRD;O%0BryTTGs}Zz{VytodGVGN-I1bLy zNDI`cp(H*Cf5QNmhpw|CJH!~W02+}-?tw>t>0MkO_j+OyAo^!Q=@@(dkxS8UWBvsg zPd`@vq;B#Huo*a}?BC_tiJ}J+6L^#?lnnH0V8i~9fB2s`;v?OG8ag5aW+(0riY#1X zy&~!>f~C$T;K3;hP`iRw`PtX$_X@iwJbHxNs^xX3 zxXS~X>jpm12v$j7zV}E_cv*!aL8@*(;LoRAd|3E&CrlO8RSx?T5bp|6m4=i5@mY~i zjc~6fVE6zix!TqH#22q%-Cx~{6Q8mMF;gQD^w>$y_1=H~Ssk>GEuGO3N1b!6URw;n zK_Q?`5asc*W3}jZ%4w-V0FWQ1zILQ~X2S160KEYzJrNay({vz}4Xd~3I^&-(=WNu) z>lf|=V^$RZ;}@A<;5S{9Qg7ey1<6oY?Mb=hysS%{@k3Z?$@qmhqdH25r6-+V$B~lI zbD>F>4Mr2~SVzRBLnWY*fLFSVE@BmE(vY(O%0OD&DE5t5#@-*P4Kj8P7!2$E-jY}Y zAO>+^Z#^N{8o>E$(EWH#F546!$g%WB>`f(moalaTNhrvr8tw2UD>PWtaj;f+8lG4N z*DeRNwIf(B-ORQB1lG$=KiDBfUa_}R9e zLHD9{Rk6#!!YPEDP-zoHZbGK-vpHzW-dIsrFif)Zk{m0|MjNvU|6mwH-D6_@p>tAx zG)WYqMo2x~J(bKN!&qcOPw0abPAFsVS~x~zKz5?)#baD@8F3PpE8R7}G2aul^dvT^ zEC;;Q66E=~^)`>5)~@9; zX6CkrWr{12Vsj$O3v4Q;z!Eu;U`ua&AG+Zz#vBai$_-bpI6dH9q&1U1YV$?y>EK=c zxYTEqmyJTM8IYf+24mqIeUiEJ@Ezw^20(KSBhVHU@UzY>fjNw2wp8tt{W6g6hw zq$xF9N?P~w)5z6yGUPr~a$%N7UA+0uWsy3H$zM>-*hw$iL-(70=|Lz52fIgkRoB)xcB@I_RIa?5$8 zThWlP%_JIqPxt*G=;m_fozcQ9J-f)uY5YdH{#no5R|Y1|A^07q_>L5YNVqE;o!7lX zBgN^ry7X1KdpIZGo}lZ*?`N=@lvhbAd|buZJB$^USJ-U zBgNdR;4@{xcAnCMbG2mCaqK!v?pI^_fyZy2wek1BHR&h%;pLm=5^_&Zzh3PO( z**JOG=sD%}&HkFb)O%(Y|8P!|Ogf>esVYQIj@;&ELq^um^}CM@AcJ!ruo#Poo+SSD zz1~ba2BskjDR{I;NmUB*Xk?kol;3Th+&VAQM)gILUxGhAPq8>qRTG#ewyE5B4t073 zJ>8_tt##<@`%sWM)FppCo1d%X-pcE>Z>z@Ea7)O8oo1QBsx%ls!h(EQ`=QKy-r3yK zIUOU_XU!2Xj~rEM=Dlwo*BBhz!Yum;THHyvCR|NI&=E0*OL7BfsLMRtm*{`j-@=PN%q#@&RL6JW9o&CuAdn`$A9lDeA6m;z zn(rh$uG4w=mJv%uM>vnIR)C9EKhDsJ9V_)kJoIKE%X}g8`q3})jn`pqE1b|fDfQ{% z27NU`*#nP<(@obdqXUjTaL--Eej#?5%&nMBaiZ%yzY=Q+rGDVy5GV_LsYbX#h;<|3|P3R-ahs4|=(@~%Wt=04YKc~@06suH_CH(i0< z&49HwMZhqWLhRpjuuD!Ob(f*V7fXU{)u9@Crm`hN1>sfc8cE6NAb#1tp`+X(f3>EI zCXmh|4Omn^KMpU<7FG#%tbJ&Ja(EJ5ADyOYt-p{uMQQ^%%=QX9PYzwo^0p!oabN9H zO3zm_f1U3uy(K+1)~L`c^X7B?^OI@hOTmk!v9kUF)mB>Kd7PHs%@M(pVQ4CHx%L?a z{-=40`d1+S*GCLkpwfB#sjofzPFYb;+;e8R;!1`JKUV^Cj~smkrOO$NGVSxpjyRjb zJvVf_D;OjPV8pA9R-O5PseY4Q)ScQpc;n}mQ{REUOV*7cW&euY;UpAkNuBu) z4|tW3XWKK=&(%(vk&}RIE{seoeT7OChknUC=i<>Z1n7%6qKI?14ePelira8hMxz}e z?~{wX8LHPav>kY^wp#ITc8UUDqe$0ZDdcV6R4HK@@A9|iC=IN+bakM;)EolU+Wo$}p0c4I7_CCF>!zkt^r8MaH*8UfIhz)$I&5-& zofx4{BmE}n7eohI!+Tz~TdFMiCQ;B@Bv7d;U8PkP9S!8V`nr3sNG148>x z?6-({^BA3{sKZS|XfIg{dVI!Qhj^H#(88(*_$Hmte*Q4G5O;OGH+R{{ey~gv$Yx~OM1Gqu;7HlI4%w1`#j8i58cnA{ z6*DMh<|eORs6-R08P!X;5)3|Sdon6M&YbFPQ95e;yf%DCaZ@fhtLLOFpM;QDsiVCv zOHWRRQ%bYMP80nweXY7Js=D=;&F0f4(khHkXX(M3)#y+xX_`^U46ST9IDmlw1Ajn1 zg#s)7XOK%xW7Mxvu0y=JjeBy{yTWh)^MJy&12k=)-~p=s&(J|f6&ZDJi;K$}dASG( z`EaAt$4i+=Tjz6=Q!mGiyU#OHC2RS1JjXQh47Z(c>Ss$~cjx-`dBmNowNV08z0cE2 z;U1k_>E;NK@s1hbB-dJcv}4#yj+wLqicjaCr}H?B=C!S57TrEg%qv2C^CxRd%R$kn zsi)U%gJ`rShDzpc)4l092);tsa)VTvKTF(ju*9L0UR_ifvTUn+H^nr`d?&;x(MWv| z9^C_p%em1SW9_i=^9}2VH$68bLTO*5kds5=^3@R0rJxsi3df!R*D9~M)sGes-QhHX zyH!CS=R@~6%W%y61Ntjin(OuqZF}SX3X30b{0ij7YYpu>J9)jKpHdYjvOg4VwJZ?l zTwF;G7eeFk>2FT`WWx8Lk0zk+iv&d*>0698!?|nGG%;{jzIBhWi9xQJzbIDN4#pshHIgQ%b*kc^hw^(l#frX8SLfkhP=no3(0 zR0N(kS?15XU(&X>bso-Qd;T$?2NY2_{lf{3>sD6&%Za}`89!P6C(i#{GvE&B)};yD z*a2Rfs&bz7Va3YAc8MPR(_NYj!DAZgL{Zg*>Q!7}SbX~;@9WXNRfoFld$Pw@1mqYe zYz)Bl{}rNj-4;hm{`W7%O`(A{S>)@`8~^R%@jUjB&hKSoBRWR^cpu!y%HU+;LOqjP zCvK}ySJ>W#I@^IaRFngD8t0hmd>OE?{R*Eye-7bap!?r-5U!d60s~xOM*7C%UT^mk zs%^k$@!1oAcenvLf>?S$V8-^t6Ikr`i;mNvZwlDf($D)~|NdSGzIB4%=6OKMjd#ZE zOT+C{8kBFZht5hs!K+3Zv7v#nBv>`N;m5O+6U+ZzQ82qo2)T5R{oha6E|Hc?zPL7B z>ICa6TU$dHhLg@VHeVkDKI696+~_Jb6DTbnCBG;6&tvnpA@43Aw;X7d?A}%8p90)p zP#I{zpsG5Qiz;uY)cMP81AeW1eYmM%V9m1weSP6~ zJZ%!pk&dOdi>ezYYM^qFR{jZI*XEjQ!j()$t%4gCu88qMd9kmG?2AdkvGL+`jD$u{ z=GUhzTnfDmUPRzj0-D^exGcC&y^{J%qKN$BHo*-BBNTy z)*7%c?`OA%U!-=ZXH;)dS$I+?9TqNKCF&{?xj_i%JxF`nfMCiNQ%T39-0p>a}q$GCo${Pd|}6 zlH3>F@#y=Q!mx_46cyZyaF&63o39Ak-CpsQWj#>ne0-A>Q^gg}bPefd$nE_$ ztkW%ZQJTtQ`N(#Sxdb*rA4CDK$a*XAO^i<{y2_p*GCZL) zU8kcb5%D6zgoLIbUx$+s#&su}hJ0;scc2OJDpy)AWlVZC^w&Hl4|3UQErLPV5R- zLy#CDUkh8%zC6TOFg}U*MF62-phk#+X74#A13BVQY?o)>T4=pyuK6;Hx|1ZtOlnXA zs>Q9l**-%W0|{qVZcmV2pG9V1gNY=~VmzWfv3g2hmtMw0D7E)eblN}6bUiA7v!Anc zxjp1wBibLwk-bZG@p=r(*#8MGbBSM+W=EVns7&ydwHlQ@`qaTpXJJCDHT zeap)vO11X?9ld$VVh$;o=9W?)_NIE}HU)PyL4Q3Ry}|Q95v@s+C(uaM{6LVlLi3yP zM-Pr`0$?y*$+ABeMxFQlo0em#f=7S$T>m4shOSR@2L$6+NoleyAK6{{Olt^{e&a`- z@R)2i-P7O4i?nbdnZ{Npy0lZQJ3pdjzBrSmb(5Bn)(ZQ+IIJ=#S?;iLVf(VrrC}U3 zgIV7#K0ePU zix7;i?66B$KYjuSf69hHFWC7e>JUE!KRrMV&Y6;#I?LG0uW`e9XFdo>U#uM8D_XH_ zY!8CD(z4!YfeO^ckOsaTzJna}BuE)jkgZ>PJM_NoF_uRnH2MOuE79X;{Tk)2Ld)sS zqWTNQ*o;_dyJQEIQsrgAW-)(=;N*{9v4+SvS7cU5wDX1z=rAHbw$fZBf9nE? zY~Em#c71a(Q&aZ1AQP`WE;E3Q@^vUuy=u!N!OkruNadt357Xf!kqh(OFe=JC`bMzb zJ++emih68m+&K5u7JT~5ru7^N_Qc+)k0!ErQg$|$1HiuJPXAbJ83-n*Pk7l4mE4?C zD>i^JaWBifi@R<#ITUzPRkdTU((tg%(yr@6Q1{xVQJPVOV9xWU1lxPR?h+)~l-8;d z3)8g+8Tl5bRYiR>H>JKf>v>lPf-_}ZDTm;aEwIM5;UUt?! z+zx^=_^d^v`ctpH>?L_`_r7&19Q>>hUB zLgM^9zzoZ~q^0@@_ZFX-M!RnYw^=6pppwHswy*wF%7Ne3_-4Epoik~7IQY$NTsq@{ z(&MT;{nU36W+w;xWnVw|TDZ1xNU*^JZ+GegJ7j`w~>R#3xNEa;i zN6IJ!3mo3?n%$F|9w4oOA<3mE)l|y**D43fKf%1Hvgj*vlgs(v>XfCQhP@C-6gMn* zOtSTIJhF88$D0_jT^+;FNyd&2XkQ=?Oi`gHQ8dB!oiS ziR4lzCd0yf|53qxQr+pqG2VbNie}4=>C*DdR_!GD)xp=HeXBHN)Fn82*g_6U#7^Kg zt94W+-*vQIC({49U1LR+gj?By{k*2FGv!+2EiMnE9ZD1J=Jk6NeVV*gvn|D@e@)=$?lt`Wf?>oibIwjaq#ws4Ed*?ZUKu2yUCTizt~6K zS^MAcfW=ignx(TV{S@Up{Lpn>h9}shK@T>zh>qc+?`i*TlI($g5#poX6^zn~xnl5; z<&k2@4E<%!d)AIBzzBj{U1G6}$@~+al;}yoLV0s=K&2s*sBKv9FnM8z@#8YhwZS>l z0nPeaLwc?Af^E}-h7Jqf$g}RjVg+<|b!5H_$BTyjQNKRm%u4L{7!&ik9=3J8K$s?D zZ%RCG%Ic6dFR=TluZT3Nbn1|9MC)B!8hL`UD0Q>xv=4%0Q`!$EQLA&a{&{VSQ+SZ& zW_To|p(nGMx2ly!DYi{I(<|n&4q3m;5dd5OQx{e4oO_@pYv%=J(uo`7wk1cEL z>mDgzRMPnHph{O?MN&D-wP=H6US*?NUaWzYlKH2L&PoQcnU~&?h7JtIw1|B-;4GNa zQ-81#kHDTPK!iF53o=+((m9hyOjpu0yUTiWonyUxmV_})Dof=9C?5NMroEmr^ur=l zIDBhuFBX26kuJ9>S)wMzTFw`s4i^FsF>8lL7^0#xs%p~u@A=SKhcmi6gN`mM9di=) zs1X>H)l`3ckkBAcvnIs@NKz1AUgacLN!(CcOv4yst@K1JS>B;J%0w~m868Vc;h)zp zP4I6mHt`A7HMo1S4 z_B$!%Ky4^F zziI$X*31ulN8W1raXhg;iY4QD%A~wKn0`A&gV#7TuPTg3o;h)kG%`tMB1OVP(PKz} z4Q+Q9(J(7V5^QWin6%ugnh&dvdmsAa7k+;3y%IMow?F~U{Y}a!KK7-+o=vq4HUDCO-y<;{*=%BJfb5d(^Dovd47Im2Yxd}zreZwO8 z<&u;4LR%r}aZTvMr(r|e&T_o6b@Rg+N!{{0?aO<&!M$RYM#~Qi4)fyE`xDwLnuuh0 z-s_05(L#K$=Ok^?lViSgH>!N{vkFa@inq!5%IlkFy6O|&!xIlB(v7~Ld4P#bUn$5( z9ndS8r#U7%uKDY%3RN)m6j<{}oqeDPb!Fi~vao!3Q>F8Bea?9|mkCoNxa{OiyFMo~ z)tU5^C0?aj9@PQ!jWDB*XVMrdC~bLnaX}u=!O(Rr6lR_-F_hs*2mQfLX{8qRSa~`} zhpX_zG;M~J`G-ay(pmSZiCr+1<+?)Two;im%({Ar<5qzPMa4$qSBq7PNPOxxZrWco zGl*tnFylRCQOVD1Bb*d*d1#etM|+)&C6el#NOzsO>7j_0wfLKpeLs%Sw_3S${KOnw_Zkd9rku>A+Bq5r(*ULx^UAV7b;;3+hEu`1b0Rg9kN>L)u@&U zbrVU{PK`uFU2|fjw1L_gO;a(}$_{RsKMX9&Y|2fS3cg|!hGl<8k@Jr=29I(Sr>A|cPl>1SnWoZ?_X+qc{38&HaaVq zag)x8#P8Qv9xZE?q%95HI(74K$_WN8rV&^~`cWqH{q+`_h8td)^ zpYRV7NGTy>V`x>n#K}q5`JS8epTgC9XJ7Fk)v=s8+|Fw;hi|lY7dAhB|Xni_W@!C%Xx`&EdE~(mr4~^0IJJ}da3BBH8FOnU&%X_V= zwe;jln%35mvlu1TwK~$j#N$<^@pH=k)p& zcRA55XDi(yOLtE)tUx@h>A?1JZs%~wjPZ{JZH$;!pY(-d(@vuV0dk1O+C;Ba3r77u zCMCuJ;X2QG=oRt;)d`2nkig5~R8pC6b7l#8=?p^F?5{u)t! zNLm|y7QG%dZ-la)&LhR20q@nr+{g>gNp7&{h0kVI-|NO)G`;wtNwL9;A#yBiB+p6N z4NsgpI;1=d$yJX}LaO*m^MDE7);wQlkc24&Ep2Z*ydf1t5C98oQntCMZAR=pr)XoF=#HNil0i zK&c~70y&LlCf+E1DIqCZa$_P#RWZT@6;>aVjrD=gV*NTis#otO5vevcgjx$`$8xkE z(8j(Bh?pWY@f2O`l4_#=YGq6Y(-lTyuXis>Gha_Ep7S~jD>~Ju_R~?qyUnuKG&-C- zjq$DDWDWGs%Gj#VyZmfmIAER}B*Pw90aZSJuHa-c*+!1Z5wpP*Zn|*0tzat*u2z=drZ#1@ zjy;VA`@x~$@bb+f@hzu{X4%EWjjs)NzalBrMtp_jQdl`Z+VDF!&LRa&rnI!-OZLVWUOs@V&&wp2(VQ&~=#CkYKQK>OI2xf7~Nt`77lQmJYC;F?^1BX6c`7JNBRDPugk5 z8N`thS(UO3?#fM^n!*|sjhrT<*y*OHNX-;DZT{+WM>mT5MO2Hbi=jG_!`L}LPI9fJ zP!lp{eWSIQy2S^To!>tD;T}<;fd#}Or>J>Xxlk9_1Fm)D%5g}|%X;B_QNZ-f#kZ|T z2}dEnfczeaGya_~%P_nJC&L}Kj4kLw)W&9A7ZY1{3`au}vi)U6z1voD&XKQvbpIYv zPGm(deP^^ka^Mqr5-;!RAOEyx!0TIZaaJCICDQ1U#ym68$SDbEGPC}^?&KqTa+#nh z<~$*rxrW62K#*^^a@edZu{@Ni6ucu?QwP(j(4aAXE@!7JFM9NDx+;4{dRSZj?&QoP z3-d^(RT)pLL~7BMW^j`nDliBGF9xHshTFtBfL=jAyZR^|^*+cDlWU_0iTr^TP&y>? zUp)M}Lz^`Y{O%#y<7?(oQw}k4k*Q0W3@`H+=Figj?%E4J@EPKX#(RqkcA-Dsccw|eq z`g*pS!OLJ6x;`+Y^ezz1%5XFK1WPwpUk`*=^oef4K^iST~3+;AdxWh36M3@M1{6rvh)Qw>vGTq8`U!lM3J( z-y{C)?#059{>CGyNrmw(v!xfz$AhZMfA70x>ZQ(>8H5i$^rQ6t)vR-oc7dA|=>8pj z3x?SbD{(@P(~~w@$6Vg3jOLG>8-lU-1zrpxFU;ruj;8L{3e~Nv8%A&6@F`jByK>y* zI<^!2=8hJ~4O;mynxyIb{Q+8)wcR7`dJB1{^mBWMUkVHns4o=~u7g8S-%c8vfw?Xd z!Qs=NRfbdtefg<3KRbOT%Nr@|U=O}_)?AJIDN||)t4BNr^>HSE#>e^cw1cl^*ftef zfFo#^o^dJog=x1<4$Uu^<dNVzsI`VLA4agx84F7IQz1-B-*JuVV$(Rra!NLr{+@W2I`BTNB+s-@bfT%<=WAq zw_bH8hE^}J<_jT=T))zxPs;j8@co+lDyqTylsfL8t|cyU$pdyKRdq@?>H~Mt;rdN- zdy?iCpFAj|rgq23)n(M?eUiz4%;%YrrBf_bECS~NXNTMbPgNA(20c+4$JU7gx-e2# zs+(KnF+zLoCNSTiCpPfKRiVc^4E>LLV+E>Zp~=l%P*|{w()5oWOdrk26D&|*IR{0n z(NC0wGle8wM%6D+L=N0iE}MPI8G+@2udzs;j%cP<9(ppJ+OVQUHllUS^h9+IIQbz> zZ|&s!<3sqlXO3l%ppUCZfi3plP*A)s7k&lHP1i~av<(M&VqA@4fArhbbWeyqgR*PLvh@DL#_!xBaeR;dIaGuYA*RC<)*C13+={lP zQ(kBVdIx*Y(UdpNeCBaDE=sGkPvd*T;M1mDcv}iKzJph5|I?U$0^AHQFpB4mOb&TS zlvCR7vk)Km?3j*R=J3PRm7=vpA5Jek_>Vs4zj|OwhYBX0D~#CxPd63sH+W|Tr=7W? zPViqlz%lq~tV+?}TM%HN6Y)ECfWd*8MnGwR@H@V@VL^rjt0eqSVf2U2ic2(0W(D2w0GmAKGXW(Q6;DxVvS@DBzAiSw8smy;2op-ebGF;D_kL+WU zG|5qKd}d(G^ptHk?-p2k_{rE7!Bavki%v<~`0r#D_D^l{v%X5dnIp&sm2dCnJ#n$N z(YJ(rBS&QaVEG_CuoQHKdb_YnU5y{!G%Iyt|EOaBzRBm9X$HMToMf2cjPiZ3B9-r1 z^5rhmrGTlLw9NPn`CfrRfo|`#B(!>%csB4=vK{kL&+v;wy^6l{u1P>WUQ*-4fbMX~ z-ilqhqNsIdlIv)lFn!Bl7Zwhg54w(~D*D^a23Z#DfQ!x_l8J~E8?)EQh$ELQGT|W+ z@`X>C*Tj+e7iUd|B4gN%vOT@}zmZm~=Bnp4)p}=JvWKod5?NKD*7oI|9x7ONo~L%( z++S@gRU2CiPsEkdZ;!iT|Jv=!3Du9BN1GX|Ky8BCC3Mjn_%|vEFrh^5tz zX$2llMInkO^1Y@tP@OW~i1se53p1kf?{UMwEehYC!|5&0Iz?*Jqg9g<=_EsG;nKuX zgA&lDTW1`CqKra54aC0kLWo$So`jONhK5q>?XbHC^_@_gC^#Gogjxw)j;~vtnOP*L zTi&lZ+I!)4baclC$%J5FnI}G+C|BRvzIoW<#!;!&PxukMe9EcvuXX_+HKOsBpZB!L z!sMFJ{n@fA{j*pI-6G?SVP=gU2()IHmo7rfk#}IH` z#mg?=e$lmL^mHhF!Wo(p{eF7Ee#YP(b1$=;e?Gl+SHm(5>82R-@(r+9eRL(gR4Z6U7{kt=@Ah z1BO%~IU*ZrWUSLl2W*j1j+z3&p(VR_9#+`CjI#UCJ+iw|$B-S=?bep!T3|}^@6W`A zT0(r=(i6;iHyE-nRqgiaj9SP}XKe4@&+AK`j>k!K;6}rFEOTquU1kw~g!%s#8zDg* zgcr5@d1-9N%-JirjMrWgsTqEPkK2r%H*HiX{;zA| z0Ty~-KCTn9hvS)nrw^Papw_NltMCZjc_3&OnssEz<`)|2AGHU14+i64*kU`}&A_xx z$29L|E$5Js85Jul^?V+-cSG}KYNi*hfgV1;n6wH?O~&kxyX7V)`6Kf#Dk*lo{a=|& z=G1e?4Dnizy!cFBTc}mn0T$EAF3+d)h-M2J^faG;gEo z^f?mvf6iEd+;!*79rX+URhI?O2&3?YM^v_>%8i=@|99r{0J0vhxuySm)PwwPPsH|g zSuD|iRbnw5%#L`xfBBzNAZ1{XWG3uEKJGp3cEqneZ?W0$0gf#WrW0qu zFgX5q@Q=7_65HV?!t{5))mrSv!~WEKjdAGfxWWJHPH+25T4VhEBLk{QffFS#w$WDI zk2&%^TAeQYB}GHw33diqbd{#`*hz+I1<2f@mfUF5{SKOW{m9LD-Z$Vc)QLTXn3$NR z3~0E9XAyX9-aSX0xMD2yXyzP4A`)lb1t}+FRDDTAq&I1($LJI9Cs|8bwrdI)Qv5ye zi|6qR3j?zQRqu*uFhk!C%y2$Y08Qa2XI@eDZEl=Mqx^rmaKc zmE*nC)i>qHcw4unz9m1R#%g{r^oD!~a z7&P+6FI0v8g;Tov4s(G=u4*VlDRpwsLZiM+JAzAB;IfQ3&jKe7%v4Uit<=suiPsSl zv@{7QzF~VJmO=HhUkO-nVUT(Ct`B~_JS_?9ZuiR}OImlxm3&k0Q#0uIm}*$~bYED> zh5vD%kB;)DfzIe{cSuSg~2ZZ1rUI7RAC8 z;8>Dg@6RUn0=!QH)15Et`R9l@iq_PjwHxmhYTvtN>JBkm(gC`a615*C(!Pi~(nwTL znW#6&dhsgr`J@sQ&blSx=6ZS3Az$yLuqvAuGA2g~J^6E^b3`Q_1PgKsf%4q_%m9(EiyKf1c;SeE}n?qKmsO?S_5*XhTq@wp- z%8&<^y4@O^7TGb*AEP4tfW8qdei344%+bE)+6tBo2+}w)W~R3$Dm!at6CPUr$|PX` zwkx-#bspOAuRLyvlS%V=8On!(@G^oKhMxidES=U*0}jqXYVsmguQf9<#WMmj7Xh%+?_qj%pM`Tl7vuk zWF?23v-c(mAtcToMaWsn-oMvLeLj7@pWpBIM}O$<-tX6VzMik=d^|KC0te)`)dpn8 zPk{@&9A53|8z}tjW|tM0__+)EpbhFIx>9!_ zU`hF<&qqR05-`62wyp4E>EcuubNb4GX<4OVtY4(3g3idI`tmg)N-ttqO1AbTlrc8< zLdP)*UBCOc-#)TZ2UUu&A&< zQ}ugsGOnd!eqKqRgVQi8;x&@#lJE?)Ox>=3kKcy}TY2H59qlP2A6j_7;2i}XkO(5p zia8NB+>NvlhFW+WLkoTJXgYIYEmNt4gIQ%e)$^KoMQB&iM3~I_tDpUCHv=-AlCv&y z!{)2p?d?F~XWc$1$x`IYowymH1!s5ZJS|7by!RTeA~D#urh=3fpJ!O%3+nwJ-tv5AUiGLYX1~puIEI#d=d$H_7 zEGoQ^g(3knBFg+!HY~rh-B{WCs{yk4~-3PU%@MR#l$sSt0)j? zt0T108s2#K3c@Uo2>&8drq$*@%xU0&g}NDY$5KNqeZ1bsz+iu=xm(4<*XSHIamTjd zw{Uk$+O2S6&)XkBnwtO7n)hgT(#JE?ov}O0cEo$R-LT8I6WPCwEzgv$shpgR$ORqy zQzIh@(v*nv@}vTYzM~UAS2(+c;1YsT7$4B}cYUfvqIVNnXcp!!eN-b4Ig^-G_(N;t zgi)$V5v?eFD4j?8m09g%LyQ3$jZA>XS|z{6tM*SDJgjohhv2Sj9Ak^& zp%Q}1lUkVaER)h)ucj}jU!P)TVti7=Xm4U>zRQ3*pY;(sWCTypuy}10ygWF&T48`g z7<(kZ>c5*?Oil6eSA~ze(lKdUrrxb(eHadC<~RavP%fFyXlL3}PNgpEZsD(IM7oP5 zi=V)TNT|;)Zh|}%^j|li%Ye!&DZMLSST#wB>3-( zA4e-$8Io>CyQEFmye)KZxnVD7ai$4+D#3_BjZ|FJ?gv1PF$Bw6CDUL1G9kP5l1UtY zvFlW!#tLL!TG@>F8N;Yv;$)h^cTRpAcm5(?Nw)xnT47!Z@ADJRL$*3cq$54AUG6Wmn5Po#NpP-`+vGm#Qx7^;f7|?fpE{FV$CSn1+yTX?E!MRw zOQ2?-anfw)A!gL_ODJYk8U&17DC2)t#IJ#hcS6}}z1b7jdW~Ywh1g2S8TM09l#;iNu%^EG9x#IAPNN z_fP-JxCDCn$ZHbdSsd!xxd}61=QfFS%B1#DkBPSj6nle43hk-goW7DXT!ljd8%09y z3i{V}1v5neKzBk&DeY!*%bidtzB|M2{<2H{#B#(xmA=FS3E9Dm(HmMeW3R|nLhRXa zCDMkP-%cEy2xfbOvXa*~Ud$I_Og^aTES6!A-Zti|T#mN%EkdZq{8Q*Qs?s=HGTi^#5O;+#=MkfD9f2p)vgCRn3ekgQJ5b6zEuTfS)S_}cCRfN%Gp;4%%v`}e z{9uy9l14qaRBCsI>X1OL!TmUkAs1xTHU-yXLYQ*NlbQ=m5&{bh-sB1|V&yU{LNJiG zC>NWzsS9`q$RotQ)S1rk2<>`NMsY<34-Jk_?X6rvzh3~En-)nVN;SG;Q>k5dr6h%`akrZvmLE@d=|u3&Y+Z?~H@71flo;M>7TMk3wGi3Xg|768uL<)|(US=& zyc++~T8?(sKBMG`70KkTAZuOC6xrN)^5~B{hzz}Tbi}Sk@Eh6K>T;6L#nI#6dUN}p zi&m}s1b#}I+DkR<9geu`i8u!+We+dO_cmRpbI^{g)%eofPbju5t*Bd;6!#g9WDHd_ zoST;77k)`v?unw&skj7nX`9Tb^x|XULkwUrl{&okPG68p1HH(&R!w-)?umhoCkUQW zTND0EkBc0zYjB6h!`R$!KDg3WdzL?yOm2CyyTxCc*kyI8$3qp1yZ&P07r17q<2GyA zJQs}eSN9xl9IyY3*;L=Cw zGq&nC?J-au7OdVR4oMd{9{oblEnK{VybX1Y6Nf!9l+$p3-Z*yWy(Csk-?LS`Vu^}g z?zTpYU|xP)ekb>($1jf+M%F|y(Ob@g!X@=PI=pT3FmzZI*%#9=~cXfqUnz zsja)U@UaAIKa;BBvjV3LylQ^@K=+-HtTDLZn%mlX)uj8OU5}j`m%VXx^mvfaV>(U8 zhUIFKb_d>PJ*lq^VeW!Dn;}?!`7d=+1aa_+k3vmtk@JYj@RvuQkCY`m=p&PFS$)I~`*e5WmD6>)M*)(1{?Cc4O7G#e7q@d65Q1dq1qKmgom^On%uDgN1Q#1eKSLaYf}Y z)w70kTaMUaq(K75SE&A5ScSXjga8SI(zd$HlvK$F?aY%wvxm zn*4R^2H%qEE!md44t(^Q!YGplV&=zs4{jAuyN*v9l;53=r{RBIz)uprpv{ea{LZF2 zwJF3U;{s{(nWxFOyl09CD!0deXu2D<8=aOBYhzvn2OoSs20Eq~lI?;jZs?86S?Jeo^!mDn?2GJgXaQxGBFnu+m zc2ahCAisYSUMTKCP4BAl!9ox+VN{B0tqTk5H_xm*-6>wWY$eGQkkS@4`Z8G7P&vy) zW&R`I7t^oYC(oGjVJ&HPpBLD(I4U1=EShb1C&`(C!WmoxQXNqI=@K-C&n9mL$_A0Q z$Nz+$BaF&{hCfhuk$Qmr4qG+)twzDWE^y(G9aor{qRLK$dM|%v)qLDg9hI+js_-dU zP~0xr_6PW0(D_@Im-!9e4~j9p;^vbrGd|2j=BJWNFy@=`D>Ldm!^wqVih5Bv^vEf+DZMg2mO?P7*cu4 zt8z5}&y#rWZ0gv@>o9f}7Mbmav4A^wdazkyn)^E{`!6B@DzF&ILM@UD(1eu7kJ04K z7bXdngP~jP$vYgZSu=QmPZ2>qp!r|p0-bBNt~WGP0l&HTHX(!YeC@cl{b#1|XVgiw0&-dQ5==0@5&(PU3o9Q`nG9Y4v1YydKtcX)d)xy-#255+s|*2Y z&%0f&+qb=`7~3dfV2|4aDW2u_^>h{Y|Dddmx%WutCTnoSInl-3?JTvt)4{ zXAWbR}UgtM$82YGyra{k&6!ZS5xeAKQd}GLx#nw6>+CD|J!Tw79x3&2X8D!eX{$3_WO}+)&-$S`R|+HOudHffzW+ zzNs+>Y(z%zARlGZ0L)}F5@3G*Zn*^pedY1j)}Q2^i+=ahs-5d&I9@a zL%^M8C7E42Hw91vy`tL2wAsi}=wG$!b{F?T-KP$K)EyW>8*cWSf8g*CoCV4wApC=m zpe3NtfRv)Ok?miUSsD2$gyJWV2?U5*WP5eqY-4_lSNER`Ag}y~7_E{Jx=MGJiM4B_ zU^k;sDJTRtwP0EHv2deF%;V;l&+9c>y!!`-W`1NwKMu{lkhS7GekV5PadTZo({aS1uFk&i`8+Yv0&H>@Fx@wJ>m!&c4Gh8z$OT!4l&_dn!9d z)qp(;QQaR=6C-q@`MNn7g9N=9zuo5Z%pgXX*NjL?M0)a zjF46wI}dl@u(rU)90vgMPy9qIZOBQHSXaNxFD0~4i3;ViU@Vy!9PY+^sTDgo40SX? zm?w7HbGmX8ds>);uYGPSUVP$n)y>~uC`mwY1Wrh}P_!&Inm?)Q0o`%`BXPF33kYQn zp-=@7?jw7jT`2HL(d9;;G3|9eS2iC{hU|RH$5&EqT58{sraX^ueZf2y+KL>+`GwGj zN}lW>-G)B6mc?Rh<_p}QQU>*<)OREgGNdkRWZS~~r;93U5s^pNmErBBek(3xXLcVo zRc`U@Z?HR1K+KK(($Vxe=q&<^MhZCy)8C^bge!jalmnyW(=C#w-888aU6zWL`gbhv zL%!;SP_!A^k4^JQafpOnp^48|4AEb8r^TWCG4JwEC|6$LIesYuI(+YJ-D$#0a6sjCe#*04$0X_dcifxp26te0_O!F4=U)D+ zWT8&rIsM3)I7}(lexU;O2}_+*1p%@1#G_te!V|r$0hX_wv)0_)y~Ca1X;4o7D6xEd zqp&UNkcu{Ar4pHUnNOphzA8L5A>iUhYyiu(qx_lyJ?R>bMVDMl$@dwYGp4=GMOwMI z9A5xVq&|(3`+qp>^f$s5K9L`_b9W|aIS^B{s$yR-Cs{G#5AVZ@ z8QV{!Fwa2Hz((RHEmA9%S%=@`34I!|;3Mg>cuv+iH~;=gb65!e#PJGGmq!yuB)H2| z6gw19MuE1>UWKRXH)^@P5!PeOe*yxm#Tpo7H`RvW zBd(`dw!gNa$K(^WbRjb-8yX&2nf|8=p(Y@0yS=PcjA9mn{#8m2B8;H;<@U+{R$9U; zd)1?tTduGX`l-Frx~S|>jx?-{+vV1IH+#WQ;a<@$`53o z$V~eWc?j6uCZMbzh%(UyzCXlA6Nuiw#3ukVci>$f9JN2T%Yf#9yy;K5^xf_#gMNG7 z={FhmpRf3T$$1ojbIf`u4p?P~h`0gV_Al`gY?KJ7jVUqRn>XeE|7=0qLZ~eurzK~# zjIT!&9|DH|L-gAsLT!oe8Gn{G4bc8u@)eE{_KwI5oF%ZA2}Fl~ze*wi{U1*TiG868 zz*P2Ip8g^sgjm6I4$eu`(OVgT{um9a9)W9fz3@sbn4iH zql9@9U6Ia_hp+uC^f_FC!%yB&|2m<+-=pb25eVM%v$EvRZ(li3C9g4T09%`&M}Cc! z>n;KF^S4Csnh`Vv(TB+ddDFH*LKPG0w|r^6A;=ezP4L0-Vm$Th5gtI75YUZ(@4>5k z1X(4z5K9@bF3ol4WI!g#f!a8nVGK|y|NMLK9|8>^!v8)_htJ6m1Ew)STz?Plrz{^N zj{iOK;)Vk%mVd0@!2znj@@w=e=q8OSSIUh+Y8M~5w4qg ze{bU-%liS`RMbcBrSyk+HIH9V04TQr9iE72-gmu*G6C&|lBV__%OBuCChSM4Vu)|Nd?g64oAt7kWnzxY_#+qyPo)7yzDG#d2{`T+jxG zIsv?yl(3#tKfWybXFL=l)G%m;*tQs`lmUuGZtxFqhKi{HFNo+3HK;)Vu7k%Gz;pzm zcsfadM=vd{Q~4Hv#sJzjakt!5*KrJBp(8*cQP1^89FT?w) zGJ44V(NlGJYHp@+|T_N;fAs54TyIK)h*lS z*dYX1v+|>{Z`&8GR0kl&F{D-5`NKJXIq1NJ&l;gNxEvqJ#NJhuOPDD=&ImyM0cWi3 z3qT?P&Y=YjmL&+4oV+Ds)t$dTR1siZ5=eZ zg?l@M#c4iIe^V12bE5A1b3Fz4HeYe_^`W}%-KR#p*uHPN#RIT=Ir(+y!6;Fhu&XKp zA9k* zBc0xaRzqpvtOTVQBgiG>iP+64Isb~B*1T4(Ea^G!8 zl@YMcNWVsg@wd$o1zwbc<>=4cfD{XC@SJ)$Pq(T9XCaqKWi9n9xo2Z+u=9-mOTK_H zv~d#2N1FBNZk^`+7aNz21SsAaY5d%5g~7j0$!yDleVJ5UVGQBVnSqi(*ixXyk)UAu|rkz zjr>Tqz_e83TO2Qh_PYc$%}UUe)g8(0D`m?p&%9n_$+ui|ro**{dJ_t}0wbGxx)KU` z1*MBQ9%NjSkb@a%npg)c(uYev4bHCn9l+q1*1)3S3o{mFBF^5chq9QYaHuTx9{kqF z_tF{TFl%Lk8bZl%75EqEBx%OR)sa$NIIpwYS_0Wp+F;klj)zvs7xZ`VRLzu$kYafY zM^Mf?Hb-NNkm*Ij5t34@zjUD+p(Ydck&8eVd#Lelf#r#O%`c$OkK)hP4R>HcULh4< zad_Gmk0lp(E5~-|b71+Sg=lU3InqnGxSV=^ZRjA-U`SxaUXa=5$7*(Ku2?&!v*UEH zz%q0py4Uldl>9I(&b0Lf9i(b_r!gGxU>aS(44Rn-C()$~JTVR{WI-$&1<{s#8nLgz zBF?oUO*yDE*d=}+J8-)Zn7R)=1wOz!5qU~pyiRd zVE2m?F*2YdTDhdq;;e{@Cp*XxfB&ccv8TB)nVOnfx8}6NPeA3dGG;{^gb<3a*OYaO zoCt6FheE9I1@vOT(KsN|={b(<>D>FiUbk*7w>GG`W7dnKKP=q-uittc19VGacn1GD z&QBjuxiRQH>;0jzQ_4A4tsdLz(UZRzDw6LJT)MoW83^JT`N97jWwFSIeRyX#PP=En zLxo}u1|wT*=YJK(uRa?vMg?HN0Lhx+e&}}ac$_S8h|Sw6xp^={y3fp#zn8^Rq%= zhX5zS;XRz6QrBaP$L}I~9{4SjUN;)4_9{}^`%Xz$+RJne)LjQRQ(`D7D1bLM0mSOy zhPn`Y;DlACjj==8;FaD1bR}kE!(<@NRbxZg?O+uiqgcHnz(q6!B8L}$%TDd~Xz+pO zaptf2oPd?>z4r<7n^%!Nq`cU7&uipY3Z3MnrK7$ACfBEPPZmnTdoG?lE6c+K_-^6LRqwCV1JpQvc9F?Wyu4U3jaPBtQBplXb4 z_RBRo?|*Gnvl=yvS*jp6cP~Z2ha7z6Dx?Iji9=BG4T+lN5QAT!XuALuZParq%m$n6&00Z+MrUIa*aXh&i z?y+9$1zYW2s z%^;c@ZN$&IzeU-Ufkyl+9mM>D*5~}eL6hj8*l0)l$sdQ=v_0>;R_dAlMV!naqhC$V zaw1nbFsPN(6PkCiI6h;9Z|(ED}&E6dm##675Ci3o^wo4=IXkwOyDkGAEScF57;|ut9nw>)w((v0~bHnxelgb36T*%Xd-U zOsk-$n%7tBZ@Ymzwb}-|$^2~W=xKlFoMS3kU(+DDw8>tSC;3O;&)Z!fu%tTv67%^} z%drONOiYR8ez*J%&30B+->`%smw00u&g?x$P=Xcxbq)%5Zo2l?){d)h^`|T^-WC{5 zWP@a7Qu4Q#G7f}2eGmr2UFsn9U@M*D#paBC?d>|du4|LeHwX`rt63;vdY%71!}4OT zEWdW2;q4xh{#skT;`39FQ`_C1<6KYoNqmyME|4aRKga*1kA;ANR(_2@fA+W4r;$Y< zm!gX#k4;Cw>?ZcU*ZG96)a-hJqKPAOL1E(h z-yWp6L2?}F`jo+<3fGuqD!QlS4F3om_tJabQtKU1zwuB>g(ZBQ_5r?HnUCbs!h@rQ zE;S>o`7pr5L4GlSYk4k-t#Az;(bVr8I1%U8gq5sXm0Wt7rJ)Ou|0W(~l5y2S{%N|q z9Vqs#T~)yl{`toJrO1F{?Vi@H&kTE4Dh;|m;x0wGtY3ol0rKB)QtmrF?CtYLOyl7*Tzfsa1X(pnipcbhEia z;7I;lFYy&ooGX}s4tXgGTqlmdY!kf)qx%^KK1&3QyfuI`r-kfML>mOJqQIR}}e?OWnFPNp666EYE+TC;6-{$s>#p4OaY@8A>RYd~{VH;k&RZOEH zx2Mh^LOG2HmD_iBww~v_)F&DF*U)6^n1c4Bd^QdO3EYjhBCfCbu*YH2aVGE?P+nrr zX=Is*8Zo$>AQ`7%8dxuSe8~2XOM-Co?GWsO_gsV)f|IMk#UC~ImgM8unSAM+=zfrVyETZavT&QiCk2IIjdSQd+nUNat;%-TGy|a9uJz-)a7`CeNOC=x|8| zpX~l+@=er0eA_}iY(-pTS)_)Gzo;~CtR4E8BZQygIJnoCFw<85~ZBGq6hDz#_ zPjy=kaGsxEVY2PklNKYXZZyOQP&MX!>I;ZW9q4)Lj5E`tzf46@6(bpkQ;7}77V(BR z^{W}UD5#Emx$YHvHC1rA-atuep6_f}+ia)kvJXkc^}pydTkUdkez?&Y4;~)*SJ$E$ zi29WOvK>B5{)}H726-%CHJ;fOP83Tzd}mHF&LmRDaVEw?5gV5+(wW1PudC`<%J;(6 zZ``It>LY4&&-u_%4sdt&2B%ExB71&BNh4aUlAoTo=Qul|25H=-9*C^UL{6?@81z3r zdPmM|EbZkXVJ(!rMSE|X7wU@uJViIXS69R3NQXr8U{4-?#6cXBVZ#qD=k8UnGxVN0 zMF)AwoPX(`r)vHb2>Iry0gpzWh?ZJ}n)z*4_P0dsnKO3pp=m)9Fxhn4FGiPc+_clE zc|=5!{YLqE?}8pS#3<}-jBO0!nIToOtz)BN7f&lx^C2=%spN4{iV3gr5!CATiOuTF zddIYK8zm``#&ZMT5XWFu!lBHs4Zb3I&jMx<1_nsFO|Iv~QcvYvQKqMPvD!*Hvjo&E zOmLWGR(a9dB{; zV0+Do6ydQO$bpi25NQ0Zq4WQGj2C+1J~o$8i!)bad=9Ftr6n2v3?cwPfNQ|*A@ENT z;yi79QhSSx!C1^S$C=7z^vldW+LFi$(}=$EObT)i){xU<*nuNj=`w3{Bbs0p=~?usl-_urj16pu)jAfVvjS6iHXwaySo zc441EBcIF@;o7?0%=N;hZTa<#fS*8lqs=@5Wdv1HSY?Z%kkACHY=n)Mq4umfH zKGoGGB__fHG!{BlRi&oni`&MouDKb+U1oZJWoGl_cMzO;+fYB(_Mt*3Ln455RGEGs z=Np90g@meftM?o;jJazaA1?fi9Bl1@Wux~Xc7bBWQUgSI1R8skO5SD2zY(}0;E=7W zvYgkvDcum$+luHB_bwqS*|?>}t7RslBSbh;ZW6R6<;7^cmn0&VxTNObgC(*t4?Hx%% zIYPJ`o4vov$*!4Ke)P>SJF+yen7yX^MgwZ`TM%PD6BwcoBANHnUqoZpJX5$7_V?#U z)G>l>`b|s3)TiF%F+Yj>i}>1uS4u}2&S|jz6%1ii8DEinuSCq0c)lpGKGW*-aSB%v zZLQ~5uDEd+-MTl zs#?b{OlSM8AvxLBtFH?!HM-O-e}cm?u<>vXbIvp@A-7`4L&ohhGaD@ zX@)dU5ADgw1Q3nBPj>R*oqu1ews6XH_synDbw#1`v4^%#?rD(|k@UgS>~;r#h5 za8db~MfJOG|aXr^*qFx}6)LRP)XJyI*z6-_NmA z!W_$ge=lXLqw_xV)zyjSNW?@k(R!zUv-JpCIj%`}f1~V^lfH($L~ax0D?6Y31FK2) z@3|h`+qv~gql=oUH~yX&iOE*ICv@h+2^nC0sI*wf@o=Rq1N1jVe=7fbcMgKiFveQ_@ z)7blM%z|)!J&1|aX~?lKhE)Rtfs?qslg>lyDaE`Z)8y(6IW*7h)2Hy$&Uipn8cHYC4FV+%-zNKWByR$*dHM(BAUbD$l zR)SpJCL%^ zc(LyRJ}>=G$z3{>EfTrqM$PC?aa7nN0*V+D;(Y<{)w;sny7I+4o%ypVrLT4ZdlFWT@KoS~^Y%cdoJF)rDqy584wWY*PzbX};5ok(W^kdds~u z{BE$?8X(r3Tp3I98LIJIca=V23a`Uu%kgtSiBlZ+)`{*Zd=J1H7C*F|)Fy#V_cx>% zOeWUscEy=w1e_A@e)OXhT>vpZ?eu=AojsxXvsc)7i;|z3p7~TUrBP$%54@=E?7Z`H zCBcXI-^=P8H@26f(w|qozAt_Ti&7TU&Sjy%JqzbT=RL?B#H7yhvt8(&TFN5I_O_ma z-1Xtd^{$80px)3WUC6`xNKfMfHdn19uJ_3MenDwNPvD4u@3hv)_!UgV6YN>06wzSB z<AIYZK(_h+zz&x6YBO_hEGU^x27^iYre+W10@rn zax2!2p(SN7@xGshB1IF*FU3Hn{2hH(j!*xKjBSmKzl<7hFXN+lG=ZSR1^5ija>Dn! zm`$p_85*Z-89MER*18rSN`jFnd{(`&FRr$g<5>R5%W(d_O@-bN4U%-pW@WLqu-Sq| zG~5#2F8{+p$WEdrL)$%0J>OPl_jr(u*=s7-ns{XlQX$Otv{=M?0VcxsbD<5l0X(pT zHQ>q2LrP+t6Zdl8+}MEBSw;7VUYUYZnB6oQY*(IYFkbuZ4HvWfVVfTq=ua4eIIiQXm^?#Q(N1U*jMYo1?(>e7`ory z-x|#G|IsYGhxx#0ewJ`>@q(Y<9A#ME6t2?(L-`&fpXq_udFY18LMLUm*V=n|O&CSf zVu$3*i97J;7pn&9UasbP*4T}W<;lI;O4}N8+8tb%-xvwlZ!i_gx_Ii~+>aim5Xiq6 z+8(e}Dc>Etyu6_EiFuD>dS@V0UZ7;-$~OL31@ER(G|A_|h5cIT@9P-$j@@0`^+6uR zl8IvZS5qODSLS(=w8H(Vux0m%$&5Z&`orR?tM?b-%{;hBHd%w|=CnYgXl(NN9x=mDa0=I3J>uQ4OwhsI5HI8pPN#e52Npe>0iZ|$O}Q=OeTHxn>OkRKPKHWvtp4Zkz6VxTnE{s~+ zH+bNwru^hM^xH4V_UGZp9bs>RYE}XlH~8sOpU&oBKLi;$!Dh5r?NUd>kccV8+%oJX z2G<${s^aOagF%b($?|HUQBNb5V?F+#PU61xL9dpK-$~OCu$VV(O6}v#dbPH2j><3f z8cCl`F;LG#hu!Y!y^htrE8AC-{Y@RSOAO#`*n$ZRb5<(<{&J^$rWR{>NeXee><{bO zjg#%?C6M~qCieZjfRDFCdk2U6eOA()_B0)Lb{O_xVvurR(C;-%s5_}dG}%sh6V}#! zsdi%g!mG6?4a~K=UPdhH_A36Xz;VTrHjUDbnuV+f{H&2lF}qP;sR9um*F9<~vj&Q_ zE!{&Ra@UdYC?78z!a3|{X)yc#vHa@{i_$_AhZ12Io-)W{seBU=R+KWRU@+W;qWFX^ zpM965n@4ADUKZj?@c~_^vX=icB;$*#S_An`<|-Z7w9;TLaiTx~j9T~i6CRB=?SiEJY=n!u^6r?+?=7}Fg@a-> z^1II_wLv7eLZvG|-M?HV0ZFCj5oPR=D%4xjTPqHTY~q}YweCj>@2=7q7Sm&=g(g&6G)D-^8cJswnI6&$?)uJ z(NpQEvAfR$wAFl!ZIeeiBWd=Z$i;(Y{jDm66<6t<&F;?wBjnM!#O|c!{`-IVc##G} zBaeTY5z@(9io*M)402pHQJtTUd|8oQ<8e9pnNhC+$|+vXxHm=1w1fkmcjjLTz|7|w z1#a*B@|73Wl;QTz#vhbQ=Fm=x=D9Y%FTlbEirh!rlC!Ugpv?7nuH}T5T&glAPj8}# z@)j()O=G}3QSS0Vi^MZp^2x%tLMFSnj%RZ}h-M#K$_-iX=;=dgV?DON9g)o%X=N^0 z4MpCT6PgYQY3e!)xqCF1mV8!Oa}1{cSTdw|lMz<#6f>4n6iT7W z;}WH?9#CwUUh)d6-o%>09(RqQQ>GBzYWwOzRhD_$I~LB2f`MCD{J4u+c#SgUxOjKr zaPiAx&-69XR;Dpl5u8%sgR2KLzHR;1Tm=)4$v>@o-HMMhJkLrBvKx2q}4 zQcjMEr_+MhSmso*ruH;!S}J-_G zUI(EOmanVaj47)|u4q!#q*nk7uI_%@FTp zN+Xx`^T=x~KjML#G90Jxe|ht2$;Oc_XNYwC@w}IwtPGq>Tlf3n`jetL?)^F(n%bym zN6xRi?%fd%tF=vy$vxFw>zLYS8^%@?S_M&=OLT~mh%ci<$KFo0eNBapDM+bS&W!i~ z$H|3l!reZ;$j#frx{lpsS7)Fko{#!q-Mjd}Z%jn5;^#0<;0)i~Cn>f5s^xbCYWHkw zCCz`stETlf)f)C2<7!MF_7%d5pNe_~AFno#NcO_`iDWjxE{lr}T?@3~jkVUXS-Dh} zS2}L|F{{-pOq(?>6YDo+p8mGBA%RC2r&UxX@>q!N*dR~lvLrKh*YBH?OpCSA*oD1P z7;(q~T0A##ckN?YOds?~_Ch+uFVf4+B%S;=j3n>*T^;!9MgP&Qxs8NFHJ|0Qu`P+f zM9jWwbf0JO{n92e=kM;qPLh8jWh;By&wVoR%C68T{pKWd^XvJe5 znCza_YC44b`Cw)Tii&+u*5^3wu;uZt;F+_*P_)Evkl&?tEp{{bMfSCWy?KmrwYYJrFZFbKLG*!TI{kKK>+UAL3U(mh7_h zxsB-i1{{$tiIaWvN+a&sGmkCHjk|NGBAegQIL)JbY+w~B9u%=D2zB?2vLh}tYbp{ zuqg<^f%l!GWAZ!o@cH?hrO6mlT$|lJ?i*YW%^bT>Ilpz25H3gJT zn4){}%G5ddai>PR^~R0mFZ3kf1^@vCHlFiEIbY@Zi^W9ULBwOPwR>y zW$XH$(jYr_`o~X0?%(DY_`+S%PaOMZn}-kZJF}N}Wom!0=ve#>vACTHn2v$_$dFdm zOzyyaniON5^!+O2`?`Vi`)M!sDPvJs*0SW06)VER{LAwIlis=%UC*MziqG9(_bN30 zZghHIbb0jZYAsEQw^#AD^qX9&X8W>E%W#&u_Vcm3ZCW415_*7L#1nI*B>9e_*p@Qp zz#Ed~47P3LX-s25Yh33{a5c!RocxZYrzVjBhQ|r31HC%;;rM`DhH&GB*E|8I*(^N5vdam;LwwkA)O=5Kd-UOLu&a4yu5Y*jF9myH2 zS8K--qm>acK`l#N5MkT?ep4qY`gDAWEV$&qzq@p3ME|m8Ou^8>6c9^U81KgP8d2zK4W#<8{7G8l-D zlz^M=?yWP24$e;>6j-M*16rQ!t#GQN{G_+Hk++$=5Eey{8ReSE5^Udz!PLjT&zQ3m zvYDW_DCFcKYB~Dge&$zUr|GJ@7<6c(NSjjO0tJ2*(scpBT*ABe`S| zQ)#h2mlr3M82qw6TieDltFpBhp}t{UDR3st!vapc*K|@uD<|iXRWS$}Bm+Bocyv3f zj~BR);6HfI!Ixo|*=@-&@iV2xFEYIEb~Ar$Y#{nC!<6AO<5Xdw(Zf%fk6+ObWJA4S zPF^{r2B@;}zrLwgac4bxZcFie*_zF3ux~90Z>t9!hiB$lF1PB?_h&7~R^HXzQYmZ* zHpogWa9dYS7=85L>nxXb;x;r8u@djf+$^pl##08FLBwfU26vuFv`vo6XuZU|{CX)5 zn)Cc>D$>hv{I=RUZ&^!fqfC))-z9fAL#$Yf&1)$8IavC1GSBVpYrQO184ifNVadh3 zL8T%YiK@%5AL8x)>nyRboNzEO&+TMUKs67aMNf#bOU=baVRbCeI~?57`u1(2(U?4B zMXVQ1#is%7RTEKNtWR-d*E^9@jv^x^pN)BQy1%qeD0#T2^O$w11x908$!E7dd#k4k zEWXSB!Sdtc6PH`Z)0up;x+?$6#6FGf<5c-bYd03mmlUM+dT`vHM?amx@GR%SLZ#H>kN)4v-ZsrH@+ z4VS(9bX~Sgx1wiZPrxg)rrAX<`@h!v4i&a;zkYG=v$=3=kVOeYI`P2mAX*#?ZBnkA z;%xjHKn#`L)@?j^6$jw^!puMYu%3LrwkH!^XTP zbZggr#xUqrSz#z?6qI#7*|#*IT_g1Bvv}IOM#%Kmmmy!TFr%o;hzp%17@k!7>mY~XsL$HGtYuqdQL4t$foo9Rb zk;Hl}C@Lu+zKCvW{hH<~I6>l=-nqh)PYP zBCFHxRsP6xs#~=~V0vTm`xEN{sdG)RJAyb8ncQ@qG}V>bxwQ64M0{X$(1^hZiLW&u zLb~$p_QGex`1UiC8b%{wJi2k9W|`$j%?+7pzx8J_@rG8peW$W6$~troa5g`KrPvBo z)xXq64u>`%SZ}JI^^n2bkFR*T-WG1nb5_EzX7b{)f95Ci&|dFm#Cx8Lo$9Mq&suMZ z&HD|jx#d#a?$O=O%DKyJz}!u<+TN}abeQz<98)wf;)iFwQXVPx&HKSBwBROWgIdgF z;)vucvJ9VDk}W4I_{N-ZyUQFIUNZ9OmSeb-u%}6mD}{6#)nf3%6La&?p*y*1GQWhgraIMZ^qDR%}KhJ-2X@+-A7(%V0a5>8P-r8bh|iPy{_G#bv4x zL~52_wEN9Slghc~nj3vPGj#q^Jp$zD1eKm*>dSEy(lr;oys<0o zs-n1l6}nreJ$rm_6#@hz zfq+VbvL_%?A{IzzKp=?9U@1@}p+I~I1dx;ninsu>iBUre0>&U1!Y+;AhP^SCL8a4~ z{_Okl<}G*LIrpA3=biI?_gI+J?xxFEc4UakGWS^vhK-lB}D$8KxW(Lt*<*K@89mzAC!)Ue_O?z#WQ?IiP} z!1!jjalknpUhpl`iTItY?8Ih;Aoz!yua3r?yS%e1eRI=r-bVrIzE5X65_WN(x+ZK1 zTdH!oiM~~F1Sgk=b@qcB&_%y#@cicf)+IKqm!grUO%FjBu7g9QY&(uaG{9&lW^?96 z+G72N1VkA|U$_Ygi+=qSsa(L*UiG!~*$2pOj<$HL`%PC_1@$g{CQex#20H#v0#7N! zsAz|wxj=5HIl*wo@Bv5xEDS$|y#Y2DTAi;qyvvToF`#T4zfgOos(Yp+Fp8Fz5&3#z zX(rZI;CYe8lp2&Cy2=S4anJh_Vk9-k(w%6X{&0;%Ax6Aioo>a`wKlp+-#Yq}_sV#W z$7~HB-?@l5HwRzh12c$$qRS5u{caMjl%DJY7vxJ$@tx~s&oRPYv#f4@a*lT*(gS)^=z*cFj{0z7+F<`gdV|U?RM&+#{@lDt zpumqvvv;*9HLoB&u@&Xot{3(QmW@h8S^h zWQ33c+T|6ylb(J zaA7G61u;{XQ)50T{gsJ|X>|LHzlg3hjQJ5zXN1Aqs5oR7A_^%Gu~ByZ*wN~p%A_K4 zAMLQ{n*1T<^TLWo+NJ5pj-WAPvLT=Cq$6vV%YMmSJg>V*=z9ci97d(KQ?YjWX(2ma z;dB*K>&fcs^a!n#`+iXeGi{4dk`o3Z2Q2L2m z50hWtQJ(I^H8%FKD-<47e@X}u9&UT#VZ~S#Ob%#93p zE+cWNTt-KATL{O~6dO>ZlNWADkKHy2>$yKG?zm3&xsxFZ4zacs__e2j?Kx0q%-=!bl03rnh9ZLf|DR8L*U;6(as;$~-!+>> zD!{;M2f(wb3l9jgk!XqK>S_bLlA{0vs&+(h_iw_;mW0WuB0xz45%FKB=9`+R(izHH zhtKzWr#?h<$hQH)R8LEpHVJ_81%n}<)d>rM9MDb+2~8Fv0E)5*Tv90-+JMIes|QJ& zwN?VPKwmLbmx)yGN&!NQ(Et6zL*KKqx7JR}QfE&?a{h8`d~fcCcZxvYtO1)` to work) - # 1 - is not truthy - - local val=$(tr '[:upper:]' '[:lower:]' <<<"$1") - case $val in - 1 | t | true | y | yes) - return 0 - ;; - *) - return 1 - ;; - esac -} - -function get_cert { - local HOSTPORT=$1 - local SERVER_NAME=$2 - local CA_FILE=$3 - local SNI_FLAG="" - if [ -n "$SERVER_NAME" ]; then - SNI_FLAG="-servername $SERVER_NAME" - fi - CERT=$(openssl s_client -connect $HOSTPORT $SNI_FLAG -showcerts /dev/null) - - echo "WANT CN: ${CN} (SNI: ${SERVER_NAME})" - echo "GOT CERT:" - echo "$CERT" - - echo "$CERT" | grep "CN = ${CN}" -} - -function get_upstream_endpoint { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - run curl -s -f "http://${HOSTPORT}/clusters?format=json" - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output " -.cluster_statuses[] -| select(.name|startswith(\"${CLUSTER_NAME}\"))" -} - -function assert_upstream_missing_once { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - - run get_upstream_endpoint $HOSTPORT $CLUSTER_NAME - [ "$status" -eq 0 ] - echo "$output" - [ "" == "$output" ] -} - -function assert_upstream_missing { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - run retry_long assert_upstream_missing_once $HOSTPORT $CLUSTER_NAME - echo "OUTPUT: $output $status" - - [ "$status" -eq 0 ] -} - -function assert_envoy_version { - local ADMINPORT=$1 - run retry_default curl -f -s localhost:$ADMINPORT/server_info - [ "$status" -eq 0 ] - # Envoy 1.8.0 returns a plain text line like - # envoy 5d25f466c3410c0dfa735d7d4358beb76b2da507/1.8.0/Clean/DEBUG live 3 3 0 - # Later versions return JSON. - if (echo $output | grep '^envoy'); then - VERSION=$(echo $output | cut -d ' ' -f 2) - else - VERSION=$(echo $output | jq -r '.version') - fi - echo "Status=$status" - echo "Output=$output" - echo "---" - echo "Got version=$VERSION" - echo "Want version=$ENVOY_VERSION" - - # 1.20.2, 1.19.3 and 1.18.6 are special snowflakes in that the version for - # the release is reported with a '-dev' suffix (eg 1.20.2-dev). - if [ "$ENVOY_VERSION" = "1.20.2" ]; then - ENVOY_VERSION="1.20.2-dev" - elif [ "$ENVOY_VERSION" = "1.19.3" ]; then - ENVOY_VERSION="1.19.3-dev" - elif [ "$ENVOY_VERSION" = "1.18.6" ]; then - ENVOY_VERSION="1.18.6-dev" - fi - - echo $VERSION | grep "/$ENVOY_VERSION/" -} - -function assert_envoy_expose_checks_listener_count { - local HOSTPORT=$1 - local EXPECT_PATH=$2 - - # scrape this once - BODY=$(get_envoy_expose_checks_listener_once $HOSTPORT) - echo "BODY = $BODY" - - CHAINS=$(echo "$BODY" | jq '.active_state.listener.filter_chains | length') - echo "CHAINS = $CHAINS (expect 1)" - [ "${CHAINS:-0}" -eq 1 ] - - RANGES=$(echo "$BODY" | jq '.active_state.listener.filter_chains[0].filter_chain_match.source_prefix_ranges | length') - echo "RANGES = $RANGES (expect 3)" - # note: if IPv6 is not supported in the kernel per - # agent/xds/platform:SupportsIPv6() then this will only be 2 - [ "${RANGES:-0}" -eq 3 ] - - HCM=$(echo "$BODY" | jq '.active_state.listener.filter_chains[0].filters[0]') - HCM_NAME=$(echo "$HCM" | jq -r '.name') - HCM_PATH=$(echo "$HCM" | jq -r '.typed_config.route_config.virtual_hosts[0].routes[0].match.path') - echo "HCM = $HCM" - [ "${HCM_NAME:-}" == "envoy.filters.network.http_connection_manager" ] - [ "${HCM_PATH:-}" == "${EXPECT_PATH}" ] -} - -function get_envoy_expose_checks_listener_once { - local HOSTPORT=$1 - run curl -m 5 -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output '.configs[] | select(.["@type"] == "type.googleapis.com/envoy.admin.v3.ListenersConfigDump") | .dynamic_listeners[] | select(.name | startswith("exposed_path_"))' -} - -function get_envoy_public_listener_once { - local HOSTPORT=$1 - run curl -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output '.configs[] | select(.["@type"] == "type.googleapis.com/envoy.admin.v3.ListenersConfigDump") | .dynamic_listeners[] | select(.name | startswith("public_listener:"))' -} - -function assert_envoy_http_rbac_policy_count { - local HOSTPORT=$1 - local EXPECT_COUNT=$2 - - GOT_COUNT=$(get_envoy_http_rbac_once $HOSTPORT | jq '.rules.policies | length') - echo "GOT_COUNT = $GOT_COUNT" - [ "${GOT_COUNT:-0}" -eq $EXPECT_COUNT ] -} - -function get_envoy_http_rbac_once { - local HOSTPORT=$1 - run curl -m 5 -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output '.configs[2].dynamic_listeners[].active_state.listener.filter_chains[0].filters[0].typed_config.http_filters[] | select(.name == "envoy.filters.http.rbac") | .typed_config' -} - -function assert_envoy_network_rbac_policy_count { - local HOSTPORT=$1 - local EXPECT_COUNT=$2 - - GOT_COUNT=$(get_envoy_network_rbac_once $HOSTPORT | jq '.rules.policies | length') - echo "GOT_COUNT = $GOT_COUNT" - [ "${GOT_COUNT:-0}" -eq $EXPECT_COUNT ] -} - -function get_envoy_network_rbac_once { - local HOSTPORT=$1 - run curl -m 5 -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output '.configs[2].dynamic_listeners[].active_state.listener.filter_chains[0].filters[] | select(.name == "envoy.filters.network.rbac") | .typed_config' -} - -function get_envoy_listener_filters { - local HOSTPORT=$1 - run retry_default curl -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output '.configs[2].dynamic_listeners[].active_state.listener | "\(.name) \( .filter_chains[0].filters | map(.name) | join(","))"' -} - -function get_envoy_http_filter { - local HOSTPORT=$1 - local FILTER_NAME=$2 - run retry_default curl -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output ".configs[2].dynamic_listeners[] | .active_state.listener.filter_chains[].filters[] | select(.name == \"envoy.filters.network.http_connection_manager\") | .typed_config.http_filters[] | select(.name == \"${FILTER_NAME}\")" -} - -function get_envoy_http_filters { - local HOSTPORT=$1 - run retry_default curl -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output '.configs[2].dynamic_listeners[].active_state.listener | "\(.name) \( .filter_chains[0].filters[] | select(.name == "envoy.filters.network.http_connection_manager") | .typed_config.http_filters | map(.name) | join(","))"' -} - -function get_envoy_dynamic_cluster_once { - local HOSTPORT=$1 - local NAME_PREFIX=$2 - run curl -m 5 -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output ".configs[] | select (.[\"@type\"] == \"type.googleapis.com/envoy.admin.v3.ClustersConfigDump\") | .dynamic_active_clusters[] | select(.cluster.name | startswith(\"${NAME_PREFIX}\"))" -} - -function assert_envoy_dynamic_cluster_exists_once { - local HOSTPORT=$1 - local NAME_PREFIX=$2 - local EXPECT_SNI=$3 - BODY="$(get_envoy_dynamic_cluster_once $HOSTPORT $NAME_PREFIX)" - [ -n "$BODY" ] - - SNI="$(echo "$BODY" | jq --raw-output ".cluster.transport_socket.typed_config.sni | select(. | startswith(\"${EXPECT_SNI}\"))")" - [ -n "$SNI" ] -} - -function assert_envoy_dynamic_cluster_exists { - local HOSTPORT=$1 - local NAME_PREFIX=$2 - local EXPECT_SNI=$3 - run retry_long assert_envoy_dynamic_cluster_exists_once $HOSTPORT $NAME_PREFIX $EXPECT_SNI - [ "$status" -eq 0 ] -} - -function get_envoy_cluster_config { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - run retry_default curl -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output " - .configs[1].dynamic_active_clusters[] - | select(.cluster.name|startswith(\"${CLUSTER_NAME}\")) - | .cluster - " -} - -function get_envoy_stats_flush_interval { - local HOSTPORT=$1 - run retry_default curl -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - #echo "$output" > /workdir/s1_envoy_dump.json - echo "$output" | jq --raw-output '.configs[0].bootstrap.stats_flush_interval' -} - -# snapshot_envoy_admin is meant to be used from a teardown scriptlet from the host. -function snapshot_envoy_admin { - local HOSTPORT=$1 - local ENVOY_NAME=$2 - local DC=${3:-primary} - local OUTDIR="${LOG_DIR}/envoy-snapshots/${DC}/${ENVOY_NAME}" - - mkdir -p "${OUTDIR}" - docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/config_dump" > "${OUTDIR}/config_dump.json" - docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/clusters?format=json" > "${OUTDIR}/clusters.json" - docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/stats" > "${OUTDIR}/stats.txt" - docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/stats/prometheus" > "${OUTDIR}/stats_prometheus.txt" -} - -function reset_envoy_metrics { - local HOSTPORT=$1 - curl -m 5 -s -f -XPOST $HOSTPORT/reset_counters - return $? -} - -function get_all_envoy_metrics { - local HOSTPORT=$1 - curl -m 5 -s -f $HOSTPORT/stats - return $? -} - -function get_envoy_metrics { - local HOSTPORT=$1 - local METRICS=$2 - - get_all_envoy_metrics $HOSTPORT | grep "$METRICS" -} - -function assert_upstream_has_endpoint_port { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - local PORT_VALUE=$3 - - run retry_long assert_upstream_has_endpoint_port_once $HOSTPORT $CLUSTER_NAME $PORT_VALUE - [ "$status" -eq 0 ] -} - -function get_upstream_endpoint_in_status_count { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - local HEALTH_STATUS=$3 - run curl -m 5 -s -f "http://${HOSTPORT}/clusters?format=json" - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output " -.cluster_statuses[] -| select(.name|startswith(\"${CLUSTER_NAME}\")) -| [.host_statuses[].health_status.eds_health_status] -| [select(.[] == \"${HEALTH_STATUS}\")] -| length" -} - -function assert_upstream_has_endpoints_in_status_once { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - local HEALTH_STATUS=$3 - local EXPECT_COUNT=$4 - - GOT_COUNT=$(get_upstream_endpoint_in_status_count $HOSTPORT $CLUSTER_NAME $HEALTH_STATUS) - - [ "$GOT_COUNT" -eq $EXPECT_COUNT ] -} - -function assert_upstream_has_endpoints_in_status { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - local HEALTH_STATUS=$3 - local EXPECT_COUNT=$4 - run retry_long assert_upstream_has_endpoints_in_status_once $HOSTPORT $CLUSTER_NAME $HEALTH_STATUS $EXPECT_COUNT - [ "$status" -eq 0 ] -} - -function assert_envoy_metric { - set -eEuo pipefail - local HOSTPORT=$1 - local METRIC=$2 - local EXPECT_COUNT=$3 - - METRICS=$(get_envoy_metrics $HOSTPORT "$METRIC") - - if [ -z "${METRICS}" ]; then - echo "Metric not found" 1>&2 - return 1 - fi - - GOT_COUNT=$(awk -F: '{print $2}' <<<"$METRICS" | head -n 1 | tr -d ' ') - - if [ -z "$GOT_COUNT" ]; then - echo "Couldn't parse metric count" 1>&2 - return 1 - fi - - if [ $EXPECT_COUNT -ne $GOT_COUNT ]; then - echo "$METRIC - expected count: $EXPECT_COUNT, actual count: $GOT_COUNT" 1>&2 - return 1 - fi -} - -function assert_envoy_metric_at_least { - set -eEuo pipefail - local HOSTPORT=$1 - local METRIC=$2 - local EXPECT_COUNT=$3 - - METRICS=$(get_envoy_metrics $HOSTPORT "$METRIC") - - if [ -z "${METRICS}" ]; then - echo "Metric not found" 1>&2 - return 1 - fi - - GOT_COUNT=$(awk -F: '{print $2}' <<<"$METRICS" | head -n 1 | tr -d ' ') - - if [ -z "$GOT_COUNT" ]; then - echo "Couldn't parse metric count" 1>&2 - return 1 - fi - - if [ $EXPECT_COUNT -gt $GOT_COUNT ]; then - echo "$METRIC - expected >= count: $EXPECT_COUNT, actual count: $GOT_COUNT" 1>&2 - return 1 - fi -} - -function assert_envoy_aggregate_metric_at_least { - set -eEuo pipefail - local HOSTPORT=$1 - local METRIC=$2 - local EXPECT_COUNT=$3 - - METRICS=$(get_envoy_metrics $HOSTPORT "$METRIC") - - if [ -z "${METRICS}" ]; then - echo "Metric not found" 1>&2 - return 1 - fi - - GOT_COUNT=$(awk '{ sum += $2 } END { print sum }' <<<"$METRICS") - - if [ -z "$GOT_COUNT" ]; then - echo "Couldn't parse metric count" 1>&2 - return 1 - fi - - if [ $EXPECT_COUNT -gt $GOT_COUNT ]; then - echo "$METRIC - expected >= count: $EXPECT_COUNT, actual count: $GOT_COUNT" 1>&2 - return 1 - fi -} - -function get_healthy_service_count { - local SERVICE_NAME=$1 - local DC=$2 - local NS=$3 - local AP=$4 - local PEER_NAME=$5 - - run curl -m 5 -s -f ${HEADERS} "consul-${DC}-client:8500/v1/health/connect/${SERVICE_NAME}?passing&ns=${NS}&partition=${AP}&peer=${PEER_NAME}" - - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output '. | length' -} - -function assert_alive_wan_member_count { - local DC=$1 - local EXPECT_COUNT=$2 - run retry_long assert_alive_wan_member_count_once $DC $EXPECT_COUNT - [ "$status" -eq 0 ] -} - -function assert_alive_wan_member_count_once { - local DC=$1 - local EXPECT_COUNT=$2 - - GOT_COUNT=$(get_alive_wan_member_count $DC) - - [ "$GOT_COUNT" -eq "$EXPECT_COUNT" ] -} - -function get_alive_wan_member_count { - local DC=$1 - run retry_default curl -sL -f "consul-${DC}-server:8500/v1/agent/members?wan=1" - [ "$status" -eq 0 ] - # echo "$output" >&3 - echo "$output" | jq '.[] | select(.Status == 1) | .Name' | wc -l -} - -function assert_service_has_healthy_instances_once { - local SERVICE_NAME=$1 - local EXPECT_COUNT=$2 - local DC=${3:-primary} - local NS=${4:-} - local AP=${5:-} - local PEER_NAME=${6:-} - - GOT_COUNT=$(get_healthy_service_count "$SERVICE_NAME" "$DC" "$NS" "$AP" "$PEER_NAME") - - [ "$GOT_COUNT" -eq $EXPECT_COUNT ] -} - -function assert_service_has_healthy_instances { - local SERVICE_NAME=$1 - local EXPECT_COUNT=$2 - local DC=${3:-primary} - local NS=${4:-} - local AP=${5:-} - local PEER_NAME=${6:-} - - run retry_long assert_service_has_healthy_instances_once "$SERVICE_NAME" "$EXPECT_COUNT" "$DC" "$NS" "$AP" "$PEER_NAME" - [ "$status" -eq 0 ] -} - -function check_intention { - local SOURCE=$1 - local DESTINATION=$2 - get_consul_hostname primary - - curl -m 5 -s -f "${CONSUL_HOSTNAME}:8500/v1/connect/intentions/check?source=${SOURCE}&destination=${DESTINATION}" | jq ".Allowed" -} - -function assert_intention_allowed { - local SOURCE=$1 - local DESTINATION=$2 - - run check_intention "${SOURCE}" "${DESTINATION}" - [ "$status" -eq 0 ] - [ "$output" = "true" ] -} - -function assert_intention_denied { - local SOURCE=$1 - local DESTINATION=$2 - - run check_intention "${SOURCE}" "${DESTINATION}" - [ "$status" -eq 0 ] - [ "$output" = "false" ] -} - -function docker_consul { - local DC=$1 - shift 1 - retry_default docker_exec envoy_consul-${DC}_1 "$@" -} - -function docker_consul_for_proxy_bootstrap { - local DC=$1 - shift 1 - - local CONTAINER_NAME="$SINGLE_CONTAINER_BASE_NAME"-"$DC"_1 - - docker.exe exec -i $CONTAINER_NAME bash.exe -c "$@" -} - -function docker_exec { - if ! docker.exe exec -i "$@"; then - echo "Failed to execute: docker exec -i $@" 1>&2 - return 1 - fi -} - -function docker_consul_exec { - local DC=$1 - shift 1 - docker_exec envoy_consul-${DC}_1 "$@" -} - -function kill_envoy { - local BOOTSTRAP_NAME=$1 - local DC=${2:-primary} - - PORT=$( cat /c/workdir/$DC/envoy/${BOOTSTRAP_NAME}-bootstrap.json | jq .admin.address.socket_address.port_value ) - PID=$( netstat -qo | grep "127.0.0.1:$PORT" | sed -r "s/.* //g" ) - tskill $PID -} - -function must_match_in_statsd_logs { - local DC=${2:-primary} - local FILE="/c/workdir/${DC}/statsd/statsd.log" - - COUNT=$( grep -Ec $1 $FILE ) - echo "COUNT of '$1' matches: $COUNT" - - [ "$COUNT" -gt "0" ] -} - -function must_match_in_prometheus_response { - run curl -m 5 -f -s $1/metrics - COUNT=$( echo "$output" | grep -Ec $2 ) - - echo "OUTPUT head -n 10" - echo "$output" | head -n 10 - echo "COUNT of '$2' matches: $COUNT" - - [ "$status" == 0 ] - [ "$COUNT" -gt "0" ] -} - -function must_match_in_stats_proxy_response { - run curl -m 5 -f -s $1/$2 - COUNT=$( echo "$output" | grep -Ec $3 ) - - echo "OUTPUT head -n 10" - echo "$output" | head -n 10 - echo "COUNT of '$3' matches: $COUNT" - - [ "$status" == 0 ] - [ "$COUNT" -gt "0" ] -} - -# must_fail_tcp_connection checks that a request made through an upstream fails, -# probably due to authz being denied if all other tests passed already. Although -# we are using curl, this only works as expected for TCP upstreams as we are -# checking TCP-level errors. HTTP upstreams will return a valid 503 generated by -# Envoy rather than a connection-level error. -function must_fail_tcp_connection { - # Attempt to curl through upstream - run curl -m 5 --no-keepalive -s -v -f -d hello $1 - - echo "OUTPUT $output" - - # Should fail during handshake and return "got nothing" error - [ "$status" == "52" ] - - # Verbose output should enclude empty reply - echo "$output" | grep 'Empty reply from server' -} - -function must_pass_tcp_connection { - run curl -m 5 --no-keepalive -s -f -d hello $1 - - echo "OUTPUT $output" - - [ "$status" == "0" ] - [ "$output" = "hello" ] -} - -# must_fail_http_connection see must_fail_tcp_connection but this expects Envoy -# to generate a 503 response since the upstreams have refused connection. -function must_fail_http_connection { - # Attempt to curl through upstream - run curl -m 5 --no-keepalive -s -i -d hello "$1" - - echo "OUTPUT $output" - - [ "$status" == "0" ] - - local expect_response="${2:-403 Forbidden}" - # Should fail request with 503 - echo "$output" | grep "${expect_response}" -} - -# must_pass_http_request allows you to craft a specific http request to assert -# that envoy will NOT reject the request. Primarily of use for testing L7 -# intentions. -function must_pass_http_request { - local METHOD=$1 - local URL=$2 - local DEBUG_HEADER_VALUE="${3:-""}" - - local extra_args - if [[ -n "${DEBUG_HEADER_VALUE}" ]]; then - extra_args="-H x-test-debug:${DEBUG_HEADER_VALUE}" - fi - case "$METHOD" in - GET) ;; - - DELETE) - extra_args="$extra_args -X${METHOD}" - ;; - PUT | POST) - extra_args="$extra_args -d'{}' -X${METHOD}" - ;; - *) - return 1 - ;; - esac - - run curl -m 5 --no-keepalive -v -s -f $extra_args "$URL" - [ "$status" == 0 ] -} - -# must_fail_http_request allows you to craft a specific http request to assert -# that envoy will reject the request. Primarily of use for testing L7 -# intentions. -function must_fail_http_request { - local METHOD=$1 - local URL=$2 - local DEBUG_HEADER_VALUE="${3:-""}" - - local extra_args - if [[ -n "${DEBUG_HEADER_VALUE}" ]]; then - extra_args="-H x-test-debug:${DEBUG_HEADER_VALUE}" - fi - case "$METHOD" in - HEAD) - extra_args="$extra_args -I" - ;; - GET) ;; - - DELETE) - extra_args="$extra_args -X${METHOD}" - ;; - PUT | POST) - extra_args="$extra_args -d'{}' -X${METHOD}" - ;; - *) - return 1 - ;; - esac - - # Attempt to curl through upstream - run curl -m 5 --no-keepalive -s -i $extra_args "$URL" - - echo "OUTPUT $output" - - echo "$output" | grep "403 Forbidden" -} - -function upsert_config_entry { - local DC="$1" - local BODY="$2" - - echo "$BODY" | docker_consul "$DC" consul config write - -} - -function gen_envoy_bootstrap { - SERVICE=$1 - ADMIN_PORT=$2 - DC=${3:-primary} - IS_GW=${4:-0} - EXTRA_ENVOY_BS_ARGS="${5-}" - ADMIN_HOST="0.0.0.0" - - PROXY_ID="$SERVICE" - if ! is_set "$IS_GW"; then - PROXY_ID="$SERVICE-sidecar-proxy" - ADMIN_HOST="127.0.0.1" - fi - - if output=$(docker_consul_for_proxy_bootstrap $DC "consul connect envoy -bootstrap \ - -proxy-id $PROXY_ID \ - -envoy-version "$ENVOY_VERSION" \ - -http-addr envoy_consul-${DC}_1:8500 \ - -grpc-addr envoy_consul-${DC}_1:8502 \ - -admin-access-log-path="C:/envoy/envoy.log" \ - -admin-bind $ADMIN_HOST:$ADMIN_PORT ${EXTRA_ENVOY_BS_ARGS} \ - > /c/workdir/${DC}/envoy/${SERVICE}-bootstrap.json"); then - - # All OK, write config to file - echo $output - #echo "$output" > /c/workdir/${DC}/envoy/$SERVICE-bootstrap.json - else - status=$? - # Command failed, instead of swallowing error (printed on stdout by docker - # it seems) by writing it to file, echo it - echo "$output" - #return $status - fi - - -} - -function read_config_entry { - local KIND=$1 - local NAME=$2 - local DC=${3:-primary} - get_consul_hostname $DC - docker_consul_exec "$DC" bash -c "consul config read -kind $KIND -name $NAME -http-addr=\"$CONSUL_HOSTNAME:8500\"" -} - -function wait_for_namespace { - local NS="${1}" - local DC=${2:-primary} - get_consul_hostname $DC - retry_default docker_consul_exec "$DC" bash -c "curl -sLf http://${CONSUL_HOSTNAME}:8500/v1/namespace/${NS} >/dev/null" -} - -function wait_for_config_entry { - retry_default read_config_entry "$@" -} - -function assert_config_entry_status { - local TYPE="$1" - local STATUS="$2" - local REASON="$3" - local DC="$4" - local KIND="$5" - local NAME="$6" - local NS=${7:-} - local AP=${8:-} - local PEER=${9:-} - - status=$(curl -s -f "consul-${DC}-client:8500/v1/config/${KIND}/${NAME}?passing&ns=${NS}&partition=${AP}&peer=${PEER}" | jq ".Status.Conditions[] | select(.Type == \"$TYPE\" and .Status == \"$STATUS\" and .Reason == \"$REASON\")") - [ -n "$status" ] -} - -function delete_config_entry { - local KIND=$1 - local NAME=$2 - get_consul_hostname primary - retry_default curl -sL -XDELETE "http://${CONSUL_HOSTNAME}:8500/v1/config/${KIND}/${NAME}" -} - -function register_services { - local DC=${1:-primary} - wait_for_leader "$DC" - docker_consul_exec ${DC} bash -c "consul services register workdir/${DC}/register/service_*.hcl" -} - -# wait_for_leader waits until a leader is elected. -# Its first argument must be the datacenter name. -function wait_for_leader { - get_consul_hostname primary - retry_default docker_consul_exec "$1" bash -c "[[ $(curl --fail -sS http://${CONSUL_HOSTNAME}:8500/v1/status/leader) ]]" -} - -function setup_upsert_l4_intention { - local SOURCE=$1 - local DESTINATION=$2 - local ACTION=$3 - get_consul_hostname primary - retry_default docker_consul_exec primary bash -c "curl -sL -X PUT -d '{\"Action\": \"${ACTION}\"}' 'http://${CONSUL_HOSTNAME}:8500/v1/connect/intentions/exact?source=${SOURCE}&destination=${DESTINATION}'" -} - -function upsert_l4_intention { - local SOURCE=$1 - local DESTINATION=$2 - local ACTION=$3 - get_consul_hostname primary - retry_default curl -sL -XPUT "http://${CONSUL_HOSTNAME}:8500/v1/connect/intentions/exact?source=${SOURCE}&destination=${DESTINATION}" \ - -d"{\"Action\": \"${ACTION}\"}" >/dev/null -} - -function get_ca_root { - get_consul_hostname primary - curl -s -f "http://${CONSUL_HOSTNAME}:8500/v1/connect/ca/roots" | jq -r ".Roots[0].RootCert" -} - -function wait_for_agent_service_register { - local SERVICE_ID=$1 - local DC=${2:-primary} - get_consul_hostname $DC - retry_default docker_consul_exec "$DC" bash -c "curl -sLf 'http://${CONSUL_HOSTNAME}:8500/v1/agent/service/${SERVICE_ID}' >/dev/null" -} - -function set_ttl_check_state { - local CHECK_ID=$1 - local CHECK_STATE=$2 - local DC=${3:-primary} - get_consul_hostname $DC - - case "$CHECK_STATE" in - pass) ;; - - warn) ;; - - fail) ;; - - *) - echo "invalid ttl check state '${CHECK_STATE}'" >&2 - return 1 - ;; - esac - - retry_default docker_consul_exec "$DC" bash -c "curl -sL -XPUT 'http://${CONSUL_HOSTNAME}:8500/v1/agent/check/warn/${CHECK_ID}' >/dev/null" -} - -function get_upstream_fortio_name { - local HOST=$1 - local PORT=$2 - local PREFIX=$3 - local DEBUG_HEADER_VALUE="${4:-""}" - local extra_args - if [[ -n "${DEBUG_HEADER_VALUE}" ]]; then - extra_args="-H x-test-debug:${DEBUG_HEADER_VALUE}" - fi - # split proto if https:// is at the front of the host since the --resolve - # string needs just a bare host. - local PROTO="" - local CA_FILE="" - if [ "${HOST:0:8}" = "https://" ]; then - HOST="${HOST:8}" - PROTO="https://" - # Fix in the CA_FILE parameter: for Windows environments, the root path starts with "/c" - extra_args="${extra_args} --cacert /c/workdir/test-sds-server/certs/ca-root.crt" - fi - # We use --resolve instead of setting a Host header since we need the right - # name to be sent for SNI in some cases too. - run retry_default curl --ssl-revoke-best-effort -v -s -f --resolve "${HOST}:${PORT}:127.0.0.1" $extra_args \ - "${PROTO}${HOST}:${PORT}${PREFIX}/debug?env=dump" - - # Useful Debugging but breaks the expectation that the value output is just - # the grep output when things don't fail - if [ "$status" != 0 ]; then - echo "GOT FORTIO OUTPUT: $output" - fi - [ "$status" == 0 ] - echo "$output" | grep -E "^FORTIO_NAME=" -} - -function get_upstream_endpoint_port { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - local PORT_VALUE=$3 - run curl -s -f "http://${HOSTPORT}/clusters?format=json" - [ "$status" -eq 0 ] - echo "$output" | jq --raw-output " -.cluster_statuses[] -| select(.name|startswith(\"${CLUSTER_NAME}\")) -| [.host_statuses[].address.socket_address.port_value] -| [select(.[] == ${PORT_VALUE})] -| length" -} - -function assert_upstream_has_endpoint_port_once { - local HOSTPORT=$1 - local CLUSTER_NAME=$2 - local PORT_VALUE=$3 - - GOT_COUNT=$(get_upstream_endpoint_port $HOSTPORT $CLUSTER_NAME $PORT_VALUE) - - [ "$GOT_COUNT" -eq 1 ] -} - -function assert_expected_fortio_name { - local EXPECT_NAME=$1 - local HOST=${2:-"localhost"} - local PORT=${3:-5000} - local URL_PREFIX=${4:-""} - local DEBUG_HEADER_VALUE="${5:-""}" - - run get_upstream_fortio_name ${HOST} ${PORT} "${URL_PREFIX}" "${DEBUG_HEADER_VALUE}" - - echo "GOT: $output" - - [ "$status" == 0 ] - [ "$output" == "FORTIO_NAME=${EXPECT_NAME}" ] -} - -function assert_expected_fortio_name_pattern { - local EXPECT_NAME_PATTERN=$1 - local HOST=${2:-"localhost"} - local PORT=${3:-5000} - local URL_PREFIX=${4:-""} - local DEBUG_HEADER_VALUE="${5:-""}" - - GOT=$(get_upstream_fortio_name ${HOST} ${PORT} "${URL_PREFIX}" "${DEBUG_HEADER_VALUE}") - - if [[ "$GOT" =~ $EXPECT_NAME_PATTERN ]]; then - : - else - echo "expected name pattern: $EXPECT_NAME_PATTERN, actual name: $GOT" 1>&2 - return 1 - fi -} - -function get_upstream_fortio_host_header { - local HOST=$1 - local PORT=$2 - local PREFIX=$3 - local DEBUG_HEADER_VALUE="${4:-""}" - local extra_args - if [[ -n "${DEBUG_HEADER_VALUE}" ]]; then - extra_args="-H x-test-debug:${DEBUG_HEADER_VALUE}" - fi - run retry_default curl -v -s -f -H"Host: ${HOST}" $extra_args \ - "localhost:${PORT}${PREFIX}/debug" - [ "$status" == 0 ] - echo "$output" | grep -E "^Host: " -} - -function assert_expected_fortio_host_header { - local EXPECT_HOST=$1 - local HOST=${2:-"localhost"} - local PORT=${3:-5000} - local URL_PREFIX=${4:-""} - local DEBUG_HEADER_VALUE="${5:-""}" - - GOT=$(get_upstream_fortio_host_header ${HOST} ${PORT} "${URL_PREFIX}" "${DEBUG_HEADER_VALUE}") - - if [ "$GOT" != "Host: ${EXPECT_HOST}" ]; then - echo "expected Host header: $EXPECT_HOST, actual Host header: $GOT" 1>&2 - return 1 - fi -} - -function create_peering { - local GENERATE_PEER=$1 - local ESTABLISH_PEER=$2 - run curl -m 5 -sL -XPOST "http://consul-${GENERATE_PEER}-client:8500/v1/peering/token" -d"{ \"PeerName\" : \"${GENERATE_PEER}-to-${ESTABLISH_PEER}\" }" - # echo "$output" >&3 - [ "$status" == 0 ] - - local token - token="$(echo "$output" | jq -r .PeeringToken)" - [ -n "$token" ] - - run curl -m 5 -sLv -XPOST "http://consul-${ESTABLISH_PEER}-client:8500/v1/peering/establish" -d"{ \"PeerName\" : \"${ESTABLISH_PEER}-to-${GENERATE_PEER}\", \"PeeringToken\" : \"${token}\" }" - # echo "$output" >&3 - [ "$status" == 0 ] -} - -function assert_service_has_imported { - local DC=${1:-primary} - local SERVICE_NAME=$2 - local PEER_NAME=$3 - - run curl -s -f "http://consul-${DC}-client:8500/v1/peering/${PEER_NAME}" - [ "$status" == 0 ] - - echo "$output" | jq --raw-output '.StreamStatus.ImportedServices' | grep -e "${SERVICE_NAME}" - if [ $? -ne 0 ]; then - echo "Error finding service: ${SERVICE_NAME}" - return 1 - fi -} - -function get_lambda_envoy_http_filter { - local HOSTPORT=$1 - local NAME_PREFIX=$2 - run retry_default curl -s -f $HOSTPORT/config_dump - [ "$status" -eq 0 ] - # get the full http filter object so the individual fields can be validated. - echo "$output" | jq --raw-output ".configs[2].dynamic_listeners[] | .active_state.listener.filter_chains[].filters[] | select(.name == \"envoy.filters.network.http_connection_manager\") | .typed_config.http_filters[] | select(.name == \"envoy.filters.http.aws_lambda\") | .typed_config" -} - -function register_lambdas { - local DC=${1:-primary} - # register lambdas to the catalog - for f in $(find workdir/${DC}/register -type f -name 'lambda_*.json'); do - retry_default curl -sL -XPUT -d @${f} "http://localhost:8500/v1/catalog/register" >/dev/null && \ - echo "Registered Lambda: $(jq -r .Service.Service $f)" - done - # write service-defaults config entries for lambdas - for f in $(find workdir/${DC}/register -type f -name 'service_defaults_*.json'); do - varsub ${f} AWS_LAMBDA_REGION AWS_LAMBDA_ARN - retry_default curl -sL -XPUT -d @${f} "http://localhost:8500/v1/config" >/dev/null && \ - echo "Wrote config: $(jq -r '.Kind + " / " + .Name' $f)" - done -} - -function assert_lambda_envoy_dynamic_cluster_exists { - local HOSTPORT=$1 - local NAME_PREFIX=$2 - - local BODY=$(get_envoy_dynamic_cluster_once $HOSTPORT $NAME_PREFIX) - [ -n "$BODY" ] - - [ "$(echo $BODY | jq -r '.cluster.transport_socket.typed_config.sni')" == '*.amazonaws.com' ] -} - -function assert_lambda_envoy_dynamic_http_filter_exists { - local HOSTPORT=$1 - local NAME_PREFIX=$2 - local ARN=$3 - - local FILTER=$(get_lambda_envoy_http_filter $HOSTPORT $NAME_PREFIX) - [ -n "$FILTER" ] - - [ "$(echo $FILTER | jq -r '.arn')" == "$ARN" ] -} - -function varsub { - local file=$1 - shift - for v in "$@"; do - sed -i "s/\${$v}/${!v}/g" $file - done -} - -function get_url_header { - local URL=$1 - local HEADER=$2 - run curl -s -f -X GET -I "${URL}" - [ "$status" == 0 ] - RESP=$(echo "$output" | tr -d '\r') - RESP=$(echo "$RESP" | grep -E "^${HEADER}: ") - RESP=$(echo "$RESP" | sed "s/^${HEADER}: //g") - echo "$RESP" -} - -function assert_url_header { - local URL=$1 - local HEADER=$2 - local VALUE=$3 - run get_url_header "$URL" "$HEADER" - [ "$status" == 0 ] - [ "$VALUE" = "$output" ] -} - -# assert_upstream_message asserts both the returned code -# and message from upstream service -function assert_upstream_message { - local HOSTPORT=$1 - run curl -s -d hello localhost:$HOSTPORT - - if [ "$status" -ne 0 ]; then - echo "Command failed" - return 1 - fi - - if (echo $output | grep 'hello'); then - return 0 - fi - - echo "expected message not found in $output" - return 1 -} \ No newline at end of file diff --git a/test/integration/connect/envoy/main_test.go b/test/integration/connect/envoy/main_test.go index aa83bb6bbec12..b81a72e37ddcb 100644 --- a/test/integration/connect/envoy/main_test.go +++ b/test/integration/connect/envoy/main_test.go @@ -1,14 +1,12 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build integration +// +build integration package envoy import ( - "flag" - "io/ioutil" - "log" "os" "os/exec" "sort" @@ -18,31 +16,11 @@ import ( "github.com/stretchr/testify/require" ) -var ( - flagWin = flag.Bool("win", false, "Execute tests on windows") - flagResourceAPIs = flag.Bool("enable-resource-apis", false, "Execute tests with resource apis enabled.") -) - func TestEnvoy(t *testing.T) { - flag.Parse() - - if *flagWin == true { - dir := "../../../" - check_dir_files(dir) - } - - var testcases []string - var err error - if *flagResourceAPIs == true { - os.Setenv("USE_RESOURCE_APIS", "true") - testcases, err = discoverResourceAPICases() - } else { - testcases, err = discoverCases() - } + testcases, err := discoverCases() require.NoError(t, err) runCmd(t, "suite_setup") - defer runCmd(t, "suite_teardown") for _, tc := range testcases { @@ -62,7 +40,7 @@ func TestEnvoy(t *testing.T) { } } -func runCmdLinux(t *testing.T, c string, env ...string) { +func runCmd(t *testing.T, c string, env ...string) { t.Helper() cmd := exec.Command("./run-tests.sh", c) @@ -74,35 +52,7 @@ func runCmdLinux(t *testing.T, c string, env ...string) { } } -func runCmdWindows(t *testing.T, c string, env ...string) { - t.Helper() - - param_5 := "false" - if env != nil { - param_5 = strings.Join(env, " ") - } - - cmd := exec.Command("cmd", "/C", "bash run-tests.windows.sh", c, param_5) - cmd.Env = append(os.Environ(), env...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - t.Fatalf("command failed: %v", err) - } -} - -func runCmd(t *testing.T, c string, env ...string) { - t.Helper() - - if *flagWin == true { - runCmdWindows(t, c, env...) - - } else { - runCmdLinux(t, c, env...) - } -} - -// Discover the cases so we pick up both ce and ent copies. +// Discover the cases so we pick up both oss and ent copies. func discoverCases() ([]string, error) { cwd, err := os.Getwd() if err != nil { @@ -124,84 +74,3 @@ func discoverCases() ([]string, error) { sort.Strings(out) return out, nil } - -// discoverResourceAPICases will discover the Envoy tests case files but will contain -// a filter in it to only return those case for which functionality has been added -// to the V2 catalog resources. -func discoverResourceAPICases() ([]string, error) { - cwd, err := os.Getwd() - if err != nil { - return nil, err - } - - dirs, err := os.ReadDir(cwd) - if err != nil { - return nil, err - } - - var out []string - for _, fi := range dirs { - // TODO(proxystate): enable this to only include tests cases that are supported. - // Currently the work is in progress, so it is wired up in CI, but this excludes any tests from actually running. - if fi.IsDir() && strings.HasPrefix(fi.Name(), "case-don-match-me-on-anything-yet-because-i-am-not-ready") { - out = append(out, fi.Name()) - } - } - - sort.Strings(out) - return out, nil -} - -// CRLF convert functions -// Recursively iterates through the directory passed by parameter looking for the sh and bash files. -// Upon finding them, it calls crlf_file_check. -func check_dir_files(path string) { - files, err := ioutil.ReadDir(path) - if err != nil { - log.Fatal(err) - } - for _, fil := range files { - - v := strings.Split(fil.Name(), ".") - file_extension := v[len(v)-1] - - file_path := path + "/" + fil.Name() - - if fil.IsDir() == true { - check_dir_files(file_path) - } - - if file_extension == "sh" || file_extension == "bash" { - crlf_file_check(file_path) - } - } -} - -// Check if a file contains CRLF line endings if so call crlf_normalize -func crlf_file_check(file_name string) { - - file, err := ioutil.ReadFile(file_name) - text := string(file) - - if edit := crlf_verify(text); edit != -1 { - crlf_normalize(file_name, text) - } - - if err != nil { - log.Fatal(err) - } -} - -// Checks for the existence of CRLF line endings. -func crlf_verify(text string) int { - position := strings.Index(text, "\r\n") - return position -} - -// Replace CRLF line endings with LF. -func crlf_normalize(filename, text string) { - text = strings.Replace(text, "\r\n", "\n", -1) - data := []byte(text) - - ioutil.WriteFile(filename, data, 0644) -} diff --git a/test/integration/connect/envoy/run-tests.sh b/test/integration/connect/envoy/run-tests.sh index 900d3cbfd33b7..ba0d6fa810902 100755 --- a/test/integration/connect/envoy/run-tests.sh +++ b/test/integration/connect/envoy/run-tests.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail @@ -15,7 +15,7 @@ DEBUG=${DEBUG:-} XDS_TARGET=${XDS_TARGET:-server} # ENVOY_VERSION to run each test against -ENVOY_VERSION=${ENVOY_VERSION:-"1.27.0"} +ENVOY_VERSION=${ENVOY_VERSION:-"1.23.1"} export ENVOY_VERSION export DOCKER_BUILDKIT=1 @@ -179,14 +179,6 @@ function start_consul { license=$(cat $CONSUL_LICENSE_PATH) fi - USE_RESOURCE_APIS=${USE_RESOURCE_APIS:-false} - - experiments="experiments=[]" - # set up consul to run in V1 or V2 catalog mode - if [[ "${USE_RESOURCE_APIS}" == true ]]; then - experiments="experiments=[\"resource-apis\"]" - fi - # We currently run these integration tests in two modes: one in which Envoy's # xDS sessions are served directly by a Consul server, and another in which it # goes through a client agent. @@ -270,7 +262,6 @@ function start_consul { agent -dev -datacenter "${DC}" \ -config-dir "/workdir/${DC}/consul" \ -config-dir "/workdir/${DC}/consul-server" \ - -hcl=${experiments} \ -client "0.0.0.0" >/dev/null fi } @@ -798,9 +789,6 @@ function common_run_container_gateway { function run_container_gateway-primary { common_run_container_gateway mesh-gateway primary } -function run_container_gateway-ap1 { - common_run_container_gateway mesh-gateway ap1 -} function run_container_gateway-secondary { common_run_container_gateway mesh-gateway secondary } diff --git a/test/integration/connect/envoy/run-tests.windows.sh b/test/integration/connect/envoy/run-tests.windows.sh deleted file mode 100644 index 23a67b76ab6d0..0000000000000 --- a/test/integration/connect/envoy/run-tests.windows.sh +++ /dev/null @@ -1,916 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - - -if [ $2 != "false" ] -then - export $2 -fi - -readonly self_name="$0" - -readonly HASHICORP_DOCKER_PROXY="docker.mirror.hashicorp.services" - -readonly SINGLE_CONTAINER_BASE_NAME=envoy_consul - -# DEBUG=1 enables set -x for this script so echos every command run -DEBUG=${DEBUG:-} - -XDS_TARGET=${XDS_TARGET:-server} - -# ENVOY_VERSION to run each test against -ENVOY_VERSION=${ENVOY_VERSION:-"1.27.0"} -export ENVOY_VERSION - -export DOCKER_BUILDKIT=0 - -if [ ! -z "$DEBUG" ] ; then - set -x -fi - -source helpers.windows.bash - -function command_error { - echo "ERR: command exited with status $1" 1>&2 - echo " command: $2" 1>&2 - echo " line: $3" 1>&2 - echo " function: $4" 1>&2 - echo " called at: $5" 1>&2 - # printf '%s\n' "${FUNCNAME[@]}" - # printf '%s\n' "${BASH_SOURCE[@]}" - # printf '%s\n' "${BASH_LINENO[@]}" -} - -trap 'command_error $? "${BASH_COMMAND}" "${LINENO}" "${FUNCNAME[0]:-main}" "${BASH_SOURCE[0]}:${BASH_LINENO[0]}"' ERR - -readonly WORKDIR_SNIPPET="-v envoy_workdir:C:\workdir" - -function network_snippet { - local DC="$1" - echo "--net=envoy-tests" -} - -function aws_snippet { - LAMBDA_TESTS_ENABLED=${LAMBDA_TESTS_ENABLED:-false} - if [ "$LAMBDA_TESTS_ENABLED" != false ]; then - local snippet="" - - # The Lambda integration cases assume that a Lambda function exists in $AWS_REGION with an ARN of $AWS_LAMBDA_ARN. - # The AWS credentials must have permission to invoke the Lambda function. - [ -n "$(set | grep '^AWS_ACCESS_KEY_ID=')" ] && snippet="${snippet} -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID" - [ -n "$(set | grep '^AWS_SECRET_ACCESS_KEY=')" ] && snippet="${snippet} -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY" - [ -n "$(set | grep '^AWS_SESSION_TOKEN=')" ] && snippet="${snippet} -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN" - [ -n "$(set | grep '^AWS_LAMBDA_REGION=')" ] && snippet="${snippet} -e AWS_LAMBDA_REGION=$AWS_LAMBDA_REGION" - [ -n "$(set | grep '^AWS_LAMBDA_ARN=')" ] && snippet="${snippet} -e AWS_LAMBDA_ARN=$AWS_LAMBDA_ARN" - - echo "$snippet" - fi -} - -function init_workdir { - local CLUSTER="$1" - - if test -z "$CLUSTER" - then - CLUSTER=primary - fi - - # Note, we use explicit set of dirs so we don't delete .gitignore. Also, - # don't wipe logs between runs as they are already split and we need them to - # upload as artifacts later. - rm -rf workdir/${CLUSTER} - rm -rf workdir/logs - mkdir -p workdir/${CLUSTER}/{consul,consul-server,register,envoy,bats,statsd,data} - - # Reload consul config from defaults - cp consul-base-cfg/*.hcl workdir/${CLUSTER}/consul/ - - # Add any overrides if there are any (no op if not) - find ${CASE_DIR} -maxdepth 1 -name '*.hcl' -type f -exec cp -f {} workdir/${CLUSTER}/consul \; - - # Copy all the test files - find ${CASE_DIR} -maxdepth 1 -name '*.bats' -type f -exec cp -f {} workdir/${CLUSTER}/bats \; - # Copy CLUSTER specific bats - cp helpers.windows.bash workdir/${CLUSTER}/bats/helpers.bash - - # Add any CLUSTER overrides - if test -d "${CASE_DIR}/${CLUSTER}" - then - find ${CASE_DIR}/${CLUSTER} -type f -name '*.hcl' -exec cp -f {} workdir/${CLUSTER}/consul \; - find ${CASE_DIR}/${CLUSTER} -type f -name '*.bats' -exec cp -f {} workdir/${CLUSTER}/bats \; - fi - - # move all of the registration files OUT of the consul config dir now - find workdir/${CLUSTER}/consul -type f -name 'service_*.hcl' -exec mv -f {} workdir/${CLUSTER}/register \; - - # move the server.hcl out of the consul dir so that it doesn't get picked up - # by the client agent (if we're running with XDS_TARGET=client). - if test -f "workdir/${CLUSTER}/consul/server.hcl" - then - mv workdir/${CLUSTER}/consul/server.hcl workdir/${CLUSTER}/consul-server/server.hcl - fi - - # copy the ca-certs for SDS so we can verify the right ones are served - mkdir -p workdir/test-sds-server/certs - cp test-sds-server/certs/ca-root.crt workdir/test-sds-server/certs/ca-root.crt - - if test -d "${CASE_DIR}/data" - then - cp -r ${CASE_DIR}/data/* workdir/${CLUSTER}/data - fi - - return 0 -} - -function docker_kill_rm { - local name - local todo=() - for name in "$@"; do - name="envoy_${name}_1" - if docker.exe container inspect $name &>/dev/null; then - if [[ "$name" == envoy_tcpdump-* ]]; then - echo -n "Gracefully stopping $name..." - docker.exe stop $name &> /dev/null - echo "done" - fi - todo+=($name) - fi - done - - if [[ ${#todo[@]} -eq 0 ]]; then - return 0 - fi - - echo -n "Killing and removing: ${todo[@]}..." - docker.exe rm -v -f ${todo[@]} &> /dev/null - echo "done" -} - -function start_consul { - local DC=${1:-primary} - - # 8500/8502 are for consul - # 9411 is for zipkin which shares the network with consul - # 16686 is for jaeger ui which also shares the network with consul - ports=( - '-p=8500:8500' - '-p=8502:8502' - '-p=9411:9411' - '-p=16686:16686' - ) - case "$DC" in - secondary) - ports=( - '-p=9500:8500' - '-p=9502:8502' - ) - ;; - alpha) - ports=( - '-p=9510:8500' - '-p=9512:8502' - ) - ;; - esac - - license="${CONSUL_LICENSE:-}" - # load the consul license so we can pass it into the consul - # containers as an env var in the case that this is a consul - # enterprise test - if test -z "$license" -a -n "${CONSUL_LICENSE_PATH:-}" - then - license=$(cat $CONSUL_LICENSE_PATH) - fi - - # We currently run these integration tests in two modes: one in which Envoy's - # xDS sessions are served directly by a Consul server, and another in which it - # goes through a client agent. - # - # This is necessary because servers and clients source configuration data in - # different ways (client agents use an RPC-backed cache and servers use their - # own local data) and we want to catch regressions in both. - # - # In the future we should also expand these tests to register services to the - # catalog directly (agentless) rather than relying on the server also being - # an agent. - # - # When XDS_TARGET=client we'll start a Consul server with its gRPC port - # disabled (but only if REQUIRE_PEERS is not set), and a client agent with - # its gRPC port enabled. - # - # When XDS_TARGET=server (or anything else) we'll run a single Consul server - # with its gRPC port enabled. - # - # In either case, the hostname `consul-${DC}-server` should be used as a - # server address (e.g. for WAN joining) and `consul-${DC}-client` should be - # used as a client address (e.g. for interacting with the HTTP API). - # - # Both hostnames work in both modes because we set network aliases on the - # containers such that both hostnames will resolve to the same container when - # XDS_TARGET=server. - # - # We also join containers to the network `container:consul-${DC}_1` in many - # places (see: network_snippet) so that we can curl localhost etc. In both - # modes, you can assume that this name refers to the client's container. - # - # Any .hcl files in the case/cluster directory will be given to both clients - # and servers (via the -config-dir flag) *except for* server.hcl which will - # only be applied to the server (and service registrations which will be made - # against the client). - if [[ "$XDS_TARGET" == "client" ]] - then - docker_kill_rm consul-${DC}-server - docker_kill_rm consul-${DC} - - server_grpc_port="-1" - if is_set $REQUIRE_PEERS; then - server_grpc_port="8502" - fi - - docker.exe run -d --name envoy_consul-${DC}-server_1 \ - --net=envoy-tests \ - $WORKDIR_SNIPPET \ - --hostname "consul-${DC}-server" \ - --network-alias "consul-${DC}-server" \ - -e "CONSUL_LICENSE=$license" \ - windows/consul:local \ - agent -dev -datacenter "${DC}" \ - -config-dir "C:\\workdir\\${DC}\\consul" \ - -config-dir "C:\\workdir\\${DC}\\consul-server" \ - -grpc-port $server_grpc_port \ - -client "0.0.0.0" \ - -bind "0.0.0.0" >/dev/null - - docker.exe run -d --name envoy_consul-${DC}_1 \ - --net=envoy-tests \ - $WORKDIR_SNIPPET \ - --hostname "consul-${DC}-client" \ - --network-alias "consul-${DC}-client" \ - -e "CONSUL_LICENSE=$license" \ - ${ports[@]} \ - windows/consul:local \ - agent -datacenter "${DC}" \ - -config-dir "C:\\workdir\\${DC}\\consul" \ - -data-dir "/tmp/consul" \ - -client "0.0.0.0" \ - -grpc-port 8502 \ - -datacenter "${DC}" \ - -retry-join "consul-${DC}-server" >/dev/null - else - docker_kill_rm consul-${DC} - - docker.exe run -d --name envoy_consul-${DC}_1 \ - --net=envoy-tests \ - $WORKDIR_SNIPPET \ - --memory 4096m \ - --cpus 2 \ - --hostname "consul-${DC}" \ - --network-alias "consul-${DC}-client" \ - --network-alias "consul-${DC}-server" \ - -e "CONSUL_LICENSE=$license" \ - ${ports[@]} \ - windows/consul:local \ - agent -dev -datacenter "${DC}" \ - -config-dir "C:\\workdir\\${DC}\\consul" \ - -config-dir "C:\\workdir\\${DC}\\consul-server" \ - -client "0.0.0.0" >/dev/null - fi -} - -function start_partitioned_client { - local PARTITION=${1:-ap1} - - # Start consul now as setup script needs it up - docker_kill_rm consul-${PARTITION} - - license="${CONSUL_LICENSE:-}" - # load the consul license so we can pass it into the consul - # containers as an env var in the case that this is a consul - # enterprise test - if test -z "$license" -a -n "${CONSUL_LICENSE_PATH:-}" - then - license=$(cat $CONSUL_LICENSE_PATH) - fi - - sh -c "rm -rf /workdir/${PARTITION}/data" - - # Run consul and expose some ports to the host to make debugging locally a - # bit easier. - # - docker.exe run -d --name envoy_consul-${PARTITION}_1 \ - --net=envoy-tests \ - $WORKDIR_SNIPPET \ - --hostname "consul-${PARTITION}-client" \ - --network-alias "consul-${PARTITION}-client" \ - -e "CONSUL_LICENSE=$license" \ - windows/consul:local agent \ - -datacenter "primary" \ - -retry-join "consul-primary-server" \ - -grpc-port 8502 \ - -data-dir "/tmp/consul" \ - -config-dir "C:\\workdir\\${PARTITION}/consul" \ - -client "0.0.0.0" >/dev/null -} - -function pre_service_setup { - local CLUSTER=${1:-primary} - - # Run test case setup (e.g. generating Envoy bootstrap, starting containers) - if [ -f "${CASE_DIR}/${CLUSTER}/setup.sh" ] - then - source ${CASE_DIR}/${CLUSTER}/setup.sh - else - source ${CASE_DIR}/setup.sh - fi -} - -function start_services { - # Start containers required - if [ ! -z "$REQUIRED_SERVICES" ] ; then - docker_kill_rm $REQUIRED_SERVICES - run_containers $REQUIRED_SERVICES - fi - - return 0 -} - -function verify { - local CLUSTER="$1" - if test -z "$CLUSTER"; then - CLUSTER="primary" - fi - - # Execute tests - res=0 - - # Nuke any previous case's verify container. - docker_kill_rm verify-${CLUSTER} - - echo "Running ${CLUSTER} verification step for ${CASE_DIR}..." - - # need to tell the PID 1 inside of the container that it won't be actual PID - # 1 because we're using --pid=host so we use TINI_SUBREAPER - if docker.exe exec -i ${SINGLE_CONTAINER_BASE_NAME}-${CLUSTER}_1 bash \ - -c "TINI_SUBREAPER=1 \ - ENVOY_VERSION=${ENVOY_VERSION} \ - XDS_TARGET=${XDS_TARGET} \ - /c/bats/bin/bats \ - --pretty /c/workdir/${CLUSTER}/bats" ; then - echo "✓ PASS" - else - echo "⨯ FAIL" - res=1 - fi - - return $res -} - -function capture_logs { - local LOG_DIR="workdir/logs/${CASE_DIR}/${ENVOY_VERSION}" - - init_vars - - echo "Capturing Logs" - mkdir -p "$LOG_DIR" - - services="$REQUIRED_SERVICES consul-primary" - if [[ "$XDS_TARGET" == "client" ]] - then - services="$services consul-primary-server" - fi - - if is_set $REQUIRE_SECONDARY - then - services="$services consul-secondary" - - if [[ "$XDS_TARGET" == "client" ]] - then - services="$services consul-secondary-server" - fi - fi - - if is_set $REQUIRE_PARTITIONS - then - services="$services consul-ap1" - fi - if is_set $REQUIRE_PEERS - then - services="$services consul-alpha" - - if [[ "$XDS_TARGET" == "client" ]] - then - services="$services consul-alpha-server" - fi - fi - - if [ -f "${CASE_DIR}/capture.sh" ] - then - echo "Executing ${CASE_DIR}/capture.sh" - source ${CASE_DIR}/capture.sh || true - fi - - for cont in $services; do - echo "Capturing log for $cont" - docker.exe logs "envoy_${cont}_1" &> "${LOG_DIR}/${cont}.log" || { - echo "EXIT CODE $?" > "${LOG_DIR}/${cont}.log" - } - done -} - -function stop_services { - # Teardown - docker_kill_rm $REQUIRED_SERVICES - - docker_kill_rm consul-primary consul-primary-server consul-secondary consul-secondary-server consul-ap1 consul-alpha consul-alpha-server -} - -function init_vars { - source "defaults.sh" - if [ -f "${CASE_DIR}/vars.sh" ] ; then - source "${CASE_DIR}/vars.sh" - fi -} - -function global_setup { - if [ -f "${CASE_DIR}/global-setup-windows.sh" ] ; then - source "${CASE_DIR}/global-setup-windows.sh" - fi -} - -function wipe_volumes { - docker.exe exec -w "C:\workdir" envoy_workdir_1 cmd /c "rd /s /q . 2>nul" -} - -# Windows containers does not allow cp command while running. -function stop_and_copy_files { - # Create CMD file to execute within the container - echo "icacls C:\workdir /grant:r Everyone:(OI)(CI)F /T" > copy.cmd - echo "XCOPY C:\workdir_bak C:\workdir /e /h /c /i /y" > copy.cmd - # Stop dummy container to copy local workdir to container's workdir_bak - docker.exe stop envoy_workdir_1 > /dev/null - docker.exe cp workdir/. envoy_workdir_1:/workdir_bak - # Copy CMD file into container - docker.exe cp copy.cmd envoy_workdir_1:/ - # Start dummy container and execute the CMD file - docker.exe start envoy_workdir_1 > /dev/null - docker.exe exec envoy_workdir_1 copy.cmd - # Delete local CMD file after execution - rm copy.cmd -} - -function run_tests { - CASE_DIR="${CASE_DIR?CASE_DIR must be set to the path of the test case}" - CASE_NAME=$( basename $CASE_DIR | cut -c6- ) - export CASE_NAME - export SKIP_CASE="" - - init_vars - - # Initialize the workdir - init_workdir primary - - if is_set $REQUIRE_SECONDARY - then - init_workdir secondary - fi - if is_set $REQUIRE_PARTITIONS - then - init_workdir ap1 - fi - if is_set $REQUIRE_PEERS - then - init_workdir alpha - fi - - global_setup - - # Allow vars.sh to set a reason to skip this test case based on the ENV - if [ "$SKIP_CASE" != "" ] ; then - echo "SKIPPING CASE: $SKIP_CASE" - return 0 - fi - - # Wipe state - wipe_volumes - - # Copying base files to shared volume - stop_and_copy_files - - # Starting Consul primary cluster - start_consul primary - - if is_set $REQUIRE_SECONDARY; then - start_consul secondary - fi - if is_set $REQUIRE_PARTITIONS; then - docker_consul "primary" consul partition create -name ap1 > /dev/null - start_partitioned_client ap1 - fi - if is_set $REQUIRE_PEERS; then - start_consul alpha - fi - - echo "Setting up the primary datacenter" - pre_service_setup primary - - if is_set $REQUIRE_SECONDARY; then - echo "Setting up the secondary datacenter" - pre_service_setup secondary - fi - if is_set $REQUIRE_PARTITIONS; then - echo "Setting up the non-default partition" - pre_service_setup ap1 - fi - if is_set $REQUIRE_PEERS; then - echo "Setting up the alpha peer" - pre_service_setup alpha - fi - - echo "Starting services" - start_services - - # Run the verify container and report on the output - echo "Verifying the primary datacenter" - verify primary - - if is_set $REQUIRE_SECONDARY; then - echo "Verifying the secondary datacenter" - verify secondary - fi - if is_set $REQUIRE_PEERS; then - echo "Verifying the alpha peer" - verify alpha - fi -} - -function test_teardown { - init_vars - - stop_services -} - -function workdir_cleanup { - docker_kill_rm workdir - docker.exe volume rm -f envoy_workdir &>/dev/null || true -} - - -function suite_setup { - # Cleanup from any previous unclean runs. - suite_teardown - - docker.exe network create -d "nat" envoy-tests &>/dev/null - - # Start the volume container - # - # This is a dummy container that we use to create volume and keep it - # accessible while other containers are down. - docker.exe volume create envoy_workdir &>/dev/null - docker.exe run -d --name envoy_workdir_1 \ - $WORKDIR_SNIPPET \ - --user ContainerAdministrator \ - --net=none \ - "${HASHICORP_DOCKER_PROXY}/windows/kubernetes/pause" &>/dev/null - - # pre-build the consul+envoy container - echo "Rebuilding 'windows/consul:local' image with envoy $ENVOY_VERSION..." - retry_default docker.exe build -t windows/consul:local \ - --build-arg ENVOY_VERSION=${ENVOY_VERSION} \ - -f Dockerfile-consul-envoy-windows . - - - local CONSUL_VERSION=$(docker image inspect --format='{{.ContainerConfig.Labels.version}}' \ - windows/consul:local) - echo "Running Tests with Consul=$CONSUL_VERSION - Envoy=$ENVOY_VERSION - XDS_TARGET=$XDS_TARGET" -} - -function suite_teardown { - docker_kill_rm verify-primary verify-secondary verify-alpha - - # this is some hilarious magic - docker_kill_rm $(grep "^function run_container_" $self_name | \ - sed 's/^function run_container_\(.*\) {/\1/g') - - docker_kill_rm consul-primary consul-primary-server consul-secondary consul-secondary-server consul-ap1 consul-alpha consul-alpha-server - - if docker.exe network inspect envoy-tests &>/dev/null ; then - echo -n "Deleting network 'envoy-tests'..." - docker.exe network rm envoy-tests - echo "done" - fi - - workdir_cleanup -} - -function run_containers { - echo "Starting containers" - echo $@ - for name in $@ ; do - echo "Starting container" - echo $name - run_container $name - done - echo "Done running containers" -} - -function run_container { - docker_kill_rm "$1" - "run_container_$1" -} - -function common_run_container_service { - local service="$1" - local CLUSTER="$2" - local httpPort="$3" - local grpcPort="$4" - local CONTAINER_NAME="$SINGLE_CONTAINER_BASE_NAME"-"$CLUSTER"_1 - - docker.exe exec -d $CONTAINER_NAME bash \ - -c "FORTIO_NAME=${service} \ - fortio.exe server \ - -http-port ":$httpPort" \ - -grpc-port ":$grpcPort" \ - -redirect-port disabled" -} - -function run_container_s1 { - common_run_container_service s1 primary 8080 8079 -} - -function run_container_s1-ap1 { - common_run_container_service s1 ap1 8080 8079 -} - -function run_container_s2 { - common_run_container_service s2 primary 8181 8179 -} -function run_container_s2-v1 { - common_run_container_service s2-v1 primary 8182 8178 -} -function run_container_s2-v2 { - common_run_container_service s2-v2 primary 8183 8177 -} - -function run_container_s3 { - common_run_container_service s3 primary 8282 8279 -} -function run_container_s3-v1 { - common_run_container_service s3-v1 primary 8283 8278 -} -function run_container_s3-v2 { - common_run_container_service s3-v2 primary 8284 8277 -} -function run_container_s3-alt { - common_run_container_service s3-alt primary 8286 8280 -} - -function run_container_s4 { - common_run_container_service s4 primary 8382 8281 -} - -function run_container_s1-secondary { - common_run_container_service s1-secondary secondary 8080 8079 -} - -function run_container_s2-secondary { - common_run_container_service s2-secondary secondary 8181 8179 -} - -function run_container_s2-ap1 { - common_run_container_service s2 ap1 8480 8479 -} - -function run_container_s3-ap1 { - common_run_container_service s3 ap1 8580 8579 -} - -function run_container_s1-alpha { - common_run_container_service s1-alpha alpha 8080 8079 -} - -function run_container_s2-alpha { - common_run_container_service s2-alpha alpha 8181 8179 -} - -function run_container_s3-alpha { - common_run_container_service s3-alpha alpha 8282 8279 -} - -function common_run_container_sidecar_proxy { - local service="$1" - local CLUSTER="$2" - local CONTAINER_NAME="$SINGLE_CONTAINER_BASE_NAME"-"$CLUSTER"_1 - - # Hot restart breaks since both envoys seem to interact with each other - # despite separate containers that don't share IPC namespace. Not quite - # sure how this happens but may be due to unix socket being in some shared - # location? - docker.exe exec -d $CONTAINER_NAME bash \ - -c "envoy.exe \ - -c /c/workdir/${CLUSTER}/envoy/${service}-bootstrap.json \ - -l trace \ - --disable-hot-restart \ - --drain-time-s 1 >/dev/null" -} - -function run_container_s1-sidecar-proxy { - common_run_container_sidecar_proxy s1 primary -} - -function run_container_s1-ap1-sidecar-proxy { - common_run_container_sidecar_proxy s1 ap1 -} - -function run_container_s1-sidecar-proxy-consul-exec { - local CLUSTER="primary" - local CONTAINER_NAME="$SINGLE_CONTAINER_BASE_NAME"-"$CLUSTER"_1 - local ADMIN_HOST="127.0.0.1" - local ADMIN_PORT="19000" - - docker.exe exec -d $CONTAINER_NAME bash \ - -c "consul connect envoy -sidecar-for s1 \ - -http-addr $CONTAINER_NAME:8500 \ - -grpc-addr $CONTAINER_NAME:8502 \ - -admin-bind $ADMIN_HOST:$ADMIN_PORT \ - -envoy-version ${ENVOY_VERSION} \ - -- \ - -l trace >/dev/null" -} - -function run_container_s2-sidecar-proxy { - common_run_container_sidecar_proxy s2 primary -} -function run_container_s2-v1-sidecar-proxy { - common_run_container_sidecar_proxy s2-v1 primary -} -function run_container_s2-v2-sidecar-proxy { - common_run_container_sidecar_proxy s2-v2 primary -} - -function run_container_s3-sidecar-proxy { - common_run_container_sidecar_proxy s3 primary -} -function run_container_s3-v1-sidecar-proxy { - common_run_container_sidecar_proxy s3-v1 primary -} -function run_container_s3-v2-sidecar-proxy { - common_run_container_sidecar_proxy s3-v2 primary -} - -function run_container_s3-alt-sidecar-proxy { - common_run_container_sidecar_proxy s3-alt primary -} - -function run_container_s1-sidecar-proxy-secondary { - common_run_container_sidecar_proxy s1 secondary -} -function run_container_s2-sidecar-proxy-secondary { - common_run_container_sidecar_proxy s2 secondary -} - -function run_container_s2-ap1-sidecar-proxy { - common_run_container_sidecar_proxy s2 ap1 -} - -function run_container_s3-ap1-sidecar-proxy { - common_run_container_sidecar_proxy s3 ap1 -} - -function run_container_s1-sidecar-proxy-alpha { - common_run_container_sidecar_proxy s1 alpha -} -function run_container_s2-sidecar-proxy-alpha { - common_run_container_sidecar_proxy s2 alpha -} -function run_container_s3-sidecar-proxy-alpha { - common_run_container_sidecar_proxy s3 alpha -} - -function common_run_container_gateway { - local name="$1" - local DC="$2" - local CONTAINER_NAME="$SINGLE_CONTAINER_BASE_NAME"-"$DC"_1 - - # Hot restart breaks since both envoys seem to interact with each other - # despite separate containers that don't share IPC namespace. Not quite - # sure how this happens but may be due to unix socket being in some shared - # location? - docker.exe exec -d $CONTAINER_NAME bash \ - -c "envoy.exe \ - -c /c/workdir/${DC}/envoy/${name}-bootstrap.json \ - -l trace \ - --disable-hot-restart \ - --drain-time-s 1 >/dev/null" -} - -function run_container_gateway-primary { - common_run_container_gateway mesh-gateway primary -} -function run_container_gateway-secondary { - common_run_container_gateway mesh-gateway secondary -} -function run_container_gateway-alpha { - common_run_container_gateway mesh-gateway alpha -} - -function run_container_ingress-gateway-primary { - common_run_container_gateway ingress-gateway primary -} - -function run_container_api-gateway-primary { - common_run_container_gateway api-gateway primary -} - -function run_container_terminating-gateway-primary { - common_run_container_gateway terminating-gateway primary -} - -function run_container_fake-statsd { - local CONTAINER_NAME="$SINGLE_CONTAINER_BASE_NAME"-"primary"_1 - # This magic SYSTEM incantation is needed since Envoy doesn't add newlines and so - # we need each packet to be passed to echo to add a new line before - # appending. But it does not work on Windows. - docker.exe exec -d $CONTAINER_NAME bash -c "socat -u UDP-RECVFROM:8125,fork,reuseaddr OPEN:/workdir/primary/statsd/statsd.log,create,append" -} - -function run_container_zipkin { - docker.exe run -d --name $(container_name) \ - $WORKDIR_SNIPPET \ - $(network_snippet primary) \ - "${HASHICORP_DOCKER_PROXY}/windows/openzipkin" -} - -function run_container_jaeger { - echo "Starting Jaeger service..." - - local DC=${1:-primary} - local CONTAINER_NAME="$SINGLE_CONTAINER_BASE_NAME"-"$DC"_1 - - docker.exe exec -d $CONTAINER_NAME bash -c "jaeger-all-in-one.exe \ - --collector.zipkin.http-port=9411" -} - -function run_container_test-sds-server { - echo "Starting test-sds-server" - - local DC=${1:-primary} - local CONTAINER_NAME="$SINGLE_CONTAINER_BASE_NAME"-"$DC"_1 - - docker.exe exec -d $CONTAINER_NAME bash -c "cd /c/test-sds-server && - ./test-sds-server.exe" -} - -function container_name { - echo "envoy_${FUNCNAME[1]/#run_container_/}_1" -} -function container_name_prev { - echo "envoy_${FUNCNAME[2]/#run_container_/}_1" -} - -# This is a debugging tool. Run via 'bash run-tests.sh debug_dump_volumes' on Powershell -function debug_dump_volumes { - local LINUX_PATH=$(pwd) - local WIN_PATH=$( echo "$LINUX_PATH" | sed 's/^\/mnt//' | sed -e 's/^\///' -e 's/\//\\/g' -e 's/^./\0:/' ) - docker.exe run -it \ - $WORKDIR_SNIPPET \ - -v "$WIN_PATH":"C:\\cwd" \ - --net=none \ - "${HASHICORP_DOCKER_PROXY}/windows/nanoserver:1809" \ - cmd /c "xcopy \workdir \cwd\workdir /E /H /C /I /Y" -} - -function run_container_tcpdump-primary { - # To use add "tcpdump-primary" to REQUIRED_SERVICES - common_run_container_tcpdump primary -} -function run_container_tcpdump-secondary { - # To use add "tcpdump-secondary" to REQUIRED_SERVICES - common_run_container_tcpdump secondary -} -function run_container_tcpdump-alpha { - # To use add "tcpdump-alpha" to REQUIRED_SERVICES - common_run_container_tcpdump alpha -} - -function common_run_container_tcpdump { - local DC="$1" - - # we cant run this in circle but its only here to temporarily enable. - -# docker.exe build --rm=false -t envoy-tcpdump -f Dockerfile-tcpdump-windows . - - docker.exe run -d --name $(container_name_prev) \ - $(network_snippet $DC) \ - envoy-tcpdump \ - -v -i any \ - -w "/data/${DC}.pcap" -} - -case "${1-}" in - "") - echo "command required" - exit 1 ;; - *) - "$@" ;; -esac diff --git a/test/integration/connect/envoy/test-sds-server/Dockerfile b/test/integration/connect/envoy/test-sds-server/Dockerfile index 73f72667b95a0..5ea87089c7047 100644 --- a/test/integration/connect/envoy/test-sds-server/Dockerfile +++ b/test/integration/connect/envoy/test-sds-server/Dockerfile @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 FROM golang:latest diff --git a/test/integration/connect/envoy/test-sds-server/certs/gen-certs.sh b/test/integration/connect/envoy/test-sds-server/certs/gen-certs.sh index 2c416ad146db6..bf46e5da0abf5 100755 --- a/test/integration/connect/envoy/test-sds-server/certs/gen-certs.sh +++ b/test/integration/connect/envoy/test-sds-server/certs/gen-certs.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 set -eEuo pipefail diff --git a/test/integration/connect/envoy/test-sds-server/sds.go b/test/integration/connect/envoy/test-sds-server/sds.go index 6223d894449d2..6c1ed208cd521 100644 --- a/test/integration/connect/envoy/test-sds-server/sds.go +++ b/test/integration/connect/envoy/test-sds-server/sds.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package main diff --git a/test/integration/connect/envoy/windows-troubleshooting.md b/test/integration/connect/envoy/windows-troubleshooting.md deleted file mode 100644 index a3a83e088808a..0000000000000 --- a/test/integration/connect/envoy/windows-troubleshooting.md +++ /dev/null @@ -1,90 +0,0 @@ -# Envoy Integration Tests on Windows - -## Index - -- [About this Guide](#about-this-guide) -- [Prerequisites](#prerequisites) -- [Running the Tests](#running-the-tests) -- [Troubleshooting](#troubleshooting) - - [About Envoy Integration Tests on Windows](#about-envoy-integration-tests-on-windows) - - [Common Errors](#common-errors) -- [Windows Scripts Changes](#windows-scripts-changes) -- [Volume Issues](#volume-issues) - -## About this Guide - -On this guide you will find all the information required to run the Envoy integration tests on Windows. - -## Prerequisites - -To run the integration tests yo will need to have the following installed on your System: - -- GO v1.18(or later). -- Gotestsum library [installation](https://pkg.go.dev/gotest.tools/gotestsum). -- Docker. - -Before running the tests, you will need to build the required Docker images, to do so, you can use the script provided [here](../../../../build-support-windows/build-images.sh): - -- Build Images Script Execution - - From a Bash console (GitBash or WSL) execute: `./build-images.sh` - -## Running the Tests - -To execute the tests you need to run the following command depending on the shell you are using: -**On Powershell**: -`go test -v -timeout=30m -tags integration ./test/integration/connect/envoy -run="TestEnvoy/" -win=true` -Where **TEST CASE** is the individual test case we want to execute (e.g. case-badauthz). - -**On Git Bash**: -`ENVOY_VERSION= go test -v -timeout=30m -tags integration ./test/integration/connect/envoy -run="TestEnvoy/" -win=true` -Where **TEST CASE** is the individual test case we want to execute (e.g. case-badauthz), and **ENVOY VERSION** is the version which you are currently testing. - -> [!TIP] -> When executing the integration tests using **Powershell** you may need to set the ENVOY_VERSION value manually in line 20 of the [run-tests.windows.sh](run-tests.windows.sh) file. - -> [!WARNING] -> When executing the integration tests for Windows environments, the **End of Line Sequence** of every related file and/or script will be changed from **LF** to **CRLF**. - -### About Envoy Integration Tests on Windows - -Integration tests on Linux run a multi-container architecture that take advantage of the Host Network Docker feature, using this feature means that the container's network stack is not isolated from the Docker host (the container shares the host’s networking namespace), and the container does not get its own IP-address allocated (read more about this [here](https://docs.docker.com/network/host/)). This feature is only available for Linux, which made migrating the tests to Windows challenging, since replicating the same architecture created more issues, that's why a **single container** architecture was chosen to run the Envoy integration tests. -Using a single container architecture meant that we could use the same tests as on linux, moreover we were able to speed-up their execution by replacing *docker run* commands which started utility containers, for *docker exec* commands. - -### Common errors - -If the tests are executed without docker running, the following error will be seen: - -```powershell -error during connect: This error may indicate that the docker daemon is not running.: Post "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/build?buildargs=%7B%7D&cachefrom=%5B%5D&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile-bats-windows&labels=%7B%7D&memory=0&memswap=0&networkmode=default&rm=1&shmsize=0&t=bats-verify&target=&ulimits=null&version=1": open //./pipe/docker_engine: The system cannot find the file specified. -``` - -If any of the docker images does not exist or is mistagged, an error similar to the following will be displayed: - -```powershell -Error response from daemon: No such container: envoy_workdir_1 -``` - -If you run the Windows tests from WSL you will get the following error message: - -```bash -main_test.go:34: command failed: exec: "cmd": executable file not found in $PATH -``` - -## Windows Scripts Changes - -- The "http-addr", "grpc-addr" and "admin-access-log-path" flags were added to the creation of the Envoy Bootstrap files. -- To execute commands sh was replaced by bash on our Windows container. -- All paths were updated to use Windows format. -- Created *stop_and_copy_files* function to copy files into the shared volume (see [volume issues](#volume-issues)). -- Changed the *-admin-bind* value from `0.0.0.0` to `127.0.0.1` when generating the Envoy Bootstrap files. -- Removed the *&&* from the *common_run_container_service's* docker exec command and replaced it with *\*. -- Removed *docker_wget* and *docker_curl* functions from [helpers.windows.bash](helpers.windows.bash) file and replaced them with **docker_consul_exec**, this way we avoid starting intermediate containers when capturing logs. -- The function *wipe_volumes* uses a `docker exec` command instead of the original `docker run`, this way we speed up test execution by avoiding to start a new container just to delete volume content before each test run. -- For **case-grpc** we increased the `envoy_stats_flush_interval` value from 1s to 5s, on Windows, the original value caused the test to pass or fail randomly. -- For **case-wanfed-gw** a new script was created: **global-setup-windows.sh**, this file replaces global-setup.sh when running this test in Windows. The new script uses the windows/consul:local Docker image to generate the required TLS files and copies them into host's workdir directory. -- To use the **debug_dump_volumes** function, you need to use it via Powershell and execute the following command: `bash run-tests.windows.sh debug_dump_volumes` Make sure to be positioned with your terminal in the correct directory. -- For **case-consul-exec** this case can only be run when using the consul-dev Docker image on this repository, since it relies on features implemented only here. These features are: Windows valid default value for "-admin-access-log-path" and `consul connect envoy` command starts Envoy. This features have also been submitted in [PR#15114](https://github.com/hashicorp/consul/pull/15114). - -## Volume Issues - -Another difference that arose when migrating the tests from Linux to Windows, is that file system operations can't be executed while Windows containers are running. Currently, when running the tests a **named volume** is created and all of the required files are copied into that volume. Because of the constraint mentioned before, the workaround we implemented was creating a function (**stop_and_copy_files**) that stops the *kubernetes/pause* container and executes a script to copy the required files and finally starts the container again. diff --git a/test/integration/consul-container/assets/Dockerfile-consul-dataplane b/test/integration/consul-container/assets/Dockerfile-consul-dataplane deleted file mode 100644 index 7270f5f658aed..0000000000000 --- a/test/integration/consul-container/assets/Dockerfile-consul-dataplane +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -ARG CONSUL_DATAPLANE_IMAGE -ARG CONSUL_IMAGE - -# Docker doesn't support expansion in COPY --copy, so we need to create an intermediate image. -FROM ${CONSUL_IMAGE} as consul - -FROM ${CONSUL_DATAPLANE_IMAGE} as consuldataplane - -USER root - -# On Mac M1s when TProxy is enabled, consul-dataplane that are spawned from this image -# (only used in consul-container integration tests) will terminate with the below error. -# It is related to tproxy-startup.sh calling iptables SDK which then calls the underly -# iptables. We are investigating how this works on M1s with consul-envoy images which -# do not have this problem. For the time being tproxy tests on Mac M1s will fail locally -# but pass in CI. -# -# Error setting up traffic redirection rules: failed to run command: /sbin/iptables -t nat -N CONSUL_PROXY_INBOUND, err: exit status 1, output: iptables: Failed to initialize nft: Protocol not supported -RUN microdnf install -y iptables sudo nc \ - && usermod -a -G wheel consul-dataplane \ - && echo 'consul-dataplane ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers - -COPY --from=consul /bin/consul /bin/consul - -COPY tproxy-startup.sh /bin/tproxy-startup.sh -RUN chmod +x /bin/tproxy-startup.sh && chown root:root /bin/tproxy-startup.sh - -USER 100 diff --git a/test/integration/consul-container/assets/tproxy-startup.sh b/test/integration/consul-container/assets/tproxy-startup.sh index 974d9368cbfdf..1e5963fe9fe9e 100644 --- a/test/integration/consul-container/assets/tproxy-startup.sh +++ b/test/integration/consul-container/assets/tproxy-startup.sh @@ -1,7 +1,4 @@ #!/usr/bin/env sh -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - set -ex diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index a74881e46ae7c..daf33bafa4080 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -7,23 +7,17 @@ require ( github.com/avast/retry-go v3.0.0+incompatible github.com/docker/docker v24.0.5+incompatible github.com/docker/go-connections v0.4.0 - github.com/evanphx/json-patch v4.12.0+incompatible github.com/go-jose/go-jose/v3 v3.0.0 - github.com/hashicorp/consul v1.16.1 github.com/hashicorp/consul/api v1.24.0 github.com/hashicorp/consul/envoyextensions v0.4.1 - github.com/hashicorp/consul/proto-public v0.4.1 github.com/hashicorp/consul/sdk v0.14.1 - github.com/hashicorp/consul/testing/deployer v0.0.0-20230811171106-4a0afb5d1373 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.2.1 - github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/serf v0.10.1 - github.com/itchyny/gojq v0.12.12 + github.com/itchyny/gojq v0.12.9 github.com/mitchellh/copystructure v1.2.0 - github.com/mitchellh/mapstructure v1.5.0 github.com/otiai10/copy v1.10.0 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.8.4 @@ -31,203 +25,70 @@ require ( github.com/testcontainers/testcontainers-go v0.22.0 golang.org/x/mod v0.12.0 google.golang.org/grpc v1.57.2 - k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 ) require ( - cloud.google.com/go/compute v1.20.1 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.1 // indirect dario.cat/mergo v1.0.0 // indirect fortio.org/dflag v1.5.2 // indirect fortio.org/log v1.3.0 // indirect fortio.org/sets v1.0.2 // indirect fortio.org/version v1.0.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/DataDog/datadog-go v4.8.2+incompatible // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 // indirect - github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/armon/go-radix v1.0.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect - github.com/aws/aws-sdk-go v1.44.289 // indirect - github.com/benbjohnson/immutable v0.4.0 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/boltdb/bolt v1.3.1 // indirect - github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect - github.com/circonus-labs/circonusllhist v0.1.3 // indirect github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/containerd/containerd v1.7.3 // indirect - github.com/coreos/etcd v3.3.27+incompatible // indirect - github.com/coreos/go-oidc v2.1.0+incompatible // indirect - github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect - github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.10.1 // indirect - github.com/envoyproxy/go-control-plane v0.11.1 // indirect - github.com/envoyproxy/protoc-gen-validate v1.0.1 // indirect + github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f // indirect + github.com/envoyproxy/protoc-gen-validate v0.10.1 // indirect github.com/fatih/color v1.14.1 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/go-logr/logr v1.2.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect - github.com/go-openapi/loads v0.21.2 // indirect - github.com/go-openapi/runtime v0.25.0 // indirect - github.com/go-openapi/spec v0.20.8 // indirect - github.com/go-openapi/strfmt v0.21.3 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-openapi/validate v0.22.1 // indirect - github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.0.1 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/s2a-go v0.1.4 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.11.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect - github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 // indirect - github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-bexpr v0.1.2 // indirect - github.com/hashicorp/go-connlimit v0.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-memdb v1.3.4 // indirect github.com/hashicorp/go-msgpack v1.1.5 // indirect - github.com/hashicorp/go-msgpack/v2 v2.0.0 // indirect - github.com/hashicorp/go-plugin v1.4.5 // indirect - github.com/hashicorp/go-raftchunking v0.7.0 // indirect - github.com/hashicorp/go-retryablehttp v0.6.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 // indirect - github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect - github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // 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-syslog v1.0.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/hashicorp/hcp-scada-provider v0.2.3 // indirect - github.com/hashicorp/hcp-sdk-go v0.61.0 // indirect - github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect - github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 // indirect - github.com/hashicorp/raft v1.5.0 // indirect - github.com/hashicorp/raft-autopilot v0.1.6 // indirect - github.com/hashicorp/raft-boltdb/v2 v2.2.2 // indirect - github.com/hashicorp/raft-wal v0.4.1 // indirect - github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 // indirect - github.com/hashicorp/vault/api v1.8.3 // indirect - github.com/hashicorp/vault/api/auth/gcp v0.3.0 // indirect - github.com/hashicorp/vault/sdk v0.7.0 // indirect - github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect - github.com/imdario/mergo v0.3.15 // indirect - github.com/itchyny/timefmt-go v0.1.5 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect + github.com/itchyny/timefmt-go v0.1.4 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect - github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.14.0 // indirect - github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect - github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect - github.com/mitchellh/pointerstructure v1.2.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/patternmatcher v0.5.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/term v0.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/oklog/run v1.0.0 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/oklog/ulid/v2 v2.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/opencontainers/runc v1.1.8 // indirect - github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect - github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.39.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect - github.com/segmentio/fasthash v1.0.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect - github.com/stretchr/objx v0.5.0 // indirect - github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - go.etcd.io/bbolt v1.3.7 // indirect - go.mongodb.org/mongo-driver v1.11.0 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/sdk v1.16.0 // indirect - go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.9.0 // indirect golang.org/x/crypto v0.14.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/exp v0.0.0-20230807204917-050eac23e9de // indirect golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect - google.golang.org/api v0.126.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect + golang.org/x/tools v0.12.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.66.2 // indirect - gopkg.in/square/go-jose.v2 v2.5.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.26.2 // indirect - k8s.io/apimachinery v0.26.2 // indirect - k8s.io/client-go v0.26.2 // indirect - k8s.io/klog/v2 v2.90.1 // indirect - k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect - sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + gotest.tools/v3 v3.5.1 // indirect ) replace ( diff --git a/test/integration/consul-container/go.sum b/test/integration/consul-container/go.sum index dfcf46c6144f4..92624fe6c9760 100644 --- a/test/integration/consul-container/go.sum +++ b/test/integration/consul-container/go.sum @@ -1,56 +1,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= -cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= -cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= fortio.org/assert v1.1.4 h1:Za1RaG+OjsTMpQS3J3UCvTF6wc4+IOHCz+jAOU37Y4o= fortio.org/dflag v1.5.2 h1:F9XVRj4Qr2IbJP7BMj7XZc9wB0Q/RZ61Ool+4YPVad8= fortio.org/dflag v1.5.2/go.mod h1:ppb/A8u+KKg+qUUYZNYuvRnXuVb8IsdHb/XGzsmjkN8= @@ -66,93 +16,39 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1 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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/datadog-go v4.8.2+incompatible h1:qbcKSx29aBLD+5QLvlQZlGmRMF/FfGqFLFev/1TDzRo= -github.com/DataDog/datadog-go v4.8.2+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 h1:K4N91T1+RlSlx+t2dujeDviy4ehSGVjEltluDgmeHS4= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.156/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= -github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.44.289 h1:5CVEjiHFvdiVlKPBzv0rjG4zH/21W/onT18R5AH/qx0= -github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/benbjohnson/immutable v0.4.0 h1:CTqXbEerYso8YzVPxmWxh2gnoRQbbB9X1quUC8+vGZA= -github.com/benbjohnson/immutable v0.4.0/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= -github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= -github.com/coreos/etcd v3.3.27+incompatible h1:QIudLb9KeBsE5zyYxd1mjzRSkzLg9Wf9QlRwFgd6oTA= -github.com/coreos/etcd v3.3.27+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= -github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf h1:GOPo6vn/vTN+3IwZBvXX0y5doJfSC7My0cdzelyOCsQ= -github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -167,405 +63,107 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= 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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= -github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= -github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ= -github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= -github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= +github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= -github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= -github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -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-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= -github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= -github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= -github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= -github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= -github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= -github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE= -github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= -github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2 h1:AtvtonGEH/fZK0XPNNBdB6swgy7Iudfx88wzyIpwqJ8= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= -github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 h1:1ZEjnveDe20yFa6lSkfdQZm5BR/b271n0MsB5R2L3us= -github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706/go.mod h1:1Cs8FlmD1BfSQXJGcFLSV5FuIx1AbJP+EJGdxosoS2g= -github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 h1:wzWurXrxfSyG1PHskIZlfuXlTSCj1Tsyatp9DtaasuY= -github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69/go.mod h1:svUZZDvotY8zTODknUePc6mZ9pX8nN0ViGwWcUSOBEA= 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-bexpr v0.1.2 h1:ijMXI4qERbzxbCnkxmfUtwMyjrrk3y+Vt0MxojNCbBs= -github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-connlimit v0.3.0 h1:oAojHGjFxUTTTA8c5XXnDqWJ2HLuWbDiBPTpWvNzvqM= -github.com/hashicorp/go-connlimit v0.3.0/go.mod h1:OUj9FGL1tPIhl/2RCfzYHrIiWj+VVPGNyVPnUX8AqS0= -github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= 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.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-kms-wrapping/entropy/v2 v2.0.0/go.mod h1:xvb32K2keAc+R8DSFG2IwDcydK9DBQE+fGA5fsw6hSk= -github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= -github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4= -github.com/hashicorp/go-msgpack/v2 v2.0.0 h1:c1fiLq1LNghmLOry1ipGhvLDi+/zEoaEP2JrE1oFJ9s= -github.com/hashicorp/go-msgpack/v2 v2.0.0/go.mod h1:JIxYkkFJRDDRSoWQBSh7s9QAVThq+82iWmUpmE4jKak= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= -github.com/hashicorp/go-plugin v1.4.5 h1:oTE/oQR4eghggRg8VY7PAz3dr++VwDNBGCcOfIvHpBo= -github.com/hashicorp/go-plugin v1.4.5/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= -github.com/hashicorp/go-raftchunking v0.7.0 h1:APNMnCXmTOhumkFv/GpJIbq7HteWF7EnGZ3875lRN0Y= -github.com/hashicorp/go-raftchunking v0.7.0/go.mod h1:Dg/eBOaJzE0jYKNwNLs5IA5j0OSmL5HoCUiMy3mDmrI= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.6.7 h1:8/CAEZt/+F7kR7GevNHulKkUjLht3CPmn7egmhieNKo= -github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= -github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= -github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= -github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= -github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= -github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= -github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-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.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/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/hcp-scada-provider v0.2.3 h1:AarYR+/Pcv+cMvPdAlb92uOBmZfEH6ny4+DT+4NY2VQ= -github.com/hashicorp/hcp-scada-provider v0.2.3/go.mod h1:ZFTgGwkzNv99PLQjTsulzaCplCzOTBh0IUQsPKzrQFo= -github.com/hashicorp/hcp-sdk-go v0.61.0 h1:x4hJ8SlLI5WCE8Uzcu4q5jfdOEz/hFxfUkhAdoFdzSg= -github.com/hashicorp/hcp-sdk-go v0.61.0/go.mod h1:xP7wmWAmdMxs/7+ovH3jZn+MCDhHRj50Rn+m7JIY3Ck= -github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 h1:n9J0rwVWXDpNd5iZnwY7w4WZyq53/rROeI7OVvLW8Ok= -github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= -github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 h1:kBpVVl1sl3MaSrs97e0+pDQhSrqJv9gVbSUrPpVfl1w= -github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0/go.mod h1:6pdNz0vo0mF0GvhwDG56O3N18qBrAz/XRIcfINfTbwo= -github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= -github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= -github.com/hashicorp/raft v1.3.11/go.mod h1:J8naEwc6XaaCfts7+28whSeRvCqTd6e20BlCU3LtEO4= -github.com/hashicorp/raft v1.5.0 h1:uNs9EfJ4FwiArZRxxfd/dQ5d33nV31/CdCHArH89hT8= -github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M= -github.com/hashicorp/raft-autopilot v0.1.6 h1:C1q3RNF2FfXNZfHWbvVAu0QixaQK8K5pX4O5lh+9z4I= -github.com/hashicorp/raft-autopilot v0.1.6/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw= -github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= -github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qRd6nFJYYS6Iqnc/8HcUmko2/2Gw8qTFEmxDLii6W5I= -github.com/hashicorp/raft-boltdb v0.0.0-20220329195025-15018e9b97e0 h1:CO8dBMLH6dvE1jTn/30ZZw3iuPsNfajshWoJTnVc5cc= -github.com/hashicorp/raft-boltdb/v2 v2.2.2 h1:rlkPtOllgIcKLxVT4nutqlTH2NRFn+tO1wwZk/4Dxqw= -github.com/hashicorp/raft-boltdb/v2 v2.2.2/go.mod h1:N8YgaZgNJLpZC+h+by7vDu5rzsRgONThTEeUS3zWbfY= -github.com/hashicorp/raft-wal v0.4.1 h1:aU8XZ6x8R9BAIB/83Z1dTDtXvDVmv9YVYeXxd/1QBSA= -github.com/hashicorp/raft-wal v0.4.1/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 h1:O6tNk0s/arubLUbLeCyaRs5xGo9VwmbQazISY/BfPK4= -github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0/go.mod h1:We3fJplmALwK1VpjwrLuXr/4QCQHYMdnXLHmLUU6Ntg= -github.com/hashicorp/vault/api v1.8.0/go.mod h1:uJrw6D3y9Rv7hhmS17JQC50jbPDAZdjZoTtrCCxxs7E= -github.com/hashicorp/vault/api v1.8.3 h1:cHQOLcMhBR+aVI0HzhPxO62w2+gJhIrKguQNONPzu6o= -github.com/hashicorp/vault/api v1.8.3/go.mod h1:4g/9lj9lmuJQMtT6CmVMHC5FW1yENaVv+Nv4ZfG8fAg= -github.com/hashicorp/vault/api/auth/gcp v0.3.0 h1:taum+3pCmOXnNgEKHlQbmgXmKw5daWHk7YJrLPP/w8g= -github.com/hashicorp/vault/api/auth/gcp v0.3.0/go.mod h1:gnNBFOASYUaFunedTHOzdir7vKcHL3skWBUzEn263bo= -github.com/hashicorp/vault/sdk v0.6.0/go.mod h1:+DRpzoXIdMvKc88R4qxr+edwy/RvH5QK8itmxLiDHLc= -github.com/hashicorp/vault/sdk v0.7.0 h1:2pQRO40R1etpKkia5fb4kjrdYMx3BHklPxl1pxpxDHg= -github.com/hashicorp/vault/sdk v0.7.0/go.mod h1:KyfArJkhooyba7gYCKSq8v66QdqJmnbAxtV/OX1+JTs= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= -github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/itchyny/gojq v0.12.12 h1:x+xGI9BXqKoJQZkr95ibpe3cdrTbY8D9lonrK433rcA= -github.com/itchyny/gojq v0.12.12/go.mod h1:j+3sVkjxwd7A7Z5jrbKibgOLn0ZfLWkV+Awxr/pyzJE= -github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= -github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= -github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/itchyny/gojq v0.12.9 h1:biKpbKwMxVYhCU1d6mR7qMr3f0Hn9F5k5YykCVb3gmM= +github.com/itchyny/gojq v0.12.9/go.mod h1:T4Ip7AETUXeGpD+436m+UEl3m3tokRgajd5pRfsR5oE= +github.com/itchyny/timefmt-go v0.1.4 h1:hFEfWVdwsEi+CY8xY2FtgWHGQaBaC3JeHd+cve0ynVM= +github.com/itchyny/timefmt-go v0.1.4/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -575,7 +173,6 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -583,39 +180,20 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ 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/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= -github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU= -github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= -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 v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= -github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= @@ -625,49 +203,24 @@ github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWK 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= -github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= -github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= -github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= 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-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.8 h1:zICRlc+C1XzivLc3nzE+cbJV4LIi8tib6YG0MqC6OqA= github.com/opencontainers/runc v1.1.8/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= -github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU= github.com/otiai10/copy v1.10.0 h1:znyI7l134wNg/wDktoVQPxPkgvhDfGCYUasey+h0rDQ= github.com/otiai10/copy v1.10.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= -github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= -github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -677,652 +230,175 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= -github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= -github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= -github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify 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= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI= github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI= github.com/testcontainers/testcontainers-go v0.22.0 h1:hOK4NzNu82VZcKEB1aP9LO1xYssVFMvlfeuDW9JMmV0= github.com/testcontainers/testcontainers-go v0.22.0/go.mod h1:k0YiPa26xJCRUbUkYqy5rY6NGvSbVCeUBXCvucscBR4= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= -github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= -github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -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/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= -go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= -go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= -go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/exp v0.0.0-20230807204917-050eac23e9de h1:l5Za6utMv/HsBWWqzt4S8X17j+kt1uVETUX5UFhn2rE= +golang.org/x/exp v0.0.0-20230807204917-050eac23e9de/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= -golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= -golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= -google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e h1:xIXmWJ303kJCuogpj0bHq+dcjcZHU+XFyc1I0Yl9cRg= -google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= -google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU= -google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= -google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 h1:wukfNtZmZUurLN/atp2hiIeTKn7QJWIQdHzqmsOnAOk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.57.2 h1:uw37EN34aMFFXB2QPW7Tq6tdTbind1GpRxw5aOX3a5k= google.golang.org/grpc v1.57.2/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.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.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= -k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= -k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= -k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= -k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= -k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= -k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= -sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/test/integration/consul-container/libs/assert/common.go b/test/integration/consul-container/libs/assert/common.go index c10cb7b9b4793..5f2431f6ff2f1 100644 --- a/test/integration/consul-container/libs/assert/common.go +++ b/test/integration/consul-container/libs/assert/common.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package assert diff --git a/test/integration/consul-container/libs/assert/envoy.go b/test/integration/consul-container/libs/assert/envoy.go index 760b1f87bc5ac..eef407c25021f 100644 --- a/test/integration/consul-container/libs/assert/envoy.go +++ b/test/integration/consul-container/libs/assert/envoy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package assert @@ -33,7 +33,6 @@ func GetEnvoyListenerTCPFilters(t *testing.T, adminPort int) { fmt.Sprintf("localhost:%d", adminPort), ) } - func GetEnvoyListenerTCPFiltersWithClient( t *testing.T, client *http.Client, @@ -85,7 +84,6 @@ func AssertUpstreamEndpointStatus(t *testing.T, adminPort int, clusterName, heal count, ) } - func AssertUpstreamEndpointStatusWithClient( t *testing.T, client *http.Client, @@ -115,7 +113,7 @@ func AssertUpstreamEndpointStatusWithClient( | length`, clusterName, healthStatus) results, err := utils.JQFilter(clusters, filter) - require.NoErrorf(r, err, "could not find cluster name %q: %v \n%s", clusterName, err, clusters) + require.NoErrorf(r, err, "could not found cluster name %s in \n%s", clusterName, clusters) require.Len(r, results, 1) // the final part of the pipeline is "length" which only ever returns 1 result result, err := strconv.Atoi(results[0]) diff --git a/test/integration/consul-container/libs/assert/grpc.go b/test/integration/consul-container/libs/assert/grpc.go index a41ef65af620e..ec72f0a651fd4 100644 --- a/test/integration/consul-container/libs/assert/grpc.go +++ b/test/integration/consul-container/libs/assert/grpc.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package assert @@ -26,7 +26,6 @@ func GRPCPing(t *testing.T, addr string) { var msg *fgrpc.PingMessage retries := 0 retry.RunWith(&retry.Timer{Timeout: time.Minute, Wait: 25 * time.Millisecond}, t, func(r *retry.R) { - t.Logf("making grpc call to %s", addr) retries += 1 msg, err = pingCl.Ping(context.Background(), &fgrpc.PingMessage{ // use addr as payload so we have something variable to check against diff --git a/test/integration/consul-container/libs/assert/peering.go b/test/integration/consul-container/libs/assert/peering.go index ab000268d7900..2cf842a4aed2b 100644 --- a/test/integration/consul-container/libs/assert/peering.go +++ b/test/integration/consul-container/libs/assert/peering.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package assert @@ -10,8 +10,6 @@ import ( "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil/retry" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // PeeringStatus verifies the peering connection is the specified state with a default retry. @@ -54,8 +52,14 @@ func PeeringExportsOpts(t *testing.T, client *api.Client, peerName string, expor retry.RunWith(failer(), t, func(r *retry.R) { peering, _, err := client.Peerings().Read(context.Background(), peerName, opts) - require.Nil(r, err, "reading peering data") - require.NotNilf(r, peering, "peering not found %q", peerName) - assert.Len(r, peering.StreamStatus.ExportedServices, exports, "peering exported services") + if err != nil { + r.Fatal("error reading peering data") + } + if peering == nil { + r.Fatal("peering not found") + } + if exports != len(peering.StreamStatus.ExportedServices) { + r.Fatal("peering exported services did not match: got ", len(peering.StreamStatus.ExportedServices), " want ", exports) + } }) } diff --git a/test/integration/consul-container/libs/assert/service.go b/test/integration/consul-container/libs/assert/service.go index 35fad6bfb15ba..135403da913a4 100644 --- a/test/integration/consul-container/libs/assert/service.go +++ b/test/integration/consul-container/libs/assert/service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package assert @@ -34,7 +34,7 @@ func CatalogServiceExists(t *testing.T, c *api.Client, svc string, opts *api.Que r.Fatal("error reading service data") } if len(services) == 0 { - r.Fatalf("did not find catalog entry for %q with opts %#v", svc, opts) + r.Fatal("did not find catalog entry for ", svc) } }) } diff --git a/test/integration/consul-container/libs/cluster/agent.go b/test/integration/consul-container/libs/cluster/agent.go index 09568f21c565c..6753fd8c017e1 100644 --- a/test/integration/consul-container/libs/cluster/agent.go +++ b/test/integration/consul-container/libs/cluster/agent.go @@ -1,22 +1,15 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster import ( "context" - "encoding/json" - "fmt" "io" - jsonpatch "github.com/evanphx/json-patch" - agentconfig "github.com/hashicorp/consul/agent/config" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/lib/decode" - "github.com/hashicorp/hcl" - "github.com/mitchellh/mapstructure" "github.com/testcontainers/testcontainers-go" - "google.golang.org/grpc" + + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) @@ -43,8 +36,6 @@ type Agent interface { Upgrade(ctx context.Context, config Config) error Exec(ctx context.Context, cmd []string) (string, error) DataDir() string - GetGRPCConn() *grpc.ClientConn - GetAPIClientConfig() api.Config } // Config is a set of configurations required to create a Agent @@ -78,8 +69,7 @@ type Config struct { UseAPIWithTLS bool // TODO UseGRPCWithTLS bool - ACLEnabled bool - TokenBootstrap string + ACLEnabled bool } func (c *Config) DockerImage() string { @@ -96,30 +86,6 @@ func (c Config) Clone() Config { return c2 } -type decodeTarget struct { - agentconfig.Config `mapstructure:",squash"` -} - -// MutatebyAgentConfig mutates config by applying the fields in the input hclConfig -// Note that the precedence order is config > hclConfig, because user provider hclConfig -// may not work with the testing environment, e.g., data dir, agent name, etc. -// Currently only hcl config is allowed -func (c *Config) MutatebyAgentConfig(hclConfig string) error { - rawConfigJson, err := convertHcl2Json(hclConfig) - if err != nil { - return fmt.Errorf("error converting to Json: %s", err) - } - - // Merge 2 json - mergedConfigJosn, err := jsonpatch.MergePatch([]byte(rawConfigJson), []byte(c.JSON)) - if err != nil { - return fmt.Errorf("error merging configurations: %w", err) - } - - c.JSON = string(mergedConfigJosn) - return nil -} - // TODO: refactor away type AgentInfo struct { CACertFile string @@ -127,39 +93,3 @@ type AgentInfo struct { UseTLSForGRPC bool DebugURI string } - -func convertHcl2Json(in string) (string, error) { - var raw map[string]interface{} - err := hcl.Decode(&raw, in) - if err != nil { - return "", err - } - - var target decodeTarget - var md mapstructure.Metadata - d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ - DecodeHook: mapstructure.ComposeDecodeHookFunc( - // decode.HookWeakDecodeFromSlice is only necessary when reading from - // an HCL config file. In the future we could omit it when reading from - // JSON configs. It is left here for now to maintain backwards compat - // for the unlikely scenario that someone is using malformed JSON configs - // and expecting this behaviour to correct their config. - decode.HookWeakDecodeFromSlice, - decode.HookTranslateKeys, - ), - Metadata: &md, - Result: &target, - }) - if err != nil { - return "", err - } - if err := d.Decode(raw); err != nil { - return "", err - } - - rawjson, err := json.MarshalIndent(target, "", " ") - if err != nil { - return "", err - } - return string(rawjson), nil -} diff --git a/test/integration/consul-container/libs/cluster/app.go b/test/integration/consul-container/libs/cluster/app.go index 001880b85f432..f434fcff135b6 100644 --- a/test/integration/consul-container/libs/cluster/app.go +++ b/test/integration/consul-container/libs/cluster/app.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster diff --git a/test/integration/consul-container/libs/cluster/builder.go b/test/integration/consul-container/libs/cluster/builder.go index 4169c1a163d9a..72228a26d6134 100644 --- a/test/integration/consul-container/libs/cluster/builder.go +++ b/test/integration/consul-container/libs/cluster/builder.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster @@ -273,11 +273,6 @@ func (b *Builder) Peering(enable bool) *Builder { return b } -func (b *Builder) SetACLToken(token string) *Builder { - b.conf.Set("acl.tokens.agent", token) - return b -} - func (b *Builder) NodeID(nodeID string) *Builder { b.conf.Set("node_id", nodeID) return b diff --git a/test/integration/consul-container/libs/cluster/cluster.go b/test/integration/consul-container/libs/cluster/cluster.go index fbee48333eb1b..aedf0ac9267a5 100644 --- a/test/integration/consul-container/libs/cluster/cluster.go +++ b/test/integration/consul-container/libs/cluster/cluster.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster @@ -15,15 +15,15 @@ import ( "testing" "time" - goretry "github.com/avast/retry-go" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" "github.com/hashicorp/serf/serf" + + goretry "github.com/avast/retry-go" "github.com/stretchr/testify/require" "github.com/teris-io/shortid" "github.com/testcontainers/testcontainers-go" - - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) // Cluster provides an interface for creating and controlling a Consul cluster @@ -93,12 +93,11 @@ func New(t TestingT, configs []Config, ports ...int) (*Cluster, error) { } cluster := &Cluster{ - ID: id, - Network: network, - NetworkName: name, - ScratchDir: scratchDir, - ACLEnabled: configs[0].ACLEnabled, - TokenBootstrap: configs[0].TokenBootstrap, + ID: id, + Network: network, + NetworkName: name, + ScratchDir: scratchDir, + ACLEnabled: configs[0].ACLEnabled, } t.Cleanup(func() { _ = cluster.Terminate() @@ -194,8 +193,8 @@ func (c *Cluster) join(agents []Agent, skipSerfJoin bool) error { } if len(c.Agents) == 0 { - // if acl enabled and bootstrap token is null, generate the bootstrap tokens at the first agent - if c.ACLEnabled && c.TokenBootstrap == "" { + // if acl enabled, generate the bootstrap tokens at the first agent + if c.ACLEnabled { var ( output string err error @@ -599,7 +598,6 @@ func (c *Cluster) PeerWithCluster(acceptingClient *api.Client, acceptingPeerName } const retryTimeout = 90 * time.Second - const retryFrequency = 500 * time.Millisecond func LongFailer() *retry.Timer { diff --git a/test/integration/consul-container/libs/cluster/config.go b/test/integration/consul-container/libs/cluster/config.go index f46be0429541e..505811d35e7f3 100644 --- a/test/integration/consul-container/libs/cluster/config.go +++ b/test/integration/consul-container/libs/cluster/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster diff --git a/test/integration/consul-container/libs/cluster/container.go b/test/integration/consul-container/libs/cluster/container.go index 0ff9038c0e5df..7ed88b0d824f5 100644 --- a/test/integration/consul-container/libs/cluster/container.go +++ b/test/integration/consul-container/libs/cluster/container.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster @@ -8,30 +8,25 @@ import ( "encoding/json" "fmt" "io" - "net/url" "os" - "os/exec" "path/filepath" "strconv" "time" goretry "github.com/avast/retry-go" dockercontainer "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" - "github.com/hashicorp/consul/api" "github.com/hashicorp/go-multierror" "github.com/otiai10/copy" "github.com/pkg/errors" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" + + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) const bootLogLine = "Consul agent running" - const disableRYUKEnv = "TESTCONTAINERS_RYUK_DISABLED" // Exposed ports info @@ -63,14 +58,10 @@ type consulContainerNode struct { clientCACertFile string ip string - grpcConn *grpc.ClientConn - nextAdminPortOffset int nextConnectPortOffset int info AgentInfo - - apiClientConfig api.Config } func (c *consulContainerNode) GetPod() testcontainers.Container { @@ -136,13 +127,6 @@ func NewConsulContainer(ctx context.Context, config Config, cluster *Cluster, po if err != nil { return nil, fmt.Errorf("error copying persistent data from %s: %w", config.ExternalDataDir, err) } - // NOTE: make sure the new version can access the persistent data - // This is necessary for running on Linux - cmd := exec.Command("chmod", "-R", "777", tmpDirData) - err = cmd.Run() - if err != nil { - return nil, fmt.Errorf("error changing ownership of persistent data: %w", err) - } } var caCertFileForAPI string @@ -188,8 +172,7 @@ func NewConsulContainer(ctx context.Context, config Config, cluster *Cluster, po clientAddr string clientCACertFile string - info AgentInfo - grpcConn *grpc.ClientConn + info AgentInfo ) debugURI := "" if utils.Debug { @@ -253,28 +236,6 @@ func NewConsulContainer(ctx context.Context, config Config, cluster *Cluster, po info.CACertFile = clientCACertFile } - // TODO: Support gRPC+TLS port. - if pc.Ports.GRPC > 0 { - port, err := nat.NewPort("tcp", strconv.Itoa(pc.Ports.GRPC)) - if err != nil { - return nil, fmt.Errorf("failed to parse gRPC TLS port: %w", err) - } - endpoint, err := podContainer.PortEndpoint(ctx, port, "tcp") - if err != nil { - return nil, fmt.Errorf("failed to get gRPC TLS endpoint: %w", err) - } - url, err := url.Parse(endpoint) - if err != nil { - return nil, fmt.Errorf("failed to parse gRPC endpoint URL: %w", err) - } - conn, err := grpc.Dial(url.Host, grpc.WithTransportCredentials(insecure.NewCredentials())) - if err != nil { - return nil, fmt.Errorf("failed to dial gRPC connection: %w", err) - } - deferClean.Add(func() { _ = conn.Close() }) - grpcConn = conn - } - ip, err := podContainer.ContainerIP(ctx) if err != nil { return nil, err @@ -321,7 +282,6 @@ func NewConsulContainer(ctx context.Context, config Config, cluster *Cluster, po name: name, ip: ip, info: info, - grpcConn: grpcConn, } if httpPort > 0 || httpsPort > 0 { @@ -340,14 +300,12 @@ func NewConsulContainer(ctx context.Context, config Config, cluster *Cluster, po } node.client = apiClient - node.apiClientConfig = *apiConfig node.clientAddr = clientAddr node.clientCACertFile = clientCACertFile } - // Inject node token if ACL is enabled, the bootstrap token not null, and cluster - // has at least one agent - if cluster.TokenBootstrap != "" && cluster.ACLEnabled && len(cluster.Agents) > 0 { + // Inject node token if ACL is enabled and the bootstrap token is generated + if cluster.TokenBootstrap != "" && cluster.ACLEnabled { agentToken, err := cluster.CreateAgentToken(pc.Datacenter, name) if err != nil { return nil, err @@ -418,10 +376,6 @@ func (c *consulContainerNode) GetClient() *api.Client { return c.client } -func (c *consulContainerNode) GetGRPCConn() *grpc.ClientConn { - return c.grpcConn -} - // NewClient returns an API client by making a new one based on the provided token // - updateDefault: if true update the default client func (c *consulContainerNode) NewClient(token string, updateDefault bool) (*api.Client, error) { @@ -457,10 +411,6 @@ func (c *consulContainerNode) GetIP() string { return c.ip } -func (c *consulContainerNode) GetAPIClientConfig() api.Config { - return c.apiClientConfig -} - func (c *consulContainerNode) RegisterTermination(f func() error) { c.terminateFuncs = append(c.terminateFuncs, f) } @@ -543,11 +493,9 @@ func (c *consulContainerNode) Upgrade(ctx context.Context, config Config) error func (c *consulContainerNode) Terminate() error { return c.terminate(false, false) } - func (c *consulContainerNode) TerminateAndRetainPod(skipFuncs bool) error { return c.terminate(true, skipFuncs) } - func (c *consulContainerNode) terminate(retainPod bool, skipFuncs bool) error { // Services might register a termination function that should also fire // when the "agent" is cleaned up. @@ -560,10 +508,6 @@ func (c *consulContainerNode) terminate(retainPod bool, skipFuncs bool) error { continue } } - - // if the pod is retained and therefore the IP then the grpc conn - // should handle reconnecting so there is no reason to close it. - c.closeGRPC() } var merr error @@ -585,16 +529,6 @@ func (c *consulContainerNode) terminate(retainPod bool, skipFuncs bool) error { return merr } -func (c *consulContainerNode) closeGRPC() error { - if c.grpcConn != nil { - if err := c.grpcConn.Close(); err != nil { - return err - } - c.grpcConn = nil - } - return nil -} - func (c *consulContainerNode) DataDir() string { return c.dataDir } @@ -631,8 +565,6 @@ func newContainerRequest(config Config, opts containerOpts, ports ...int) (podRe ExposedPorts: []string{ "8500/tcp", // Consul HTTP API "8501/tcp", // Consul HTTPs API - "8502/tcp", // Consul gRPC API - "8600/udp", // Consul DNS API "8443/tcp", // Envoy Gateway Listener @@ -649,8 +581,6 @@ func newContainerRequest(config Config, opts containerOpts, ports ...int) (podRe "9997/tcp", // Envoy App Listener "9998/tcp", // Envoy App Listener "9999/tcp", // Envoy App Listener - - "80/tcp", // Nginx - http port used in wasm tests }, Hostname: opts.hostname, Networks: opts.addtionalNetworks, diff --git a/test/integration/consul-container/libs/cluster/dataplane.go b/test/integration/consul-container/libs/cluster/dataplane.go deleted file mode 100644 index a9f8498acebf0..0000000000000 --- a/test/integration/consul-container/libs/cluster/dataplane.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package cluster - -import ( - "context" - "fmt" - "io" - "strconv" - "strings" - "time" - - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" -) - -type ConsulDataplaneContainer struct { - ctx context.Context - container testcontainers.Container - ip string - appPort []int - serviceName string - externalAdminPort int - internalAdminPort int -} - -func (g ConsulDataplaneContainer) GetAddr() (string, int) { - return g.ip, g.appPort[0] -} - -func (g ConsulDataplaneContainer) GetServiceName() string { - return g.serviceName -} - -// GetAdminAddr returns the external admin port -func (g ConsulDataplaneContainer) GetAdminAddr() (string, int) { - return "localhost", g.externalAdminPort -} - -func (c ConsulDataplaneContainer) Terminate() error { - return TerminateContainer(c.ctx, c.container, true) -} - -func (g ConsulDataplaneContainer) Exec(ctx context.Context, cmd []string) (string, error) { - exitCode, reader, err := g.container.Exec(ctx, cmd) - if err != nil { - return "", fmt.Errorf("exec with error %s", err) - } - if exitCode != 0 { - return "", fmt.Errorf("exec with exit code %d", exitCode) - } - buf, err := io.ReadAll(reader) - if err != nil { - return "", fmt.Errorf("error reading from exec output: %w", err) - } - return string(buf), nil -} - -func (g ConsulDataplaneContainer) GetStatus() (string, error) { - state, err := g.container.State(g.ctx) - return state.Status, err -} - -func NewConsulDataplane(ctx context.Context, proxyID string, serverAddresses string, grpcPort int, serviceBindPorts []int, - node Agent, tproxy bool, bootstrapToken string, containerArgs ...string) (*ConsulDataplaneContainer, error) { - namePrefix := fmt.Sprintf("%s-consul-dataplane-%s", node.GetDatacenter(), proxyID) - containerName := utils.RandName(namePrefix) - - internalAdminPort, err := node.ClaimAdminPort() - if err != nil { - return nil, err - } - - pod := node.GetPod() - if pod == nil { - return nil, fmt.Errorf("node Pod is required") - } - - var ( - appPortStrs []string - adminPortStr = strconv.Itoa(internalAdminPort) - ) - - for _, port := range serviceBindPorts { - appPortStrs = append(appPortStrs, strconv.Itoa(port)) - } - - // expose the app ports and the envoy adminPortStr on the agent container - exposedPorts := make([]string, len(appPortStrs)) - copy(exposedPorts, appPortStrs) - exposedPorts = append(exposedPorts, adminPortStr) - - req := testcontainers.ContainerRequest{ - Image: "consul-dataplane:local", - WaitingFor: wait.ForLog("").WithStartupTimeout(60 * time.Second), - AutoRemove: false, - Name: containerName, - Env: map[string]string{}, - } - - var command []string - - if tproxy { - req.Entrypoint = []string{"sh", "/bin/tproxy-startup.sh"} - req.Env["REDIRECT_TRAFFIC_ARGS"] = strings.Join( - []string{ - // TODO once we run this on a different pod from Consul agents, we can eliminate most of this. - "-exclude-inbound-port", fmt.Sprint(internalAdminPort), - "-exclude-inbound-port", "8300", - "-exclude-inbound-port", "8301", - "-exclude-inbound-port", "8302", - "-exclude-inbound-port", "8500", - "-exclude-inbound-port", "8502", - "-exclude-inbound-port", "8600", - "-proxy-inbound-port", "20000", - "-consul-dns-ip", "127.0.0.1", - "-consul-dns-port", "8600", - }, - " ", - ) - req.CapAdd = append(req.CapAdd, "NET_ADMIN") - command = append(command, "consul-dataplane") - } - - command = append(command, - "-addresses", serverAddresses, - fmt.Sprintf("-grpc-port=%d", grpcPort), - fmt.Sprintf("-proxy-id=%s", proxyID), - "-proxy-namespace=default", - "-proxy-partition=default", - "-log-level=info", - "-log-json=false", - "-envoy-concurrency=2", - "-tls-disabled", - fmt.Sprintf("-envoy-admin-bind-port=%d", internalAdminPort), - ) - - if bootstrapToken != "" { - command = append(command, - "-credential-type=static", - fmt.Sprintf("-static-token=%s", bootstrapToken)) - } - - req.Cmd = append(command, containerArgs...) - - info, err := LaunchContainerOnNode(ctx, node, req, exposedPorts) - if err != nil { - return nil, err - } - out := &ConsulDataplaneContainer{ - ctx: ctx, - container: info.Container, - ip: info.IP, - serviceName: containerName, - externalAdminPort: info.MappedPorts[adminPortStr].Int(), - internalAdminPort: internalAdminPort, - } - - for _, port := range appPortStrs { - out.appPort = append(out.appPort, info.MappedPorts[port].Int()) - } - - fmt.Printf("NewConsulDataplane: proxyID %s, mapped App Port %d, service bind port %v\n", - proxyID, out.appPort, serviceBindPorts) - fmt.Printf("NewConsulDataplane: proxyID %s, , mapped admin port %d, admin port %d\n", - proxyID, out.externalAdminPort, internalAdminPort) - - return out, nil -} diff --git a/test/integration/consul-container/libs/cluster/encryption.go b/test/integration/consul-container/libs/cluster/encryption.go index 1d7ae072bf568..3adb5a317700f 100644 --- a/test/integration/consul-container/libs/cluster/encryption.go +++ b/test/integration/consul-container/libs/cluster/encryption.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster @@ -8,7 +8,6 @@ import ( "crypto/rand" "encoding/base64" "fmt" - "github.com/hashicorp/consul/sdk/testutil/retry" "io" "path/filepath" "testing" @@ -48,98 +47,89 @@ func (c *BuildContext) createTLSCAFiles(t *testing.T) { // TODO: cleanup anything with the prefix? - retry.Run(t, func(r *retry.R) { - // Create a volume to hold the data. - err = utils.DockerExec([]string{"volume", "create", c.certVolume}, io.Discard) - require.NoError(r, err, "could not create docker volume to hold cert data: %s", c.certVolume) - }) + // Create a volume to hold the data. + err = utils.DockerExec([]string{"volume", "create", c.certVolume}, io.Discard) + require.NoError(t, err, "could not create docker volume to hold cert data: %s", c.certVolume) t.Cleanup(func() { _ = utils.DockerExec([]string{"volume", "rm", c.certVolume}, io.Discard) }) - retry.Run(t, func(r *retry.R) { - err := utils.DockerExec([]string{"run", - "--rm", - "-i", - "--net=none", - "-v", c.certVolume + ":/data", - "busybox:latest", - "sh", "-c", - // Need this so the permissions stick; docker seems to treat unused volumes differently. - `touch /data/VOLUME_PLACEHOLDER && chown -R ` + consulUserArg + ` /data`, - }, io.Discard) - require.NoError(r, err, "could not initialize docker volume for cert data: %s", c.certVolume) - }) - retry.Run(t, func(r *retry.R) { - err = utils.DockerExec([]string{"run", - "--rm", - "-i", - "--net=none", - "-u", consulUserArg, - "-v", c.certVolume + ":/data", - "-w", "/data", - "--entrypoint", "", - c.DockerImage(), - "consul", "tls", "ca", "create", - }, io.Discard) - require.NoError(r, err, "could not create TLS certificate authority in docker volume: %s", c.certVolume) - }) + err = utils.DockerExec([]string{"run", + "--rm", + "-i", + "--net=none", + "-v", c.certVolume + ":/data", + "busybox:latest", + "sh", "-c", + // Need this so the permissions stick; docker seems to treat unused volumes differently. + `touch /data/VOLUME_PLACEHOLDER && chown -R ` + consulUserArg + ` /data`, + }, io.Discard) + require.NoError(t, err, "could not initialize docker volume for cert data: %s", c.certVolume) + + err = utils.DockerExec([]string{"run", + "--rm", + "-i", + "--net=none", + "-u", consulUserArg, + "-v", c.certVolume + ":/data", + "-w", "/data", + "--entrypoint", "", + c.DockerImage(), + "consul", "tls", "ca", "create", + }, io.Discard) + require.NoError(t, err, "could not create TLS certificate authority in docker volume: %s", c.certVolume) + var w bytes.Buffer - retry.Run(t, func(r *retry.R) { - err = utils.DockerExec([]string{"run", - "--rm", - "-i", - "--net=none", - "-u", consulUserArg, - "-v", c.certVolume + ":/data", - "-w", "/data", - "--entrypoint", "", - c.DockerImage(), - "cat", filepath.Join("/data", ConsulCACertPEM), - }, &w) - require.NoError(r, err, "could not extract TLS CA certificate authority public key from docker volume: %s", c.certVolume) - }) + err = utils.DockerExec([]string{"run", + "--rm", + "-i", + "--net=none", + "-u", consulUserArg, + "-v", c.certVolume + ":/data", + "-w", "/data", + "--entrypoint", "", + c.DockerImage(), + "cat", filepath.Join("/data", ConsulCACertPEM), + }, &w) + require.NoError(t, err, "could not extract TLS CA certificate authority public key from docker volume: %s", c.certVolume) c.caCert = w.String() } func (c *BuildContext) createTLSCertFiles(t *testing.T, dc string) (keyFileName, certFileName string) { require.NotEmpty(t, "the CA has not been initialized yet") - retry.Run(t, func(r *retry.R) { - err := utils.DockerExec([]string{"run", + + err := utils.DockerExec([]string{"run", + "--rm", + "-i", + "--net=none", + "-u", consulUserArg, + "-v", c.certVolume + ":/data", + "-w", "/data", + "--entrypoint", "", + c.DockerImage(), + "consul", "tls", "cert", "create", "-server", "-dc", dc, + }, io.Discard) + require.NoError(t, err, "could not create TLS server certificate dc=%q in docker volume: %s", dc, c.certVolume) + + prefix := fmt.Sprintf("%s-server-%s", dc, "consul") + certFileName = fmt.Sprintf("%s-%d.pem", prefix, c.tlsCertIndex) + keyFileName = fmt.Sprintf("%s-%d-key.pem", prefix, c.tlsCertIndex) + + for _, fn := range []string{certFileName, keyFileName} { + err = utils.DockerExec([]string{"run", "--rm", "-i", "--net=none", "-u", consulUserArg, - "-v", c.certVolume + ":/data", + "-v", c.certVolume + ":/data:ro", "-w", "/data", "--entrypoint", "", c.DockerImage(), - "consul", "tls", "cert", "create", "-server", "-dc", dc, + "stat", filepath.Join("/data", fn), }, io.Discard) - require.NoError(r, err, "could not create TLS server certificate dc=%q in docker volume: %s", dc, c.certVolume) - }) - - prefix := fmt.Sprintf("%s-server-%s", dc, "consul") - certFileName = fmt.Sprintf("%s-%d.pem", prefix, c.tlsCertIndex) - keyFileName = fmt.Sprintf("%s-%d-key.pem", prefix, c.tlsCertIndex) - - retry.Run(t, func(r *retry.R) { - for _, fn := range []string{certFileName, keyFileName} { - err := utils.DockerExec([]string{"run", - "--rm", - "-i", - "--net=none", - "-u", consulUserArg, - "-v", c.certVolume + ":/data:ro", - "-w", "/data", - "--entrypoint", "", - c.DockerImage(), - "stat", filepath.Join("/data", fn), - }, io.Discard) - require.NoError(r, err, "Generated TLS cert file %q does not exist in volume", fn) - } - }) + require.NoError(t, err, "Generated TLS cert file %q does not exist in volume", fn) + } return keyFileName, certFileName } diff --git a/test/integration/consul-container/libs/cluster/log.go b/test/integration/consul-container/libs/cluster/log.go index 59e69a64efdaf..f2a185d532f4f 100644 --- a/test/integration/consul-container/libs/cluster/log.go +++ b/test/integration/consul-container/libs/cluster/log.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster diff --git a/test/integration/consul-container/libs/cluster/network.go b/test/integration/consul-container/libs/cluster/network.go index be6f34c77983e..e0ee10f4e35ff 100644 --- a/test/integration/consul-container/libs/cluster/network.go +++ b/test/integration/consul-container/libs/cluster/network.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package cluster @@ -20,7 +20,6 @@ func createNetwork(t TestingT, name string) (testcontainers.Network, error) { Name: name, Attachable: true, CheckDuplicate: true, - SkipReaper: isRYUKDisabled(), }, } first := true diff --git a/test/integration/consul-container/libs/service/common.go b/test/integration/consul-container/libs/service/common.go index 775113a580278..add9f1395d241 100644 --- a/test/integration/consul-container/libs/service/common.go +++ b/test/integration/consul-container/libs/service/common.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package service @@ -9,5 +9,5 @@ import ( const ( envoyLogLevel = "debug" - HashicorpDockerProxy = "docker.mirror.hashicorp.services" + hashicorpDockerProxy = "docker.mirror.hashicorp.services" ) diff --git a/test/integration/consul-container/libs/service/connect.go b/test/integration/consul-container/libs/service/connect.go index 4b9998a779c5f..4028309acb3ec 100644 --- a/test/integration/consul-container/libs/service/connect.go +++ b/test/integration/consul-container/libs/service/connect.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package service @@ -13,10 +13,11 @@ import ( "strings" "time" - "github.com/hashicorp/consul/api" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) @@ -171,15 +172,8 @@ type SidecarConfig struct { // "consul connect envoy", for service name (serviceName) on the specified // node. The container exposes port serviceBindPort and envoy admin port // (19000) by mapping them onto host ports. The container's name has a prefix -// combining datacenter and name. The customContainerConf parameter can be used -// to mutate the testcontainers.ContainerRequest used to create the sidecar proxy. -func NewConnectService( - ctx context.Context, - sidecarCfg SidecarConfig, - serviceBindPorts []int, - node cluster.Agent, - customContainerConf func(request testcontainers.ContainerRequest) testcontainers.ContainerRequest, -) (*ConnectContainer, error) { +// combining datacenter and name. +func NewConnectService(ctx context.Context, sidecarCfg SidecarConfig, serviceBindPorts []int, node cluster.Agent) (*ConnectContainer, error) { nodeConfig := node.GetConfig() if nodeConfig.ScratchDir == "" { return nil, fmt.Errorf("node ScratchDir is required") @@ -205,7 +199,6 @@ func NewConnectService( "-sidecar-for", sidecarCfg.ServiceID, "-admin-bind", fmt.Sprintf("0.0.0.0:%d", internalAdminPort), "-namespace", sidecarCfg.Namespace, - "-partition", sidecarCfg.Partition, "--", "--log-level", envoyLogLevel, }, @@ -287,11 +280,6 @@ func NewConnectService( exposedPorts := make([]string, len(appPortStrs)) copy(exposedPorts, appPortStrs) exposedPorts = append(exposedPorts, adminPortStr) - - if customContainerConf != nil { - req = customContainerConf(req) - } - info, err := cluster.LaunchContainerOnNode(ctx, node, req, exposedPorts) if err != nil { return nil, err diff --git a/test/integration/consul-container/libs/service/examples.go b/test/integration/consul-container/libs/service/examples.go index bfcaf22b2d5be..85505c5dccc5e 100644 --- a/test/integration/consul-container/libs/service/examples.go +++ b/test/integration/consul-container/libs/service/examples.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package service @@ -127,42 +127,6 @@ func (c exampleContainer) GetStatus() (string, error) { return state.Status, err } -// NewCustomService creates a new test service from a custom testcontainers.ContainerRequest. -func NewCustomService(ctx context.Context, name string, httpPort int, grpcPort int, node libcluster.Agent, request testcontainers.ContainerRequest) (Service, error) { - namePrefix := fmt.Sprintf("%s-service-example-%s", node.GetDatacenter(), name) - containerName := utils.RandName(namePrefix) - - pod := node.GetPod() - if pod == nil { - return nil, fmt.Errorf("node Pod is required") - } - - var ( - httpPortStr = strconv.Itoa(httpPort) - grpcPortStr = strconv.Itoa(grpcPort) - ) - - request.Name = containerName - - info, err := libcluster.LaunchContainerOnNode(ctx, node, request, []string{httpPortStr, grpcPortStr}) - if err != nil { - return nil, err - } - - out := &exampleContainer{ - ctx: ctx, - container: info.Container, - ip: info.IP, - httpPort: info.MappedPorts[httpPortStr].Int(), - grpcPort: info.MappedPorts[grpcPortStr].Int(), - serviceName: name, - } - - fmt.Printf("Custom service exposed http port %d, gRPC port %d\n", out.httpPort, out.grpcPort) - - return out, nil -} - func NewExampleService(ctx context.Context, name string, httpPort int, grpcPort int, node libcluster.Agent, containerArgs ...string) (Service, error) { namePrefix := fmt.Sprintf("%s-service-example-%s", node.GetDatacenter(), name) containerName := utils.RandName(namePrefix) @@ -187,7 +151,7 @@ func NewExampleService(ctx context.Context, name string, httpPort int, grpcPort command = append(command, containerArgs...) req := testcontainers.ContainerRequest{ - Image: HashicorpDockerProxy + "/fortio/fortio", + Image: hashicorpDockerProxy + "/fortio/fortio", WaitingFor: wait.ForLog("").WithStartupTimeout(60 * time.Second), AutoRemove: false, Name: containerName, diff --git a/test/integration/consul-container/libs/service/gateway.go b/test/integration/consul-container/libs/service/gateway.go index b468d9ecf1a6a..fda7b7a92693e 100644 --- a/test/integration/consul-container/libs/service/gateway.go +++ b/test/integration/consul-container/libs/service/gateway.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package service @@ -11,10 +11,11 @@ import ( "strconv" "time" - "github.com/hashicorp/consul/api" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" + "github.com/hashicorp/consul/api" + libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) @@ -144,7 +145,6 @@ type GatewayConfig struct { Name string Kind string Namespace string - Partition string } func NewGatewayService(ctx context.Context, gwCfg GatewayConfig, node libcluster.Agent, ports ...int) (Service, error) { @@ -170,7 +170,6 @@ func NewGatewayServiceReg(ctx context.Context, gwCfg GatewayConfig, node libclus fmt.Sprintf("-gateway=%s", gwCfg.Kind), "-service", gwCfg.Name, "-namespace", gwCfg.Namespace, - "-partition", gwCfg.Partition, "-address", "{{ GetInterfaceIP \"eth0\" }}:8443", "-admin-bind", fmt.Sprintf("0.0.0.0:%d", adminPort), } diff --git a/test/integration/consul-container/libs/service/helpers.go b/test/integration/consul-container/libs/service/helpers.go index eb4cb2d19f742..d7168448c208b 100644 --- a/test/integration/consul-container/libs/service/helpers.go +++ b/test/integration/consul-container/libs/service/helpers.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package service @@ -8,10 +8,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/consul/api" "github.com/stretchr/testify/require" - "github.com/testcontainers/testcontainers-go" + "github.com/hashicorp/consul/api" libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) @@ -49,11 +48,10 @@ type ServiceOpts struct { Namespace string Partition string Locality *api.Locality - Upstreams []api.Upstream } // createAndRegisterStaticServerAndSidecar register the services and launch static-server containers -func createAndRegisterStaticServerAndSidecar(node libcluster.Agent, httpPort int, grpcPort int, svc *api.AgentServiceRegistration, customContainerCfg func(testcontainers.ContainerRequest) testcontainers.ContainerRequest, containerArgs ...string) (Service, Service, error) { +func createAndRegisterStaticServerAndSidecar(node libcluster.Agent, httpPort int, grpcPort int, svc *api.AgentServiceRegistration, containerArgs ...string) (Service, Service, error) { // Do some trickery to ensure that partial completion is correctly torn // down, but successful execution is not. var deferClean utils.ResettableDefer @@ -81,62 +79,10 @@ func createAndRegisterStaticServerAndSidecar(node libcluster.Agent, httpPort int svc.Connect.SidecarService.Proxy != nil && svc.Connect.SidecarService.Proxy.Mode == api.ProxyModeTransparent, } - serverConnectProxy, err := NewConnectService(context.Background(), sidecarCfg, []int{svc.Port}, node, customContainerCfg) // bindPort not used - if err != nil { - return nil, nil, err - } - - deferClean.Add(func() { - _ = serverConnectProxy.Terminate() - }) - - // disable cleanup functions now that we have an object with a Terminate() function - deferClean.Reset() - - return serverService, serverConnectProxy, nil -} - -// createAndRegisterCustomServiceAndSidecar creates a custom service from the given testcontainers.ContainerRequest -// and a sidecar proxy for the service. The customContainerCfg parameter is used to mutate the -// testcontainers.ContainerRequest for the sidecar proxy. -func createAndRegisterCustomServiceAndSidecar(node libcluster.Agent, - httpPort int, - grpcPort int, - svc *api.AgentServiceRegistration, - request testcontainers.ContainerRequest, - customContainerCfg func(testcontainers.ContainerRequest) testcontainers.ContainerRequest, -) (Service, Service, error) { - // Do some trickery to ensure that partial completion is correctly torn - // down, but successful execution is not. - var deferClean utils.ResettableDefer - defer deferClean.Execute() - - if err := node.GetClient().Agent().ServiceRegister(svc); err != nil { - return nil, nil, err - } - - // Create a service and proxy instance - serverService, err := NewCustomService(context.Background(), svc.ID, httpPort, grpcPort, node, request) - if err != nil { - return nil, nil, err - } - deferClean.Add(func() { - _ = serverService.Terminate() - }) - sidecarCfg := SidecarConfig{ - Name: fmt.Sprintf("%s-sidecar", svc.ID), - ServiceID: svc.ID, - Namespace: svc.Namespace, - EnableTProxy: svc.Connect != nil && - svc.Connect.SidecarService != nil && - svc.Connect.SidecarService.Proxy != nil && - svc.Connect.SidecarService.Proxy.Mode == api.ProxyModeTransparent, - } - serverConnectProxy, err := NewConnectService(context.Background(), sidecarCfg, []int{svc.Port}, node, customContainerCfg) // bindPort not used + serverConnectProxy, err := NewConnectService(context.Background(), sidecarCfg, []int{svc.Port}, node) // bindPort not used if err != nil { return nil, nil, err } - deferClean.Add(func() { _ = serverConnectProxy.Terminate() }) @@ -147,52 +93,7 @@ func createAndRegisterCustomServiceAndSidecar(node libcluster.Agent, return serverService, serverConnectProxy, nil } -func CreateAndRegisterCustomServiceAndSidecar(node libcluster.Agent, - serviceOpts *ServiceOpts, - request testcontainers.ContainerRequest, - customContainerCfg func(testcontainers.ContainerRequest) testcontainers.ContainerRequest) (Service, Service, error) { - // Register the static-server service and sidecar first to prevent race with sidecar - // trying to get xDS before it's ready - p := serviceOpts.HTTPPort - agentCheck := api.AgentServiceCheck{ - Name: "Static Server Listening", - TCP: fmt.Sprintf("127.0.0.1:%d", p), - Interval: "10s", - Status: api.HealthPassing, - } - if serviceOpts.RegisterGRPC { - p = serviceOpts.GRPCPort - agentCheck.TCP = "" - agentCheck.GRPC = fmt.Sprintf("127.0.0.1:%d", p) - } - req := &api.AgentServiceRegistration{ - Name: serviceOpts.Name, - ID: serviceOpts.ID, - Port: p, - Connect: &api.AgentServiceConnect{ - SidecarService: &api.AgentServiceRegistration{ - Proxy: &api.AgentServiceConnectProxyConfig{ - Mode: api.ProxyMode(serviceOpts.Connect.Proxy.Mode), - }, - }, - }, - Namespace: serviceOpts.Namespace, - Partition: serviceOpts.Partition, - Locality: serviceOpts.Locality, - Meta: serviceOpts.Meta, - Check: &agentCheck, - } - return createAndRegisterCustomServiceAndSidecar(node, serviceOpts.HTTPPort, serviceOpts.GRPCPort, req, request, customContainerCfg) -} - -// CreateAndRegisterStaticServerAndSidecarWithCustomContainerConfig creates an example static server and a sidecar for -// the service. The customContainerCfg parameter is a function of testcontainers.ContainerRequest to -// testcontainers.ContainerRequest which can be used to mutate the container request for the sidecar proxy and inject -// custom configuration and lifecycle hooks. -func CreateAndRegisterStaticServerAndSidecarWithCustomContainerConfig(node libcluster.Agent, - serviceOpts *ServiceOpts, - customContainerCfg func(testcontainers.ContainerRequest) testcontainers.ContainerRequest, - containerArgs ...string) (Service, Service, error) { +func CreateAndRegisterStaticServerAndSidecar(node libcluster.Agent, serviceOpts *ServiceOpts, containerArgs ...string) (Service, Service, error) { // Register the static-server service and sidecar first to prevent race with sidecar // trying to get xDS before it's ready p := serviceOpts.HTTPPort @@ -224,11 +125,7 @@ func CreateAndRegisterStaticServerAndSidecarWithCustomContainerConfig(node libcl Meta: serviceOpts.Meta, Check: &agentCheck, } - return createAndRegisterStaticServerAndSidecar(node, serviceOpts.HTTPPort, serviceOpts.GRPCPort, req, customContainerCfg, containerArgs...) -} - -func CreateAndRegisterStaticServerAndSidecar(node libcluster.Agent, serviceOpts *ServiceOpts, containerArgs ...string) (Service, Service, error) { - return CreateAndRegisterStaticServerAndSidecarWithCustomContainerConfig(node, serviceOpts, nil, containerArgs...) + return createAndRegisterStaticServerAndSidecar(node, serviceOpts.HTTPPort, serviceOpts.GRPCPort, req, containerArgs...) } func CreateAndRegisterStaticServerAndSidecarWithChecks(node libcluster.Agent, serviceOpts *ServiceOpts) (Service, Service, error) { @@ -258,7 +155,7 @@ func CreateAndRegisterStaticServerAndSidecarWithChecks(node libcluster.Agent, se Locality: serviceOpts.Locality, } - return createAndRegisterStaticServerAndSidecar(node, serviceOpts.HTTPPort, serviceOpts.GRPCPort, req, nil) + return createAndRegisterStaticServerAndSidecar(node, serviceOpts.HTTPPort, serviceOpts.GRPCPort, req) } func CreateAndRegisterStaticClientSidecar( @@ -323,9 +220,6 @@ func CreateAndRegisterStaticClientSidecar( if serviceOpts.Connect.Port != 0 { req.Connect.SidecarService.Port = serviceOpts.Connect.Port } - if len(serviceOpts.Upstreams) > 0 { - req.Connect.SidecarService.Proxy.Upstreams = serviceOpts.Upstreams - } req.Meta = serviceOpts.Meta req.Namespace = serviceOpts.Namespace req.Partition = serviceOpts.Partition @@ -343,7 +237,7 @@ func CreateAndRegisterStaticClientSidecar( EnableTProxy: enableTProxy, } - clientConnectProxy, err := NewConnectService(context.Background(), sidecarCfg, []int{libcluster.ServiceUpstreamLocalBindPort}, node, nil) + clientConnectProxy, err := NewConnectService(context.Background(), sidecarCfg, []int{libcluster.ServiceUpstreamLocalBindPort}, node) if err != nil { return nil, err } diff --git a/test/integration/consul-container/libs/service/log.go b/test/integration/consul-container/libs/service/log.go index 4e64bb7e54bbf..86e10a3fc719c 100644 --- a/test/integration/consul-container/libs/service/log.go +++ b/test/integration/consul-container/libs/service/log.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package service diff --git a/test/integration/consul-container/libs/service/service.go b/test/integration/consul-container/libs/service/service.go index ca186849728c6..5e1af3ab14c73 100644 --- a/test/integration/consul-container/libs/service/service.go +++ b/test/integration/consul-container/libs/service/service.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package service diff --git a/test/integration/consul-container/libs/topology/peering_topology.go b/test/integration/consul-container/libs/topology/peering_topology.go index 74424388b75cf..bd88ea58e66e9 100644 --- a/test/integration/consul-container/libs/topology/peering_topology.go +++ b/test/integration/consul-container/libs/topology/peering_topology.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package topology @@ -43,7 +43,7 @@ type PeeringClusterSize struct { // // - an accepting cluster with 3 servers and 1 client agent. The client should be used to // host a service for export: staticServerSvc. -// - a dialing cluster with 1 server and 1 client. The client should be used to host a +// - an dialing cluster with 1 server and 1 client. The client should be used to host a // service connecting to staticServerSvc. // - Create the peering, export the service from accepting cluster, and verify service // connectivity. @@ -120,7 +120,7 @@ func BasicPeeringTwoClustersSetup( libassert.PeeringStatus(t, acceptingClient, AcceptingPeerName, api.PeeringStateActive) // libassert.PeeringExports(t, acceptingClient, acceptingPeerName, 1) - // Register a static-server service in acceptingCluster and export to dialing cluster + // Register an static-server service in acceptingCluster and export to dialing cluster var serverService, serverSidecarService libservice.Service { clientNode := acceptingCluster.Clients()[0] @@ -144,7 +144,7 @@ func BasicPeeringTwoClustersSetup( require.NoError(t, serverService.Export("default", AcceptingPeerName, acceptingClient)) } - // Register a static-client service in dialing cluster and set upstream to static-server service + // Register an static-client service in dialing cluster and set upstream to static-server service var clientSidecarService *libservice.ConnectContainer { clientNode := dialingCluster.Clients()[0] @@ -194,22 +194,13 @@ type ClusterConfig struct { ExposedPorts []int } -func NewCluster( - t *testing.T, - config *ClusterConfig, -) (*libcluster.Cluster, *libcluster.BuildContext, *api.Client) { - return NewClusterWithConfig(t, config, "", "") -} - // NewCluster creates a cluster with peering enabled. It also creates // and registers a mesh-gateway at the client agent. The API client returned is // pointed at the client agent. // - proxy-defaults.protocol = tcp -func NewClusterWithConfig( +func NewCluster( t *testing.T, config *ClusterConfig, - serverHclConfig string, - clientHclConfig string, ) (*libcluster.Cluster, *libcluster.BuildContext, *api.Client) { var ( cluster *libcluster.Cluster @@ -247,10 +238,6 @@ func NewClusterWithConfig( serverConf.Cmd = append(serverConf.Cmd, config.Cmd) } - if serverHclConfig != "" { - serverConf.MutatebyAgentConfig(serverHclConfig) - } - if config.ExposedPorts != nil { cluster, err = libcluster.New(t, []libcluster.Config{*serverConf}, config.ExposedPorts...) } else { @@ -268,18 +255,12 @@ func NewClusterWithConfig( } // Add numClients static clients to register the service - configBuilder := libcluster.NewConfigBuilder(ctx). + configbuiilder := libcluster.NewConfigBuilder(ctx). Client(). Peering(true). RetryJoin(retryJoin...) - if cluster.TokenBootstrap != "" { - configBuilder.SetACLToken(cluster.TokenBootstrap) - } - clientConf := configBuilder.ToAgentConfig(t) + clientConf := configbuiilder.ToAgentConfig(t) t.Logf("%s client config: \n%s", opts.Datacenter, clientConf.JSON) - if clientHclConfig != "" { - clientConf.MutatebyAgentConfig(clientHclConfig) - } require.NoError(t, cluster.AddN(*clientConf, config.NumClients, true)) diff --git a/test/integration/consul-container/libs/topology/service_topology.go b/test/integration/consul-container/libs/topology/service_topology.go index be0af12cf086e..6aca247f296af 100644 --- a/test/integration/consul-container/libs/topology/service_topology.go +++ b/test/integration/consul-container/libs/topology/service_topology.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package topology @@ -7,16 +7,14 @@ import ( "fmt" "testing" - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/api" libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service" + "github.com/stretchr/testify/require" ) -// CreateServices -func CreateServices(t *testing.T, cluster *libcluster.Cluster, protocol string) (libservice.Service, libservice.Service) { +func CreateServices(t *testing.T, cluster *libcluster.Cluster) (libservice.Service, libservice.Service) { node := cluster.Agents[0] client := node.GetClient() @@ -24,7 +22,7 @@ func CreateServices(t *testing.T, cluster *libcluster.Cluster, protocol string) serviceDefault := &api.ServiceConfigEntry{ Kind: api.ServiceDefaults, Name: libservice.StaticServerServiceName, - Protocol: protocol, + Protocol: "http", } ok, _, err := client.ConfigEntries().Set(serviceDefault, nil) @@ -39,10 +37,6 @@ func CreateServices(t *testing.T, cluster *libcluster.Cluster, protocol string) GRPCPort: 8079, } - if protocol == "grpc" { - serviceOpts.RegisterGRPC = true - } - // Create a service and proxy instance _, serverConnectProxy, err := libservice.CreateAndRegisterStaticServerAndSidecar(node, serviceOpts) require.NoError(t, err) diff --git a/test/integration/consul-container/libs/utils/debug.go b/test/integration/consul-container/libs/utils/debug.go index fac44c4e2e002..146a7e4cacdd1 100644 --- a/test/integration/consul-container/libs/utils/debug.go +++ b/test/integration/consul-container/libs/utils/debug.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package utils diff --git a/test/integration/consul-container/libs/utils/defer.go b/test/integration/consul-container/libs/utils/defer.go index 85d913c7dba24..867de61972a98 100644 --- a/test/integration/consul-container/libs/utils/defer.go +++ b/test/integration/consul-container/libs/utils/defer.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package utils diff --git a/test/integration/consul-container/libs/utils/docker.go b/test/integration/consul-container/libs/utils/docker.go index b807cf66fae26..109205855cd5a 100644 --- a/test/integration/consul-container/libs/utils/docker.go +++ b/test/integration/consul-container/libs/utils/docker.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package utils @@ -9,9 +9,6 @@ import ( "io" "os" "os/exec" - "strings" - - "github.com/hashicorp/go-version" ) // DockerExec simply shell out to the docker CLI binary on your host. @@ -19,18 +16,6 @@ func DockerExec(args []string, stdout io.Writer) error { return cmdExec("docker", "docker", args, stdout, "") } -// DockerImageVersion retrieves the value of the org.opencontainers.image.version label from the specified image. -func DockerImageVersion(imageName string) (*version.Version, error) { - var b strings.Builder - err := cmdExec("docker", "docker", []string{"image", "inspect", "--format", `{{index .Config.Labels "org.opencontainers.image.version"}}`, imageName}, &b, "") - if err != nil { - return nil, err - } - output := b.String() - - return version.NewVersion(strings.TrimSpace(output)) -} - func cmdExec(name, binary string, args []string, stdout io.Writer, dir string) error { if binary == "" { panic("binary named " + name + " was not detected") diff --git a/test/integration/consul-container/libs/utils/helpers.go b/test/integration/consul-container/libs/utils/helpers.go index 7f08b27b9ffe8..5f75e3e4b3f7f 100644 --- a/test/integration/consul-container/libs/utils/helpers.go +++ b/test/integration/consul-container/libs/utils/helpers.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package utils diff --git a/test/integration/consul-container/libs/utils/retry.go b/test/integration/consul-container/libs/utils/retry.go index cfe5ade347cd7..651a195cf116f 100644 --- a/test/integration/consul-container/libs/utils/retry.go +++ b/test/integration/consul-container/libs/utils/retry.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package utils diff --git a/test/integration/consul-container/libs/utils/tenancy.go b/test/integration/consul-container/libs/utils/tenancy.go index 058f9cee0147a..c116a55a4c276 100644 --- a/test/integration/consul-container/libs/utils/tenancy.go +++ b/test/integration/consul-container/libs/utils/tenancy.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package utils import "github.com/hashicorp/consul/api" @@ -25,11 +22,11 @@ func DefaultToEmpty(name string) string { return name } -// CompatQueryOpts cleans a QueryOptions so that Partition and Namespace fields -// are compatible with CE or ENT -// TODO: not sure why we can't do this server-side -func CompatQueryOpts(opts *api.QueryOptions) *api.QueryOptions { - opts.Partition = DefaultToEmpty(opts.Partition) - opts.Namespace = DefaultToEmpty(opts.Namespace) - return opts +// PartitionQueryOptions returns an *api.QueryOptions with the given partition +// field set only if the partition is non-default. This helps when writing +// tests for joint use in OSS and ENT. +func PartitionQueryOptions(partition string) *api.QueryOptions { + return &api.QueryOptions{ + Partition: DefaultToEmpty(partition), + } } diff --git a/test/integration/consul-container/libs/utils/utils.go b/test/integration/consul-container/libs/utils/utils.go index b3d8382ed45a7..7be336eb8d507 100644 --- a/test/integration/consul-container/libs/utils/utils.go +++ b/test/integration/consul-container/libs/utils/utils.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package utils diff --git a/test/integration/consul-container/libs/utils/version.go b/test/integration/consul-container/libs/utils/version.go index 24e66a8698145..bad097550278d 100644 --- a/test/integration/consul-container/libs/utils/version.go +++ b/test/integration/consul-container/libs/utils/version.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package utils @@ -7,7 +7,6 @@ import ( "flag" "strings" - "github.com/hashicorp/consul/testing/deployer/topology" "github.com/hashicorp/go-version" ) @@ -56,20 +55,6 @@ func GetLatestImageName() string { return LatestImageName } -func TargetImages() topology.Images { - img := DockerImage(targetImageName, TargetVersion) - - if IsEnterprise() { - return topology.Images{ - ConsulEnterprise: img, - } - } else { - return topology.Images{ - ConsulCE: img, - } - } -} - func IsEnterprise() bool { return isInEnterpriseRepo } func DockerImage(image, version string) string { diff --git a/test/integration/consul-container/libs/utils/version_ce.go b/test/integration/consul-container/libs/utils/version_ce.go index f7f602ade895c..2232ed8eb4e17 100644 --- a/test/integration/consul-container/libs/utils/version_ce.go +++ b/test/integration/consul-container/libs/utils/version_ce.go @@ -1,7 +1,8 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !consulent +// +build !consulent package utils diff --git a/test/integration/consul-container/test/basic/connect_service_test.go b/test/integration/consul-container/test/basic/connect_service_test.go index ee045f1286d38..650db9fef0794 100644 --- a/test/integration/consul-container/test/basic/connect_service_test.go +++ b/test/integration/consul-container/test/basic/connect_service_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package basic @@ -7,8 +7,6 @@ import ( "fmt" "testing" - "github.com/stretchr/testify/require" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" @@ -39,7 +37,7 @@ func TestBasicConnectService(t *testing.T) { }, }) - _, clientService := topology.CreateServices(t, cluster, "http") + _, clientService := topology.CreateServices(t, cluster) _, port := clientService.GetAddr() _, adminPort := clientService.GetAdminAddr() @@ -50,54 +48,3 @@ func TestBasicConnectService(t *testing.T) { libassert.HTTPServiceEchoes(t, "localhost", port, "") libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server", "") } - -func TestConnectGRPCService_WithInputConfig(t *testing.T) { - serverHclConfig := ` -datacenter = "dc2" -data_dir = "/non-existent/conssul-data-dir" -node_name = "server-1" - -bind_addr = "0.0.0.0" -max_query_time = "800s" - ` - - clientHclConfig := ` -datacenter = "dc2" -data_dir = "/non-existent/conssul-data-dir" -node_name = "client-1" - -bind_addr = "0.0.0.0" -max_query_time = "900s" - ` - - cluster, _, _ := topology.NewClusterWithConfig(t, &topology.ClusterConfig{ - NumServers: 1, - NumClients: 1, - ApplyDefaultProxySettings: true, - BuildOpts: &libcluster.BuildOptions{ - Datacenter: "dc1", - InjectAutoEncryption: true, - InjectGossipEncryption: true, - AllowHTTPAnyway: true, - }, - }, - serverHclConfig, - clientHclConfig, - ) - - // Verify the provided server config is merged to agent config - serverConfig := cluster.Agents[0].GetConfig() - require.Contains(t, serverConfig.JSON, "\"max_query_time\":\"800s\"") - - clientConfig := cluster.Agents[1].GetConfig() - require.Contains(t, clientConfig.JSON, "\"max_query_time\":\"900s\"") - - _, clientService := topology.CreateServices(t, cluster, "grpc") - _, port := clientService.GetAddr() - _, adminPort := clientService.GetAdminAddr() - - libassert.AssertUpstreamEndpointStatus(t, adminPort, "static-server.default", "HEALTHY", 1) - libassert.GRPCPing(t, fmt.Sprintf("localhost:%d", port)) - - // time.Sleep(9999 * time.Second) -} diff --git a/test/integration/consul-container/test/catalog/catalog_test.go b/test/integration/consul-container/test/catalog/catalog_test.go deleted file mode 100644 index 5be52792d8218..0000000000000 --- a/test/integration/consul-container/test/catalog/catalog_test.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package catalog - -import ( - "testing" - - "github.com/stretchr/testify/require" - - libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" - libtopology "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" - - "github.com/hashicorp/consul/internal/catalog/catalogtest" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func TestCatalog(t *testing.T) { - t.Parallel() - - cluster, _, _ := libtopology.NewCluster(t, &libtopology.ClusterConfig{ - NumServers: 3, - BuildOpts: &libcluster.BuildOptions{Datacenter: "dc1"}, - Cmd: `-hcl=experiments=["resource-apis"]`, - }) - - followers, err := cluster.Followers() - require.NoError(t, err) - client := pbresource.NewResourceServiceClient(followers[0].GetGRPCConn()) - - t.Run("one-shot", func(t *testing.T) { - catalogtest.RunCatalogV2Beta1IntegrationTest(t, client) - }) - - t.Run("lifecycle", func(t *testing.T) { - catalogtest.RunCatalogV2Beta1LifecycleIntegrationTest(t, client) - }) -} diff --git a/test/integration/consul-container/test/consul_envoy_version/consul_envoy_version.go b/test/integration/consul-container/test/consul_envoy_version/consul_envoy_version.go index c37dfc8116640..72c4964ffbf4d 100644 --- a/test/integration/consul-container/test/consul_envoy_version/consul_envoy_version.go +++ b/test/integration/consul-container/test/consul_envoy_version/consul_envoy_version.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package main diff --git a/test/integration/consul-container/test/debugging.md b/test/integration/consul-container/test/debugging.md deleted file mode 100644 index 2957b520ac074..0000000000000 --- a/test/integration/consul-container/test/debugging.md +++ /dev/null @@ -1,78 +0,0 @@ -# Remote Debugging Integration Tests - -- [Introduction](#introduction) - - [How it works](#how-it-works) -- [Getting Started](#getting-started) - - [Prerequisites](#prerequisites) - - [Running Upgrade integration tests](#debugging-integration-tests) - - [Building images](#building-images) - - [Remote debugging using GoLand](#remote-debugging-using-goland) - - -## Introduction - -Remote debugging integration tests allows you to attach your debugger to the consul container and debug go code running on that container. - -### How it works -The `dev-docker-dbg` Make target will build consul docker container that has the following: -- [delve (dlv) debugger](https://github.com/go-delve/delve) installed. -- a port exposed on the container that allows a debugger from your development environment to connect and attach to the consul process and debug it remotely. -- logs out the host and port information so that you have the information needed to connect to the port. - -The integration tests have been modified to expose the `--debug` flag that will switch the test from using a `consul:local` image that can be built using `make dev-docker` to using the `consul-dbg:local` image that was built from `make dev-docker-dbg`. - -The test is run in debug mode with a breakpoint set to just after the cluster is created and you can retrieve the port information. From there, you can set up a remote debugging session that connects to this port. - -## Getting Started -### Prerequisites -To run/debug integration tests locally, the following tools are required on your machine: -- Install [Go](https://go.dev/) (the version should match that of our CI config's Go image). -- Install [`Makefile`](https://www.gnu.org/software/make/manual/make.html). -- Install [`Docker`](https://docs.docker.com/get-docker/) required to run tests locally. - -### Debugging integration tests -#### Building images -- Build a consul image with dlv installed and a port exposed that the debugger can attach to. - ``` - make dev-docker-dbg - ``` -- Build a consul-envoy container image from the consul root directory that is required for testing but not for debugging. - ``` - docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=consul:local --build-arg ENVOY_VERSION=1.24.6 -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - ``` - -#### Remote debugging using GoLand -(For additional information, see [GoLand's documentation on remote debugging](https://www.jetbrains.com/help/go/attach-to-running-go-processes-with-debugger.html#attach-to-a-process-on-a-remote-machine).) -##### Set up the Debug Configuration for your test -- Create the configuration for debugging the test. (You may have to debug the test once so GoLand creates the configuration for you.) -- Go to `Run > Edit Configurations` and select the appropriate configuration. -- Add `--debug` to `Program arguments` and click OK. - - isolated -##### Obtain the debug port of your container -(This is required every time a test is debugged.) - -- Put a breakpoint in the test that you are running right after the cluster has been created. This should be on the line after the call to `topology.NewCluster()`. -- Debug the test and wait for the debug session to stop on the breakpoint in the test. -- In the Debug window, search for `debug info` on the Console tab and note the host and port. - - isolated -- Go to `Run > Edit Configurations` and add a `Go Remote` configuration with the host and port that your test has exposed. Click OK. - - isolated -- Debug the configuration that you just created. Verify that it shows as connected in the `Debugger` of this configuration in the `Debug` window. - - isolated -##### Debug the consul backend -- Set an appropriate breakpoint in the backend code of the endpoint that your test will call and that you wish to debug. -- Go to the test debugging tab for the integration test in the `Debug` window and `Resume Program`. - - isolated -- The remote debugging session should stop on the breakpoint, and you can freely debug the code path. - - isolated - -#### Remote debugging using VSCode -(For additional information, see [VSCode's documentation on remote debugging](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#remote-debugging).) - -[comment]: <> (TODO: Openly looking for someone to add VSCode specific instructions.) diff --git a/test/integration/consul-container/test/envoy_extensions/ext_authz_test.go b/test/integration/consul-container/test/envoy_extensions/ext_authz_test.go index cf00105345fa4..3c43cdbdbd039 100644 --- a/test/integration/consul-container/test/envoy_extensions/ext_authz_test.go +++ b/test/integration/consul-container/test/envoy_extensions/ext_authz_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package envoyextensions diff --git a/test/integration/consul-container/test/envoy_extensions/otel_access_logging_test.go b/test/integration/consul-container/test/envoy_extensions/otel_access_logging_test.go deleted file mode 100644 index 87bb7b4d6165f..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/otel_access_logging_test.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package envoyextensions - -import ( - "context" - "fmt" - "io" - "net/http" - "os" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/testcontainers/testcontainers-go" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" - libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" - "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" -) - -// TestOTELAccessLogging Summary -// This verifies that the OpenTelemetry access logging Envoy extension works as expected. -// A simulated client (a direct HTTP call) talks to its upstream proxy through the mesh. -// The upstream (static-server) is configured with a `builtin/otel-access-logging` extension that -// sends Envoy access logs to an OpenTelemetry collector for incoming HTTP requests. -// The OpenTelemetry collector is deployed as a container named `otel-collector` on the local network, -// and configured to write Envoy access logs to its stdout log stream. -// -// Steps: -// - Create a single agent cluster. -// - Create the example static-server and sidecar containers, then register them both with Consul -// - Create an example static-client sidecar, then register both the service and sidecar with Consul -// - Create an OpenTelemetry collector container on the local network, this doesn't need to be registered with Consul. -// - Configure the static-server service with a `builtin/otel-access-logging` EnvoyExtension targeting the -// otel-collector service. -// - Make sure a call to the client sidecar local bind port results in Envoy access logs being sent to the -// otel-collector. -func TestOTELAccessLogging(t *testing.T) { - t.Parallel() - - cluster, _, _ := topology.NewCluster(t, &topology.ClusterConfig{ - NumServers: 1, - NumClients: 1, - ApplyDefaultProxySettings: true, - BuildOpts: &libcluster.BuildOptions{ - Datacenter: "dc1", - InjectAutoEncryption: true, - InjectGossipEncryption: true, - }, - }) - - launchInfo := createLocalOTELService(t, cluster) - - clientService := createServices(t, cluster) - _, port := clientService.GetAddr() - _, adminPort := clientService.GetAdminAddr() - - libassert.AssertUpstreamEndpointStatus(t, adminPort, "static-server.default", "HEALTHY", 1) - libassert.GetEnvoyListenerTCPFilters(t, adminPort) - - libassert.AssertContainerState(t, clientService, "running") - libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server", "") - - // Apply the OpenTelemetry Access Logging Envoy extension to the static-server - consul := cluster.APIClient(0) - defaults := api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: "static-server", - Protocol: "http", - EnvoyExtensions: []api.EnvoyExtension{{ - Name: "builtin/otel-access-logging", - Arguments: map[string]any{ - "Config": map[string]any{ - "LogName": "otel-integration-test", - "GrpcService": map[string]any{ - "Target": map[string]any{"URI": "127.0.0.1:4317"}, - }, - }, - }, - }}, - } - consul.ConfigEntries().Set(&defaults, nil) - - // Make requests from the static-client to the static-server and look for the access logs - // to show up in the `otel-collector` container logs. - retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Second}, t, func(r *retry.R) { - doRequest(t, fmt.Sprintf("http://localhost:%d", port), http.StatusOK) - reader, err := launchInfo.Container.Logs(context.Background()) - require.NoError(r, err) - log, err := io.ReadAll(reader) - require.NoError(r, err) - require.Contains(r, string(log), `log_name: Str(otel-integration-test)`) - require.Contains(r, string(log), `cluster_name: Str(static-server)`) - require.Contains(r, string(log), `node_name: Str(static-server-sidecar-proxy)`) - }) -} - -func createLocalOTELService(t *testing.T, cluster *libcluster.Cluster) *libcluster.LaunchInfo { - node := cluster.Agents[0] - - cwd, err := os.Getwd() - if err != nil { - t.Fatal(err) - } - - req := testcontainers.ContainerRequest{ - Image: "otel/opentelemetry-collector@sha256:7df7482ca6f2f3523cd389ac62c2851a652c67ac3b25fc67cd9248966aa706c1", - AutoRemove: true, - Name: "otel-collector", - Env: make(map[string]string), - Cmd: []string{"--config", "/testdata/otel/config.yaml"}, - Mounts: []testcontainers.ContainerMount{{ - Source: testcontainers.DockerBindMountSource{ - HostPath: fmt.Sprintf("%s/testdata", cwd), - }, - Target: "/testdata", - ReadOnly: true, - }}, - } - - ctx := context.Background() - - exposedPorts := []string{} - li, err := libcluster.LaunchContainerOnNode(ctx, node, req, exposedPorts) - if err != nil { - t.Fatal(err) - } - return li -} diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/otel/config.yaml b/test/integration/consul-container/test/envoy_extensions/testdata/otel/config.yaml deleted file mode 100644 index ae2ba85f4fe73..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/testdata/otel/config.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -receivers: - otlp: - protocols: - grpc: - http: - -processors: - batch: - -exporters: - logging: - verbosity: Detailed - -service: - pipelines: - traces: - receivers: [otlp] - processors: [batch] - exporters: [logging] - metrics: - receivers: [otlp] - processors: [batch] - exporters: [logging] - logs: - receivers: [otlp] - processors: [batch] - exporters: [logging] diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/Dockerfile b/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/Dockerfile deleted file mode 100644 index 31e2dd93d0428..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -FROM tinygo/tinygo:sha-598cb1e4ddce53d85600a1b7724ed39eea80e119 -COPY ./build.sh / -ENTRYPOINT ["/build.sh"] diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/README.md b/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/README.md deleted file mode 100644 index 173e27bf3709e..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Building WASM test files - -We have seen some issues with building the wasm test files on the build runners for the integration test. Currently, -the theory is that there may be some differences in the clang toolchain on different runners which cause panics in -tinygo if the job is scheduled on particular runners but not others. - -In order to get around this, we are just building the wasm test file and checking it into the repo. - -To build the wasm test file, - -```bash -~/consul/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files -> docker run -v ./:/wasm --rm $(docker build -q .) -``` \ No newline at end of file diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/build.sh b/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/build.sh deleted file mode 100755 index 6affddf298eb1..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -cd /wasm -tinygo build -o /wasm/wasm_add_header.wasm -scheduler=none -target=wasi /wasm/wasm_add_header.go \ No newline at end of file diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/go.mod b/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/go.mod deleted file mode 100644 index 703b71414fae0..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module main - -go 1.20 - -require github.com/tetratelabs/proxy-wasm-go-sdk v0.21.0 diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/go.sum b/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/go.sum deleted file mode 100644 index e09133fbccbf5..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/go.sum +++ /dev/null @@ -1,6 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/tetratelabs/proxy-wasm-go-sdk v0.21.0 h1:sxuh1wxy/zz4vXwMEC+ESVpwJmej1f22eYsrJlgVn7c= -github.com/tetratelabs/proxy-wasm-go-sdk v0.21.0/go.mod h1:jqQTUvJBI6WJ+sVCZON3A4GwmUfBDuiNnZ4kuxsvLCo= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/nginx.conf b/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/nginx.conf deleted file mode 100644 index 06533f75ac1a7..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/nginx.conf +++ /dev/null @@ -1,13 +0,0 @@ -server { - # send wasm files as download rather than render as html - location ~ ^.*/(?P[^/]+\.(wasm))$ { - root /www/downloads; - - add_header Content-disposition 'attachment; filename="$request_basename"'; - types { - application/octet-stream .wasm; - } - default_type application/octet-stream; - } -} - diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/wasm_add_header.go b/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/wasm_add_header.go deleted file mode 100644 index 91aeae6956764..0000000000000 --- a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/wasm_add_header.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package main - -import ( - "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm" - "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types" -) - -func main() { - proxywasm.SetVMContext(&vmContext{}) -} - -type vmContext struct { - // Embed the default VM context here, - // so that we don't need to reimplement all the methods. - types.DefaultVMContext -} - -func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext { - return &pluginContext{} -} - -type pluginContext struct { - // Embed the default plugin context here, - // so that we don't need to reimplement all the methods. - types.DefaultPluginContext -} - -func (p *pluginContext) NewHttpContext(contextID uint32) types.HttpContext { - return &httpHeaders{} -} - -type httpHeaders struct { - // Embed the default http context here, - // so that we don't need to reimplement all the methods. - types.DefaultHttpContext -} - -func (ctx *httpHeaders) OnHttpResponseHeaders(int, bool) types.Action { - proxywasm.LogDebug("adding header: x-test:true") - - err := proxywasm.AddHttpResponseHeader("x-test", "true") - if err != nil { - proxywasm.LogCriticalf("failed to add test header to response: %v", err) - } - - return types.ActionContinue -} diff --git a/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/wasm_add_header.wasm b/test/integration/consul-container/test/envoy_extensions/testdata/wasm_test_files/wasm_add_header.wasm deleted file mode 100755 index 520e7e144ada5b0bc7dc9e1860e1908d88f76add..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 400008 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

`iwmH7Z&?GiIK^# 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 OMi:8080/debug?env=dump` and checks for `FORTIO_NAME=` -// in the response. -func assertHTTPRequestToServiceAddress(t *testing.T, client *libservice.ConnectContainer, serviceName string, port int, expSuccess bool) { - upstreamURL := fmt.Sprintf("http://localhost:%d/debug?env=dump", port) - retry.RunWith(requestRetryTimer, t, func(r *retry.R) { - out, err := client.Exec(context.Background(), []string{"curl", "-s", upstreamURL}) - t.Logf("curl request to upstream service address: url=%s\nerr = %v\nout = %s", upstreamURL, err, out) - - if expSuccess { - require.NoError(r, err) - require.Contains(r, out, fmt.Sprintf("FORTIO_NAME=%s", serviceName)) - t.Logf("successfuly messaged %s", serviceName) - } else { - require.Error(r, err) - require.Contains(r, err.Error(), "exit code 52") - } - }) -} diff --git a/test/integration/consul-container/test/jwtauth/jwt_auth_test.go b/test/integration/consul-container/test/jwtauth/jwt_auth_test.go index 939dec13882bf..b75e608de6de4 100644 --- a/test/integration/consul-container/test/jwtauth/jwt_auth_test.go +++ b/test/integration/consul-container/test/jwtauth/jwt_auth_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package jwtauth diff --git a/test/integration/consul-container/test/multiport/explicit_destination_test.go b/test/integration/consul-container/test/multiport/explicit_destination_test.go deleted file mode 100644 index a65ff2095dbcd..0000000000000 --- a/test/integration/consul-container/test/multiport/explicit_destination_test.go +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package multiport - -import ( - "context" - "fmt" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" - "github.com/stretchr/testify/require" - "testing" - - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/proto-public/pbresource" - libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" - libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service" - "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" -) - -// TestMultiportService_Explicit makes sure two services in the same datacenter have connectivity -// with transparent proxy enabled. -// -// Steps: -// - Create a single server cluster. -// - Create the example static-server and sidecar containers, then register them both with Consul -// - Create an example static-client sidecar, then register both the service and sidecar with Consul -// - Make sure a request from static-client to the virtual address (.virtual.consul) returns a -// response from the upstream. -func TestMultiportService_Explicit(t *testing.T) { - t.Parallel() - - cluster := createCluster(t) - followers, err := cluster.Followers() - require.NoError(t, err) - client := pbresource.NewResourceServiceClient(followers[0].GetGRPCConn()) - resourceClient := rtest.NewClient(client) - - serverIP := cluster.Agents[1].GetIP() - clientIP := cluster.Agents[2].GetIP() - - serverService := createServerServicesAndWorkloads(t, resourceClient, serverIP) - createClientResources(t, resourceClient, serverService, clientIP) - - _, clientDataplane := createServices(t, cluster) - - _, port := clientDataplane.GetAddr() - - assertDataplaneContainerState(t, clientDataplane, "running") - libassert.HTTPServiceEchoes(t, "localhost", port, "") - libassert.AssertFortioName(t, fmt.Sprintf("http://localhost:%d", port), "static-server", "") -} - -// createServices creates the static-client and static-server services with -// transparent proxy enabled. It returns a Service for the static-client. -func createServices(t *testing.T, cluster *libcluster.Cluster) (*libcluster.ConsulDataplaneContainer, *libcluster.ConsulDataplaneContainer) { - n1 := cluster.Agents[1] - - // Create a service and dataplane - serverDataplane, err := createServiceAndDataplane(t, n1, "static-server-workload", "static-server", 8080, 8079, []int{}) - require.NoError(t, err) - - n2 := cluster.Agents[2] - // Create a service and dataplane - clientDataplane, err := createServiceAndDataplane(t, n2, "static-client-workload", "static-client", 8080, 8079, []int{libcluster.ServiceUpstreamLocalBindPort}) - require.NoError(t, err) - - return serverDataplane, clientDataplane -} - -func createServiceAndDataplane(t *testing.T, node libcluster.Agent, proxyID, serviceName string, httpPort, grpcPort int, serviceBindPorts []int) (*libcluster.ConsulDataplaneContainer, error) { - // Do some trickery to ensure that partial completion is correctly torn - // down, but successful execution is not. - var deferClean utils.ResettableDefer - defer deferClean.Execute() - - // Create a service and proxy instance - svc, err := libservice.NewExampleService(context.Background(), serviceName, httpPort, grpcPort, node) - if err != nil { - return nil, err - } - deferClean.Add(func() { - _ = svc.Terminate() - }) - - // Create Consul Dataplane - dp, err := libcluster.NewConsulDataplane(context.Background(), proxyID, "0.0.0.0", 8502, serviceBindPorts, node, false, "") - require.NoError(t, err) - deferClean.Add(func() { - _ = dp.Terminate() - }) - - // disable cleanup functions now that we have an object with a Terminate() function - deferClean.Reset() - - return dp, nil -} - -func createServerServicesAndWorkloads(t *testing.T, resourceClient *rtest.Client, ipAddress string) *pbresource.Resource { - serverService := rtest.ResourceID(&pbresource.ID{ - Name: "static-server-service", - Type: pbcatalog.ServiceType, - }).WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"static-server"}}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }).Write(t, resourceClient) - - workloadPortMap := map[string]*pbcatalog.WorkloadPort{ - "tcp": { - Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "mesh": { - Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - } - - rtest.ResourceID(&pbresource.ID{ - Name: "static-server-identity", - Type: pbauth.WorkloadIdentityType, - }).Write(t, resourceClient) - - rtest.ResourceID(&pbresource.ID{ - Name: "static-server-workload", - Type: pbcatalog.WorkloadType, - }). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: ipAddress}, - }, - Ports: workloadPortMap, - Identity: "static-server-identity", - }). - Write(t, resourceClient) - return serverService -} - -func createClientResources(t *testing.T, resourceClient *rtest.Client, staticServerResource *pbresource.Resource, ipAddress string) { - rtest.ResourceID(&pbresource.ID{ - Name: "static-client-service", - Type: pbcatalog.ServiceType, - }).WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"static-client"}}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }).Write(t, resourceClient) - - workloadPortMap := map[string]*pbcatalog.WorkloadPort{ - "tcp": { - Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "mesh": { - Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - } - - rtest.ResourceID(&pbresource.ID{ - Name: "static-client-workload", - Type: pbcatalog.WorkloadType, - }). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: ipAddress}, - }, - Ports: workloadPortMap, - Identity: "static-client-identity", - }). - Write(t, resourceClient) - - destId := staticServerResource.GetId() - destRef := &pbresource.Reference{ - Type: destId.Type, - Tenancy: destId.Tenancy, - Name: destId.Name, - Section: "", - } - rtest.ResourceID(&pbresource.ID{ - Name: "static-client-upstreams", - Type: pbmesh.DestinationsType, - }). - WithData(t, &pbmesh.Destinations{ - Destinations: []*pbmesh.Destination{ - { - DestinationRef: destRef, - DestinationPort: "tcp", - ListenAddr: &pbmesh.Destination_IpPort{ - IpPort: &pbmesh.IPPortAddress{ - Ip: "0.0.0.0", - Port: libcluster.ServiceUpstreamLocalBindPort, - }, - }, - }, - }, - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"static-client"}, - }, - }). - Write(t, resourceClient) -} - -func createCluster(t *testing.T) *libcluster.Cluster { - cluster, _, _ := topology.NewCluster(t, &topology.ClusterConfig{ - NumServers: 3, - BuildOpts: &libcluster.BuildOptions{ - Datacenter: "dc1", - InjectAutoEncryption: true, - InjectGossipEncryption: true, - AllowHTTPAnyway: true, - }, - Cmd: `-hcl=experiments=["resource-apis"] log_level="TRACE"`, - }) - - return cluster -} - -// assertDataplaneContainerState validates service container status -func assertDataplaneContainerState(t *testing.T, dataplane *libcluster.ConsulDataplaneContainer, state string) { - containerStatus, err := dataplane.GetStatus() - require.NoError(t, err) - require.Equal(t, containerStatus, state, fmt.Sprintf("Expected: %s. Got %s", state, containerStatus)) -} diff --git a/test/integration/consul-container/test/observability/access_logs_test.go b/test/integration/consul-container/test/observability/access_logs_test.go index e48b05a1254d4..43931cf4ea2a4 100644 --- a/test/integration/consul-container/test/observability/access_logs_test.go +++ b/test/integration/consul-container/test/observability/access_logs_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package observability @@ -72,7 +72,7 @@ func TestAccessLogs(t *testing.T) { require.NoError(t, err) require.True(t, set) - serverService, clientService := topology.CreateServices(t, cluster, "http") + serverService, clientService := topology.CreateServices(t, cluster) _, port := clientService.GetAddr() // Validate Custom JSON diff --git a/test/integration/consul-container/test/observability/metrics_leader_test.go b/test/integration/consul-container/test/observability/metrics_leader_test.go index 781e657a9f35a..4d3a024e9b609 100644 --- a/test/integration/consul-container/test/observability/metrics_leader_test.go +++ b/test/integration/consul-container/test/observability/metrics_leader_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package observability diff --git a/test/integration/consul-container/test/peering/rotate_server_and_ca_then_fail_test.go b/test/integration/consul-container/test/peering/rotate_server_and_ca_then_fail_test.go index 77639b78d1a71..86285f2c605a2 100644 --- a/test/integration/consul-container/test/peering/rotate_server_and_ca_then_fail_test.go +++ b/test/integration/consul-container/test/peering/rotate_server_and_ca_then_fail_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package peering diff --git a/test/integration/consul-container/test/ratelimit/ratelimit_test.go b/test/integration/consul-container/test/ratelimit/ratelimit_test.go index e598e0ceb8ad6..18258c2ab8db4 100644 --- a/test/integration/consul-container/test/ratelimit/ratelimit_test.go +++ b/test/integration/consul-container/test/ratelimit/ratelimit_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package ratelimit @@ -32,6 +32,7 @@ const ( // - logs for exceeding func TestServerRequestRateLimit(t *testing.T) { + t.Parallel() type action struct { function func(client *api.Client) error @@ -51,7 +52,6 @@ func TestServerRequestRateLimit(t *testing.T) { mode string } - // getKV and putKV are net/RPC calls getKV := action{ function: func(client *api.Client) error { _, _, err := client.KV().Get("foo", &api.QueryOptions{}) @@ -99,13 +99,13 @@ func TestServerRequestRateLimit(t *testing.T) { action: putKV, expectedErrorMsg: "", expectExceededLog: true, - expectMetric: true, + expectMetric: false, }, { action: getKV, expectedErrorMsg: "", expectExceededLog: true, - expectMetric: true, + expectMetric: false, }, }, }, @@ -127,13 +127,10 @@ func TestServerRequestRateLimit(t *testing.T) { expectMetric: true, }, }, - }, - } + }} for _, tc := range testCases { - tc := tc t.Run(tc.description, func(t *testing.T) { - t.Parallel() clusterConfig := &libtopology.ClusterConfig{ NumServers: 1, NumClients: 0, @@ -147,9 +144,12 @@ func TestServerRequestRateLimit(t *testing.T) { ApplyDefaultProxySettings: false, } - cluster, client := setupClusterAndClient(t, clusterConfig, true) + cluster, _, _ := libtopology.NewCluster(t, clusterConfig) defer terminate(t, cluster) + client, err := cluster.GetClient(nil, true) + require.NoError(t, err) + // perform actions and validate returned errors to client for _, op := range tc.operations { err := op.action.function(client) @@ -165,9 +165,17 @@ func TestServerRequestRateLimit(t *testing.T) { // doing this in a separate loop so we can perform actions, allow metrics // and logs to collect and then assert on each. for _, op := range tc.operations { - timer := &retry.Timer{Timeout: 15 * time.Second, Wait: 500 * time.Millisecond} + timer := &retry.Timer{Timeout: 10 * time.Second, Wait: 500 * time.Millisecond} retry.RunWith(timer, t, func(r *retry.R) { - checkForMetric(r, cluster, op.action.rateLimitOperation, op.action.rateLimitType, tc.mode, op.expectMetric) + // validate metrics + metricsInfo, err := client.Agent().Metrics() + // TODO(NET-1978): currently returns NaN error + // require.NoError(t, err) + if metricsInfo != nil && err == nil { + if op.expectMetric { + checkForMetric(r, metricsInfo, op.action.rateLimitOperation, op.action.rateLimitType, tc.mode) + } + } // validate logs // putting this last as there are cases where logs @@ -182,65 +190,43 @@ func TestServerRequestRateLimit(t *testing.T) { } } -func setupClusterAndClient(t *testing.T, config *libtopology.ClusterConfig, isServer bool) (*libcluster.Cluster, *api.Client) { - cluster, _, _ := libtopology.NewCluster(t, config) +func checkForMetric(t *retry.R, metricsInfo *api.MetricsInfo, operationName string, expectedLimitType string, expectedMode string) { + const counterName = "consul.rpc.rate_limit.exceeded" - client, err := cluster.GetClient(nil, isServer) - require.NoError(t, err) - - return cluster, client -} - -func checkForMetric(t require.TestingT, cluster *libcluster.Cluster, operationName string, expectedLimitType string, expectedMode string, expectMetric bool) { - // validate metrics - server, err := cluster.GetClient(nil, true) - require.NoError(t, err) - metricsInfo, err := server.Agent().Metrics() - // TODO(NET-1978): currently returns NaN error - // require.NoError(t, err) - if metricsInfo != nil && err == nil { - if expectMetric { - const counterName = "consul.rpc.rate_limit.exceeded" - - var counter api.SampledValue - for _, c := range metricsInfo.Counters { - if c.Name == counterName { - counter = c - break - } - } - require.NotEmptyf(t, counter.Name, "counter not found: %s", counterName) + var counter api.SampledValue + for _, c := range metricsInfo.Counters { + if c.Name == counterName { + counter = c + break + } + } + require.NotEmptyf(t, counter.Name, "counter not found: %s", counterName) - operation, ok := counter.Labels["op"] - require.True(t, ok) + operation, ok := counter.Labels["op"] + require.True(t, ok) - limitType, ok := counter.Labels["limit_type"] - require.True(t, ok) + limitType, ok := counter.Labels["limit_type"] + require.True(t, ok) - mode, ok := counter.Labels["mode"] - require.True(t, ok) + mode, ok := counter.Labels["mode"] + require.True(t, ok) - if operation == operationName { - require.GreaterOrEqual(t, counter.Count, 1) - require.Equal(t, expectedLimitType, limitType) - require.Equal(t, expectedMode, mode) - } - } + if operation == operationName { + require.GreaterOrEqual(t, counter.Count, 1) + require.Equal(t, expectedLimitType, limitType) + require.Equal(t, expectedMode, mode) } } -func checkLogsForMessage(t require.TestingT, logs []string, msg string, operationName string, logType string, logShouldExist bool) { - if logShouldExist { - found := false - for _, log := range logs { - if strings.Contains(log, msg) { - found = true - break - } +func checkLogsForMessage(t *retry.R, logs []string, msg string, operationName string, logType string, logShouldExist bool) { + found := false + for _, log := range logs { + if strings.Contains(log, msg) { + found = true + break } - expectedLog := fmt.Sprintf("%s log check failed for: %s. Log expected: %t", logType, operationName, logShouldExist) - require.Equal(t, logShouldExist, found, expectedLog) } + require.Equal(t, logShouldExist, found, fmt.Sprintf("%s log check failed for: %s. Log expected: %t", logType, operationName, logShouldExist)) } func terminate(t *testing.T, cluster *libcluster.Cluster) { diff --git a/test/integration/consul-container/test/resource/http_api/acl_enabled_test.go b/test/integration/consul-container/test/resource/http_api/acl_enabled_test.go deleted file mode 100644 index f2615a891e7d8..0000000000000 --- a/test/integration/consul-container/test/resource/http_api/acl_enabled_test.go +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_ServerAgent_Endpoints(t *testing.T) { - t.Parallel() - - numOfServers := 1 - numOfClients := 0 - cluster, resourceClient := SetupClusterAndClient(t, makeClusterConfig(numOfServers, numOfClients, true), true) - - resource := Resource{ - HttpClient: resourceClient, - } - - defer Terminate(t, cluster) - - testCases := []testCase{ - { - description: "should write resource successfully when token is provided", - operations: []operation{ - { - action: applyResource, - expectedErrorMsg: "", - includeToken: true, - }, - { - action: readResource, - expectedErrorMsg: "", - includeToken: true, - }, - { - action: listResource, - expectedErrorMsg: "", - includeToken: true, - }, - { - action: deleteResource, - expectedErrorMsg: "", - includeToken: true, - }, - }, - config: []config{ - { - gvk: demoGVK, - resourceName: "korn", - queryOptions: defaultTenancyQueryOptions, - payload: demoPayload, - }, - { - gvk: demoGVK, - resourceName: "korn", - queryOptions: defaultTenancyQueryOptions, - }, - { - gvk: demoGVK, - queryOptions: defaultTenancyQueryOptions, - }, - { - gvk: demoGVK, - resourceName: "korn", - queryOptions: defaultTenancyQueryOptions, - }, - }, - }, - { - description: "should return permission denied", - operations: []operation{ - { - action: applyResource, - expectedErrorMsg: "Unexpected response code: 403 (rpc error: code = PermissionDenied desc = Permission denied", - includeToken: false, - }, - { - action: applyResource, - expectedErrorMsg: "", - includeToken: true, - }, - { - action: readResource, - expectedErrorMsg: "Unexpected response code: 403 (rpc error: code = PermissionDenied desc = Permission denied", - includeToken: false, - }, - { - action: listResource, - expectedErrorMsg: "Unexpected response code: 403 (rpc error: code = PermissionDenied desc = Permission denied", - includeToken: false, - }, - { - action: deleteResource, - expectedErrorMsg: "Unexpected response code: 403 (rpc error: code = PermissionDenied desc = Permission denied", - includeToken: false, - }, - }, - config: []config{ - { - gvk: demoGVK, - resourceName: "prince", - queryOptions: defaultTenancyQueryOptions, - payload: demoPayload, - }, - { - gvk: demoGVK, - resourceName: "deleteme", - queryOptions: defaultTenancyQueryOptions, - payload: demoPayload, - }, - { - gvk: demoGVK, - resourceName: "keith", - queryOptions: defaultTenancyQueryOptions, - }, - { - gvk: demoGVK, - queryOptions: defaultTenancyQueryOptions, - }, - { - gvk: demoGVK, - resourceName: "deleteme", - queryOptions: defaultTenancyQueryOptions, - }, - }, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.description, func(t *testing.T) { - for i, op := range tc.operations { - if op.includeToken { - tc.config[i].queryOptions.Token = cluster.TokenBootstrap - } - - err := op.action(&resource, tc.config[i]) - if len(op.expectedErrorMsg) > 0 { - require.Error(t, err) - require.Contains(t, err.Error(), op.expectedErrorMsg) - } else { - require.NoError(t, err) - } - } - }) - } -} - -func Test_ClientAgent(t *testing.T) { - t.Parallel() - - numOfServers := 1 - numOfClients := 1 - cluster, resourceClient := SetupClusterAndClient(t, makeClusterConfig(numOfServers, numOfClients, true), false) - - resource := Resource{ - HttpClient: resourceClient, - } - - defer Terminate(t, cluster) - - testCases := []testCase{ - { - description: "should write resource successfully when token is provided", - operations: []operation{ - { - action: applyResource, - expectedErrorMsg: "", - includeToken: true, - }, - }, - config: []config{ - { - gvk: demoGVK, - resourceName: "test", - queryOptions: defaultTenancyQueryOptions, - payload: demoPayload, - }, - }, - }, - { - description: "should return unauthorized when token is bad", - operations: []operation{ - { - action: applyResource, - expectedErrorMsg: "Unexpected response code: 403 (rpc error: code = PermissionDenied desc = Permission denied", - includeToken: false, - }, - }, - config: []config{ - { - gvk: demoGVK, - resourceName: "test2", - queryOptions: defaultTenancyQueryOptions, - payload: demoPayload, - }, - }, - }, - } - - for _, tc := range testCases { - tc := tc - t.Run(tc.description, func(t *testing.T) { - for i, op := range tc.operations { - if op.includeToken { - tc.config[i].queryOptions.Token = cluster.TokenBootstrap - } - - err := op.action(&resource, tc.config[i]) - if len(op.expectedErrorMsg) > 0 { - require.Error(t, err) - require.Contains(t, err.Error(), op.expectedErrorMsg) - } else { - require.NoError(t, err) - } - } - }) - } -} diff --git a/test/integration/consul-container/test/resource/http_api/client/client.go b/test/integration/consul-container/test/resource/http_api/client/client.go deleted file mode 100644 index bdd9d70cd17c0..0000000000000 --- a/test/integration/consul-container/test/resource/http_api/client/client.go +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package client - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "strings" - "sync" - "time" - - "github.com/hashicorp/consul/api" -) - -// QueryOptions are used to parameterize a query -type QueryOptions struct { - // Namespace overrides the `default` namespace - // Note: Namespaces are available only in Consul Enterprise - Namespace string - - // Partition overrides the `default` partition - // Note: Partitions are available only in Consul Enterprise - Partition string - - // Providing a peer name in the query option - Peer string - - // RequireConsistent forces the read to be fully consistent. - // This is more expensive but prevents ever performing a stale - // read. - RequireConsistent bool - - // ctx is an optional context pass through to the underlying HTTP - // request layer. Use Context() and WithContext() to manage this. - ctx context.Context - - // Token is used to provide a per-request ACL token - // which overrides the agent's default token. - Token string -} - -// Client provides a client to the Consul API -type HttpClient struct { - modifyLock sync.RWMutex - headers http.Header - - config api.Config -} - -// Headers gets the current set of headers used for requests. This returns a -// copy; to modify it call AddHeader or SetHeaders. -func (c *HttpClient) Headers() http.Header { - c.modifyLock.RLock() - defer c.modifyLock.RUnlock() - - if c.headers == nil { - return nil - } - - ret := make(http.Header) - for k, v := range c.headers { - ret[k] = append(ret[k], v...) - } - - return ret -} - -// NewClient returns a new client -func NewClient(config *api.Config) (*HttpClient, error) { - // bootstrap the config - defConfig := api.DefaultConfig() - - if config.Address == "" { - config.Address = defConfig.Address - } - - if config.Scheme == "" { - config.Scheme = defConfig.Scheme - } - - if config.Transport == nil { - config.Transport = defConfig.Transport - } - - if config.HttpClient == nil { - var err error - config.HttpClient, err = NewHttpClient(config.Transport) - if err != nil { - return nil, err - } - } - - return &HttpClient{config: *config, headers: make(http.Header)}, nil -} - -// NewHttpClient returns an http client configured with the given Transport and TLS -// config. -func NewHttpClient(transport *http.Transport) (*http.Client, error) { - client := &http.Client{ - Transport: transport, - } - - return client, nil -} - -// request is used to help build up a request -type request struct { - config *api.Config - method string - url *url.URL - params url.Values - body io.Reader - header http.Header - Obj interface{} - ctx context.Context -} - -// setQueryOptions is used to annotate the request with -// additional query options -func (r *request) SetQueryOptions(q *QueryOptions) { - if q == nil { - return - } - if q.Namespace != "" { - // For backwards-compatibility with existing tests, - // use the short-hand query param name "ns" - // rather than the alternative long-hand "namespace" - r.params.Set("ns", q.Namespace) - } - if q.Partition != "" { - // For backwards-compatibility with existing tests, - // use the long-hand query param name "partition" - // rather than the alternative short-hand "ap" - r.params.Set("partition", q.Partition) - } - if q.Peer != "" { - r.params.Set("peer", q.Peer) - } - - if q.RequireConsistent { - r.params.Set("consistent", "") - } - - if q.Token != "" { - r.header.Set("X-Consul-Token", q.Token) - } - - r.ctx = q.ctx -} - -// toHTTP converts the request to an HTTP request -func (r *request) toHTTP() (*http.Request, error) { - // Encode the query parameters - r.url.RawQuery = r.params.Encode() - - // Check if we should encode the body - if r.body == nil && r.Obj != nil { - b, err := encodeBody(r.Obj) - if err != nil { - return nil, err - } - r.body = b - } - - // Create the HTTP request - req, err := http.NewRequest(r.method, r.url.RequestURI(), r.body) - if err != nil { - return nil, err - } - - // validate that socket communications that do not use the host, detect - // slashes in the host name and replace it with local host. - // this is required since go started validating req.host in 1.20.6 and 1.19.11. - // prior to that they would strip out the slashes for you. They removed that - // behavior and added more strict validation as part of a CVE. - // This issue is being tracked by the Go team: - // https://github.com/golang/go/issues/61431 - // If there is a resolution in this issue, we will remove this code. - // In the time being, this is the accepted workaround. - if strings.HasPrefix(r.url.Host, "/") { - r.url.Host = "localhost" - } - - req.URL.Host = r.url.Host - req.URL.Scheme = r.url.Scheme - req.Host = r.url.Host - req.Header = r.header - - // Content-Type must always be set when a body is present - // See https://github.com/hashicorp/consul/issues/10011 - if req.Body != nil && req.Header.Get("Content-Type") == "" { - req.Header.Set("Content-Type", "application/json") - } - - // Setup auth - if r.config.HttpAuth != nil { - req.SetBasicAuth(r.config.HttpAuth.Username, r.config.HttpAuth.Password) - } - if r.ctx != nil { - return req.WithContext(r.ctx), nil - } - - return req, nil -} - -// newRequest is used to create a new request -func (c *HttpClient) NewRequest(method, path string) *request { - r := &request{ - config: &c.config, - method: method, - url: &url.URL{ - Scheme: c.config.Scheme, - Host: c.config.Address, - Path: c.config.PathPrefix + path, - }, - params: make(map[string][]string), - header: c.Headers(), - } - - if c.config.Namespace != "" { - r.params.Set("ns", c.config.Namespace) - } - if c.config.Partition != "" { - r.params.Set("partition", c.config.Partition) - } - if c.config.Token != "" { - r.header.Set("X-Consul-Token", r.config.Token) - } - return r -} - -// doRequest runs a request with our client -func (c *HttpClient) DoRequest(r *request) (time.Duration, *http.Response, error) { - req, err := r.toHTTP() - if err != nil { - return 0, nil, err - } - start := time.Now() - resp, err := c.config.HttpClient.Do(req) - diff := time.Since(start) - return diff, resp, err -} - -// DecodeBody is used to JSON decode a body -func DecodeBody(resp *http.Response, out interface{}) error { - dec := json.NewDecoder(resp.Body) - return dec.Decode(out) -} - -// encodeBody is used to encode a request body -func encodeBody(obj interface{}) (io.Reader, error) { - buf := bytes.NewBuffer(nil) - enc := json.NewEncoder(buf) - if err := enc.Encode(obj); err != nil { - return nil, err - } - return buf, nil -} - -// requireOK is used to wrap doRequest and check for a 200 -func RequireOK(resp *http.Response) error { - return RequireHttpCodes(resp, 200) -} - -// requireHttpCodes checks for the "allowable" http codes for a response -func RequireHttpCodes(resp *http.Response, httpCodes ...int) error { - // if there is an http code that we require, return w no error - for _, httpCode := range httpCodes { - if resp.StatusCode == httpCode { - return nil - } - } - - // if we reached here, then none of the http codes in resp matched any that we expected - // so err out - return generateUnexpectedResponseCodeError(resp) -} - -// closeResponseBody reads resp.Body until EOF, and then closes it. The read -// is necessary to ensure that the http.Client's underlying RoundTripper is able -// to re-use the TCP connection. See godoc on net/http.Client.Do. -func CloseResponseBody(resp *http.Response) error { - _, _ = io.Copy(io.Discard, resp.Body) - return resp.Body.Close() -} - -type StatusError struct { - Code int - Body string -} - -func (e StatusError) Error() string { - return fmt.Sprintf("Unexpected response code: %d (%s)", e.Code, e.Body) -} - -// generateUnexpectedResponseCodeError consumes the rest of the body, closes -// the body stream and generates an error indicating the status code was -// unexpected. -func generateUnexpectedResponseCodeError(resp *http.Response) error { - var buf bytes.Buffer - io.Copy(&buf, resp.Body) - CloseResponseBody(resp) - - trimmed := strings.TrimSpace(buf.String()) - return StatusError{Code: resp.StatusCode, Body: trimmed} -} diff --git a/test/integration/consul-container/test/resource/http_api/helper.go b/test/integration/consul-container/test/resource/http_api/helper.go deleted file mode 100644 index cb70b6606021f..0000000000000 --- a/test/integration/consul-container/test/resource/http_api/helper.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "fmt" - "net/http" - "strings" - "testing" - - "github.com/stretchr/testify/require" - - libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" - libtopology "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" - client "github.com/hashicorp/consul/test/integration/consul-container/test/resource/http_api/client" -) - -func makeClusterConfig(numOfServers int, numOfClients int, aclEnabled bool) *libtopology.ClusterConfig { - return &libtopology.ClusterConfig{ - NumServers: numOfServers, - NumClients: numOfClients, - LogConsumer: &libtopology.TestLogConsumer{}, - BuildOpts: &libcluster.BuildOptions{ - Datacenter: "dc1", - ACLEnabled: aclEnabled, - }, - ApplyDefaultProxySettings: false, - } -} - -type Resource struct { - HttpClient *client.HttpClient -} - -type GVK struct { - Group string - Version string - Kind string -} - -var demoGVK = GVK{ - Group: "demo", - Version: "v2", - Kind: "Artist", -} - -var defaultTenancyQueryOptions = client.QueryOptions{ - Namespace: "default", - Partition: "default", - Peer: "local", -} - -type WriteRequest struct { - Metadata map[string]string - Data map[string]any -} - -var demoPayload = WriteRequest{ - Metadata: map[string]string{ - "foo": "bar", - }, - Data: map[string]any{ - "name": "cool", - }, -} - -type config struct { - gvk GVK - resourceName string - queryOptions client.QueryOptions - payload WriteRequest -} - -type operation struct { - action func(client *Resource, config config) error - expectedErrorMsg string - includeToken bool -} - -type testCase struct { - description string - operations []operation - config []config -} - -var applyResource = func(resource *Resource, config config) error { - _, err := resource.Apply(&config.gvk, config.resourceName, &config.queryOptions, &config.payload) - return err -} -var readResource = func(resource *Resource, config config) error { - _, err := resource.Read(&config.gvk, config.resourceName, &config.queryOptions) - return err -} -var deleteResource = func(resource *Resource, config config) error { - err := resource.Delete(&config.gvk, config.resourceName, &config.queryOptions) - return err -} -var listResource = func(resource *Resource, config config) error { - _, err := resource.List(&config.gvk, &config.queryOptions) - return err -} - -func (resource *Resource) Read(gvk *GVK, resourceName string, q *client.QueryOptions) (map[string]interface{}, error) { - r := resource.HttpClient.NewRequest("GET", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName))) - r.SetQueryOptions(q) - _, resp, err := resource.HttpClient.DoRequest(r) - if err != nil { - return nil, err - } - defer client.CloseResponseBody(resp) - if err := client.RequireOK(resp); err != nil { - return nil, err - } - - var out map[string]interface{} - if err := client.DecodeBody(resp, &out); err != nil { - return nil, err - } - - return out, nil -} - -func (resource *Resource) Delete(gvk *GVK, resourceName string, q *client.QueryOptions) error { - r := resource.HttpClient.NewRequest("DELETE", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName))) - r.SetQueryOptions(q) - _, resp, err := resource.HttpClient.DoRequest(r) - if err != nil { - return err - } - defer client.CloseResponseBody(resp) - if err := client.RequireHttpCodes(resp, http.StatusNoContent); err != nil { - return err - } - return nil -} - -func (resource *Resource) Apply(gvk *GVK, resourceName string, q *client.QueryOptions, payload *WriteRequest) (*map[string]interface{}, error) { - url := strings.ToLower(fmt.Sprintf("/api/%s/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind, resourceName)) - - r := resource.HttpClient.NewRequest("PUT", url) - r.SetQueryOptions(q) - r.Obj = payload - _, resp, err := resource.HttpClient.DoRequest(r) - if err != nil { - return nil, err - } - defer client.CloseResponseBody(resp) - if err := client.RequireOK(resp); err != nil { - return nil, err - } - - var out map[string]interface{} - - if err := client.DecodeBody(resp, &out); err != nil { - return nil, err - } - - return &out, nil -} - -type ListResponse struct { - Resources []map[string]interface{} `json:"resources"` -} - -func (resource *Resource) List(gvk *GVK, q *client.QueryOptions) (*ListResponse, error) { - r := resource.HttpClient.NewRequest("GET", strings.ToLower(fmt.Sprintf("/api/%s/%s/%s", gvk.Group, gvk.Version, gvk.Kind))) - r.SetQueryOptions(q) - _, resp, err := resource.HttpClient.DoRequest(r) - if err != nil { - return nil, err - } - defer client.CloseResponseBody(resp) - if err := client.RequireOK(resp); err != nil { - return nil, err - } - - var out *ListResponse - if err := client.DecodeBody(resp, &out); err != nil { - return nil, err - } - - return out, nil -} - -func SetupClusterAndClient(t *testing.T, clusterConfig *libtopology.ClusterConfig, getServerHttpClient bool) (*libcluster.Cluster, *client.HttpClient) { - cluster, _, _ := libtopology.NewCluster(t, clusterConfig) - - // create a http api client for resource service - var resourceHttpClient *client.HttpClient - if getServerHttpClient { - apiClientConfig := cluster.Servers()[0].GetAPIClientConfig() - apiClientConfig.Token = "" - resourceClient, err := client.NewClient(&apiClientConfig) - require.NoError(t, err) - - resourceHttpClient = resourceClient - } else { - apiClientConfig := cluster.Clients()[0].GetAPIClientConfig() - apiClientConfig.Token = "" - resourceClient, err := client.NewClient(&apiClientConfig) - require.NoError(t, err) - - resourceHttpClient = resourceClient - } - - return cluster, resourceHttpClient -} - -func Terminate(t *testing.T, cluster *libcluster.Cluster) { - err := cluster.Terminate() - require.NoError(t, err) -} diff --git a/test/integration/consul-container/test/snapshot/snapshot_restore_test.go b/test/integration/consul-container/test/snapshot/snapshot_restore_test.go index 91fcec05bb026..70fa0d2d41434 100644 --- a/test/integration/consul-container/test/snapshot/snapshot_restore_test.go +++ b/test/integration/consul-container/test/snapshot/snapshot_restore_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package snapshot diff --git a/test/integration/consul-container/test/tproxy/tproxy_test.go b/test/integration/consul-container/test/tproxy/tproxy_test.go index 15eae0c210906..cbeaff398f86a 100644 --- a/test/integration/consul-container/test/tproxy/tproxy_test.go +++ b/test/integration/consul-container/test/tproxy/tproxy_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tproxy diff --git a/test/integration/consul-container/test/trafficpermissions/tcp_test.go b/test/integration/consul-container/test/trafficpermissions/tcp_test.go deleted file mode 100644 index 6175acdd5ac93..0000000000000 --- a/test/integration/consul-container/test/trafficpermissions/tcp_test.go +++ /dev/null @@ -1,657 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package trafficpermissions - -import ( - "context" - "fmt" - "strings" - "testing" - - "github.com/hashicorp/consul/sdk/testutil/retry" - - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" - libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service" - "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" - "github.com/stretchr/testify/require" -) - -const ( - echoPort = 9999 - tcpPort = 8888 - staticServerVIP = "240.0.0.1" - staticServerReturnValue = "static-server" - staticServerIdentity = "static-server-identity" -) - -type trafficPermissionsCase struct { - tp1 *pbauth.TrafficPermissions - tp2 *pbauth.TrafficPermissions - client1TCPSuccess bool - client1EchoSuccess bool - client2TCPSuccess bool - client2EchoSuccess bool -} - -// We are using tproxy to test traffic permissions now because explicitly specifying destinations -// doesn't work when multiple downstreams specify the same destination yet. In the future, we will need -// to update this to use explicit destinations once we infer tproxy destinations from traffic permissions. -// -// This also explicitly uses virtual IPs and virtual ports because Consul DNS doesn't support v2 resources yet. -// We should update this to use Consul DNS when it is working. -func runTrafficPermissionsTests(t *testing.T, aclsEnabled bool, cases map[string]trafficPermissionsCase) { - t.Parallel() - cluster, resourceClient := createCluster(t, aclsEnabled) - - serverDataplane := createServerResources(t, resourceClient, cluster, cluster.Agents[1]) - client1Dataplane := createClientResources(t, resourceClient, cluster, cluster.Agents[2], 1) - client2Dataplane := createClientResources(t, resourceClient, cluster, cluster.Agents[3], 2) - - assertDataplaneContainerState(t, client1Dataplane, "running") - assertDataplaneContainerState(t, client2Dataplane, "running") - assertDataplaneContainerState(t, serverDataplane, "running") - - for n, tc := range cases { - t.Run(n, func(t *testing.T) { - storeStaticServerTrafficPermissions(t, resourceClient, tc.tp1, 1) - storeStaticServerTrafficPermissions(t, resourceClient, tc.tp2, 2) - - // We must establish a new TCP connection each time because TCP traffic permissions are - // enforced at the connection level. - retry.Run(t, func(r *retry.R) { - assertPassing(r, httpRequestToVirtualAddress, client1Dataplane, tc.client1TCPSuccess) - assertPassing(r, echoToVirtualAddress, client1Dataplane, tc.client1EchoSuccess) - assertPassing(r, httpRequestToVirtualAddress, client2Dataplane, tc.client2TCPSuccess) - assertPassing(r, echoToVirtualAddress, client2Dataplane, tc.client2EchoSuccess) - }) - }) - } -} - -func TestTrafficPermission_TCP_DefaultDeny(t *testing.T) { - cases := map[string]trafficPermissionsCase{ - "default deny": { - tp1: nil, - client1TCPSuccess: false, - client1EchoSuccess: false, - client2TCPSuccess: false, - client2EchoSuccess: false, - }, - "allow everything": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - // IdentityName: "static-client-1-identity", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - client1TCPSuccess: true, - client1EchoSuccess: true, - client2TCPSuccess: true, - client2EchoSuccess: true, - }, - "allow tcp": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - // IdentityName: "static-client-1-identity", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - { - PortNames: []string{"tcp"}, - }, - }, - }, - }, - }, - client1TCPSuccess: true, - client1EchoSuccess: false, - client2TCPSuccess: true, - client2EchoSuccess: false, - }, - "client 1 only": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "static-client-1-identity", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - client1TCPSuccess: true, - client1EchoSuccess: true, - client2TCPSuccess: false, - client2EchoSuccess: false, - }, - "allow all exclude client 1": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Namespace: "default", - Partition: "default", - Peer: "local", - Exclude: []*pbauth.ExcludeSource{ - { - IdentityName: "static-client-1-identity", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - }, - }, - client1TCPSuccess: false, - client1EchoSuccess: false, - client2TCPSuccess: true, - client2EchoSuccess: true, - }, - "deny takes precedence over allow": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "static-client-1-identity", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - tp2: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "static-client-1-identity", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - client1TCPSuccess: false, - client1EchoSuccess: false, - client2TCPSuccess: false, - client2EchoSuccess: false, - }, - "deny all exclude service + allow on that service": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_DENY, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Namespace: "default", - Partition: "default", - Peer: "local", - Exclude: []*pbauth.ExcludeSource{ - { - IdentityName: "static-client-1-identity", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - }, - }, - tp2: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "static-client-1-identity", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - client1TCPSuccess: true, - client1EchoSuccess: true, - client2TCPSuccess: false, - client2EchoSuccess: false, - }, - } - - runTrafficPermissionsTests(t, true, cases) -} - -func TestTrafficPermission_TCP_DefaultAllow(t *testing.T) { - cases := map[string]trafficPermissionsCase{ - "default allow": { - tp1: nil, - client1TCPSuccess: true, - client1EchoSuccess: true, - client2TCPSuccess: true, - client2EchoSuccess: true, - }, - "empty allow denies everything": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - }, - client1TCPSuccess: false, - client1EchoSuccess: false, - client2TCPSuccess: false, - client2EchoSuccess: false, - }, - "empty deny denies everything": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_DENY, - }, - client1TCPSuccess: false, - client1EchoSuccess: false, - client2TCPSuccess: false, - client2EchoSuccess: false, - }, - "allow everything": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - client1TCPSuccess: true, - client1EchoSuccess: true, - client2TCPSuccess: true, - client2EchoSuccess: true, - }, - "allow one protocol denies the other protocol": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - { - PortNames: []string{"tcp"}, - }, - }, - }, - }, - }, - client1TCPSuccess: true, - client1EchoSuccess: false, - client2TCPSuccess: true, - client2EchoSuccess: false, - }, - "allow something unrelated": { - tp1: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: staticServerIdentity, - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - IdentityName: "something-else", - Namespace: "default", - Partition: "default", - Peer: "local", - }, - }, - }, - }, - }, - client1TCPSuccess: false, - client1EchoSuccess: false, - client2TCPSuccess: false, - client2EchoSuccess: false, - }, - } - - runTrafficPermissionsTests(t, false, cases) -} - -func createServiceAndDataplane(t *testing.T, node libcluster.Agent, cluster *libcluster.Cluster, proxyID, serviceName string, httpPort, grpcPort int, serviceBindPorts []int) (*libcluster.ConsulDataplaneContainer, error) { - leader, err := cluster.Leader() - require.NoError(t, err) - leaderIP := leader.GetIP() - - token := cluster.TokenBootstrap - - // Do some trickery to ensure that partial completion is correctly torn - // down, but successful execution is not. - var deferClean utils.ResettableDefer - defer deferClean.Execute() - - // Create a service and proxy instance - svc, err := libservice.NewExampleService(context.Background(), serviceName, httpPort, grpcPort, node) - if err != nil { - return nil, err - } - deferClean.Add(func() { - _ = svc.Terminate() - }) - - // Create Consul Dataplane - dp, err := libcluster.NewConsulDataplane(context.Background(), proxyID, leaderIP, 8502, serviceBindPorts, node, true, token) - require.NoError(t, err) - deferClean.Add(func() { - _ = dp.Terminate() - }) - - // disable cleanup functions now that we have an object with a Terminate() function - deferClean.Reset() - - return dp, nil -} - -func storeStaticServerTrafficPermissions(t *testing.T, resourceClient *rtest.Client, tp *pbauth.TrafficPermissions, i int) { - id := &pbresource.ID{ - Name: fmt.Sprintf("static-server-tp-%d", i), - Type: pbauth.TrafficPermissionsType, - } - if tp == nil { - resourceClient.Delete(resourceClient.Context(t), &pbresource.DeleteRequest{ - Id: id, - }) - } else { - rtest.ResourceID(id). - WithData(t, tp). - Write(t, resourceClient) - } -} - -func createServerResources(t *testing.T, resourceClient *rtest.Client, cluster *libcluster.Cluster, node libcluster.Agent) *libcluster.ConsulDataplaneContainer { - rtest.ResourceID(&pbresource.ID{ - Name: "static-server-service", - Type: pbcatalog.ServiceType, - }). - WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{"static-server"}}, - Ports: []*pbcatalog.ServicePort{ - { - TargetPort: "tcp", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - VirtualPort: 8888, - }, - { - TargetPort: "echo", - Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - VirtualPort: 9999, - }, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - VirtualIps: []string{"240.0.0.1"}, - }).Write(t, resourceClient) - - workloadPortMap := map[string]*pbcatalog.WorkloadPort{ - "tcp": { - Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "echo": { - Port: 8078, Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "mesh": { - Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - } - - rtest.ResourceID(&pbresource.ID{ - Name: "static-server-workload", - Type: pbcatalog.WorkloadType, - }). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: node.GetIP()}, - }, - Ports: workloadPortMap, - Identity: staticServerIdentity, - }). - Write(t, resourceClient) - - rtest.ResourceID(&pbresource.ID{ - Name: staticServerIdentity, - Type: pbauth.WorkloadIdentityType, - }). - Write(t, resourceClient) - - serverDataplane, err := createServiceAndDataplane(t, node, cluster, "static-server-workload", "static-server", 8080, 8079, []int{}) - require.NoError(t, err) - - return serverDataplane -} - -func createClientResources(t *testing.T, resourceClient *rtest.Client, cluster *libcluster.Cluster, node libcluster.Agent, idx int) *libcluster.ConsulDataplaneContainer { - prefix := fmt.Sprintf("static-client-%d", idx) - rtest.ResourceID(&pbresource.ID{ - Name: prefix + "-service", - Type: pbcatalog.ServiceType, - }). - WithData(t, &pbcatalog.Service{ - Workloads: &pbcatalog.WorkloadSelector{Prefixes: []string{prefix}}, - Ports: []*pbcatalog.ServicePort{ - {TargetPort: "tcp", Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, - }, - }).Write(t, resourceClient) - - workloadPortMap := map[string]*pbcatalog.WorkloadPort{ - "tcp": { - Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP, - }, - "mesh": { - Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH, - }, - } - - rtest.ResourceID(&pbresource.ID{ - Name: prefix + "-workload", - Type: pbcatalog.WorkloadType, - }). - WithData(t, &pbcatalog.Workload{ - Addresses: []*pbcatalog.WorkloadAddress{ - {Host: node.GetIP()}, - }, - Ports: workloadPortMap, - Identity: prefix + "-identity", - }). - Write(t, resourceClient) - - rtest.ResourceID(&pbresource.ID{ - Name: prefix + "-identity", - Type: pbauth.WorkloadIdentityType, - }). - Write(t, resourceClient) - - rtest.ResourceID(&pbresource.ID{ - Name: prefix + "-proxy-configuration", - Type: pbmesh.ProxyConfigurationType, - }). - WithData(t, &pbmesh.ProxyConfiguration{ - Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{"static-client"}, - }, - DynamicConfig: &pbmesh.DynamicConfig{ - Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, - }, - }). - Write(t, resourceClient) - - dp, err := createServiceAndDataplane(t, node, cluster, fmt.Sprintf("static-client-%d-workload", idx), "static-client", 8080, 8079, []int{}) - require.NoError(t, err) - - return dp -} - -func createCluster(t *testing.T, aclsEnabled bool) (*libcluster.Cluster, *rtest.Client) { - cluster, _, _ := topology.NewCluster(t, &topology.ClusterConfig{ - NumServers: 1, - NumClients: 3, - BuildOpts: &libcluster.BuildOptions{ - Datacenter: "dc1", - InjectAutoEncryption: true, - InjectGossipEncryption: true, - AllowHTTPAnyway: true, - ACLEnabled: aclsEnabled, - }, - Cmd: `-hcl=experiments=["resource-apis"] log_level="TRACE"`, - }) - - leader, err := cluster.Leader() - require.NoError(t, err) - client := pbresource.NewResourceServiceClient(leader.GetGRPCConn()) - resourceClient := rtest.NewClientWithACLToken(client, cluster.TokenBootstrap) - - return cluster, resourceClient -} - -// assertDataplaneContainerState validates service container status -func assertDataplaneContainerState(t *testing.T, dataplane *libcluster.ConsulDataplaneContainer, state string) { - containerStatus, err := dataplane.GetStatus() - require.NoError(t, err) - require.Equal(t, containerStatus, state, fmt.Sprintf("Expected: %s. Got %s", state, containerStatus)) -} - -func httpRequestToVirtualAddress(dp *libcluster.ConsulDataplaneContainer) (string, error) { - addr := fmt.Sprintf("%s:%d", staticServerVIP, tcpPort) - - out, err := dp.Exec( - context.Background(), - []string{"sudo", "sh", "-c", fmt.Sprintf(` - set -e - curl -s "%s/debug?env=dump" - `, addr), - }, - ) - - if err != nil { - return out, fmt.Errorf("curl request to upstream virtual address %q\nerr = %v\nout = %s\nservice=%s", addr, err, out, dp.GetServiceName()) - } - - expected := fmt.Sprintf("FORTIO_NAME=%s", staticServerReturnValue) - if !strings.Contains(out, expected) { - return out, fmt.Errorf("expected %q to contain %q", out, expected) - } - - return out, nil -} - -func echoToVirtualAddress(dp *libcluster.ConsulDataplaneContainer) (string, error) { - out, err := dp.Exec( - context.Background(), - []string{"sudo", "sh", "-c", fmt.Sprintf(` - set -e - echo foo | nc %s %d - `, staticServerVIP, echoPort), - }, - ) - - if err != nil { - return out, fmt.Errorf("nc request to upstream virtual address %s:%d\nerr = %v\nout = %s\nservice=%s", staticServerVIP, echoPort, err, out, dp.GetServiceName()) - } - - if !strings.Contains(out, "foo") { - return out, fmt.Errorf("expected %q to contain 'foo'", out) - } - - return out, err -} - -func assertPassing(t *retry.R, fn func(*libcluster.ConsulDataplaneContainer) (string, error), dp *libcluster.ConsulDataplaneContainer, success bool) { - _, err := fn(dp) - if success { - require.NoError(t, err) - } else { - require.Error(t, err) - } -} diff --git a/test/integration/consul-container/test/troubleshoot/troubleshoot_test.go b/test/integration/consul-container/test/troubleshoot/troubleshoot_test.go index 538f4f2c27796..d0152611c878f 100644 --- a/test/integration/consul-container/test/troubleshoot/troubleshoot_test.go +++ b/test/integration/consul-container/test/troubleshoot/troubleshoot_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot @@ -31,7 +31,7 @@ func TestTroubleshootProxy(t *testing.T) { ApplyDefaultProxySettings: true, }) - serverService, clientService := topology.CreateServices(t, cluster, "http") + serverService, clientService := topology.CreateServices(t, cluster) clientSidecar, ok := clientService.(*libservice.ConnectContainer) require.True(t, ok) diff --git a/test/integration/consul-container/test/upgrade/acl_node_test.go b/test/integration/consul-container/test/upgrade/acl_node_test.go index 67b5fa12ad171..94886a4e27a42 100644 --- a/test/integration/consul-container/test/upgrade/acl_node_test.go +++ b/test/integration/consul-container/test/upgrade/acl_node_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/upgrade/basic/basic_test.go b/test/integration/consul-container/test/upgrade/basic/basic_test.go index fe9f28fa2240e..40406caebeefb 100644 --- a/test/integration/consul-container/test/upgrade/basic/basic_test.go +++ b/test/integration/consul-container/test/upgrade/basic/basic_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/upgrade/basic/fullstopupgrade_test.go b/test/integration/consul-container/test/upgrade/basic/fullstopupgrade_test.go index 75ae754fd5b90..6b4a047952bc4 100644 --- a/test/integration/consul-container/test/upgrade/basic/fullstopupgrade_test.go +++ b/test/integration/consul-container/test/upgrade/basic/fullstopupgrade_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/upgrade/basic/healthcheck_test.go b/test/integration/consul-container/test/upgrade/basic/healthcheck_test.go index b0988cd280c29..fde78c182ea3f 100644 --- a/test/integration/consul-container/test/upgrade/basic/healthcheck_test.go +++ b/test/integration/consul-container/test/upgrade/basic/healthcheck_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/upgrade/catalog/catalog_test.go b/test/integration/consul-container/test/upgrade/catalog/catalog_test.go deleted file mode 100644 index 61c479c989d4b..0000000000000 --- a/test/integration/consul-container/test/upgrade/catalog/catalog_test.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package catalog - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/go-version" - - "github.com/hashicorp/consul/internal/catalog/catalogtest" - "github.com/hashicorp/consul/proto-public/pbresource" - libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" - "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" -) - -var minCatalogResourceVersion = version.Must(version.NewVersion("v1.17.0")) - -const ( - versionUndetermined = ` -Cannot determine the actual version the starting image represents. -Scrutinze test failures to ensure that the starting version should -actually be able to be used for creating the initial data set. - ` -) - -func maybeSkipUpgradeTest(t *testing.T, minVersion *version.Version) { - t.Helper() - - image := utils.DockerImage(utils.GetLatestImageName(), utils.LatestVersion) - latestVersion, err := utils.DockerImageVersion(image) - - if latestVersion != nil && latestVersion.LessThan(minVersion) { - t.Skipf("Upgrade test isn't applicable with version %q as the starting version", latestVersion.String()) - } - - if err != nil || latestVersion == nil { - t.Log(versionUndetermined) - } -} - -// Test upgrade a cluster of latest version to the target version and ensure that the catalog still -// functions properly. Note -func TestCatalogUpgrade(t *testing.T) { - maybeSkipUpgradeTest(t, minCatalogResourceVersion) - t.Parallel() - - const numServers = 1 - buildOpts := &libcluster.BuildOptions{ - ConsulImageName: utils.GetLatestImageName(), - ConsulVersion: utils.LatestVersion, - Datacenter: "dc1", - InjectAutoEncryption: true, - } - - cluster, _, _ := topology.NewCluster(t, &topology.ClusterConfig{ - NumServers: 1, - BuildOpts: buildOpts, - ApplyDefaultProxySettings: true, - Cmd: `-hcl=experiments=["resource-apis"]`, - }) - - client := cluster.APIClient(0) - - libcluster.WaitForLeader(t, cluster, client) - libcluster.WaitForMembers(t, client, numServers) - - leader, err := cluster.Leader() - require.NoError(t, err) - rscClient := pbresource.NewResourceServiceClient(leader.GetGRPCConn()) - - // Initialize some data - catalogtest.PublishCatalogV2Beta1IntegrationTestData(t, rscClient) - - // upgrade the cluster to the Target version - t.Logf("initiating standard upgrade to version=%q", utils.TargetVersion) - err = cluster.StandardUpgrade(t, context.Background(), utils.GetTargetImageName(), utils.TargetVersion) - - require.NoError(t, err) - libcluster.WaitForLeader(t, cluster, client) - libcluster.WaitForMembers(t, client, numServers) - - catalogtest.VerifyCatalogV2Beta1IntegrationTestResults(t, rscClient) -} diff --git a/test/integration/consul-container/test/upgrade/common.go b/test/integration/consul-container/test/upgrade/common.go index cbbf9aea35af3..44bdcca25180a 100644 --- a/test/integration/consul-container/test/upgrade/common.go +++ b/test/integration/consul-container/test/upgrade/common.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - package upgrade import ( @@ -69,7 +66,7 @@ func CreateAndRegisterStaticClientSidecarWith2Upstreams(c *cluster.Cluster, dest ServiceID: libservice.StaticClientServiceName, } - clientConnectProxy, err := libservice.NewConnectService(context.Background(), sidecarCfg, []int{cluster.ServiceUpstreamLocalBindPort, cluster.ServiceUpstreamLocalBindPort2}, node, nil) + clientConnectProxy, err := libservice.NewConnectService(context.Background(), sidecarCfg, []int{cluster.ServiceUpstreamLocalBindPort, cluster.ServiceUpstreamLocalBindPort2}, node) if err != nil { return nil, err } diff --git a/test/integration/consul-container/test/upgrade/ingress_gateway_grpc_test.go b/test/integration/consul-container/test/upgrade/ingress_gateway_grpc_test.go index 174769d53170f..36a807a7ce131 100644 --- a/test/integration/consul-container/test/upgrade/ingress_gateway_grpc_test.go +++ b/test/integration/consul-container/test/upgrade/ingress_gateway_grpc_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/upgrade/ingress_gateway_sds_test.go b/test/integration/consul-container/test/upgrade/ingress_gateway_sds_test.go index a237bd98b2300..c31f8007b2e3f 100644 --- a/test/integration/consul-container/test/upgrade/ingress_gateway_sds_test.go +++ b/test/integration/consul-container/test/upgrade/ingress_gateway_sds_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/upgrade/ingress_gateway_test.go b/test/integration/consul-container/test/upgrade/ingress_gateway_test.go index e4bc12629fe5e..c0acfeb775b5b 100644 --- a/test/integration/consul-container/test/upgrade/ingress_gateway_test.go +++ b/test/integration/consul-container/test/upgrade/ingress_gateway_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/upgrade/l7_traffic_management/resolver_default_subset_test.go b/test/integration/consul-container/test/upgrade/l7_traffic_management/resolver_default_subset_test.go index 9feb9d82092a1..b8282bcb0c3e6 100644 --- a/test/integration/consul-container/test/upgrade/l7_traffic_management/resolver_default_subset_test.go +++ b/test/integration/consul-container/test/upgrade/l7_traffic_management/resolver_default_subset_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade @@ -73,8 +73,8 @@ func TestTrafficManagement_ResolverDefaultSubset(t *testing.T) { assertionFn := func() { _, serverAdminPortV1 := serverConnectProxyV1.GetAdminAddr() _, serverAdminPortV2 := serverConnectProxyV2.GetAdminAddr() - _, adminPort := staticClientProxy.GetAdminAddr() // httpPort - _, port := staticClientProxy.GetAddr() // EnvoyAdminPort + _, adminPort := staticClientProxy.GetAdminAddr() + _, port := staticClientProxy.GetAddr() libassert.AssertEnvoyRunning(t, serverAdminPortV1) libassert.AssertEnvoyRunning(t, serverAdminPortV2) diff --git a/test/integration/consul-container/test/upgrade/peering/peering_control_plane_mgw_test.go b/test/integration/consul-container/test/upgrade/peering/peering_control_plane_mgw_test.go index b88781bd790af..6bd4c13aabaf5 100644 --- a/test/integration/consul-container/test/upgrade/peering/peering_control_plane_mgw_test.go +++ b/test/integration/consul-container/test/upgrade/peering/peering_control_plane_mgw_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/upgrade/peering/peering_http_test.go b/test/integration/consul-container/test/upgrade/peering/peering_http_test.go index 9c48727d83a64..037d1606064bb 100644 --- a/test/integration/consul-container/test/upgrade/peering/peering_http_test.go +++ b/test/integration/consul-container/test/upgrade/peering/peering_http_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package upgrade diff --git a/test/integration/consul-container/test/util/test_debug_breakpoint_hit.png b/test/integration/consul-container/test/util/test_debug_breakpoint_hit.png deleted file mode 100644 index 2eae03da3b9054fcdb47666519eb01dff236f07b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 654866 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⁣Ay^S9AP4qh8s0d22j<^l|2SS9D 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�nTf;{(^NV-ocnk%F0GSj#GVu@{}^{e%BPo6sU`fE+_ib z9rR#5Hzc|LA#n)jgtl)p0)wFw-o{GyF^GBEwfX zKnclPIA2I7{xt-y%$5H;kc9E=ZnCd|&|aT%;IA3efh?L25)w@KMo}kc$2c($4P1uy z3DyEYIIOIK^I(Cw9v;KgM|z2V|D(=}Mx#b(0NJs>MHId0YsU`iQZ`Z zq%Cerga?pHlQ^^Dl}m}4$_%RZW(4f)#)rv}=g5gX$0~v;3A{f6F%0}ontEb0DzUs9 z{@~LuUeFU<`YLk9dvQl1-Iueh24i z*G&xV1F=WH3G%eb4*D~Jc6bn%mmix2?9ImlZc~6$EJQ>^_bmhkBjQom1xtyHE_bqp z(B^UV3&ed}!gMZZoF!F%ebY2Fgr+|&NK%q>F7N3io)VWU~YKhiw0UiOKKN1 zx1!I9rC|q8yrROilVC_U^&beBPZjv6nPozI$k^@22rvF;23lINpcNNOB>)iw1*Wx` zXTrz0kGXTlRV;>4>?OiH%Xl?LGXeQbKo~1<@k{0^*iL5tz59p*`IlMyb?bo@iYgNTxTG?jvE0lPQ>`N>CvL+ZCLwmzE=|#YgQTeOGS8-Reu6yUf`=0v(m+4@Yzt!g4J`n!_;Hj zM@HWSGDt#oopTo0Jl|H?k$`Pgw3|h_AwWNzt%Ygs35qucAz*^HJm&GL{wPpBGkm{` zW&dMiVz&_(O~>~$8c)>)eygX|zv8?kp_-%e&}BPEv&094Q2M1*Ra6l0yZ_wnJ{ucP z<(iFQ&#M1~7LGfh1_ z8%r#e;%6Tg$WJf=4RBl;8heA7$<1!AR#*g)KJ`Y;?nZjSpeL>z7>_stlVTKsa z3cgVXuT8;f%Lu0YOV?sMA~EmQgF-sVKlbk* zXct==SjZ0h#o#-`7eOTNidzr5Hmp^%?%f8yE6}FjUNo~IwzdHnU>}(u0Mvt7vlXhzdL#)}o#V*Xj(iDUj3>iL#ifA-cb zM#LiaS)x#z8L8TDc0kATd?}J@pdK4Wix5=-|CT}rLZlRq6tGHFUciuh?BG*ysPrlW zGH&vc>Q~%_;Kbf*(9ffGJkb8z=4A@O}8=I@tl!yht!5duJ3oj8jqm-yF5 zyeKXtqD>b{ z^J@4 zogRSJPPWQfC{rtQ8+5nIaiP7~2yQt2{c5qZP|!AVH2mSu3%(7e+zdi;A!99pU+&mLcj8kNbBY zLA-(MjI+PoFZ+Xkfju-ne%jIfU~QB+O>&%~lp46)CzhnQ?iKwl{b6jUq(+koG1J`(G{5N&ycXzMh&seDAJqHXJs zg{0n#SHBCiGWVcDv^cm~<<=?ep|k4~47|8hMEI62F0kE|K?SYS_V9p!>-R-eSVqe& zq5y_(3uTb4o>v8li2%+Yw}q<>fh#tonAJR5W8t zJ5<)x1_SlywkK!B8a&F41{gv38fGPI_`2$I0z;*X-_7@BFPCWf-F_Exf1+Ce%Qh@g zHo0tDzKCtj9147GjQhBJq2}=my_`MpoW$d-#1NF{5q*E(BlYTcj#g%nqK4HZI!#Nb z4TJ2Fl?U&nbqfU}i2np~f%w4~kFQGb0GO{mx7BjaigknhUik#+R4FsB`qAzZod9;L z03jh^8%Q+Jf+}m6y|v2x4Dhu6q>)r|BhC446Hf)Pkq@(*+Irozh^oeu&P7p!*961h-AkFEkXPUb1wl0=lq z7|k?Br84G-<-M(*=C04Rnyj_i=`7C@OEZ-WBPPG6*r;I{5zB2R14dlvHfVtx(ZZjn zt>1Ul07Y|$hlkBP0uAfqAV4t4*6*+G-Yx!gIU59hMb3WHf$1yifeYP71W>)ak}68( z2qsky9UdzkM$F@#3=3cLcNwWD(AQSR7K{`D10u{%DF`A0UXTo)7WKeJxv0426uC`M8`AD3Q;F0hJ1b-v-BaCv_qbDHe;5uI+ha4MUSPCPq#VU)*L=+QA~ z>GA!MnK74Nhs5csufEWLx&?FR-EPmyKG%bFR^AD|XFYvCgIrvW*Q~cETsJBQR!BJO zWxI%piQ%(tVTNNB)<@Y7bzPQ>Y<_(p2422udUCQD8|-yqB@EHv_RPK zH;MmYKd403!wdFHxdzzpr){zN4S{-Q>GL!!sKCA{zl^^ZI>`6ks$40kngeNBE}yGz zvmw4l6V=X?+GpKQslwvp$qmK}U+}hr=6v0y4iqTJrnk%Sj?>5SSlH!r8Y6CgXRqF* z%6^{a1N`Zn3eh97skzz+DXy|ymF!}>)@54N9JPpdrq~L?@6#!5!j`gt0)EOGeR)~b z{R{mY-!t7ufKbr&SJ6O|(N+7>fe<8YaS?hDBsPZqM6g0uU5L_k(`CCYGaU@|L$qIB zC*k;RcC2IF6w&;^U!b9+ON0)Qeq+ujnJP8uy<53IVx|L!{}2+LcWyHuk41qNKX{t> zlui*2TM^qIe6q)*27P2;umeJ3ZD%Jn&2Bb(x3de*s6^Z}_Sc6kIw!0V;!)6+{ooQ@ zfr9pO0_ASK|2tHqS@HgU6M%|O%5>+Zj}fZtjN*R!V`@LNB9N`@_XkWf2yxW~x8Bl& zoM#l7WyORUbG-Zhu<7gOo;?D_T4s<#{)}9=&74f--hei8-P@aVh%7i-b^AARXG*F1 z2yTBVE8|X4#|4Ms3XedugFud0nZ{pRV8uoK*_@ZG*sB*I(BSu{ zQpp!#p-=P(T$e3>*7pGgVJ-RPrQV74VZ0<9%V53}gbF!7-Oxa!<3Tc0v!HU`6uR~X z$fMtSldOVO^%m?|ELU5^!1c|enIO?V{J=(C#942B5949&w84;Z zJpIu!Dx4mqu%&_G<+sby@X#x6b>fl*&is9v9N!Y3=CFj(aths6@=F#EloS0|z~s@u z>#%&q%-E&@S3ya{(--gv*z-M`L+hy`Pw4&?lJxm~3z4v=Y zA&YmJrLC(gN|vp1$ZTf(O(QPH>z|srgqd6s7rRYV3KnTd|Z@5`LWE?qHIvQTgPimVOlbz!`>) zGp*mO!yYMD=-o~&(kflpZ{iS+lo4DqW2sXglIz`B?*WFevn#%S89)Ltet;E6=LGCt zmR~8okYQ>N%{UYmsvKq{Mtb)mPnj9yUVE=t-C@h;;51rE(w>co(o+&vTl05u2N||p z*{A|USX_FpJ;G>ZAm8-tk!F=ceq1NW*uW)-bq!gxlU>$f>U&d02_P(96^aDOi+B7d7|9rwvFIdb&#XQ3@)&jA#61?OnEpC69Vq1CmH%+GEh z*bvewf8hfCLsycs0Vf&cy+yJ4`_aN-2z`Kk0&sYTQ)Xo`Aos#e#FI%F@t8(LobeSh8Po_ zQoDBsKqr=20s@KaCOfT>x9}Hwe7( zX3jXu4H-RJwaHVG$Dn0HNlCVNZ7zeM6#i{+W((cwXn>UU^=7%ur%)23@ju zW|WJipJ}O6W(x$06ogI@qu5SJy17;dx3mc0&lu5_I- zWhaj3s1!__*cxa8r9@u?LHBvBLW<$!Ec{I40^0urVu*di0T6J_hC<*4*;_wk(2*Kn z63~RQnZ+W65D{h>o)*gp#(pA>m^qW~e*D+WnI{gzb)KFiAbFLC7&&9vJ(<8|KBVY# zo#f^2kZP5K#o()^rlw-&omV8h>#U&YKhdnxem=pmSr&wnPJsWk4eF!XCeQXAP5QDz zn5C_)L-HV}zSX~{J^N-%2e)5$eqSLrqtK5C51)N0h0M2v@7tAu!Z3ct!pYJCkZ%bO z55LouR+Es6Px*?}h%3S;Fb1Fpo%EKLmP{*}4bm;g?b2HE!CZhg zr|Vp420_9DcOoBxNb=iGx}WYYvQz*G3OcSV5lzkIpST=?5dj}>l=UiqE$4Jtp2Gv0 z>IL?ufN8_!YF7T{#S&jc`7u_kE3szwWQQ$y zo>l9KVG^Q@3r{pQ?`@7pfYg~o2N$GH!`M++jY&0UmKYRe?971)n35x}t<;~R?%@Xl z)0Iv06t8_l77g!S-aV_Te9#LFt|D{3+)32^lduqn()=m;oDxE4|F5w~$GP{j^D^+c zt?$+ouke`#W3b);KHo^8%C$?$fO8QNC_wq7dO?JtXMhN!c|$bBQ3yl$Sma|XLO)J-{NSw+ONqDa`X42IUO(Fuk6#A;G1b>Ln*=7b z?>%gP>ZShjD_!Y7oSuunf@Y7MD-Q-!(4W(>UKs8zRsbtzs=|Ml6XMds$rM zugWY4l-^vZ^L7MovSGgE=8e?Yiw(K*;G)2O0Che8JF)-GZ2J`Rki&h1D+Y`^9puW} z)C1Pxf1}~zLaKGOgD-k6s1+eVtfTb8hGg%ghEP`DI>yd)z{a5dPv6A>k@6Qe+Kn3C z?u}jgT^0~V|GV$vI!}3DpGq4Xe$BzQOdQ3V?{?Pnk}v5h3L&8W>HCYNd$*7pGpUa6 z${*}ozw}3)9!nL%_pn4fN00f^cCqPGy>ur;(Mv%_%iGfUU>6yoIxvXdro-p?M}12S zWM{1}I}B0Kt5Tq&xi`J%?e_bZA=E_kmo_*6WRC`L@KeZqLK{I$j{Q_YP&YJJHSBnU zib6)s9BGxo-Xwe`?Mm{rN@YOT2Wv^~Iol5zDQm0v6y?5F>IWwp|2huI&d!Jw+iicKxYj5Za1RDcctfZv7C-%^^ zPgn`uKxRuO?{$wT>#(n!$ie zr**{is4Mo$Ms+iEwnwcvJiZBTFGR8y7Z6?-oM{dy;7tkK2EI*MkCBx43qbtmVo})kAIFRr2O+N z<@DZ>cwthVnMy8g%_wgOtW?Qx-A}IAdazb%JH!zU=d0Nu#0R%d({!+4POYkZl9Ex+ zb8g~O)A+#{GjOVGWy}8z#Ib}sg+`-o{XQdU-CD_4{c~JG%(-FoOP<60<1)8OLkaug zCt?eI=*hHX12p(@-pmCs$s9&TIHFatnCK8z8k*r~#2pC%nbgNEAny-H9IC#O>7a`CrPYwKfndQ>)Jcvb`RPKG%TooJU zlOX1Dsb49LU|rK}Z<S)f%pHk7JfQRf|!|g`f}GdcJbV)22IiFy{^Rfz|v-f3(7* z#90HW)Quu%3vm}LmtLQjlN@hn;47vMKXQe0CPogbSd5C579~1ZYB0K%TX4@SFQ?0- zIZy;RD|nU_oao~0)1L*W2Xb=Ef{Fjn>u$4f_Yffp`=6fg72dvm+bQ+aVzFe)b(Ial zh(Pz%$8V7LJf~o=X~gF9y{IC+Rg%)m@-`E5$hToUvRU8y~xZYNXYHd$Hs#;RyUF}~5(A2RYu?wsk_+q*aS?&19qZK#xV&2_3e zOJ1RBU)Wet5S5f)({V{0EjdrtIbXIb;Kg!Mq!l z7-QDYbU;;&d*^|oR+%Y7eqZULWT1?w;}R}o02RBQ2S1&dbLglXHRYrzI=@GabKHWX z)e3<GxiqAStvjZIKR`r z54@Z0oi0&0DAH$%Q%zQ+l{X%9i@I5F|HiZS8SJ3UM%CP1hl>9!6do`q>iz(t_T%tJ z#Qg3rI+aaDG6Z9K{GJpnc9}Sk>`^QqjJaN65#DE^HUf{$Jf%{zs4!`Jd^k6QM=$DV zTuGnOSEuvJx*}OM2x9YX63QXNbKZC`d$3W*F)z3;EC)++4H>-UDeMqnu37ed<>-mF z^|!0;hEvIpdcZKkG*i)&&38x74qmF{YBHxK?81yv&5~SsSVEHY?zyj365ZW=w!&!@ zu0>*zkzS!lRL9u^joq(yuI{t!={C@!m{l$`s4>?TQa+2`3T@%qDl1%&+mKrOlAzOc zbSNrr)O9qe(?!Qm5a3APBWK29pOY;ZfYI0}ET8ptv&kqoc5&DdFb7clL%{~f&` zvG_>Gq4evjLtfE|??H3hGSw@xorEqvS=e>Hmgpp|qy3MVX9>Nkhhr;91|PmsrFw58Y3t4D zqd~#GuF0UYeCSt;@O4^p{xh;egHg-D9jPBWc5YZE{SQ?A`tYKYPFEMC)|p;9+nz!U zS977+D;uh_g-0hRUB?^Bq7`FPQ3n}Ox@;gJ#M$#Bky{qx8rb!~qk%yz)yet1FT8=W zZr~L_LIXzf(Z(Oa%z*ee@ybuhu>0~fWeaN7T}=A;=w3a7G+;PkK92jJn&Ny>ps+nM z8Q5||Q~Ur_lR;uRs;TzNYxBY6=RSSX!bcK6m1FGw(;BAAm=P;vzmy%SRsvJ!06Ehh zslZt7IZ&V<0<)J5f+ISBHsqzMAys*3DHwboNRtVd_hFQTRq`mWL@Gu#@`s_H~T(g!7l1mt318&)nm7H{}<5H~QTwJR8L|}BZn|*UQD)X6k zV(R}z)>{X)-G0%7!QI`VP~5FpaVb_xfda)Hid%7ll;RErin}`$*Wy~-A-KCkWb=Oa zx3fF5GnxFCnI!Xho_p^(=bqzhLhhYxuQQteCgc7eJP^2UshKm;rrqS$MA?2$?q1JR zy1T6<-bAOGwRik?Ux^Rh$R(ZRHzVS-TXjDZCPy^fw6TTHmP=!FR(c-*Aagawe7&XF#u1Y>;9I{j@-W{swgLt0)~Af zJ$cyf>B zOA5euQ8)L?hYRrxfdU8BTXv+=>2TwzfNz|aqEF7V7eBh;7YU*dEXUx@m#{xw8c7$2 z*k5w#lB~urRrfPtao2t(5a(8P%I5PtUod;hqayC3pE%(g{Hp(+!#y~x4_^w?cRv7I zEJRHBmtE%8cSG^xrneyOU&pLi4nN#iq{5Agt8Z%Y4i!+>|?2LhhcOCF;4XQo3(f)l$S3`sNINYnnuE^x-w3gp`qA}1}RrVEY z-~}>AjQ#K=)Up&0pLp9RFmC@3gi160-a}-YJ}(Y^AR4}@(D{Z2RGh6fH@ml~`KWSn zVdOSR}@Q|I-3*h#qLYdyf8BiDvf^-Om7ZCuIQb9d)) z>^H_X`xPfYWrj%(BG#&hG6!KZ@xKn^)Fy|d@bGu8z`dZG5sFAMX-Qq>8LJ{RX*-~Dpn zdr?b#sbsB3JF1qT-dPi?THPMsz@t92{e%;Qfse@-!DUVxvrCXDn9Zdas6eFsDH{EQ zQUbfFj0^$E;HKXau_~d3TJsRO#ifyjs^GVRNM%Wb`SfMK%PtPg??vogWCq=j))^L$ zPVsJj#D8O@oNY?GeZir3jkPJz#p!U!$J%F< z&#n{r9rMe2Bhtbj+*EG0DEvdu6%;9{p~rrh=2IgB$Y+Kd`Cls^*aebi&`IC_py#RA znhkUn9bBlz0Vyz3PP#gfbg10_4$__b#d)NMf$XjM*M8|C)XW6W20L(CAop(yTQdDu z%U{}6JOQuv0qw|RI?mi|!lr+bBic3j%MLsd$X$b$IFS2{jD+Ni#VxR?SWoro)-(O{ z5MS1}8j)o+YP5>kYG@I?C>TV_>n2rC3Sb3``3A|4eW#8Ht*HcL2wq+j;mdh*YMiBF zM!g-wwycg$e=nSCC@}cEJ`y*Nz{6fO@9BzhUU?>ZQcm*fZmEQqQ|;jP|8vNAFj3ud z)P=8qP#7(UzKkxMXEGe^5m=E>x{+bwv}!+wEg~V~r=+JoowK?Bv;6H+7Ps6HF&J%l zI~`tkSx{8=VfnqY7#2qv-OB@8Yyfx9flMkQF=oa4pKe>!ID1}@K3?e2gTpf_FPe9G zEs%VOZsV?kDNS-SSD_7>SNq&zXUE9PW`vm}V9cs%(|y~04B+|u(secB9~|5M|9AoD zRvCsZhN;mDG9j0!XC@s6N;45#49D6WPv=UZ^*|f=r+siRU{sW>V~;FLc{Pxcd3ek3y^(CP#3sbYH>WM581^c%RLVJM46i2HnUH^N77k(dsAUcr>!k@ps(}4?C`!Yhm^H zGMlNj)p!UVr(*Kkd<|{oyNy7dzQKV)9MD@9|-!%fz9l{J(wz zZ6y3$$l}0Yxq62RNdV?xgBfZ*raIEI5s)`Vs{K7>H^Kyh@#>-!_HMk>%fj2VZuqm= z481Cu?%DDPN;88PKUEssK?toC7=?v#hhm_@)4-@$s&~N%NMUUcW=uhFnR-CZEhQn; zOYoESrACd6(JRlihOT6H^k0>bEx;8&pi@Ow>Rr<{&YZMnaA%ZwFNdTgZA94VLZ$A= z4+0zt^dncd?}&~3)@K+*nM|*3al`{Gq+<&HRZm;4K=J zcZZA)Y2bkqxuGvT%5K1NlbFcLS7}53-#H>cvJ*eCP!k1~vJ*p6!dd=p4E~>vZ7yUx zS^`32q-gl>J-uM;pZfYJvm7`LkdUKw2J)j$R`*MA(@#=|==9tJ4AX69b z8r;;{9g3UMrTId;&|B<^$J^+RYQYgqacuRCuxR*wSSi_q^iE;sGrPvpz_XF*J{4ZZ zQ_eEKPmyACDwS}U;^m{wb{h1V=py%hd7>h9f=SRX5uWGUOsN(eVfMM&(+<$wA0nS^ ziJUUv50=xmIo;Ptf=ZQSQq$AVv<_Lw(rzk-obpn>=rSz0`71=vb1_VrR-$MhR3pL- zS~d56p4rrl;F?})BFwr@s79cNu7y9yel-&Ud537f?p+XDVriM(9_>J2 z#aW%N+{2@n!?6Yp=_rjGJ1CWY3*b?GbyNH9XBpQdN7^>gt>J;)k0M!&{uFc|}M>}D}JUDenu ztVYL1)zrgMmdU+cwu$8rk*ZemWaP*tELl0kSy|CZC&&P@6=Rsa7FzYBPk7IC9M3bs zxxExC;S)3*GAerkt*v{ZhW4C?bBKoEj?geU6z}m7|0-UF^32r{2org& z3B|8=$aMbziRZJqCKT=J>Bu=D<4TPYxF2W2=i~E3T|tVszQM+Ga9wgLR7ZDqaF?-C z`*Cj+UQg{P<5zI4_t&=-zDZ>LW(x{tH9Yfhl;V-og@`YH!~6JTGF2?$ha8Vrof18Z z-uQ48b`$Fxs;{rhTVHg2$mN~*3vhg$__W?4)Bl%)(&sK8Xk1qF(pb5QKlbiyGzvpB z468u|DmHIBxx5q;qt3v^jGVI}fjnI^nyFGP<^NtUwHDX%*Y&_WsUh{k!u%@23GQ?D zh7uZe7~04V^I?>1U~S8AFx$i9l5N!e)WNYdv;ICcL|t_0Vx-^=_oX&pie^yvOMGN1 zjkfJGo1TcSS-{cO63;aaAwr}^joirS{nd-rRLO?t0-bYh&24SFCu9ZT4f`Se?|JSp zNa@Gy_D>}GMX|B5D~1;*spH<{N946C4<`o)xKQuBGV?(d(8&qr@rVaCB_U?K3s}Yo^6n>fwFn4+}`{>5>e* z8_oaetZvy+6S3uVj34Q+;P?G9fl8yZ}TQlQ{@QOad5I%fDzWsAcFincI=`EcCZ4yY+P z&|^+)3or#g55;6dPrC;OSnLbV{fl(QZ*GOU9{*m^e8%kA?#jf1Ty76GvTOb6T=3kw zz&ZG1wW8-5FfB}5)xO&17o*0ma|B5Ie&N99PsvZxM|a9b5lhpSHs7T)!uA~Q#%WYUxRs=11ghW z4m_6ZNj0RYnshl|CFwLAmsK#l{V4NLAFi>x?PN)v)kB6*>nf!%wcx^mc5bh0soB9T zWx7SzglgOv!ib-&@9mG7HRyTkuBYhqG40;ZxFoiX&7(|*Kw?ZkG_y+xtK|MRFG6qG zeV;*M+6rQL{L)eLvU?LgDAHMja2T{fQaG<=QC>WNGT2L92F2SZnvhI@@g4 zGMF_dbF%+}d6L3|w252tsV$4`p-0z+2X*+mOs$nP5#wt+o%br0oF9+sV$OzFQaude zsUsuU#7Dq##t*BXFz0WEX;V5ecMq&UP)fI`?b<*M_pxCJWNC$+!DB2ZKa15$l7WyW zE8xu^TiJa=MrKHSso@G~e=u>S@b@PRPetzOlP^R7=@7oO<;Obbp++I@>8!(XGjbxA z+ZXtN_OsC@Y*L{iRl<5g@9OcGad zg&a?Vb`p(lhptt#ec8)7c=WVQkol3vwD>!?5R>i6$%f%zqZ~Z z%NxACwhz2LvOrs8TJls1tt&(>Mn9>5&3%AnU9ED=lu-cV<1)%f)?9n60Y>x zMJ}c8@aoDx88CMJ0hkMSKr;cIyLJQj<9yzl?Y<_}sP^%{ImgQ>stKN$HqLZs1KG7B zp&ZS0G1CEnWOWG3+Z)=DS4nNW#a5eu((^RYc&XBNeGsE)CZGF!Ap56C=-9iHNNfY5 z3`32$T7>w60D?SQ&ctM=Hw4SXPmkEKSF5=^XnxLSfo}Ip!41;Fv1;EC6y5@3@oYkq zO>CIedvkXgFoPZ3rY^^GgM(c5=GV&Np}Tua7@hx8-qxdywcRcAqU%ZFCNYNW6_C6K z8t1|5CA{~Q%YBqG9i$d@Lx%4-4^EukxIN$R3`W&_CLpsZ#a0{z_5onf#E8>@0sGK3^twydSQJ*#mJx-rsJe^bsTuy3Rl;0|3 z4@FDkHvSi(MM=MDiq}ej8Jp>6N1TzAh0p`>Ag5hV4)IX>c!HYxK3j0s9t*vl2zQ+9 zTvvf(QUfLS_c{%`&i5blDcIh3Ad30B$~^X5KUSx6XBN=IBrk1IOQkoId6-_6c%)=(ghF^r9wt zMs3wvD9o>tx4&fVEI;?STS`R)W2+qYbdR(eU}bpi8%ogPZUY3`o*qo%QNmSn+%y}^ z61^^a>rDdZBj$8~+6l7{_UKw82!m$e<5x{7+qFO0Lr-#Qd&oBxx*7n0)7BrH?-%RF zd6Z+9FQI1OnRC}G98f2q^GQ7C8+*ic>6gQne8r9_N=W=79j!?lAoUdM*1hdM+=<9K zs5w-Cb|5Mw+r7k=H8jYAOA;0pwzb?6O7mSyqi7EzXLT$VcytOWpUHWn2ZZ+p8;$v7 z{{IG)x-ib5d^J+>5P`!`5|zbxo31VDini79MJ_UL$f!Vi<9(K*HVU$Wx_=Abvi@(o z0nOeFKeIZIOA`GAT`Chi^4V_gaV4~jtr}et6)L+LB)V=A>>lc07n;WwkR0}h%A*MW z`5AU8gsuZ8DYR`@Hnop%4CVAv<*t+)Ya^aY3Zt_t>@tBN6ivq3`llg(EN^|}Otbx$ zL*Fu`!k{;pF7^B&k>}ZYSw4397#}6news`TkB4+p>arsJ%@l9&&#W1gn_m56s>aGA z)WX9`uxPxP1%y9C3-jNF!en9z4DFbCV9i&8PseJUMUqR%$|r?^%_aP@iT%bsB;$GZ zFp{*sVJ}xb;qH7&R)+*#S2S;e1pnLZa?s9sCweUesrYWYC9Pd&J=KGpNYC3G@UR$b>(#B8MItHJ;Eq|;!^x5^~r54 zSifen++|h=VgLS%gEzf-v=a@4S)tapqX$(iR=l4J?WXADyrNkQ=vQOa`TEp4siq#B zo?yzWU|QX!q@V+P+n9g`%qm52+o3XKTDM2$C}jW%z3}BAb2?(zEco}f#)u}1<7!MN z`zU)dbBZBseZOj19{eFmN=Jd}%AnCZ(2r=C*fxW%uhyDuV7l+>u@Kfbj+$|~iu?Sf zx$W_+?|p>a!H3lec9Xwk6OLzkB*-^njo(vS#SX}vuR0ZfX_!Yvp||4koXOqB>nXKxYsw8+|)Y1_a4N5Ck)hWB($K*3RwJm8rSDWg5Q!wdJq>GdPw#OacC!OX}2_V1XjP!I`~cUb%T;C2%6 z;&a^!;G=awUv)X))3#e`y{GlAvN6Dz2?*H+Rt(Y2%9+~&{4_pgWn^=ZW(q;UeAE={ zQ&-=l>0Wdzr1*NHU#5GWa3i{av@l%4zW!07stwmdiSdn1L6nTnhZ}?MZ&BMYxd;qn zx!LxZE&5fW1N$#-Z?sZw(r)b{d&lU~(>31_$Um1JY^BwQaS3L(ra@?k{++BNvITv% zgYkJ)q2Kp>MN+il%%G;g&|si|LB~@(Q8~z*7g}Y{eA0j~$i{`weDzutQpUe(Zh5Xz z#p~sJ`bCerI%E=}=qbs_Y_6oOl`a-*jF5)oY4%&rPLB0ax+(YwIk~u&-)HRO;@}`@ zX=zvpH?vh?C0{jCPitAiHf4gx`2yaS5b!P{QS(og%TWrPz?AM zBv&N=W``8ff87AERJQ}*gD4V~&4uNeVdoUj&p)VM@eZHrnz?c)m4?XO_%xLzGEOKx z#Hod=#Vgx&;ZxxbfXCPt?!SmQ^M+tg7qhdHF;n{&SW|<@Y$~O?3V7A@(t7ipDNLlV z$jp2-m2wHUcPFE;yLyz*s*KE<7dC(aV?fGGICrODQ{HhOtx4P#!06&;n< zdG)DTQV}nbc>9`vJeK&D^eso_cFEfi$UF2*Hwk=%ISgd6d2Dy_vK1({=pj-JCz93H~?ys~ca1T#?TyB6V@wGGCc-#aZDZd~+O>(gl~ zmyIe~TBkoPga=#5H(whL8<==DA`px%twK084Dp7X%kIcP!HcY&Mh%Cs=tsjJjc=HF z0;;yw3h!gBa+}e1IX~%t_GMmII^Y}UXP$^c<)ch4tQ*bzcoG1CUrgyP-=r*+|C01% zkKjDrU{#~p&o{`_8VBU5F4b^)AI8zt1-yQ_XBxcNoS8*0@$&c_Tv(%2)CW0I;}u{- z!P%JX>-+qa^Cn?w%>A13CK};0Pu*o#KP*jl#!cqHzD#csxkB73l$4Cx4|Qoiy))&2 z<)A)n!?1T&`>7-PV*o}Io}S|N+}zv+xbc(+Lx-QjAD3u zDUlF4L}t7Atv85=ftguR7*?Uvv;C$U3mFZKaamPlpE0uzfEdlutJ+oWgW^r{T{2!p z=U-Mh4bx7D+x#4Q-Jg0CEG!N%z-Kaj*xaH3R7~1vebN9;yL3nN#<@Jho2(?E3tGaF zU}$zZR2UhEedD%&wd;Nn&PDDhyrI#Lr{+n@Bjz(dq`Uk>JXU*=1J_U|xHStOEYxhH zF1L7dds^=l?;2JugaZCnPJhSjW`2M^MbA4&)LsbIx-zGXW724vQj^v zyIB9pckK9XdsE79fGp{KMenfsR9f-1yH75YL+Q&mCsQ%qdztS=PMnZT+kzQH^#@N{ zAp*6DACgTr+t?rE=iaWfIrc1rE%bVEM4rQWe`-E!dzCt~)J?u`muhv89FPc=${5^hV&*C<9jtv;BLYuFZ*y1Y~Ag7yg? zz{7vNyJoDX-4=FW>U6#}SZP7uB5V@-qk-EAz4e9ck2)O|#prCT$vsXEB>FHVg`3+wSK`2#QCab|mW_!JYs$4d$5(a?} zR^D+3%&2&@^l`Htx#ZDb)!t7?lV%lE*&#uv{$ILqv%Zs522{C4P)q?=H5kIU9y z*Fx?=cFL(i)LhZ7!tq3_{u~V40~n`@DJxfDd8)l zQs=H~Qx`8xpQa&s6BK4V`X%=^cLSo7y}cS=LKCcEAzoeljd(L^x23l&lOW*!# z6Y$n?xE1A(z;HJaO-Ok3Bhq2Ur=v4YEgV%cx~tU&o&ajc$E8wv6?86mk=Y5wDcYHk zYmAJc%D;a7h>p||wG}*}W6efk@=r}fOw@gp)$S#*yqz^nNV6QuEJ(?Hu}Q}8qj0Ak z4fysQ4F`~FkSr-(LOmLmvsu>HKlElk@MaF^znP0LX zPe*B%d+4Aqs+bA*@LbPOIt%Dq5ieEKH7YU$Xw+E32Q?Zs+1>pKB}V6T=0f_ffA1t;{z6$SH+rkvI#oz^I{=kIlYK zXI+F4&0v(7Kz$i3*1EFcT(iGF9}Ai*zZ7ohjYGlsLMb z($eu)tt^u>o{4+33f-mW7Cq|=n3c5B5Obl)9mtu@&{8$wS2L%UdrUWzOq=*LRYWd9tEZs4)e9XOxfo*OOR2qj|^54e{3( zM;haFZ9|y*8HD*CKhSer+|>taFmrF&gC?UopLj#6dv0&+AOTRN>fY6f6cqJUZ^R3R zf2wCGH9Z^)xq75Gb259Qtq;~QB}TiuM5gm2&hyE(UCxW0DE`oAGEV4JwzMAj@0$g^ zG9fJjC6CAYAKjiP_@G?f9aAq;VcvS|-+EcIeFW@l8JG}fck-gHC*3#oV$${#Q|R8m z-uU-u_SY&T%3IsKJr2Bk$fm8^>O79)>3R`fJBc%;{j3Sg03hCeQC9BI?^S^Rh zH@J2%(lc!r<7eDgHU%o16=e1Y0&gl(?@WwQjh_GiweS;C7|z8T5)v=e+TG!}{I)`c z290DjA*bcKL@wzpDIl)(bk5`~mthk+TrE2Fkz;Pu&M{8SUeCZlfG7d-f^jCkI(s6% z4!BBMvNcAqB4O86_(Ybm?BAzW(OGQ0c>(tX#gAc$oJ$}mW$J)G13Fn_vZAMFM3nau zMtN57a6m=DQgVXY@{Y>*oC<(;k!}FLckEX$Vp;Pd0PZ!~#h9G#_6O;RJy&k&hZ>cU z`P848vT{IiKzRla)Aglr8D>D{qN!O&tz?i8O9R>PTMUxT2r?14OClf~mv%%el7wJg z2SLVo?*a;WFY&%dDJeePQza9NQVDa+*WU zp^u({uaf1%wbMz0+uPeC$b6b4%$p!hlyBF>HbG0OMc0ze2V|*x#fhSQsKE-x>IMuQ zDS5zEX|Z;%s$56 zl}fQ97M9+)3?dG%1C*Rq33j*7J<>%h&~+oh(_59Kk+BV}1sfT`TGpn5A9Zw6bF+e9gtgXCYt=@Vw6 z=jBC&8e^Gqoc^Od@g6i8wYD#_SVq*mQ8jAMLld-4(=$HNa(9z9gBN^1qAsCc@+YEa zQTQmd^Dzidf57%uHuDN{;r{2PkgzQQ;UR70e&Blt^x7mN7PYL2gAb$1qv!{e z<$VbYCFM+siYINnp6FFhqCKPNja$b;-Wx@*Qr&6P|C zVUn;n#KIGThh+^7tBOXE&~W@n&7H11^0H`gX1d3tPh3^_# zJs7E<;+>q*wN*>8qIk0fz*uRd2JqB!0k!>xz&zn2F&Jq}?yDz?_i;nu#A#6_H=uU( zQt0O@Nfy1N5Y12U_XIxr$Z>}+)e`=5ZIW1D8y*R>+A;&45)cOgwQ}!5x0e`~23LZ~ zn|=js;!-Cr#4I;=>t#R!^5XAbNf$PHH#UFMNUwPABQV)~SaR-m(4rE1Gfvs2qvX`v zm-#uUYxdsj?MtQc2Ac1~N%3r2MusS@wW}$pCav{j%X4iH=xRH(;;Ga7XP^-F$>P0@ zU(}sCSv)eLHfdXHtH{$ci&-`oj}?jH@0seezO6|_^Eu=GD@OwKy`;sH%P**kEpC>< zSn*1I3w7AahGsGsWye%1BD)4V?1nX9$Ms=(;-Jaof!W9hmUXfRRFauM<%hq17~xz zWd(bKQQkHqr6deH*d9=o1Q!6j5~JX<8My6x_SHDg3f1LFyyxzax~Y{Fij0g5uWwVG z&+F?YFeo`W+4pnx3{u@JU|mf`%SoSNhrMja0VZhdNDd5&FP773EH1hv_3O^CFZzX zAnWCzLHG&*u2yR*7gp5pRu~|Wb|c8xtZ{E97wHQ$aR^L*V5T01`4|!^z4M5wNUcS~ zikI(QO;wr}oIPTcUP8e=R5a@AXt~-{!2kmAzC*Di@rvl4UlKHGV&G1BvT|UPg>kB_ z{9kU$dgK}QG4gXb2rW*1@MU*Pb-{0woKdV(aKriZ24j92ckkynA0lHD2cqA#G7<2< z^Resk6@L60_z$dQru973P2)l}*%Cps1@e8CAewB$CR5_;3D1?fnq+7LcO7!e+=^J+ zlJX%xz<8Ayr4ZIn?!gIRcnY+X*zCQ^*siwh%VL~5U4 zS_B7;AFWs+|IQ$iM%D$=L`=x(>S@Q~9R?+vu-w70Yz}*HDEO_hGS!xmENA0)rlv0Y zqP2}i!MVEed}qeEpauUEP3vx6z9%t5{p&Dxx<@@RKiN>{cZ~+3L1<`tUA{S}EG2@6 zE84nAxvMf4*ZC%(>unPq*ArSJfMRFheZ#;b6BWXt?8hn+G=ZMk2abiFpVH(BbU`1V ze_rza;%8@hyF&|CTastY7tyP|1?eXygn z8_~8N6gJ7zpDAG<63bx~V54+`I{)}V5i?BE47REilup>jWd5iIVry;lMJB^h`{%%Z z&%@uSQliVl8E8V1mdqjrDcz4DiV;mvD>HtnuT`uc*cnDBu;XLEr%Avu&mVwKHXQSw z(6^hWTg~n)4r_nH$jaN}{>M6WEkmwqdt@6s*eY7B#&zl4>qI32@6fF$35VEpn0(n8 zqZzYVS-f86+2B^zTj{wlkF#Y8{eDT)7J?Cpw*6cnc_w@O^!XTqaT5lgDz)XTdn>|C60lVj_R5cab*A9ed@1$eU6 zZ4zUm&{^{;Zluzn8}Ij%HMIjc6!^D&OXFLrNgBE&aGZ^2^4#fS3qxiY&z?z30{B_v zzkvm@8y0qeyr3Sm*4D;|ZqJ|m3YRgsAW*aq)GTEUj>OsH3O=sFx?H3+s4qW_60HK? z|3cXi51{6DPUT;Ag&d2)bi`m<1u)9<4(anL*{v6wS#(=bkiARU5r(+6hIy5v(5mOq zgOhn?tmoG8UtB4$kW;$+Fr4u+H*yD>!Ka6#_&u(O2lw~HL(OHwbWTyM+`_m^8pQ`D z<&Yg$9e62VH=sMk`*|HMm;oGqgo*TWloDdPfqneO3?=-n;!oLU>fGaaKSo%MIznXF zdR4DqmA0SQoGKAOZ*Aqsg3@YEhs`0Uh*vKGE;d6ho-CY{C6E9`L+aa(U(G-0q#TFA zepf-)-_Lg3OtI`o9MhfuKlduq|DHd5BKFVxmHHh3mDR70F!BL0rjk=$bs#S|FBj6}eTKnwKWvXf5Lv*1eKG@Anox&iC{lz`uU0wfNqe>eX0WiK##puC1V*BC^Ir}8Ul#vaO%Pk!HGZ*Dj*Jf8J7Tp|iTL4yj4p-KUKllAS;|X_ z-pUD;g8?!zo40j*`LnWCNZ$d%NYZa&{X!qbcl8@O)(&N!+IoE88sFoA0Ml=~Wh8(% z)}SOL@8&E|%ow$anLBgN24|G=v3*)|`lia&gpDyiPS>E+tVsDW`7;$EDdT|~GER6# zXsX>vi%P2Erx=V%0ns<;h>P)|aQ^>$Ewm60)Zf=~<82(G<;gK)QpGJJ522&(a5G90 zqQ@lvoN%s}DNSrvbKm}5N@C)P;LWy>3y;#Njwg!NUKxX`%~M$-YNLV%*JNV6;+j`O zyL5@@iHa>z6Ai7+iL+qcrHY$7^uT1-j=Y#`j?Taw1e=5JA!JXq^oNUk0fN)4oFCBW zAV`y?(1CvU*HI1F_PK_)e{9C5$!dpt?;Mk*M>HOdrROy7P{`$ErrB2a`_2yw%^JCQ zy^Sg)-+LU62{C%@;jtU0=HC!KR>jp~-zW2@^h5vlnYm%ZL$v)*nkc+^74)P_C0t#v z@o8u#g^3ZJHh!q4H6d|}_HuA>(fkY$N^eljse{aK$)#0{}32yQ)XEHv<*)rAm zs1lCBC~Qlt+wl>F{K|6?RhJLdyST)%w{;u%ZN%ARiqM)9KPWM6iUH}Wf{4;C1^Mck zDpiK+c&`kezmq_XaH&xZh3`Ood~=vGm76jJd;+JXxBO9~EoXS+xH-ox**2Uu{kIJV zmRz)bW1k89Dk>)PcrBn$+xASilv{IaQha`RbIK2V`>;6_AZ6jW2K(z^3w_3CwJ?i4 zzzOGDG&X-~cfSJ!;&q}d7yQkSnN?m%n~f%<%bkPL^jg|${_D=`NpCL>UxDU9y6}GfQtcHN&XLkf z@?$@6Wfji^t^a?)Ayhaq9wO|4;Cfg z$44+JF~p}z>On_GhsUA2cTV+tmh9*2ZooTU0q#Na&I={1ExaAy>zRuG^Tie$=4M=k zMU1ktpT%_>0Vaq16Fqy{RbSxH)^i*9-J4m{P0dMXYCm^IJ!lT#69@XU5M?IGC-T#l zmy4dAKUddA)L#g}s6?^w*W3JDs@12Twt1|5MnwfXxL55ia7}c~BKV4NWz>IpXHazn zODT?828K7$&xWeO>uR$vl@@vplxde6u7Ypc!;C<=rYqgtG6!A6%=5YMEuR+`FQruy#Zgj{Q z0IlJ>S-v0GXrrg9jhB9Dg&brOfD9U$14o#7ljSWNTsKx1Tn;Aes&)4M^l4FOhzO6F ze_)4qzKCww`e~CjGHS@9-sT)!n(i}-RoKPnUeW@Au~J}c&hsz@V%L=uD2yM@w^X}5 zx>5Q2tbh_ZRH+XPC($TD*1wCh>mr!r7=db6jOZerXm2i%%arW8azm=PQWLuNeGc5o zCA@ie6LZpeR4gb7NUgXN1F*9p(!7PJ+a+P+n|HC9ijsCmBo+F#bUNBvGCnh72vj;$561FOb z^<3=P{SPB#oCeMmuuTR`{h;BS=;XjG3qK#rz!yB{p3gyKwc@3f>$iu;p4q^CtI+Hv z2CsbpPn*a+uV@fiak)tkLWB1`ig<@ZLb1qYGE1L}DJ)O~2+a~nf5rjSI;0-;1BTQE zNrie27^A-^B~|jaZS-w6pD&$*x8@mu!0`D*nO`8+C*lz>E3+=JYt7&b*CJ z!ClYuCnW#wc7va~2++iB3RjHiOlm+<`+o(?LHw(!m6a(jaZ5%uDvtO6#0KKkIV z#Bfg7>!WTP)Byi{S{XH9nB@LR%Mf7v--(C6-+%buj)sB|lo7GIFkOqQPCP4jejM*?{2!K>hQ#LlMFQra4<(6p9l8tl_EyeZ)oG`0Eh{YMmx zs~yihkJPzbUth6*{Ejbb)+Kxx^|*}P&tKn1F1~)LUXzAFbL*bOy%5c=@uCIE6PvBM z3(#>B##Hay5sTc|#d!erSvT&_@Wg^tEy(H)<||}$|I;kchr(ljw?m|g=?Mq>|JCCl zP_lk=AuBIyMe0OXkh1+JJz8!DwZ%yI*B#*Zy~FG;>T;coNH9DQOwV>k)-+hZ)rBET z#5Kz%(GYHIh!;Hakx{sfLHSeAJNWtQbi2j8N}A3liK1#0`iAj+K3DOFtRR1Vina~F zn`A24d7(n+4z{QDg(6rTW*83$_7`E)5~#bi!~UZK>6>jsOiy)JnzQ**L1_FQh`aO) zH*9`nodQEA<7S&e&>J1@_Z6{E&m7IHo+_Vj4?IhPuJzweE5Ol0RGSLq&3V!9R6uk^%0Ko-r|(LAm>kZ7N17W zk-3OCPnF1sV&VPCq_2mvJCcE+oIz=$UDoxrMf~Z&I2ezQtdGZFz(3EyjEUs_+ZDBhe;g@ zeeD1S{nPq=#+?#}Wa!}tpZSupPq?K3G&xHn^VDO{O^6-r_kI24{ON0c(ss8FUpkg} z_(3<*xqJd~67erO@H49mIYy!{-o(A`QhzITMF$qgQt^+m{-7Jk5cdTPzGsliNUM5W zpk&rvhhVutTJlHGzoDrQCHp86eZcHMN=pmiOcXE81mDqZ!cq}CJp!PeH0@J8cg=kt zs|-Z>922v=E>ZjL?RDEmk}8Xf-_FbB={A2`=v!IA7)y0Wc6S%h`Ax=S+~1FK3+fAf zt>C?ZADWeur&>T~nSvu~ys10E&EY^+g$GoAKY7j*n!E;nR0nvo*}*xVOh$uC@wo#5 z2wL8;r-|k7*g!A4xUmbeZXEgNr!mye02g3OcFfU#!1+s>w9D%gB4Kk(QGl6YPSDH9VKo;lv*Hy(uGwm)i?&p6DJYvU{``X8;UL4Lo)Ew!L+@5f(0*8QK=aZvpj4Tr0)%~v_fH3aI_Xt9 zYpI3ATWlqyhIlP&N0jvqX$jay!4qL9t43KsD*7 ze07sLPLr@y65ks-@1|WFh5a$Bi+}Y*{4{|h1?J}FW;aFG|KQdKPa>y+S`H4>6FEZJ znqMjpryWCw0avqArU!7r>f{TaC40cn-eN{6U~SE&p*rUY7KjA$#Nfnf_pmZ{pDA64 z7pCPX>L{255<}?hekFKEHZHxlA?|XPMklnIYalJ-;G&s*_jm~3zIbXn$Ns**kwFgM z()znV13Y9VY}iT-Q`q9M)_&~ki#I!nIc__c5ei;f+x;1=U5C;;ww4`Uq5JRBH7gP8v?an z|M=u-Gh7b|zXF23=5kt3eu&2kzs1_p$>=6-sV;^?Nb@~a}kg?Jc>bT!t1{&VQ$MixFp-q@XZ8P zlNAV1JHYY|G&Y@UuUaBxSPu2>gP*Mwr@C5cqSzAKg6oS7KVIM_HFw+&M?eQWN(6h= z>j>ack+u$xB{RK;K@(CY5sWD)GI%{Ac+>D%uCB@eb2bx}GVo5(d=foy3X~e0`L(d; zYiVNd%nEAB)cIgP)~tNt3j)#s0K(VjpvSj<|_N!dCB<7(8C5ko5o+tG0A&iHA zcKb4tQ821eo~Yo=Tfc*2zOy=1K16l9S+D)BHEzrHNz)7 z7!+(}YU$8_&|?_|hA*weD5tA=bW1r?FbzvsaPI$^+TY&H*mdz4SBxA%;e&B$2c`A@ z*Ds{8wgx%FbyeGdTAS${c&P2J;McWoIi;tozulajd1`{}`oRCLLQFsK_A77|PA>~V zUEqmijp)k)z@Lh+aYso0+S9S=`B6ytuDRK8RV3x}F;(|-DPnXpHB$TRV~b*#K7tP% z?ti{VxnhU&%-lUSx6U~x{sBY?#!Df&{p*g0gOel4J*)`EIF;?aM@~2ySqS+vyt}yq zl>AH8XUIgGP80q6iQu?6mFw}{l1SrbYfl? z{ryWd`Z&Y!baNlH))7UdPd?kSgI#1XX(ytqR1m(Z+`2zIOR0yigcl0Qe{T>Bd3%Yz z)#DdRXtrT>ELk)ABE&urRNxJa+W*%Kiy8<0pO%D~65f^k-y;C3EvS(PRhHuaV(cxW z;%c^bQCxyckf1?=ySqd10Kq*#Ah^4`ThQPTTpADVL4t=s<23H>ei!e~zUSDgfd|x8{ksWD?p=~WyJum|iA^+0(X{uY7Ccs7HzpAdwV^gL5|af2=u7*z zKu{~}yqO;w8OsVh$Uq(oVd+6=^(!7%dXXQ$J$&p6a+a zC-mow0RE~lC{_UyT!i5(!-PK|5D^Xz&du(2GU`XU;|vFrkWux*%?0-vgw8ye3G#Ok z#>J-<(?Th^v({Fxt{dd9C;D2UAt3EXk=N^Qi|LAxY%+qpgJ?LIUIS4u9bJYkDsYA= z6lh+5IpED9KS!4SaxFBEy^_VwIF6zo_XxWK-4D@H=b$K-YHY9BSnaQzd!V@*fjS#iLbff@RQN_rwC-3R~5IX z6!s@JqibX&H^>3xb5Jli!?hDeeTIVwrsDtz!~jj&8crUc<@3|w!*!1|uYBeJ8FMFp z5Z<^_Z9??MhQh|Fv-32(QIgstT1R)ISwO~-Z5He*KBqE(3J08_sD<&zTj-q=!TGAj z?8^_J&gz}CE;W0nhOKwPjPAf(czMY6`}(KpOe5;>xnHO@TDq)%X17#2x1kc zH;y3P0aBKTh`e1YN-!qZ_c!8y=HQG!Kh`aWzDa=X>78jKo{5oA{3AQAM0*MQ38|9Ha&0RO-I7re`e9gFZeBy&L_!H8+*G z*1g!m2uCV_1a`GCPHYn}fllggh)x|OwfbxZ3%<4v5|Fu)|IQeGYxk1Z-cw#V1gRA> zCy9MFbL>0t+t)Z+VNFC#9M8xn_1hZDLL6gec7M+e+wq3}AuA%|q#MyEPhudJu>{B- z%7Mv%9{8It(7ID&!#BM={teJ=C4YJd{P^R#kNxm@+!GQ)p;qk*W4c>`G|PN`gf0!I zi~PH29%TY_kb@9V#{F>w<;$~ z%hTw26vz&{%c@(ZGB2?JEx7MpcS(cHzqKeCXDNaZk%oz56~7}1`ZDTFe6tH02ElwD zGYSAQ2eV0V-0hfl23N8 z;?_Bg*GPANH=!jgkll{;tIIYK?+eutTL1`}!r)+;F4w1mN#=jDh18%6{P1<+CK zLMP3z&@t{8(Judg@u5Mf|8DL>K--XoE!TLAMS1g?^~>)*LACU)QX>_LZx1*SdRS!- zbb^x*TIuD5S~CU$j?bu3ZC=;R`KRrhIG=WU!!V3zD$E6XRBVNG$FM zQOr^l7t1N*2VojF3&a~;5^BcKu^ z#l|XG2=BasF-t9ptO!0xH0f6|LVXP+!~#To4GSaJNjtg$E3rui(WsQtExC{F>TotW zMsMR=co?)&%xsx?FKV8 zFG3jr*c$Qn?4B>jUd3_Uo0S<_9htswE{+h@-|(1!wg~TL+*|dLb?mG<4%Bpl_IGxA zRzl+U)xrij2NjRT+jYPK{22-}8iE&i&=MC2r`i%})`~DS%qy`s?edRNH5*>q}mmE3bN!g6mEBUbZ*i9{#NK}GtjC3n? z!#t2!at_Bh^ygP^X}%X(Il*YDWCOenmOfXMN#!%qwRz0KVSNyyk(?=IrOT*piPCY> z?hvwI*YIJr7c?jSaLF!IPTXI&l z>=>3l^^NZwU3p;oGP{KeF*hYd5Z0&pWHXbP<3?!IVA#5!b}3zh$^4<-@MnZnr|}kkEXGi2f$fKU>=RL8tLTrpfp58DdJqZ@2wg9VzZNOV$K=%6lb$8k6q8&&lUMK07_9H z6W4R+Vnubj5=~Ibzf%tsJB`M(^%LC-dF~dC$R5x-tSr4)6MS!M@daCQI)nIHHnvd> zKJKpi@EG5(q*Bq}ezLGCQ3J7~EIe#$^Lj|$XD&mJ@+)U?!!k0CXx{<#(eB8cRQX?O zokL%q-eoUP38ICyqrko6b|947R+ifq@qSWf$GQm@eg6qu{|r?E(Tsy1BKc&&XGD+$ zVkU;-zu!K_^xn+pZSDIwTRP3~_M+(Gm;tZ?VgT4bsS$V?3w}a)#Pnt$mC4NXt+5S$ za}r-8o*O4up}p<0k0NWrj;F_$Cy+(DY`yJrfc*o{&>P;C%d*B3;|0<=XpoTsw2}BU z=5(dY`|6?h_q)4e>WkGKtCC0wJw=mppnH3JzsJ3CdgSMIq`JS4oUt(<`xayc8_U@7 zZxevw#d$y@vW@{Xpd&-5pBCs#PGug(c<;B#Zl1;wK5Uyk26T$NhwiIVB>!|2E)~^} z$S*2wdz_yhkBK!_Fqgdje7)jF806^-CIcXvpN#uj2KNDwX3jl|)nfp70Ms(l>0xl% zPy%IO;>8(!m)+wz&=*4kd75&s(W>?BczS$uKYr1vY?Ws8Q2oVaN45CXaO>^?$*hxl z%adLb6o}b{zSq1m_|&sEeWCg=-}x{m7!Q;)42bU^wB@3NHbB=>UB`e@Q&YqGx!$>5 zo>>UvrMz7QD6wro_jZShfX_<=^`kyLoz!%qIhWeP{&{|P93zhvn>4VsqmD+pM^u^q4Ei(5$!KB9L1R}Vrv)Exwd2+!5 zHIwf1RFE+^`QCnA7FX*Vp#+#e`$O+&z?Zx3I`_2d)!@(>AcytMy}9RyK2fz}PNz5g zJxC-__dU;HWQD<{U{*K&e(@8)P6Q?k8NB(3MtJdhqQS~-XRaKdftj5G=JQx)0)tTf zbr?=pvw>F%4HG|Zeicc`M!aa_uJ!sZB085Y`JlL#kx$b-K9YcRM$?_k79QTo)xt59 zjcEUXJU$oD6g>J=HI^+zsY|y4VS{Qr!#K&0A(@A~y~h61cT6k-XZ)k8M(Vv6XXVC1 z9#PUY7M>BUq8L=$AY7gy*sa9fJ@)u&A?$j!e?)?{+o7viQD)H_8?TsFmm!|#ZBB+ga>GEzBhb>_QCA@|60sG~kqwA~?Od#4rKa9?k-k>U9Olfp6u1f88i zv=gAaz{tZ`kfAjaKhI?jV!3$DQSuRl#lXOKM`xR>ADR{~6CE)=IYqQ+1%^h^HO_qd z8UB;j;LtQ^#lOZax##ERpFf;w>>e-^dIjW}PD{3s^Cwgd=fNSD6C-7AUNt?#uMPrv z(fS_l*~BQt=5ClWY<{CpD?t)58gEu{Ff%>de#9RYxH36rhl$gF0?s~GbN`fz(-rv}2w*l}P&>E}X|HqAPf+vi$a*`=In`Yp zFqkc%CLGJ2nJ7&x*liKh=8>RQ7cz>v>a4ufHxp#O+?S$K-+}(vlJ9}jB31a@IOk*` z*(2XA!rK_(o#W@)OESVfe(@1bLmPA9ue-lU!*mZF7og+x7pkjG-Z$>FKr3n#zu$!7 zFAJO~_*azC6=jOgQPTcCBCOgeqXtN$;<6XddT~LgdM?#n+_S&|R6Z(TjPQ(#n_Grt zLq>(i)&0puOBV;s#g#{);Ou#FWSkY+LlGsH7SR}t&ovZ=or9)~Zl@S5f!fWlARpTK zybv*`n1AZ)%wQnV(z(jzbT%;pR!WX%R=3^)Imh>k4~LSEj_~Sm1;q_()(~BBO8xRo zyl98pn$aU>9Sme&Cz96nYX(oIt5+e%$KyTWx0i3&g@rvYFvIg^Q82i%7V0Z2nW9!g zXny@z9dfL}fo&^6hgn+@jVH9R<(7U|+M;bH;`aozHIj{-m-lw?MO~xi-MoHd%hgRp1nAc=IhM)VsSiN;(#n)f*o6_(R^LxtAMXuk>8nd39(U;Uv$!DY>x3>T!-K(6FG4 z>3jbUr*pas)ZOrn#qJfc9yi%1Qu&n}ATI;}c#K;#)C03Endbf3s_rq%XM4}hf2!Qr zV3$GHt|RZThAJ;89dL8K#S^#F3&PLezC7^F?T1D$yaPNSW&wSoRfOZN3N(Y3l_nrd zA-)d$ubPa6zI_4yGyD8E8Y}o^3X1U7pS} zeIc(i6^VU_7V(DVec^M976F{h)x2s9ZOXwBmP!#xL=h+)j`Yj0!;IA<*eqsT{atA}o`yJJnBGNfy*d4%Ojd3v-KT zQud4elP~Xgk@0Llgy4P)sHQg>VjN*hM75vR)TUNJbpiG?f_T5Q(}OUoVmhNXC+B&g z?fa`l`Zw^w+DT9>EcgOx=K=ONRA>v$`)59XY~Tcf_2(w>JbA7{J(Kl6uKoJAMU~@C zF#q{W{osQm66s84>;{^L3qUOzRt6C?(H^eR??tQBOKnUS|KlnO4!!Zw;6Kq!{j7)dF$IU7W-!wdx!`%>a)(Dir7ewrz)x`|(D; zT<8B=WsDmQj_?{rU zb6X@P>z<3FH1S-?@gQ5)AHy^VbXKNo;Zh8si%rV$xLd~yg(y%a)l_3o7wsxWMh3&m zZ{^WNppFh!V9tl<2%7O{n17fEc)VW)b#hxOf;jU%k4uq6u`Z;G&Ig0DGby3)py>wn z4S;qntv^#hKUgrd4}l3-x6r?fc{R0BLRydD<33*qH4wV1zy(OsH;{!3=Z)9)S&Aqt zRRo0r8r*^px}qc;2yYZBNpib+h`MG~XE8N##Afd-*gR6xyH0OK#gv^MdBFNZuuycQkX1iZO_N|sWHFfoSjn2ie3Lg zIfQOk1c?1jL;v{gSaNdg6gBAMVmUZ4z}cizW)#tG;-gRvvb}$OacA}}^RbFSaG=x7 zM(N9Qo}c!Fr1FfLB*jlftw{OS-Jn>04=?nJDUG zTfH#*t@~#8cx|mdz2d!BqhW}T0BERRC71aYKmc)3!x})20&KKb>zh2O!>*S^U4c^~ z3q8NNEqh>iwlPHy;L1ROPS>Tkkxl@AUCQjnb>~$BKXNXcO~xO&t(TBw?)(`y7tPg) zXjhEi5|+>AoF@{;E^(^8rNB|S$^becK-E=1E;ZxnA0;g^lq>n%2a#9kSUk)YK}*a= zCYNR(ReCqyyufaTYg!~XU|4v*@(+~=j+%i~mF6c*%6Dvh=AUhXJ};IG#=uDjp110NVx0%I1fI2AvY%bA~O*aRJ z-%Gue;~r;USpmM(Mw^w$+=?iVU+)l4eyR2I(5e7zrPC$)7>Z_OmiHApn|` zv8DQ4rLgb!=D`|5qw6LW1@^F(Z$Y7jM9em4pV4n8Qz3j5n(rJFcRq6lrX7BngJY6#nUeoa(yaNrC^5RO+=SSqW zAV@9~5o9?XX9RQ@cBW~!1PuT=;qc6cjWfPOE$Sk=_Ey5Sa@J14FtG{G^0%^2#S4mg zn-Xvg-`xD>Bc*D_9)`8SOq>eojyjubZeD+fQ&Tvd^heR5zL~&roqch!lSp-aVkI{pYbXbl^Y>G(LJY!z$sx^a{Q91QHrpr7??MEys;tu2y%@ z?w6Q&RY#P=nzXe(U!3|sYn*6&F)_W5G?CRK>Oh%Z#=#q^2Lgh(Y%YA@-N>ycdNVds zWUlYRK2UkZJfgwhcDdi;DHHph(=_J2f%&xt`BQNvsO8ci^EIkr@`9pS=H4$5V&Ye_ zwjqe8l$;>DM^x=_J_+SHv^ies3nR=$*c!z4NyP`Offjm$_$>?tKv#GY0W^FmQ*l99 z!gXye#hMO`cUIr1nz{DMJ}t0J{xMMVcKv-CCMvG-BbL=(&(k`MDrZsA_i}uALfwz~ zawT-HJy@;fmTPiw|6P`*#W{7-KYXIjm(60@?{wB1gvk>B->WdtToIT4Mh1S+|p|I$Y#eL3`8X@@J}q z&i_70BqAhh}}rYoRL%a$5X+psbZQRXjg9<7L5jx zpdWrX4V&>c(QLySFjqC6aI<@;mu%!hU(km?5JQpyzA1)O(qN1`9(W!%ujEK}j_ls2 zB_7CxL4dmK>$mGQb#-A87LHTs+fdH&2M2R?wVy|SYCC0gV&TZf4LK1MU~dX2e6Ao{ z#KG?dfEPKmb%`%UiqGHQ^+u=<=la?`#M0%o8^0f^|ABrqlzf{s;taL`%Nog#&g*?| z*5oAp-O^%G7y5;%%75`9HT4#hc;&?BJneU>ahRtRXHby_Zc3^3cmUJ)pMJ|~kx(=} zrItD1_ERSAepn*|Y{aq?zRAij0nvvSaKG`?n;InSPOgsUhn7pYPvqQnwF!M+?w@ic zfr99l`=2mlX>9Th2%ZPCY+65D8+cnp9{{qcnjb8PIo@}Kq`8%O^Rva*U_ez(n4XaA ztUTk)T=4*>Koj_B3|;90mV&6OoV7oPJw=1p_QC{lh_^a;mYl4hxqmQs;Q*7EOPmNO z2O;ffqpYNUo|!{bFNuC>qyBZ(`7u{pj$s?Xs(jGCBM@m)XlWCPvV05}X6yh~L%Sz! z6(PBbL!hVF7a#7%Z*dX7j6Zc6%5$^+X>kt3USGBfO?ox+VV>6O znTh~|>sY!Rj|PTo`{<*2)Sm5$OR;CgU2+(xJ3&{uiT1YR%60?I#~v+P&j5UktS7U- zMPlV8PH3{)ns8>G|1(MrsYoF7F8e$W%5$vrQ4YKU5QYww9i=cCcB79>+zC{63wdBy zWJ_LU_lxdzZd4gG!vM$;v!}Kv+@B8t!!y68i03_5`K7gSOglZJ5PN%@6lMwIk?Qb5~8O3744Z& zzJ8PY)r%UWm?R8}Jd#uAANoY+BNztPv4 z{@{!fa~)jPezg)#7Vm&AB%MrlUNP8P05>FIex>nwMDWwQ>`=czvL6?DT4_}kA#_di z$VAI|NJnyVeg%4g-~}BRKK>>JF7-i@L)931e$_sxB?}ge9+QQ zRpPOTx)pLZ(k3x)`>p&He$PU-!qa1z+TJUN^_eG}5RYQw7jdw0!0Ik$7AW%B6zikt zWdANIYU2Btpe_OF;N)!A)r!pyNDiX(Lf{Q2A7nyT{bb_!aPK5jmt=@R7JynXm(eqx zEgVuP?-x8c7~X^3-nECtp|uGwYGP`M&P~ddE?7F*En0*vpE%`qe_rlK-NLLs4+jwL z29_qn#%hD!QohChZ6aRtjK54!W%szLNd}k5UgtJo{VXomw?sS#+W5t6dAn&!Kf=ns z{bf}vLS1%Cl671vr1Yhlew$k>ijM-=LiBDJTy6x3&r-F-0j% z@tQ}AeT^|THg*r+Dx9GJ+ExGn`P2Bahrf(V*8bhsV9#T0aepY}w{N?QB2f?&tnC*` zXq225v2!vBw!hB}MI83IVs9_^$sXW_^$o@7>IKRZ^H`%+Ijboi!~F3&{{0AEp8uUa z8U1VI{Zz-#pwHvX0;++&*euqMXuSAuTs9HgzlBm6AO7dPwXFR9MB-5cFRkh z+^zn2E{)-*|Q>{jwRXL@pI;GC&RKxv;*q(B#z%RWNdt;cavLZn@-l! zvW)a+eNz!Mm!eI2n0LzAjGevv&*QS=BG1Ij9$u9{n}dW- zlg2TAO=b`jqkJ`s$+EB}n(Nd@AX?WVMj^uYr;=rvo16|hD`LJC`m@ux7Xiwl)b706 zAviw1ioM_SePw{#=IvtRq(=q8funW5?c;RBBo#HPfM>xVsFiURlahMai{W|8&o8$h zcV~9$bG^Kd63kTj|lKR9q#V;lHC`7&pMVZliGK_R2F%}U0$eOh8cPWcHF^%b(D`6wa_{xrNa2& zI0hb4`&I-^hi|Ou<2sLCcb3eGza3Z5k=O&Yxi7U{!@;|f(t zI4V#P>dlvm!larE@O31EXSp6l(0vCD#u*$Q9w-xdmXR-Lcv^Dd^<8v*r49aZF#l$I z`6;!7Gq~(?GCj9A#VNt=vW}Hp_2%mS#1dcaGuGj}!JVzm#&N6Da6)sKKTuD~hiop+ zJA&~K#xCcbs)`_+d`{ijyh@Np&`K-{bCYPf(Pa)N_Bkue<*e$t!~b zfzAT`R+{IhZZcuNxT}X+-vOkOaGg{`U-;T01u;E6VsUZtlR(MM`C79&sgRWxlh;Lx z!(wV`l$Ms3)#|Z!i#Iht`FcHi#xZ*HHaxc7_x88#!62dh{`=PU^^TSttTtek?9FdA zz3-wyGBs7`I@=s>s5zKDMgH?#a^A4E`&@m+wfw|S`pO`i?VSEmOkY3C+&Q$J92(o6 z5IPyJu%>3x?6SEa-weY>Of;T!eyQa#wn&HAeO34)$+D?W__)5L|ARhU;&i+}8cfIC zZB$@t%n)fevzt%1a3HhiMJaBZpr_|-voZF~+_)d~rPn}ht?I*ZoGgK-045=06LsWepN$yVcami-QiKwmWZF)QZi&o6mftz{9}h_s*!T^PVW^p-u2&FvtHPkWc7|+nvi`9X1Q-zVXX+icN=m z-&Kc10P4-2X1MAH1H0&~fpF6u&>#Q(GO~c_zxI0&x|pbNNBBDucNFOL$0gmn{W4$n zKzvH~W=p1;e+FP54h1N4Ol|{CaTwe-X{6}lum5%EFOtB({5yIhc0Ra&jUIc4`k&!r zQoF;Kh(tqPuiH6|pZ+5^8BB;sh0v!r-W@oAe)Nsx6aD+hKhyq?&jg}fH!x|PVWj?{ z0)OY!WrYmrR|5ekM1e8fm}tl**dda z{dd3)u6*zQ^^bo4jCbLN&Ryl?><8CBV|6Ehe(Ig?eb*<`D$zYGLzB`=@$zQ=+Z7;& z1X#NB>xm%IwYPt7IAMnYc6O@E!tRmk37~i`C_cgeGg8!-pC$Bcb8UKA7^%49l>hZN zU%p&np*7^V2vFeVFURye&)x$9JUghi`yWTg$`9NcgRVIv_g8>N zS-_FF50Z&2`{Ji=4dzia#d+yy6GfS&NSk^W!$OSBuX zFO5$Hbndt3`%nW)!05Kd4gIY^&FJYkG*^dp%NDj@dKRp}Yn!QtwZeVd=$N^XO(;$S z_D?S=CpsGczi;0cl>^2BZoLFpl>go$N(M{^x2^uCXm|N>HUt6rhAAL0aIWe8hz#B9 z0o3_K)^^f!-Yc9#Gye{Fh1~c@E=<4^RhvWe|6N(W>;|G2l^Ux3iA?riD%Hpx5bvm{ z|J_$Z)?#z_LGOJ=2}WQXy63+pRuMfat`5KUVZeYCZs*68fNskl(Y?LQA>wYp?TD(Wi+XEJM zc4YNS+I62-%MBmtVPIfR7oDE_fWu1Jc5VeNasYqq-nt@AGV&v@2p#(Qnh7f%Jq+^O zb<8)o;k7BQnO|(XtG;p_i)bV z3=`@X-EobDgpMqJ_gyPk3a;RLH9A^D<u82)6;SX88aU`V8j03*>$13$U9K> z6aK&Dod)-yfAVYCBvRU@lr<2{dQ6Zl4O1WqNm;O!(Xyb;20AJ%EG>x(H4s2oyTv)v zN=^G!WT?KMjwe0Nw^l=mI%pF$yQ;@Pm6hGyL5Qah=i~V;EuLE7=%2FkDU97bowqCV zyfYQI_y(T4g*6t9AhcHoKC}n6!Egv`XQx9=?>H0%wtx0~IsjQoO4?&G%PIBM)(3Z3 z#ZB|9XSd5tEKLRV^}z|=Kw!_(qGMyxAI|c^>_umCMetr3Jn`-mb0EieY2kz`BFT6= z!ci1ROinEY74>s})Z{G4>-VE7p4(RJ3NF37cl6Swnd$UKTGC%K5qjNg%ObYLAV}Z0 z_Q1SrXJf{plOe!#6*rA@Imge>{83jXKrAJvPF@L&@oQ@7;j#U(Mu*Zm?0*xaKb*8U zu$kXmoa+7Et|!(oPt3r^*7Rv_6sL3dxQh9;d@CIA{4|r5#`tC9mz?}b>a?G0)CS=5 z%a8sFgh#QTR@bE9}0`v(pQi*Cue1??g|-zEIpAo(aP!_wBDp0|5q>`0_+)T0Kj9(u;* z{G>+e)V~oesOT>TKQ2T~%&~DN>U^@K`plf>U!t{e{d|{-fl8mQlu1zB z_%VAQ4B!olOcUpZ;e!VZst{ib+;~NjeX3f`_l_K-b zOfZ(d(Z#~X4)pSUFi{vEosJc{-N13*uWXoa?0f>06NqEn!HXzhp~|K=DVo&zJtX&D zGt5KxI_n6;6Kg1?%YXd4RA+-3R#dZiP?W;6^qQd{33rB{v68^Wy?6cl0o=wI5h$j; z_B-?fcjm>8Eyg={LK4l%w#H7kSM(Hf7AX_e4qDz)=zj{@*^?lfwohaAojV+A@o9L} zfmS>-!av4I1I4Zdrk-+NpOgQGIdW%vvEhOq2mF7()&flAPu!UK#9WA(i}?v1a#MhR zD>Y~muMPM2Y!mOI*LZtLX=VS9V?8da&CE<%l9F%+ z-ltODC*AjWmzh9ekN5cjB|a&MHeZ=`Z*T8|ib?<)(aieEYOl|B*`MerysWUMCM_Uu z^81PmI0j+me%bAQj4%pKq8<$;4q(e@D?&?7IqlY-svp#sE+!Ljd~=+vZv51|y>>5h z6M&b#&r+_r9)uynsU()GSG;wy=(KHhZ{Tye;tr_X``G(^1b7y|ERWcQ1tj+Z$c9}1 zGVjw6AM#*oxO`bjxbl5twv<#vwyl7PV}&atFV%a2j>q<|v@DhrjXt+B6HTIuCvR-t z{(6my)-8YOGPN+!Krdn1@d>*po{LiIH`U%QQMnvZ_2$xK^7K1}h~9&98cUy&a@+2R z$4!d_E;Hta#3QxBXX1*cjLw3?R`C;6Jz^U_)*?aazh1<@{EcM=z)9j6C%sqt`*jLn zUjRR#k%HD;dzrvn8fa{RC=FRL!m<3k1b6ys^?I$x7?NV2CsNBhfc4$JY}2J%{fvAa z9vgeqdSvJ4Mg079-Py3cJ`guRveE)uw>`2eV7t7tv(xpB%j)Ey?)i`Fisyc1(^1QK zy7FWrsA=sC`d-=z5uRni8I%7$J@@MizI-dH}fmDXm+RgtmV1Okv`u<{=lL*FX{`$`2 z)PNg=)mA?(+db@Lr+PK=jMOB5cIMn&-q7$GNG^WJ*Kl!31^|)~kOpbh99*0Y?~8krvO)C~MajJg5|%+FACo5pLB&A8F>bR6)Ul>k?m0 zr51mOtiW?t-Q?NcOpsHePCWifXnYrG5+|aGmlUsXY52q#VI`StO`et@!)vlrui6fitcP*B`o*+!=o<&$L{2XRE@={c1_qc1U9vMp&nk(pT4K5Ee3s zQM_kBIJ{fTl*|+m!iuOdo_FCwtDL0(bN+By4GhFRoVP)wuaViSRR>N1v^Vg5wMM~OMx^6#9HV>0Bo_eW=dMxe8??_02UdnWXL|2>$e5}Z+B1!yqLi_Qm|81 z`nA<0vZs%e?(Yh($@x{=<1Qgx$irY!uC3Z%P}Vn+akQqaX(@9Nx3_nT){8<)H?Ymx z`f2=mMBTqlrEH+C$WZ!@C_P(r*ZJ2^&wkp3CvdBafNg6lbh9|#7NSIL@9lf6)R237 zT0?mMc&K14X?ZIls^WOXlcR1FzTrZH=G7=0jmVTSs7@$|!^ z+P=;BR-G%QMBz|7mv1d|O%|WV5`Lb-bSk$>?By%lnM^d2Aqf zcE#H|0SUde`X5a8RQmt4?8*<-+Z`%d#xZ<+Okz2pnDTp&V-x{4i zzqxT=^xU`6YP3$j@&;I(0Eha%!RFFr^H;J~!=BRNEyuWE5OC5})$y#BH4sm}_xNH- zaWt6Dd*XjEr>!4mNX8qXber!L815m`{#=Yb%_RM`tv_a}FbDweuWgIm6VA^sumR_& ziR1{8C=-iBVK7+BzvU)6tI5J`J5b)KoGQ2X)hT!F$+;RZ(JZuy*c0GjVC7IzPQLVW zrC!zYc~1Skx0Zg&)bz!ZX-(p%T(t_lPSD9tF*2(k z+gy|&jL6>8i%B>l02(Dfqz-;hmA`|ufc>HJy{dAX3vNhZOZaD7hdI74O?%>x*^lqx zKv&n^to@31qu99XLK7udpAd#I#TSgWj}RqN7YhX z%GYnz_)j;-_X5G8m10_*K9D!*SxZ36+Mf7^=&_1=fThEJwk}chnw*e&UZa|C)2D|r zW|>=}NBb>@?%JXEW0(bszf#;{3(CA9Lir@b8)1px@bogN9fw65_i7V+bPn!rq7{d% z);J?D8!ZAg?j5ikYR?j>^=meLzN6E#Sska;&3p96@ok$^NWdwoyL!`}{r<9W_FH^c z_qV%HVA&->oz$z*gw95}_U||kJ28}v=-LPJIk-{jDD0Tnmb#?YmKNYUF!|*i{n!bS z+=<*!c>jZ$woctZ@bT&rEM+y{yl-0Dvb5yYxW{K#igy=d15bxiC8?Y-GlfNEKgIi; zQaU{z%*^)_==O(NN-mNGmPJDLUJdU!?+KdEYp$7i*B)N$?F*M|CsU)%wk)46T6Jy`gQ)Xmn9`g&*vg5Gx?6%PHNcT$kz;P*O^WyV=ZncK;W&DnV6m) z0XPR3Na*M@8`bLNM>_&a-Q^e|1J(~l{kV(@kqrwuOs^ZfuZk(*y61+GQwe zWN!%Re%2}hH0e3w5x%Ey*H5D6n%}3q7uIFiKRM~faoxYTgavlX_{m5xo_Dcm>T_dC z$m*$tCl&GeYpnH_(~NUDOh)MBUsM!ep#{d6%-{(n!TMZO>51mhSkcUiRFMcGHdTd+lDDU3aNwF z5e>i1(ZF-b|0(|@%Yn~a`_nyQ?bCZT>SU&yQIz}dekri5C;`$}417De)MFqar=)KI&d70RrQjc>|| zT%Nz7-cv}B6jF86DvMT>x?unH)sCds7E51G`!{y0!vOxm{Z_LIaX5z=c9`P4vi$D? zZNfvLOC45p{404SL!G(MQ@TgNf}buQRDOI^=}C6sbLGbbb*zYxx-2rf?>@lVUpV_q zvcRfhd&Ym!sj^x|euFtQtliDPS49Lcxe4@mF4fE>7llJxX!rtP9$F zbz~BqihPonIk{{6e99~w#jr0`l0PRzRz~T7?|vbd1{AC?S^ismWm+nxDjr_t|Ax;T@M#TOcwx=`eg_SIh>2zdRe z98IXZeI}=j9o0) zf{`?V8!>IJC+F`Uu;-wsoQl_FMA~$}SG^Ooe}*loC<~N3zkwVOD@6Y(n9TfQ`SaS9 zlv8t6bK%86{qPQpF=S#C%amNU#5&#Z%9uj@uG;qgH?uF3Oe)1pc0^wk&4q=kbR}4+ z>gVRyixMFL2JzF`0IGFNY^kRfHv{;5sVmjZw-HY+J@j{}4UkJnEG{n3rHo7Sr%ysv zL)cc*zZ|dzlBl+Roi$T`wKukd%kC}SufCh^^_eb~-)mL}kH#m3wYXfQJ`?x9E&pgY z69_f|5%)!`^>^@BHM8Q#d#Yu=j(|F^R)5o~yD@yJt>!Xh95<+`-09P%Ofj51DEz}P zeTv3z4!f<2*A6BnN5H_!?s-V(;m~C`T+Fc9^wn7MAKkJxn#s;5N|i1>?UXUA0qX7D z^ZVTzD8bH|v&;Rx!b2@qHIWWuUGf>bI^6mZpXS4PZiS&8EaX>BewSSqI$KULHdftM zm!0B_6lP3@6R}bFJBK+55Q%cb`UcpRVg$tDyu53 zqPlUm@7OSCT(+`rAjm74`z`4!`DDX8i_{X_ctmT-364DuQjzm!LY=H$thUd?j{?SJ zq+D{cpXt@Vzjcs`^sf7`@#EzEWA+@AN>bzoDG$E+En%QitG$cliDS{D6V+K>!rgDd zqVC2@coyC5*x*h!U-h`i_{$;05FJnPOF?lef!Aj85t?PzDM-+RDCZ;q7MxXAz`G_Vyc!&J~i(afiCrx|7F4ieU=%6W2QQ3$tu+B z@HN-$23%AmM(xba5&8Qfk&sdQggA;RSh&lM&r-&iy=~5yJGP%1#k#Fd2%mq|zhNAn z=&bj7Fd}YD*~eOqE+5$?B%4i$=0LDwg@Sr3CMzlSks~H0aI7ckokIA*L~!qqap{86 zUdP98`+j%tQH5zI)v^dLGXS}MAxI9sng~>-3ULvWLcBjJa$Z+W6*Qo7OpSD=uJNn( zl|isZ8bIMTg!%IjZwr-zh z;SF^9^(rX5kC^ygWhmHSE_%-+ckkr2@Ppbt9lqiDeQ?2bg=z`BJk|HKW!m>K*ja^@ z63=JL`8Y~~+8(|Fc;nOi-YycDjU?5$X&*(uh1);6%UeP5x86}|Y4hxdLrj4`Cr0WT zCSru=Xz=ZLZqVo(soy~BtNgC<)oMX$db-B}Bv zE|p3o&pyl6+*VILpo$Hs03e#FcL}gE{C=m{Z|O&p^4ZiW8qF@GFZgSJpvJghhmMye zW!dcDKq}BLg-DS7Odj?=B`c}PdH`<+PGrdwuQ(2!1lob>Fk?YA;hbUA83333{wC&U%fK{YE78Dev;7VU85>Kh zILcNl6q-{fj1)Np7YLP-By{V$yQ`F@WS?43@h(2gmibNsd_1z&{blJ~^RGdf(fvfl zOyFYe6VFvG&Y9QRq?-8OsOtoTm1J~Nv->UKmh5l-z+*q|$z#LIzt+X79ti{sEJU8n z%;ZDcl+qfhQ7@&^Uq?cwO(VsfpP9DFH8xnNQ-p5%j-bH?6oyrPR}Ts{olM5`%? za;iS1sv1j?U@7qhH`VRRL*h*`lrw(&%bzW6Y80i&U|ZCln!0umJek=>%D}I{n7mBL zg%{1}$jg`)z110NT_oL4KzS4@C*lL28Fd2hdf?R0bRqATjeoJ@3lnPUWL*w~e{KKYsDd$v*jb+l; z$OP4<2HFq9FKTmi_BdrDf(xVlRIL`$74f3S;uP~kMZr8OaC1%wI-^dXM;%A+&FmH9Z*A~gyXR>kU67K>iZ z0*DZK6L{gK=XurujZDb$33bSKhJZju8p)hoLtet$euet~A2J#Sl)3#M8C_y&kdL}B zZMWJQHPNoI#O>&~&W?^vNDzmYmX&pU=P>&ObebV&WCVac=n^-PQi#+EThT24r<@j) zx5wTdAnR&mzW9-t@dla!o6GZvC%^k{Et4^!U(@ytSePU$C3-AlHsuxowb#2kV|Dv#mcWG8VGZ+jV=UWwQo4e(^Yqqj*UR@ggN+O^Pw6ul<7>%p)BLhv$drg~15jYV) zmOFeQ@^G^YJ3dO@??@2X0(wWhcRc1#jlDjakjb3qLLpNki_h%~m(IrSEhU3E-79$? zfj!+bmL^0RGwX;6S{bj<=YM1lsaWjA;>1vjX?i()OyAATa`!%*`GD3SH&J^W%2Cr} zz<{8kUt@C3<1DBGQh3hS_wEZz)l!WzB@^yUP^!7)PNTN@Jx!?nBH8b@E2XSKt{tE_mkT18K=1z(PBvFm(0Lam zYb>>iQ+_88@K3vLr}e;5$9I*d4Ep8O&i5~Be2ACLK-hD%|4=6W6)4hr2xy~*l=%M* z&I$Ve@owdEmVn$*YR~0G#JSh5ua6g)+~8|;BAr0ots1G?qz?~zcWpJ*Jo^TLcvBI|B~IdYt8#V$qV~RdzXZbM;!E_dUs1-glw5=Stm>mw+Yq8! zL;`U(0ws7YV$3o!NPHqy#7>ZQXqXC6z3f!*43EcN25X$SZ>@McN&H}+u1!K0Rs58U zLL_)&I4g=$rVM=jkNJ&Q1_#p{SWrR6=~*L*BEV?kdj5&V{cG+G9;g~H)7aHNES5tv zz=NT8v)D=ZOAu*&{%JQ&v~AuY!Dwl~54IY4{{kp0SWr^(bAV^@qodsY)sPt`5s^T_ z(%Ej+(8{#gy~WA($jr0~MEWTz8riD~v+9}CQ;&o^+Lefuh4)4*+q>xzDP1=v*;Fp| z1)qUT>NI7c>NMwDpJWVI3+7?-0L2Ixtm{dOzBWF4=cjinKsO?d*@_U&Q6QWKM=!`CiJsk_d|DN96R^`z;_ zJrt4Uimzc`o%L~`Gi)^3&q5~P#W&dwx{j4+bGWxQ6Fa*tU#Mk|YSomFOc`HfQzTY% z)~xm)wX26RpyU>n{K}Fq!+>gd{6b^to7^sCvS^z;qr+sl80(DI)yy?3DYb0xs(YHJ zT)i2z6)b?rDt*-;cj!>L0D0a3zrhUk)iBHnY#08Ix1(B!V}dxVgC zSQDx4S*PzqDDZ$#P;0|RkWgqF7`&sT5P#}xl1p>hw=I%gSZLobusPtDfSFpHm-m!s z;d0{fZp%@)-O_e3WaL~+Q*${lxniTheMATR`ATTpk;r8%{a5-yq9MD?EX zguiKcR*R<_zg(>Zo0kZ2unCSqb4+htTUbnpOI~!@oj;FlGo|5NokhClOQUsT?v?L) z(RX&L7myq7_Hn@Xart0s+84-se#u!8LQLrXox|f%Nj8fF&$ESY*N{0XY(oYZYidqz zq(;+IY^XwldGcGzJf?3267s)usJPxH1k}nPrr~p^R0}(6q{*MqCr zh@_ti)UZmLC`xj0H+x$TJKB&q#RFO)L9UL^^@zIELXY^til9XW?PEiCOIyvO0$3Xb zrIYhGqVJp_Id8cVGAGg1Ig>2xlmCq;(WVdJ`3<3hv;QKi0HJ&s_MvM#BWolOuhW!l z?>pncx1#oq!l+-boyEi>49QQs4b)p>nb5MsgYH95X0T-Wj*6`d8;c43={f@`4=7ljO(K{}=~*uHD5&g_jEbG|$&4y@U$xMt_d z#;yYuqp1ZdAuVmegyaveuWM|2q6>8N^@ZG)SeG{|Pj|{c+6u4;87yA)UXyz{467Yp zFKFq}=n|;V)eS<@UeUX)D`URhedB$56M?i8P^T|&m-*YC`c_l_1I63KgqWa^>vuY= zjY}4g@Shs8i>|?GEfAmr^#1I-k0;~nSSXB4l&=QD_uQ1TdcOA=MM)b;P+ELLb|I4^ z{27I(g#sGe$oVj%pszCD+Kl{qH9LxFzaOLZkU9qntq9RZ!! z1v=FAICIhgXS%=)t|c&USw@jssXY5WY1}3Csq6&$C49%L`*)_+oFouTZ|bSi|4R<} zBn0?C92gmQ0EMY72&c@zwj>H*m&Kq6-d!$Y;^9Sj?q9Lb%+5;Z7E@4ATz0aOidk8q z0qSV>tF`g3=v;u*)Kq-}bd{%~oW$maeCKnd^||~(Mj;Fm`!+>SLPC+-x;oe( z7ja{N`CvyoMmcj-b%lF8f)Q=Xj>BiahfD_Z7svX(^MNR;L8G*fWBVxA0_$3)w-0N5 zN0CUirG=vkfdd=pF`|qOeaG@D5*Llm9KKkd{R(2Uolsnzdc3L>rJnb3b7jUH8Fb

4H8lJe^cw$>+F%wtqIE$2QMwYxhTCeB3z`7jo%9}QO? z$yOpSA85YUgX*f~EzaVMqcNxYU=QI}opJHrja$9%))Yn~TW@VKT!<^J@8gU0*qPNu z?gsNjy~?Xv?^?ck@chearIST0KJcM1P_x<=Tec0JI$6`bQO)(E9$iD_6A=}4u6DJs zc%DqiBqIJDspKL2bGupHS&oKhYG~w=RqIn*CJ<5N(1#P&KnYTe=PK!q5;Ebn7geUQ z(l9Cmr%T{7#0m?jWqsV0rw&PASeHDLkqQ1;zeHY8{Vf@m`bss93KNRQlw1=0vB*~_ zS!s1QSU0p5k7Ydbe8aFMu4^75J@UuObe|TzMcyhYu}qeE zqXG5V$>R1|3|fd8wLo8~q+c$ZiFkhM;l^VHl?3Z;{{%vyFNXwA!se|U9L)@Yf*AmP zES7cUy49vGwb2wqLs(VwvS3rC5hReFAB;JDpsS?t`e^%_+sgw= z7+|7^jHT*S6lB4`uWg-k$6u*L$<*9X)ANqw<-yG@jZGqlK7I~E=Zh&nf~tgHKo7qFBfXZc=ce8efW& zA^YEC5*}~jC|i&1ixLZ9(??^Mo4>=Sjf8c-qb9f}y@9nM>pME|A705jx0i?`INQwP ze~vNp|Aqq#-_jA9IeYvD(RsH5UrYsrZSLgVmi+*X-Sr zkL2#gxnlu1Xx10Dn9+rq;Fv&0RXQU%LzT}G?IG=7EKmsboV_-r1L$9mXI~X=6eUt2 z*3>wy^em`pgs$PTV76kZWwU8!Nx$}0K>0$}>W;{;m)TG+cc|tJa?{~9qR}sEApTb1 zL5IEtvHuP4I%nUvi>$=PX8dmA;oH5$96f}KoRfKUlysuE^>gild^=JR-ZTh-=0#`B^SoQnO= z$flE>)8_+ce3Wi{eT%PJb(;Vj+i*XkRwy=O4cI$R9fxFpjC%=%q=and?Z+vdWdXRp z9N{zMZ-cez-0V+JSdvO=GA5_CerOhy#@}fD77|}@#abuTkd$0h-+`#Ff8xe9yZT5L3R?){dVK;uz} z0et&@WlZ@ZOiu6h>(|=lhL1J2C21UOW@}%Bhez}Dilb4vy%1)XJ8txpnhc_HFYM88 z<#&sA&|(DvR89!T$;goDcMMzeakCkL1haDj=;*NK5h;wOp_2`qZ?C!cKV68(qHy%Z(&74t6Wu zEQwvzkr`X8Wy8Q8(uuRZdMRo`O(0oKXDjN>*DY_=glcS?+X5W+wGpnH5qhj}MtNN$ z9^2+TlBjr4|7ThT%g+;5)VPVVQ05=z%4Mh5t+eex#mg+fvye(U^V|H_X3*QQDBP_44x zNnIrNu<|a~-`uVWJXCVKqEH}X`h!`L&Z>NtVPGW%?M+lvu6)w@HXk|WQ)SX><|Mu! z0KBkUQ+z%f(-dZvVzF2tF2w&=u(JIUs`iq*$ruXVSfgWeDVi})`@6@_ql9w3vC{1O zarcJ!3?>aA64v8ZK0v+phzsRRX#IVaul<~kkCc!X^}j<9z9T>?g%#&krR`s1va;Z29gZj%*9LUq{j|pgqj1c+lWZ)$asPd40X;rQr~v9WX=&}%oT(lXdTeVn zcJ+1BttRzzN<2TJaj5blxIf^?b<3{rI2e1A^h@pV&Dbk10rqO_*7w>GZIATdsX9z% z-*}viO*e3I77%GEm2_7=mt}l4&e~8NN?hB(Nles7d9=DfZ(tSCy|h;qKhlPm$GJ?z zaaygSOd8QCo$K)vLtvo6%Qe=k&}TYJp?^qGqI`=~-JwrdHlcP;B>?Y(JlF01xe>IY z^G*1wWR;rzUbL)kD+t@(*gu?}hic2IT7m^Nep7m)xo|&TE~K#-e-4Uc z5rsXBzelGh{Na>wP-X{3S`1|OC`N&n)O+>AoEewdQJEg{91%E17VFDrw=ZKKCQ+g(CVac7YOnn;Omc=)c1yy@` zk;raLG%~5oF9dgVneG-8cDwwFoE)D>AM7UT z<|FjZdtjwJo8)6De`c|q8ickbA+JRqlI%Y+%2z$iQBHfYi}Kh-Sn)en1hHL?lP9ZY+b(POj8NzBrJbmxD>{*2> z7PWSb0omuGM$uAM<6)?LQc&c+l$;p)jDUxV1}1f6e8-GR_)n={XOxA7YHGMaUB4@u zp1toh$VDrSiM5VE_LYlP18b^o;XDiV$xZ!uW}H&8T#qP3{64$q1A}I&NE{ocpr(g} zX6)PqZPcxl+T6g<{9fc2+#wPfQTd_QerEa6x0bVO&R*6F0#DDsc>cQ;C)4Kq;2cNL zSpAdYZTSW;kN4AjKe z$Nca4Lv5Q6*-?#NIs$)#RADra!GK-}kQUhxRRBj#m2gn!#lAJ`hzY zz|h=RODcx`gNpedd3(fwg*14yI`Q|4C0XFVs2+|^QX#P_H!@G-1Fs9F1SBZkbk^G# zK+=WJt^Ymm=zpg1U;p^8-aC+4_CJ6SaJ>31KhV~Qe~vgaIP7-is3sa)MPB1Mev;*@gl2vQ!}s>&BE(P#U?`&{W;G z_cjjvk0Jl(d`bm=K7x~h(S`WEbQu5clY0NpM|XhbJU>lKC5_=5uPU>ec7VsRn&8bvK*FE~9NB8$%Kjpgr(^z3Q^_ds0=FELMh8Pwg^B8id z&D0d1omAdRzRoHr3E63cA2eQXzw6T-)}No4cfRm;y_na6ITHopSTHodrfil)Z^kC~ z9abZ+zIRvRO=w`gSoq%HXtob05nfZ`TjyJJ+)w$=*Lssu@7J*pqksD2%5mdk=@=nr zQ2R`FFZm+`atwEbZGK{RdBeAy*yeMb>hBITEMz&gu$`Yg#(4C9e1j%RbaU79tL0npYEKBUqCF}~K;Rh98KO=#N$q)UWL9};n3Rsape^x|ZYM-Hffw^uf zx`ey_B5d3D5%TB%`uU8GV2SVw$eC|zr}*c6=^x&A+-u(Shd+M2`S`s1Hw;A4M~MC8 zpPyNA&{IZ=B9b4XN+55%ef044fBBGKBNw0;LIWdOY9+(}{GC$SaM!AtnQLXXRhO|( zeYGh!U^asd8A^Uw`IhGk3NV}sg-7U<6?4~<6C?<%JKEXQ|K}8!qdn$&9Ck76Vu3mJ z_+OKSp$NQEWi3~Q1QjA^@|-vJDFQd$aFZ*U$I_i@Y)tYFY_zusHA%#dR54u`Xiu4f zoc4&c#NR9+@ft;RDL0)&&F{a?4)En?b>NEi@p%9FKU1zm{>V3>rWDZ^|9_rDtD-#> zo(8@P$Y4(4+EGsubXOZb!W`jwj0~L0?W&Hz4NO>+*Pi|#>-q@cU-!h;MdAMQ7QAtf zfP2>x$D4m?>zg4B92ITrLhK52kK=dQRR9?8xt*c-H#MBBtdTA7y#p05FX-V4SDa~o z;yw?H5+dy*UoAtapbsg)O}btkhn6>eeVOn*Ha>PZ!N7}D?W@#SpvEgo|Nm>eZO(uk zW-|Vj7SU5ol~vEviIQ`|c7I^RH5V8uNWQNq5ASa7b8>P%dR(n16f`zAPA0kT&BT#< z?y`r37K>xk`N#mRdCItim9FW4=>l`}8j}LE5mvG5qprL?T9e%WaiA!!+R98-hJa9! zOzi`$M44V4i^;~C8ax(<-|6sCT)K#zSXmFkzlm2{8RDmVGg!Q@emjQf{fn>B-m4k# z-C6E(CXc`3mc}iq_*Wbs_JtI}!%j0Q9m;Oura7EHxc?lDg>5l61y+}obeAZ(UGhh% zoZCqA@Olcg4ER1w|e9HIQOz;A4`_cjE3dGey`g#$&TfTW#}y~TGXv3uxO42uXfKxxbL6t z&!+P`55@!*7ZsUzjsJ2w+twU1pW+D?m69^1$SdA5=njcYie;<}#zO%3Yvc8@c_o8e zl`$*A6_mO~cp5@R6?cNRIeEFNy1Gw_)ae$&)sIGg{er<@_i5AH#)s+~kxS7WSM%qh1c6roBMz8*V~6$onqFsVX~`uYk%B zu1~d9*s8x{gx^%@s5@fg`aJ%3$@`YD^ZjWP{4u5qs>$uedRg^t82C{x+HyXG&15t% z4@G33_)SVuo%wR{tJZF}=W7+;{6|iUzI~wD&!x>;z+GSGG@g;(W)t=&|CX>A;Bmf> zEuoNwLKcR*(#H6>9WGm?sUrS|5h!)&iV7qBl^8^v5h=GRKp-e96w(qtQsH|4?o0*dKc$Df8 zH9+CVS0JGMj4WrcgR#Fij&U>9^^Q>PxFEc^?1u}`7yOVoI&I{q$x0^NGpP9y66&&2 zLSmxCbm`2~H$R;3h97@${k$%%AC+zW1c4R)!lSQk_RFKXymaqc^Tz;J0!z(QYV4VM zVv->Wtt}e@1W2kbx~ zrq?c?jTOt3NasBlpJ=rDgt!9jIuH?9Tg{D*B{rZ4+Y|YAD$eM2 zZD_FjjHI_xsMLo^tcajoObj=IhWo1PYg|E_n=Yqoc)G`3d1xCjtu5X{ulmBO(;>H1 z-uJJzj=kC2*&mK|B{%f&NrZn6e&mSHgp2;6BtjKS?P#RXtbCqq+6X!fizuynB+#7b z3nH#8Es#%uQu^y`GNBVE85@_2d8z{W1cYUR+zRcoyq8DOkwDIW7N4W3=lWQMv9!mM zuj=t7P$hb+&G(5@A9I}=2t>+dw~#UzY_&L;Dq!9fM&PvEfdn~yM_PX3&&7%sJ6{xT zUiX}by2;f#7fmzHw!2#3U9P-Rnev{1>j<9y&N=A^S50OYSklxo9mU}&?DN^rk2eK@ zq?wJ*J90xIWXj1{qsLOfGFa6l85ZL8T`?u{3 zeT9!{i!sd6zITe!LR15z`!trL$6de}sldj7eDoybprzVn_MC*iHRE>!tr`NW zY2L-%(DqJ3>MW1;Y>Ll)ewxTG<)PU9i`tE8p0tIXNC=_i^&R`@`i+sFF?j~<=e=7} z!cxS4PGk&1z~l*x@4c$fS;FnUUurM*J<-GFdgMz_jv*VBfQ!Itn^m`X=WktT=W{ZW zp<4pLz^7yBcVRO@G)&$B%zCxMp{#cud*c~z>qZ=hgyZH1?Bs6Sr?d+*UOLWE8tQCp^stmZ8d@ zo5vL!=xV#DFo93SxOq}NROF2eJ&oEQF621d;}NA@s5Rm6uKA!ZLqMQNX8pm^F94}n zolY5Gs@3vL{+8m_K@719Y~$+fMb(@rtmfUv^s{(QcOGnRD&z=j`xLSZMKgBFErHh{AH8)?7M+-NTCysa2@48n1g);GR=}a)x9DiG_4Re9m7gebatb+k%zARHhAD=C<~rRj zHhynWx=_C3@BFq76g^U71uMAhd0T`t3 ztcwq|R|yEYttF838+(7;TpZ*YcS_G^9r8u|Aid_cog+tVX6}3w%x5&c`de(=J*v02 z*L-$zV1<8a@gzgQii>03vrC$eWne7+0?!XZ`ilPqS>q}xF)l`2F_}BNOOY`25`XKXEJ|E_d{D(n zxdjOPJ`R&eYG+Zux>+~E_Qy4sPqU@v&F22Rzi^V|7^I~_D*3pKjCOrYxi{00pYxWVNm3T?G|AL-oWx)bg zM&hKn3&Z2}&R23Drx((9!?7f9zOU#W2PVP~i$SvSu4aNc(NSt=$Ykp6Ql@l9?s_&| zGYKNdV-_MClQ*t<>iN>)HZ(Mwn4Pv32X@rxyc*EG%;98sFYNwe(g79bQh)$q(Qi_J za^!6?WDRs>LbbSM_khFR412=gbhLU#f;0@mlC{b}nOw#1E=j18Lp?)kSEN~q1-r>K zpWVGx@LYb&FC-)mdUAE?zARL_c4VBu(gfM>({mq8+GaX1$1xi`sSlG<#Qi%~Z&Poz zIj`2=c_!jhGF1aj5x1xio35I8imWSKv$1j6wISnK6f^ zqM{ICz3R_OXcY;N;f%N9gn}OnFgRhz=|Zc!^HqWGN-swb5NpkD4KKncTk|pQ*7Xgd zEq`3sRC^cKiGH(bSRKq1V~e60NILuVyg{L=awP0L5=TTcux#E_B~zP_RVhfk+E;Q? zAf#3u0N2ss8$bA++<7tW{fo^6Ep#BB3A6@F#tzlFMz0Tu7K$fU-_l7L zTD-Abele~UZdBx0gE=~C$HD9 z(IYkZ&)h+`yoN^|NGsh^Jn?-R8`bGi7%~sWRNq-2)7?xhvdL`ErN!D!zBT7Dd|5DT z3X&#rivoSq>AK2de?NG^?L{VhGZwiX$sW5WC6fBjo_Kxk(JjJJmM%4;JWU2PYRq0Q z_5eJJ63RcDVus-*{j`&a7Rt+k@7PIh;>ih7Hci6Xbv=W**d6kNnn%ShFLf(4Y)GLc3R?L}Bpmvc^{ytoeBXZH%Y!t0oR^mEk{%;`%Ix%2Fvzj5xjN0}4^_ znh_u_djiPlI$X}0>v^b=q_-q!)Q2mVrMh*Qde7!rVk#3j(%L>8F+Dr?vfudj!J$db z4f*@ouWk?}dKDt565}ZUz1sjU?HAB4I};s^;$uhjvEO{SBHNiW=U@m+OOW_=e% z^kE_-JXZM+$jbJPGaCZ#Z}?2Tf}cb5js< z-lnFZ9?$MK{mya&KWmkN8R+2)%}Q-ADhI91xE5fxKGi#ql_irq@M`Zu=Sm~>jjw$! zv_{ZXK_V4+m-UE7#Y#bCY+nGBO#@q`~^2Zm)1vL1B@@ znm`&>CD*q>6<5-anS6S2M8wo!%EGmu7KkB7dV24u5kXS>_q(6qZ(>?&nf>Ou`F*6W z?}iHC+gCpl+CrPf!s|DLuSm?&mbG1`w&1W$cyZJYSzU0{(NNeywL##DF+-do& z{1s2g6W?!uGc7sZ#-_Cjj?H;r%%6^{ z-_xKgrwgavok74JQWYN!^aGh+_lr`rqe2Bk%lT6o(gQHv^=+dO;>Pmjwt6z*+ZqZ! zVoSKXRVQEOo`|Wa86e98j3kLM;Uww=A~bIN>@9z0=}vWQCJ!VK1KA#(vUVj;h#?{< zW&gL{Gu7l;u0FwI2R{QFZ8|!M0|NJS?fufs{v;t4z+uc{ma#`-=I>I@1cJ zN1_5ckFmU5oT+^tAzn{6Wk)6`!30TU?n^&i=G8IH5Sc*{K0mBE4IR?&Tdsh+Mgq>< z^EaNq=|CW;TW~_M$9Z(8n@9V~FN<@Z$$EQizKZ@8jB^iyvW)yY{{uqW1SQjCH-y`t z!K=2vkARx_WiUGcw{mD;v_afM{GN6m$ti*-T`3bSK2lp+?K4lPbw(Jx-m*{N-fFd& z@SyRVZ_e|TQcpe-Fga*5BbLhj?CdjJpn;|p9UMjv;f+Q8c&2}T_|@}T2sQ>o7M!j^ zMiX?$`u>B7;_mcR4tMKX{>SrMcD4JvC$_mRB>Z1A_z^)A%c!rWWp3<$r(y4MbXFcQ zMQcz%0HgkVo7wehrVCd8=_wTggenkyWRxbo$p@pIls_=^NZK3h9WFA{xY=+=^dQee z7nT>`J&LWX=mf{K>k$c9jq*fsxOUPJunN8N1IgT@rWMbtxeu`t=IypA(2vwo`r=va zQ{zdM0^HsOSL@skl3v~h$N&iEG}bOWoutgb^!TEaa+v*MM|yMBEa%`pYz9#JUMSG1 zViHz?fe&?;QO_6kv@ui0{~AE{di8Z+^9wuE_afeBfrhh@W59M8F~4frjx;96utl)E z8+v_^`D5V8)nBhcloJEMB00xtV);dvkkCPyr}#gS9`_+@Gw-j2Opo~E&z>EC@1@?6*URbuNAfFSLYn;&oK>oJ!fRDnZO=xoaU+TLNd$P+|$Nt=RA0gGF+z$5F?< z!bKQJ!P|f2cOBB)a(&E}qn~y(7MbtvP3IU;XLv^nW6EzD*tyQv|LWFRnOkjlK+624 z&L$rP`bX{R86!4im+4D&E3>d*U4W(bw1&vi5LovvqMJttF-4RPp>@bu_B|th-aZxL z_go(LMe8MIx9t3P1kFCzmUI6_MiHh?d|2n!DZ&2)D|`{-yTaNGcaH@%JyAT)>_Qm`Cs|SKu{z*0 zCrWpBI)F0~v$w=whprZ(#2b!YC5ax#vBcu(=6nQwo5b?{4#+?!LCu+oBzr*S*$0m5nJw?0afB-rjPXuMik z`DN*Fkg$EZv8LFf`y6N%C~|oS%MJWy+}T;}wk%lZ2>p>ZRWHP6jk_?xje20YjOwvX zMi-A@a$_m@yCJmx&6mS1TZ+#sOIsw86K@s2ZQ0z*oOoVF+4Zbr%FD}}-=*jj>6R&< ze{N4>1LRDGpyqxVB0`IpbhcI*meyzB@O>94qBDuu?M>T>$K^0pWbb;97jybA3vFmu z43MF1GcRUP>S~b1IeM1xmEh92`fes`kNj|$YIt<=t+EHrn;;;xVt!*mH>Cx6Pa!z5 zJG}C3RyS(+=aF%m6*I$^4uf2j^|8%Mf~^~o z?DOIc^wKs)$=hM$pJyiNI$==5ee10kyf|f2EBuA`gw0?s4>$+^UBK!!f!qy%SpgbR z>Y8uV?=$ED*F|7$MvQv-*9P8|1~B&XDkdmi#WU8I+F7c%SvZdoMahp5DQWgsl4doR za&_1B7O(M~x71{&jkb!PlEO-WekEf>cH==cyuyf}kRc z23~9AsSH9NNRb17Bl>C`z5p;?nQT%I2`1K8%Ih0LW8Gu6Dn1oSy+axWC zd~6obefhnt!XB~0dYp^JKDy}EEr=k7=7n>uEqL64$+vD_(JlANgaqjNQt>^K9NGT0 zrv}~Hyy*F}qSjhb0c7e^zl1e^GwIOGhaV9ck_ZSqEJXOW=xxQVU$(dh;o`eu9et$oxgjwG4&7Yey{a(~0$(zuxAFkUZAPfkl?9{! z!bXBjSgX{5K{)6hp$5!$!75dj-f}HTzlYy*_i0gtkaxu6mVJPVOd`{e8I96Jb2|0s9s#G%`r4WdM4wU1gSGH%Ek=1H2$SmL{dc|- zbq~M{TH{6pVfhz=OYkhWm?N86)^Qi8zdUx{RG60K_xhAxNSu;HfCy@@n>)m$DzuNG zRg*dX6;?PJs&!Z>%XDVU|6s7_97p;r5;C zaK(h(b+2gNU+>qE@lSch0LIPlOIo!Bznm5}auKkxW7dwdp{*t-w96<)LUtZV+1MW~ z{b<#0HLmVxgZxu7My$yoGzEON;``!y!Z&txVAzI`-xap>$Ly~ zcB)LqIR}6HJ}Bu(C?6Gi3To|NS}a$kYP@Js#kyM-f3_7mgs<**`54plZfyhgT(tLs zJ&i)Rg=OAx5#C{}8qVXD#w0{NYSo;R7eW&);9RD|{Rn|o*{|z-;5Vc@NfdT3>YhY% zIC=wTw`}#eGh~OgKe;h+*4gdp5O}$(={6B!;xJnzl8OAKnp@K77BD3&Pp|O{;7`KA z{mKVt>V2Rl61f|sN|CvXNU1*9B+)FnAuhmbcF zD!9Z)A(%uZ_(s2FcQ%=n!^{Qf#G0*~r+ijq`8RTVTn|A}<9e&6udhg^NPH02;seLo zLJ3ipSjP%C04pd-6$e|eKEfkqqde^G9kfSjtWVvZkjJ=?vdNV>93vR}cz>vgo4qH( z-*G#RIC5m%Z9d}H0MhKol?T6o?zyjlG+88@?}~v}AI4ZGv~- zbkM9EqE`04K@9L;Wtg77`qWoi$v0UBk`!>YzOYP+*O_+eP8DCX2P4dj$}?GU)cm+e z-$Ri!#FV`O1f^8IeAc%MB6{@-&yC;~*z1e1lV_gC&8}-tViRMjix2GF_e8Bv(_H25 z*RKiw9Q`|Yl0!g?fSa#?&c3#*KOhT_KZtxB;V;UI0&r@Op&haW?*D{QY5-u^)}}Cu z^~D1QM!AUg;W08Y!Xo?*o&Gg@R986MRpO`q9I^|JoA)YFy^-Yj4-6ksr>i+cYBx=!v=;_qY zI?<{fJqMyw^ZY)Un*w|#*e4;+i(Kd}0)hMbF{=fDjjc>of!ho=b1#6y>o=Rf@iB#5Tr$`$qorpeB?#ycV2u zbu=1VSZMK+b!OTs!>osu9w#e#;kcaDH$nAg+VO>_Aw9m|W@NtN5mTCW2Af+Cn|lf* zIBfwa1b^_@a-4o108yxKubr(5&1doI-cag;d5oQQUzN7j$_O9}8YwQBRKvrR%B^M> z!ydelFhCEjEasLIIUkIubGL_>$O8~zf`eX7`~?RyNhBd6l*~tx@{7lPzV-Nw2zY;2SE#OtQ%d+jFX3hX^}G)b zuCi^K&c(?2R4CWUy!x-5zAlovZ!UxM2=h-3%KS%ew6b9$*{kW6&xQ_+*kHT3ZZD&PpMGfZ(S^bZI?;z#!})VQY179$;VmjwN5H$)!=LYBP|oEs4{DA+jQn_53vV#SBU`U{Yc9 zUD=GM<=ye1=eUTy>i4Cy^;Ya?q+u)1UT51Gi`?qps{GtQkh-LP>lU2SP-Uj}y&Ee` zztJV%k0oF<;)R%Dl_xCXGxt_FfF{jUPEGFfoDGvw8f4MhAZG88S@-}5lN8X2Hda%& z+K`k)_;atc`S^_tNOY_?>UvJVn6sl>5;k5p4M|k|jm0VV2Ye-5^d^w2C}# z^D)*dYjzSoFBQN+KU@7J{IW&RT>|jOySAs;b-^}K@6f2LO^WxlvE2x4L;%ee(xj6f zh2ysMFAw^Ar-&p|ZqJ1fv0EYEIdSh$>7AgXJ@lM}U$yly&k1d*UR9C{j!n$$jEKK2 znF3!!=~|{J0&6L~>1_PK>BLjlp@|u<9}Ohi@bt<~An-nYt0^RQH4YLv4f|uEf^CM# z~Iba!`m-~A|_^WOIz-aqd5jd8{qoWXM* z_TIm>*Is+hHRliEEe+$ZPA{4*GYWX z+P7nwWyY2>lU~(NwAY)!IqKq+fQM4Iiq4dRmNre$AG6<^pqj433aB3k5a_P>gs#_8 zIvCBSSWW4xrc3mtE`|$?Orn5xxbAdjwst|;yfGhngr%L$sduYNYKmxtIv6AAv{3Ow(|wIc0yiU- z-akY}hj){$*n}dzfjPOkzD(7Y*6Uiple!-Pl5U=NDgdY^3Z3)z;$(;;+q+Fh0;;Wc ziN=fXnXI%8E{8^U;+JrPjveC%2s8w?dpbHFBwQW~nHZK{lk^nGX>uL!3`*%%Qq)SB zp%b@+E!=puz-(dg9=in1iO=Z`Id2a{(HKqFn^MQ4Tr=kJ@>5p#WuKoxi);yiH}n%|_=B0uL^8OoB28^Y+`xfR;I zRrm5m%qh@%e>gfqI%b-(n9;wR*uNVrb7|~wGk3~N(kvV3NcUqj9@N%RJHtI4*O8Y| z|77$N2h@$@ut99o1`)_jL9464-4=OLsdiVMC~B1e11pgb1s)WdCZnf)NkcH^|Mc)0 zLAu07YzrHygKjadA!_7WyFN91FOLTOnOK^F>`5Y|&2<4g@CX=s1eKeN zqsub)#Ij`Y5wW(n&*`~R8SKu~mGWN|_pI}3cyB8PznFHYc~omuQee>aFfyuh!?N>* zW+!#Q9+~0cID?+0LBlCMC6yTsgfgfcF4M%s^b_?#(?xy#-+Q4y*jdhg^1$lnXwh_y zb^k_q*Aiv#BV0`FB33~hz@COrSgjEvm|8{svuxEm&9P{xT zxhTH251Dws&kz-;*YjP8TWGm?GN^IZI-L9IFFn15iX}Gy3hG@394)k3A@Z}zZ$Hmr zhQw)JsjBTQPv@4O+5ZHsf%>migQ1#yXnPE9MGnF=t9PDJLU#so%CtM({M>tv532=5 z$7MEj18zW1_}YWw!e<-B8Ft3&x>nD*uFcYe;*C7M))N=*ZI*Z*W~DB9j2f~J&30v? zAV1A&D5uDQL7gZbwtfzy+37XG#bTyRC!n3g$v+f9kjO9qiOUD$m}`!j&R84cHB#RU z4z4_qTdSK#sob6|26u|@9?!NPcfGlxVO|?vZDsBJe3%tRUhP||pfQ|rawCNI_7#HG zC@U`N=YlChPFwS<8K+CRjGs*6YKQguFKcdbs%{TUX;DY%O3ocdD5IQ67BimBa+Ayw z!O}#gBNq#%R-91&;6WnaxrqyRBz?`33N?f@&=I}mffldT153k;Q ztB4}B<*9tw+mWXt)@Fk4jf|K4?EB@9i8ABvpA$vrV_eq}?PO=o()a913 z#TV11n3L%(mq*lGo^GWc9O@5KI>JMt*bdJif~FLMA^w!K(Qltte-31P?~wbPt&c}{&m834{wg01J|-z z5mFk`ubpbL?#1#@H0mbaoErhV-+rm{|QHA+Ceu-%!!?0?a|R=m9#_M zXc5hmUP_`@MM5SWR;)IPKD69OH06vnkU$_mw2OW*e(GeKgOH9FIMHkRWrR=y(@L@Q zKEiYUN9wRQJ4KN}2M32lPN!Sax6&IM)cGM7mz~IMxumWqB@q?+hC&5e3Fj(h0H=?V zL>uMAd@YXD1j|vNEU1;+Zi;pTsFRfD0B09s(}w;FcG|jeP|9uYF74l~-F92= zhpmtpmr{>=Q1g&B%YA${T+0yhKNPhW*!3iG_Df=(u#gMu=%qA0kShz|58Ix;{&QU(hE$7IRUt2eIcs!XUU>b7@ z0jMa#M^B;xQ)ZodMLG?p1niw+ULBKU=RU6Gz@3Ll+e;$UyR`?)%$mS6 zO7?6>h^D1pi-x~``Q5Ygi!$rDOg){b1*hWMZ!ee|8wJe z4Y~16y&3FrhdjJDyYlV7WI=pHuCSZZ21NOqAlt5!dRs~o_SFf~84YDV(Wticjc_^l zM0?{E$OX3qT7<#y5w@|OncV@dmr6j6gp6{}P5QS01j!S7;ZDfoS_f${ zol%VW0BV1LggO`S1ws1hz{EI|z3(B&SfK&vnuYB-^q+R_e*|5H_uY<~1=yVSiTCw) z-%F$l8cW5MZbc!YG(tm`qE8T@u8W+dFC0bw^beOm2dJwWHkMEd=mdu`h6RMG9fW!qCk)KOAl5q>fZSHE}UMv zfm|Tb-YKI3$b7fR6gHXw@O3_1khEFPT=q5)2)f?pG?LwY{GX@u&kt~Pze99>IbiCp zift5wGIFdae#8FN6Ef~%er^v$uu!ic%Cc8eXPAm$+z2`;6o38B!biWqli3g@>bJ5C zBG8jwta+sJnhL>o?{j093?61Hh%o^Iu=c`Qu@gl?0GKUO&_?^8XZuHCTV_D9iv+`P)ciQGN+- zOv4_!J^S;WV9VCWehE)0{)Na0TPZ(90N?2Z`A#QOqc&`?3)&RjBP1^qSNqOt;?PZRQ4a%8%|k@S7m59WTvOD3Lg9o7|NckM)OOz_+@A z!EZMTefrjcV*9$VU;Ec-akq8;Ebs6CeER&?X){46@*MVV)o=h4UlaJIxEUQ2qC!j^JHzh2AT8YEk$QX&#|$Bo&roy zB1>?(RN@K?k|eYgkA}Cqlv@-b3LDS`^67h_|8-h(mY@{~c{eG3CbaMm&1D9{NJ^NNmkV#9FfJJxccAy zk?~taw_O_HUiW)BBne-hl+8rMoNsI8g)e9APY--Im4525w*YEQ9L7T4Pmm+YO$7B9 z>?$iuUk6}Uc?}JX97>HE>$Em}hk%8JjlO1If`Pc#CB}ilVKL-46%1;vl_CMj zzc2eQ%oi;CfNtS$QD39zFOhB8FSS$dwmAhN^cBk4&Z!HJsIM=h*;YeVa`Kc^?jHUP zL|EziOIZ2Y{{K^0iE9XYuaABZa8Y(e(=U_6Fq^9O8OEbLK^~DbAYGk=bBjEjL}B{t zin&RHHN~KM)qJ<*-R2~0^yF6OwClQ_z_x0`IWuTzrrmOX+ds^CVJXWZ4bTru8e$^ICKnJah=KiAV(G#LQ z`i5|2OWW-Urb7nnk3nEJRqkuE{Wa^aJqN|3tMxvbzabpJo+sZ@Vw~hg+iSM zp`z>0B-HhACmOt8Xk%3e@OTDma`5<;n6aTT7R`)vIQ++K@KeJo!3O7}EL~ z2S_^9(;qkhn0)jc2lnkpP?J41v6O#ymlXed`xCA}s5SNm@1S!bsC#$&5-tSPC;V?# z&ekAI`tq4%0K5Q}n}}a+E{d(WaozO^!MhZv!`R@F30v^C%Tt4)%!2d4!+zl~!>LMh zMuR@nqp4559kys>jv^0Wk&?HzObRUZdlS-ZW}UnvXw_D%C1ag8hO&+lZ?7h|9V>0N zF0|w0;`pjeC*|tweNmf8=V7SlFRV?W=yC?jy3GUwW0}L4!HZAC^(7-kcXbgx=5l0& z-ueX>h$|InrfsV+_c851%efC#ploV4g!8wVMnGl?u$Z9ba^C5?yF-@0 zW;#@lP?HkHlPaKTjb@8Tz!m59_?g)8=4b|xLXR)Bw6w^}$PiUvy-D9pkFXi;HLMVCCq>P%mgxdp~ftKO8h^Mn~xlF7|OA+!ywe&om)Ti{kS%V zAt>iPClI#~9V{v_9Y8G6mvw%4^$$vMlh}YPAQeU?ArBx1#cwUJfEAN~Ck~2(I2}5jG*|ZZxi7P(R=5+^cdPV0HsdgGHrPxARg%8;r#XDkEzp2H-3{q_ zMK+41n?(q%shIv&2MeK=6?d%0|7RlmqC(5ncYJiMiWl*$)*fO(SPt>Q;SW%3Tg1du ze%1T`F}r_f{n6bu=C)+hVGSoj_Yb0h%S+^%dgXJe!RozDWQ-s%j$(_GRV4nP=e`pbI zIq*_??ye1^shA;$Un?1okCo7hR8^)VYvHs3`Vu)FB5Ov6{>U0YWf2+!5Xj%swhyGv zgeU@2A~}ryq{n$kp|TgQ-5Uo=stAKp{az0RLPBuKRTxC%+n+1b@5R69ka7m^Je_jb z6(O3j=Szs?bYQN#++nv+qux_3HF$EpE_J)e;8cmkw%o*~>=sF$@iD`AhTc1d*_g=F zV9PZ3O1+0ZzzPkOqQc5SOjH6*+*&g|nN~~GJTb$ms2CYpvuI!-^AA?>zg6ZG1ki{- zz`yWX9{W?7U!py|RQ(_xcy&@R(s=-CWy5)9ipTi>*jmgsi7d^*G4$ryuO|f zcG-JK6|^TCh(`7%6=bcxYz69dK+Kl~WMJ4z#It$c946kLy&=eVm$WNHs*vsq`%t(% zoP{R!I&VVSUFaFTKcvt8yC+qrNrK@1{=Vh;04b3DVJRpm+G0MDy9D7P|0$*T-}v~i zpdo}LfQ(vip_041o@*FbWIa>kBG>}f8=wrojwutIOkuR*&oJBD(!t2R=Qc)$^2i(u zE%>3^Xm@ntfWvOxYQ+PII9A_*fdK=M)Q`4GxFh%fZC~Aw<-#Q&vSP)xi;dPV{7l_T zpC=X>J{d!gJxar$X;Nu%PQOhx!3X#yS#RAFG^m0oQ+s*bzhx{h2zm?#95kQKH~c$e z;R5FrI%6EfU)s?!PNXz9o_jz$YEz`rPq-JuZu8 z&w%ktL*K`9mU*_<6s4IE!V6pn z>@m6iTE!DuLqHgI)4-VDpo6j$WL(j}HRX>rNEwPxYNdaVA6PojTd@|%GP5UI1ypxO z+_#71c4qqvExMNt%b+&rGPlEfEch`^0(Zv}Wcrkd@w|5-`jUyMDSX{l$DJ5PU;90Z zEmXTmU)$NWI@S35v}hG!6Ylv9M+n#bZG5`XpvD7+Dw*uRj(na{2&7ax(yLVmK`H25 zoF26CHp)VUVA`1L#e;==sRJbuwU?weX#k@NIjP7K&hCdtM%J{<#}nM1kz0Z{6n896 zIF_yhloN}2)a@fenL3QdEL?i6hll-8);An*Hpq1Br+_zl%T$pmf3RQ?3F!efsz&Utl**SCL2?nv%1{2>Fag5`J{5~iGVebc&onXDZbwaUwSq+ zWv3h6+E7h5I9BIibJ0SlnL0EipA7(e{lx3n049=tpCp0o7MZ+p{VZUvlO02bbuf*^ zObj$NzAF+`t55FIH5BUY%Ql5I>U$YK=0BPcKgl80)(!e-UkwgrQv9W`x(8SJo48gN zDg1*e1c8&trcLR2Gdu+RQ1a1u*w0JI0bPH2O&}e*#|$Z^Nr-nARDrD`mVa?;5T3B_ zXDLBJ7+S6R0Lgf&6onkcftfl7QR+U~yb_CLc-3-~*YO-GVx0CzsWrRxv0!H|t-~O! z3~JpRU||f?a)K5M8cm#ebR#DUpD4F=&9cgNmEtY$akNKgV+&C=DXuhf+P-Px)+E8t~~Pp zeLKO6U>nI%3U)q>Wq~9z`>Xw3SdCWj7Iz{KRnDme7x01rz_=^3xQzhM1F(lB&Gt*# zY2d)SvPV7lHd8kX6$wFa5`zDz(96%%1p*5^;4!5$r7~|DPdLo(5NA_x@4knkn;xtG zgf(8!n?RYue|cINADo5f1W&Zb7kqbexvhbw*weKvnU73v5EGL* zdw5+pp2sLp8CDcF#)=qv(8O_HXx6gQFya5{FW8FcX4E_35pqKL$7t(kQ++*p- zvlVjIz#G4RNX)fB<#~8iGrnt=&em$Er@rj$6jLp+XM&szAMxaHDrW4d>-N6WE$smJ z8N;iy{f)1riPlbq?{zQ{QsqU^7r4uC7y5s|uJI|Pv5`h{*IIAKOjXcpsH@|3?oPOa zijrT+!#jT=#e3~)d=TO?L%Cs;5YA5nwfJ#q&Y4X^k*ebDJ~BuQV;h+ae+gNhTnOd? zAv!j<-7o%NLHMAi7!4cgFf4>TT*;k=LOkdfyr!#+{07uGOXhQB-8 z(14B)j1mHWCU9<&?qRc^a1Vh=QBkb%f!?i@YhdC67(L@2hEVeD3+-u8A+fkAnFiRd z^J_wdxDT%nU^6C9F>iacQ_mFm(rmHWuic}35;N-~;|K*+Kw+jX{|Dswr@;H?hbss? z2FAbLW`g_hPbHEG;T(;9QNuGJ`L7^zYb+BTZjJOmY@%{l{8b0>xGa6%J922i<&O+u z(|rvK(bRo~uIAKI_S;5afFXh|mNVFNwl)Fu1rj5x#Rnni?dsC1u1H^hmG>)9Q<`Yf zeQ`o>UA^@jw9yj1~kgUm1 z)W#k|5q={Am&%6^nOjifk5gafRbS}7ao9T8f=98nLv7;v%hLp4CE%z)YpK#v1(VS) z7J*Qk)2*oBxV*IQ!)^BaVJZMds#YSxyF>mIjwOE-C>pdq!092hMr4``xwtB-Vjur6 zQvPS3;6P9lXib(V?LQT0H!&Ef%5(RwjQ_w5VIrSb>t^AwS-E3rl<}K_r={x#IimVH zGgD*$4)=`I=jgA6%Nz%Qfuwq1*$N&OKE2B~TjG!dck&^A?OfAuqpW+-Z^*xd0~=9T zabID9zZWbW`LWU%gs<`h;ELaOp)#Ft0DSADH2&TG436P9NUifQaO>{uZ{!1e zv!YN$4IKbt(3<6IJ}-fD7NIqSf3TjM>5So@16S;?Fn_%*o%|;2Ch)iKQ~w@%vj06$ zhL>{^K|t?cCS(wN%pEWQoUYm|G!P3o1jToMzkiiO$g{jy*gH;v6=Fv=!mRy|G<7tW zb^J21Ou`0d+`*?C&uh0q#9N9M;;)ABf!{7Lp)_ zR3`IL0D>I(t1JW$)D;%MZw~jG%#)>iR{{Jk1tLqC${tO>$@*Q)>f~Dyn`{w2z`y?HbU0op-am!QXpF)=b ztdv!zP5swtNAdq=YhH7NAl!Xu48o*rYx{>YgBpp$R%Luv8WZv>+b00_#6rb|djKZ# z{T_zOU!&f&2Xd6xdY9YrH*wr$DLBZt@{6Ei$Uq{1nu?8{3REw1>VTiIHk*9iVF6bg zH>6sK@z>?-hMcDR_!GDZ?EuRE1+i}Nfcn6?utf~#*Ab$4!ty&LH6bv+Cp7GLP{$X% ze4k3N;Oo|2`{<0`6Zb+hmtjiuTK=|pNv!Xl%q2_s?s`#%t z@qX+bZE)!I+3s#S5K^_?`^$5xWC%Q|Byagn9)x{k6=e4R=MVo+=T^gey(Vi)@!yJX zarQZH?N(=oVjsEL)2+8|&zv1@n;TMGu@19!#WHmxK;-bob zXLA%=CWE==6Zam-#O7=vA>oL|mJHV9b#k=!^S=kL*ze%YQVw}`_aT9=Ak0XN1fb#D zPy>~dUqMYH34V5UdUUii?TugQg1)@8a=}zwoc(#FH&%EsL+TI*mi#k0V4UYvh|-2CT5#_wQy$SBG@a@wy|q zQicahqP%Uw0<(}u6N?ZO1373u*%7n+dxRJI@j%?sw#G{oF}yAAa%LP4urCyo6iWwH ztB{?93@7;f9bHWPS?cb8{>TNwfW3h%Y1s9jJ_J5-Y`mghIF##}f#47nbT`re5De*m zB^a#mkZ{pn@$hhijebGI1)`b34yj zT50rJ4?TjmeDb>){0wFmSPBRX4-c2E01GB1`>moj ziWm7v5^-llJ<$v`BWJAZiD0i@moz;)gd}O~u8ZRh+1nsmN)o1M#T_;=;m%I}u6spy zXB{CFG_Y~ZRC9j8B$gu;TTYO=NZu>h2#;>~wb3>9LsAmIx2&XOe)q;&KMCVXcx2#v z|6f%F@R!;$EWCA%^#pC6Bl#*44yQYh)KuEXSnp%nULWam+vt^=ZYo}U{B8>z2BJ2f zGV?T2LZdD&X6j3#>OF58jQOD;FYDYwnO?KC)t5xVdEFgMNlQCy6~MxErj6@#6Majd zQzM8}nDVRbrE^b6*0;4 zGYD^j4ekvl(!=ZHCFFtl*FGqAEif3j-O+>c^6~-zh5S}rT>Nd|V=Axv!+vC!vs4=W z&ac4+6Qzc{8CHA(9LnrT;c*{8d7e}@A7(QxU}I@WiWZ+!D`Mm_uGgL4y56XtX)8+*#e`{WrwpuuYj&Yucrxg~bdB zv^PwmQfX7Ut@N`!g5K)~$FImT1lgEOr+Dy3%Y_F6zz@?citE7snat(LI?7dlBYf zi%(R2g54gIK~I1R$$8#auEB0Joh>2Fc&72)3vtuk&tD{j2#Bqu z54;+Y#}?jbGrJ{(M0hQa#l>{e`qMK%L^>#qYINE3r$1Oh8i_^1V_U-@k3n|Ku;Is^ z$V$pxh(?H9k6v%F9B4@>H&H*!*lQmDC*m+XzE!dx|4|)p))kdPC8I#?7&T_Cjx0@&3YWXIp3G!Y_MxwLO zdrt7qZ6cJ|r*B>b`MSdzw=ssNAOb~8>59WO(UCsO^-Kc8#8nYe9e znx%C$p>7@hqRn$tR8~HCv&V09Wj|AU!1ZM$HF!jW~sU!n3VHrv9AB#ThHB1io1B|;^=~e z$7MZ1z0p`7Z!pxSso6H{))06bV7xsVyf(Dc|s%GC+ZAzaIzru zYRsPRoKkRcLGF)ynRV5JtH}_t#=Nk2AWM*4+gs&$SIj6(rUh0YzzJbR+8Z6jJ&fw(+;0QQJrR1 zr%LdpIeF;y2iLu7=Bu3=N@{Ag5rgB6;f44mcCry96&2pOGOZgw)iNVm{{@29pMgaR zn9i@Chq39ARY`NRmqZ069N)ZZ-rn9EM804$Z#kSgTmHOQTGD*VS+1{Mayon4#@%wQ zrLk}stW|$Ph4QarR}a#G!XN-r7`*54fcN^!s4O#@enCL$`DM(z=r z{k}&{;LTE+@Z7Sd|HSE--mN<_mq0O?{$0cz8Kw5b>%Wz&4!TEt9z z<^~^A-PtAOK~w?vwV9FdDe}6guWr_SGH2V`E}9bp{DVieGk6VA);sJwIX+*4JgGjy zQ+|RKKuWtgmXlpO9(7qnMW<1(bS0B?9nJs9{3+vS{CWnrQv{G*erefDr9yZ&%tfGH zeS~n)+i;5^$)L;pf&EdfroG+cvJbPG9E+OiyLonmR>PSYU1^k%BVB2M-AC=$;!%NTp1qCG#re%4DJXc>%Tgm zM?0!%)cwH-RrF#HyN@lpewLiSwjqmuGe~~m*3rC^d=ls;Mpp5Qmw`NR8WGCQriGW#0xcRvtQBCGbp~-k;spGi?fc;X=hL0)i zOqxEQ%WG;%R!mvspoChb15>?0py60Ym>*EZfzY8RlOHlh@+PGb=3{OS!n@>EWvMiE zds0j%bFag*;t6s$hkP?kicExl2r-GHQFz@MxEhUa4t847>~xwACSWtx&YOxF_hIyx zUs~^G4r`iT89+osM-dXaI8w*W1AeP?>hP5Nd3NJRDLQrUV(Pwcj*@>@6YWqr-R*K4 zD6w4LKtz5;gyGr_R-&Bv8-{J&VUuq4$NpQU#qTXfRIjbLOisM1z8s+27U?uNDcOcm zagv+X+I+OZcKqblHKUAT>r}RVFEGA*N@4ZmqgvbXHUj5GB$c1d(K!akN)F2>Io#F3 z^w?>g+u=CYgG(yLODCuJ)#24E%L9*IIoBTV(Aag)CPEWQN}{}t;-=Gzdm-WTWe_L5 zQm?;84X0Ycr=1ntd%c8CB`Kf^yz%iRet6H)b}giZ&)8mD&9`(-UV50l{nF=u&p{lA z_2U-~AXg1R84AoO0m`0x^P;9lYr;zhWi)4Y8y)0*n3_ic1i;{M#%c97GkM_JSw)Rc zK@Vnown59GeP~+*!Q@Te8)$~NNk*Z{H-)*~6_v!F)2lGHDfbq_KHRK~=Iiyuh$4p$FF0FuM@43p4mph*VWF6e1@Yt})K>B~=irF>1gB(+ z-^`Zmp$4vZ?3-<~6l%av$7(J1u!KSt*xa7fE90f$Loh{62h)Jq!1vp~TMd|V^4tG- z+5Ibq_+=S0jJ5X&s{D`ftk>1aq|2AwhVvd_W4)WYU8i87z>An!Rstu+=+;0SVfTmA zLZD=f3ux2L2c@qcDYH=o>Vo_2S=;5&ej7o}!TMwc9p}v%a;DwkO8#3T_ej2~-TDxt z(NHPiY)4L>A#FB!vVc|T8~Ptkw8QJlQ)$o!t3TtwO-5`j+d%l{gzynHhYVM>8D5vh_@o1;K?FYA2wDG@ws6}l5kDu z3oez1bp9P(Z;K7CwMt|*8p{M)&wZ7}O3IXFKSl0k9|!H_V+1vd z3mpuE;DWvG{Sm~~=<37xM$5iDgk5dE+?_64B9K#@JW&qYv;oMZ}r3OS2 zXCG^G`(i&_E7sB(@#iPkl4J>zrtY$0|)9^~#B@C+^&Ls+9l`#tbV= zMuX*fjFtnbzNI`@wiraLP^U|211$Cz)y$M1Z~|gWdMs|EAR8LCe@PlZP*PNkFlkv>(9O=w z{4xooYpK9%8Z6&2Mr^b{X;VZtWou$4%v`eZ!SRiab~q5Akr<)v0+tdhiP zMYxEXc_<;U{p%v@UQQC4?N@+|c(FDj?gxyNYJ^&Zkx*}qs+}^h>F~=Q0arvU(7v#Y zb@F9f!MfNZ2%l?i#Jb~HPMw*6j_XYtc~I4F9>(ayHrKXVpQ|L(=(FA^Z>fY7!yFqs z{F9p7FDSO0jv8~vtw+nH=h|7bmG2YVfBsBLsIwQ{^#DH0sZ{fZyL(ALO2P3{)Z8cA zFhg#Cw6=brUBpB4NI}@=u~~H%tQ87ADo}AW7gUHF{KnS{uHrpSa{;vfkv{P;|`xsMh(` z69b-Jq#^neBBl?jhtvj=CA-p;v?_J{FC3PsO)nLrEk6|?9Sp5f+xQekWr}CuZqP(v zzmpOmZ?@UXF@-f;JmIeotqEE#6~Q{UOl|#sDWhtH>T8l&TdX?fl%QxfCVq)LdZW>8 z@Rhi;Cw)Xkf}+NbO~Eg14+)=B5H{$mUokRTuy_4u8Mo2t3L6s4%edD{f`|2EG^Xtz zWagH8@h$Bxik?+<;V^;Fe@Ys`Q3EPy4ZH+CTIS7}V-#>D8 zPd@v2u1tYOy!}{-IKR8q@Myp#@ayqR@nYc-e%jBhtI|aKvu9;mYV|WW84(8WdX;KR@q*C3S*kt^>g_4oeMM4zU*AFeCe;lhJ8Ayar?prB$A6uCh zU zylPUN^)1|3t42oMA_5bBUb(Qzr!hyo&17S`tn6L;TR4a8OFqZlDvkQ%GPTr4g93OB z=vK!VQL}iuTPBpyp561E;W?HEmQ|I`U;74_*gY$zbLvB@g4Ru4O7gjZ4|1}g_{H&u znXkRX94qyESKzJO!{s_7XE~=gyyMK;jXeX07K7by`cLTw^5bg^es~=(v=KeBY}I0WSc~mt=u464JxdP3)G};EIO$k7LWpw2$=Bdi1XCixpyfm^A;uFb)9u3)~fbv-}^$bddw;5;$f35|hkSdjN#_(4l|E z@O^WFai6~cU_>&`y!U}WjO_XOr{-NGE(|CPt?xwz{thkgqkGh?3{E)Q-Zn3E-7Yromp=l$lTV;6GmW~45pXaS{Ee0 z<$KBEF!F}YaqRRutpDIcofYBn)_7M7Z;kmI8ar0I1A%R#hDo8zMEo1z>MbMl1UPzE z38tTqNDhXgpSLfVe@&YNA~WLfd`Lt8t{1>sbT)5*3cy@BS7T4}L~Q zVyrBCZsYFkh6?ozHrp!LMRSd-N=~bi4M?bT4839q`6;iNbgegh)KUIP-nswuP-ztN z*nnpfJyC(fvN~pEEAzTaA-3-YRDo9AjqxkzWgiDGgd;5}&LpP(Qq$i`+jIr=XLtQJ zJdYs;agP;L6fwjZf$G)R3IEs%?w6S}*`BNflgZdi`-^q`rJb|=MPHY|bVOBTO-IMW z6^WzMhTC`~T-I-aWEHm;4K8WmeF^QRnlt-(x4koVjia`8=2t|aJ~Y1JQM}Ke3w5gs znwE+ABdNONY2ck?O5|j}hgHbyPgbZoF%u7*c#it0xE;S3_GUG1bEgX$l0aUPaI89$O)B}}}?DJ}HH-1}(l(P<`#j8(&U;HCs+TwLwUVTXtRj z^-bOoaXgXtD4Kh2rhbDlhaCImUb~{yh4aa=TIPH@V3XBE;AzHlO6z zmR_)8dYsGp^yy8P55CDI4ak_JgBf9sMFQG!3wa`Pdehu=I3=xS_H;2ycDlY1Cg0yd|YS>=64aEBh7oI4! z_=`G0Yf4}bxw6=oJ^#)}K1141p6AfDQ}Ts(Mds;>%Ku z#!pa0JR**k4@`6=0=(!lknan7({~SGm7TTlS486QeIQ2t3SSf~JC}0|?-nIrZ4_4o zT%t5$_*Tmihl04N7*pG5F*FChiOyjNoYzgjtNT2CL-jn3!wa$D7AE-l&kV+fxO0}4 z)8MK7!B^5D&1b8p>_Zw?qg@dL2Jubkt6Hx|kxSh_G%%o7Tdq^Rx|ND<_eaP)*_uJT zJi$;=76cvV2-TBDm(nXGl33aZAUuylO8R8TP z@vC8NzjKGfJezOeRXJPUufJccpTgFiAi%@x_8$pL!6IK#c7HElKh_Gy=Nw*W!_qXEc%xGcM3A*y7hxuq+iD?r_yXOZREbsD=Cd9WkR>awY!N&g2J1cze4hET`L=Z~A(fN+Fe> zNTCW4WK{Zc>e+W=4j5=FP$F=pT-zBv6*Tmq#%;^$86F$U@IFnOLX!IFKJL8`ep$`j zEjY(ydO@>ys-(^kjK_d|aL{~;SlyZ=#pZI~B)>Q5_}POMUMP`!j|lHScZF_-K0DXI zHNJK*XhML|9BJq@_rMhYmMW+@0%$+dhTQA3#b8&}16jle4VWz@TUvys+;b|_ z*-$IXkHuCYugN*k>GHy*<#qUb4Ho#?QYookva%!_22ULPgc8&z+0qEq)zF$~_Nbdm zOUtE1I!o33OOaW2Ug-TX6=oV*XHgtOR^~ErJ(+45YimzGT3Wt~$eo(TKz_6CU#~zN znKMl4$RnXKEZaq?lVszw>}|4la`HKb$(XXsWTsYh8*AL6i<+9H>7i5qIA~kblQ@D| zr8)Ra8KjKbhdz?8fs7P{6cZ}A5BjcMt&AJcS~{jFS2b`{-(0yF)NCm$oIlIjW2J|l z8%Lv9)xhdhI3n9mQ=T{`Nas_{G;HXqZ1fLyuiii)!Sq7u2p9DCmBo(cNwBk2J=@+Io03U$Y=>LVxg&>*|Nz(QQ>LUCL9iqC_PX{ zEmfNBpJE`L%NGdvmlUoCH_T`IkSr=8HFOmE6JZwC7cus^AZbjgK`zSj+xVu})*6WmNw^c#3| z`;oY`gia0{`%LjcMzLSnvqOq!^*8%IKC?9sCSPHF20kJJ-NeYC8LZcTO}{;M(p0yXe~rVm+5aRE-b;eK4ZWnMmj7NL*)&OQ|*@n`?8o zQK#=$X78XZ$v;z8Bdr!p^yE&gquR=J>B$MzWyfWdwyAi?VXJXlUQb5K;Eu{}di!5y zT2(1<6X->3J$#acW)(K>qb!#)(wOeJkCS7(zr-?DdhI+16<4FaR2{6^;E-nZfGcfl zFig29C89};52Rx4{zdQV$kcfqbt(Z=8A8q*9F!1j0&a;g@OOJH*VNaE=NI3WpsEz1}O(N>mA3c<@r#EixwuM|w1BXUD8L+<}Wm<>2*s zNT1V;UVI{GIdnfqz(kQLUT}!?^UW+vwP=o!2#jG0-(-n-sq)e#A!bZ{=ZcAN#Dc8Q5- z%!wS79!I5ZA9tOhRcua{NbQ_HTFCkctuuVK`?TtFHn{oT=-eAtNl8g}c`{*J7QrB! z=tvUo>TD4?*`TT|c^BqkPgEdE~(XgLFjmfxD^TiZxo7NR2xQstL>s60^R;;xCarh)h1Yo+J(jE(WzjCrA@=hC8R z_-SnM$ms-txQOU=*I-7k>&fU9zEs-h94xwOs#)-HwIEtr{M zBO{Ctc1k(-F{m9FY+fZ*_|s@+o(xW$%FOAVJubi*f573(gsA~l5Nyxn9Z5=qZ)n^< z1Vy)jnqpjGmMeNeuX|ap72Y$bwJI4+k67z7Nl0ZK!)yiroRpMmaNTR;!A6?a3%42@ z|0x4RyF*jm=_FWceyywi$amifD{2d0R81Zwt>yNvP-tz)u&_g31*W>~@7$=7ayTiS zaSEFo{Ag5?w>`o$`Q`%Y3Oc)Nvu$CAU>r_Hn8kl!c?azKA-su;?F=IF3ReYjT5Kng zW}I-U$|5I9Hw>#+B7(0NrwH?}oQWf>ZTCLX!G;OfXQTV(O?`yMM@fo&nF&u5k;hF@ zJjB15ZraB)O`89l7+L3=+4O~#T;*n+#U|Giop>~|ADeZmja{_YDpU7$&qapy@T_D+ zHDCrlt{owg5CPNk2N4TsV=T`H2o+TfWUL^^*nOx)$jsIwm5I z**d0GkjpYwHE3e*^4WrsDv@r|6&GH=dzD7&I<*V&m3*#kzb$?%;x?3XbD16&CHJxa zHiznBhV)!ncqM7BB((WZ51|I^Q1(-dRcT{QcZY^%^@n1QYL^bstbg|13>I6A5@6X1 zqUJa3aKbXQ9_u9s)V1X|X1VZ3xtb9d6$?GUsF$%x`%W0=LbZ@=?Al9!K@miRS(Q2Y z23ygDwR_6>;9wVdz1>4yKA>VP)=5Bn6ur6>LE8$NDYHYsO1yqnO2FZy@v<;T854nM zQ$TI*S8{7<*@6E@h(-f+!k%Uumd$xS^yRH^a)m_=CWUUDK&6Gd3r^CdNKb4nfvqmp4bvD z*;ALzk$i>vFD4@DElvmP0%^AGxG3A_Xqo&pVde*(b5N@r0tIdZS)v zM4FnGR>U>9dE<+gfr1r*F;>sT-S_h7LJR(9r-E@56Z^l}YxKip1w(~_>15ekC@HF| zlzho7COWFxv>o;|kl`kj^z^$g!Y;2BlH$%%LkFa3O}2x>}BDAvwIT_SM>fP!s@5VyDpwk1zoRH3J(h2Q8;El z4R;uqEj&~BkSQ%ml#p<<$}dW-nf-X=@t&98&l7E5kOfqus=dm{xran0B-};OxE1jd zL{H8Uw8ia^Ohb9!lKv_1a^voCH>jPz9QN{tqC>aMqJKRR;l7DDNq}8EnmRbI_B8&2v!hRsMGr7R0s9a z+MBZDJVusd7{+eko3dI)LwJ=A&+y*)As|9Y+ISv*@=m%yxc(Vm^Sw{!hw>-2auY9L z;Oi5E$@MLwSXz))j^=v9_{7-EC|>uw_ge{7P5J0Y)}61}`Ew%j2t(k;&1MH~HuWad zE6k>SVdy-=sWf_o1%<@w-wi29s#PODu^A>Nro-m5aYQsPWPEJO6b+5?J?@_vZ)y(B8veXrffOhfk%%t88xCZCfRzhuybvsa#o`7(EkiQ(-ziAF1I+ zM&tjX?JdKq?7FpK>5@+AMmhuu=@1bRq`N`7V+qm?Qqmw2iXhz`i$)qGq;ye&Lh7BE#>9BTFOxiVP=BA8C02lS!HT{W24)+6^GT5XO?Ix zjBoN>imJ9n4#k)~BIj8u3b(kwy8|cf7Rw{;mg`3?tGGx$H6~q`D`Rr>K}~~oKWY5z z$Ev=xUuKn5dybXl;;JgTxi8i_ZenfKXVG(K?7;kkMJimg{hM(K-b|HNv$8W$FtNfj z#Opwy&!!@qd&c9{<4Dg%gk_G}I;U0~-OJkTtu0{oDVi@w>q|pJQe1&uv*d;h$Kbg0 z`788oVee3uN|nY#?vo4o-P1FZ5X5p|6gn&4%R}Bwt2C}VHO}C=tq;E-aV(^@otyjw z)V>^>dxhiXxgJ~793#LsAw?FJ+0E>#*4d8>K!Mi5Wbj8!o{RNdu4S=S@ly^Xv0$X` ztK7{~`B-u!K*Tcb@!Gva!ntfT)<|AB%Y2jyKiM}8;y1hmM_f7(ow$)wnBMc}CJZLo zEwWoOdhgynW-n4EB1j~(aJ##=mj_FOZJa)E<_))actwTkbCM-oqQZb}cy4f>`%)|~ zBE|18iWIZu1G0VRc^tJc;(WamF^=vpBwX{d8@Xh$@4T`wCa#?D4G;XLS9>gb@i-yBm= zO89BmMpUhw{x&w8K2RM55E%WoHx#tc(Y=Q}8sm6KNQkg|XWDEP&*P&iwV#U@FD{X~ z*EQWK@icQWAyJ0OMKs^9;M6C=y#xd}gOba(bK85x{$F`|2JH=F?wNJi0TEn<&6mfY z*#zxRF^V)kNiRH;?Pzc@a|yBtB#2u5-o-Tec6@k)q2WzYi_l;)m-2$PfNd`a5)sj= z%xY_Md}3Bl)ANi5kz%bcXahd?{c0&GJZRM3^k_wYIJYZxxew=iWpzXh`7|wBSSxXt znIzO&=gC6jVg$#vNBxh?z4XwCi<8}s&d@{6W?AZq8Pj(3e2kmRE5XZOU*hsaJJBXV zL$zSwhN32Zj@10DPKzdJx*8AJk55lm5Y&y=e>Y=ZoNZL<6MU1SV1JrkxrEoY_vi_3 zyOx;{xE?l%zu$!w=Chd=J}$vizPFeum(@;=Gk;=?$Go-RxS>rY4yk4sWU)k0xL@(r z_ZQz=VSoA3k@0R!0uTHrT^bYexe*^URjDA&*~=*2L+^=lJY?~-ea=xg&tsc%@5a3j zcX~*r&92oL#6Cn>UXjDh#KW5mW#`UDXH2>LIPHgr{~E`iYd2w;g~Oy!^67o}oc}WU zTOl8cAHJ6v6P#<~?M@w1W=Hm@`1=}k^wg|@sRn+o=iD5{Hu^K?>LBGU-PV3V814K^ zC}(y&|HA2JJJif6l#& zNEKo4R@8tAoR>aRZML#xcF$WbqoyM7hz%x9Z%z*s)8{+MPb78He)Kq*Sp55ag}@n7 zbu?atd}ajm`5$dVh?F}SNhsw^Ur-5qk3)?4mI}B6K4|^g;C&`Tk6*XQysM9m(e%T3 z_ZHVWtW1-JSq`1)?;as}ttCqv%qhRSWTlBcP#5BIBZQn?TqN3MrVq5KkxorcEvYYm zI|=u&TUwUuX)JrT*u-N!hL;kj$26gRDTh_#bi?-=Vr-h5*yML{O&gJo~nG^ZDf(9a5oPTQpcpNd80|()X`K~kKyV>L> zZqX+C7ZGjK{mdK1Fc~kR(X&ZDOnMGE*c8axkO^MPNR386^uIbHT`s!Nc^(p3e|jNt z8+j}*nS1;v@_2I_d91-|?qYI6a#6TB2ayuvB|j5Fo-cEWsM(Q1uHaqXg?hDYV`zu( zAIETwCyxDGzF>{`dcl9PA6t24pTd(dbnC~+gMZjZuqWG3miyKx|1YY zx26z*o7kzn?i*-yvrZ04i&;c6(v&1h-1Rjk)>E~1RS-RV+rQXz-iZGiL{#bohY99# zxfsfHWlXUPfR=r%qinTH631oKV`dYm&d!|WAL26!&}K2lSN(|?zc=2o$-QCyqSV@f zVx%@*X{}G~xMs4;f}~STS}qTrZe5>hQtd6{udz1B)H!eoKj@}1WHl3rMq_(-P?`^s zhl)m zP-}OoYx-0d+Sya>$7?=S-c1MQ!H z9?3y~C4R6}sUqK3HP+}x3TNipzaOo(igsUAD3!g>AZr}lP7@ZkxMfZiFZi?mf8GA#U~Le- zBUmi=atjyu7@eeRBPE|B;*a&Dw;e>L)cO z&>8rjlWk4q+UBou0X^ZAgE6JHFC1~#i>^Bqjecv5EPi1|{4^0ZrLmJ%M9l?%`k5{r*Pexig_+UAx#Gnr-^tD*8t9g*X>JyU zevSB5?VU`f*^my}U$<_@0^Itv__L|~=YiU+=eV4Z#!popz5o+>ng)#~@*2<8YlhnW zoG7OaNOKq(7zm=1K~05k+d7V@IhGs|8+?kbVH{{|^pVVG`zC4l@E|@l6Dih`nEPUd z`mv1JCBr+5#Ozy#JjeMQmOpwwh8SW~te=gxFgIXMF8T6?1a{Ladw=T_B))Wj@v6fi zLS!H712Q{DRN=?L*;ICTkzp&rUEfk{4Y>Q%EH-Q48*xM|L*fg3sfkQqy}*KScbZ*! zmd^2ZN9iXa=Zyha{O+|#T(x3q*W$$8SftO4RukCM>mnXXm_+VVbErTNykCOV8H(c3wnK z^rogq*ezxFjs-MeQz$!o@G~MFcZAyJuYQE|*i6VZhBmN5L zEgF5fcHi*=NlO(+&Jz!>n84M7JX0J@m}`-X+9CIl`D@^&PU0$jmyWk*-O_oc7DA<6 ze`LpM@9wkIx5PKH)-}8T#N4|}^?1Z`B1l`k#&kf$UKhsHlYr^EKB5m@;1_4^B@;h` z1Zg~+b-6^T$QKPy5i=?ICrJ?>fQ<)R_o5&xvX0ou!{>xVk|6KW29nCb^^{1c-5+}N4@<>f!i7l!F{24XxE&}%~uO_hA|BlU^p z!>i&`Q;`H-Z6Xr;5t9%}TEjhlILhg?mpZ(M4#Mx%%LbCxHsuUXNLz1EHGEw5lix+M zZCu07ruveiQ{l`zW<0b>2;`7B^BN;E=Sg2!;WnZPG#ETEUGpIhSlq#SJerpk{m7#5)r$D%K9e;JDeR?PiMN3~>%btv&a+&hV_8 zJTjL}`g+BH*+N7z_Ij;vJ=~9+4bInd4lFLl3?qoz9#x2KeVjaB+v)?&hbbyW>P?m< zwNCKqB|mW8`$?`}{gcdjCdVuCsIfpLJ5U1u)nWr7wgf(wXH!rqs7=Xx)7dy}A*D*; zWO!I!4lPzM(1tCZgjIihhBsryp#bqh@f`SA~Cc*X-S>eJK7u(xjw z$Rr&3yBuC6ujjOtD{TC)c1ja z0CrHYQ#8k0Z*Ok`1Vu%yk3z^s3;C3_{0|+9mi=^QrK;%M0}B*ja)-?g4U$;&zkv1| z0rFBaFp8L6M%YX_K0GK$`qcI(0XlB`;CrP58%{)S^EjHuzH$NdmJMk>&#TX8*L?ZV z!LMhe)UsiiElT@W4EDwi!-nl@iecG)YNGUnrarxngX#Wr9~V|s9ABFEm42eE*GW?{ zU{*U$B>d@QnX+H)Ir?V=|$gp;+njZKtP@s@6L|EKggsC3awD`Q>9wUc>UY z$|MRqb7bu#Lxt4$4owYBG7iT6O&GihCv*Z#2@dlIG`ASdMG7PQ+;7MG7?F>k|8AQ> z)mK=@fUhKHeM<+`Ll=bWAjxc7k1IsuY>{8XGK->`)(Z%>9)1)CMXbnb18D~RO_Er@B?`Aw&dLE%_K?{b`Z3pVpA6@tmTH&xN5aftI?HLr!}Wi}by9U#^z z6gU;lBii>F|KR7bG1o??aiXQ8EqvsJzAfe{r(yBArbBglocd4ly+GFHeEVw?RFO-9 z&Rhn?=%bE5$bhg>X59Rgtm7(M@V+xleqP}Skl54HJ;J5$MKOILU8eKjk{2Vf#>MUR z2ZClN?l}bow^Hf*PZDpeWuBN0?z%}X;!M>j z8CHxrdHpt2J8Q4l1XP;#v*8?eTQ_-iB?= ztv`@h<2N97GtdgMQRSznLV%%|p$F>h?jbm}9zBe%M-C+2xlin+ob?dt?b`viKDW?@ z`isXst%hg^UAaqLH+=`PvLRi|a#+b{XQ=*5&rYIcU~F%mc3)oH6=CQyuAZ?`))DP--( zkB){)Ozou3$WOY}B=~e}B_sE?@}BEti_eGY!QT|Ae?MXgZ)g3DX;RhaB66$0x+y#k z-1UJ#pjGACcrz~f{nb?$6(-lBpX{yhSwQ4*dmz+hO0-HvY8+;8_##otK@FCTlIuT5 z!Z+%payH8KwI7G+cG|eC#k=Bn3RZVP0-AL+*Aj;`n&CG03=%387>Jjbj)cL)cL`98 z?!yT<&=zD7xnrR>-)Q8F=!H9fC`+{CxsXydHe$AHaEk~!%qewa#SXPD&sN{uxze0F zJG_yWl|`-|$d5ze7U>0fdKpz!yv2|Y9~gzC7qSgny<u|L!rNFRmO}wnYrRjp>QlmI?cGsi z_sf+=b&#{X*uN)B+;!FZI4f7>5glEJ^KwH|giLl-?+=&qdE}tpQj?xU$E@Ia3IC6^ zY#_t}9iy^kEpfoF0ke!cVqt>k`I29I`=Dc%$d!z*1w~g&Z_w5Hy@=Vv z0@)fVJ#UgB{aSe;%DTk{KWs8y9l9V<$fgM8mHsQGk?RT?H>ZqiA*_YPw@cl#^A$JU z0$QFO1xRVdDV?1xu%{)yes%Pg z)tb@1ehF-1Nc!?ccs=LktDpJPJl;b(Bpz!6#HUunY^GJyJJ2xfju@SX9|HBLn_lVG z(;C`^iV%P-LNfsOW_Vl7Q~-Id9ry`7h$v3bijtGCVm5|hg)=_B!^{{&IbVgU=>Sd& zO*x>{n}P69{h@q-V@EsPvq&@ptLvqw%|S@YyFsKt5v#84__BY1C8BS5r%q^H$ciy1 z5_*0_(U0W8k|tpHajx87Aeoo{U0aJz%c)!c@Ni%P!}poy(;yVAT-|D`yvue%(&)^{ zVmV(<$ap6)yH-e}+Yjj-5f51p3@^|pjdOwX*x_2tU>p0hJyfSdQz5lj^%JH>sZn&y zvEM1x0akAxpS&Yg&u#8gRPPPcZgQhicI*o|r~-#-r&S(gHxq>{gmmgYD-WOSSAdr=%nXf3HF??m`Br>q!3z(qKE2=KC``weN|0}e9p?T zpz0N??I?G!z3p~aH~T2kM~?jAr6;OmSZ{^H_4+OM?b-0aD^gF&7W5Z4&4b5{kXRN+ zX1fzi-L9q}KryQu_BD0hOVv4g!L<;$D9^QJiz)u9oc(mVsPmxoyJtp3r&+S)_S4j$ zPw#zXlArE!JOl9cYQ5!&u35)+V3p`1-od;ZfHcL8e_dHe{X?$k?C`6!VAc4f7OHEn ze>|nu;Km}G#?i?6I~!?wkYt00hX*}B-s0AWfyUtjeiIkswx&g{mObawz`iZ#Bp0`t z<~`O^aM6!T=YPqDjEY)yecf=4CgiotG5>Ko7(fKl3&d<~CpI6Fjz+Gp&?IkWjLa=@ z66}hp+HZR6Lj6CErlI)xVcJpl(7}NMRIKHu#&_JfKC;r{nQCraZXQBu*** zDnj(FwpXPECJv}nk8n=Q$gz#%mQd)F^(%E@@~L)LSWLg7-3zVl%d^97`Wb1+*;=aU zT+L4oM{o&-15vwmX-b;~nTY%S>aS~?n?*zVAnSljBOc97o>BnAe}pj!Es)V&kfcvfVJNLq0gE3GJ&Vr)koFNpKReH!n|?A z7RN#aQM6prJ>`b+Tp4+0+dNGx(UAa|a9rv8FL@0r&6o=1jX2b_>peX^xAXV46;max z3w3hnPY`Ms4wz*TK$bgn#@Js**Amr5o!4XFgPDs!m||!(_G)N)2{-(!q(q&m-)}HJ+vpCky(-cUQF(m7q*|3U zZn9}?c+47-6ptg&A{OCM-a7_wghi0NA?WWX)@fO67x-yzI9(9(!M#BV`C$UDg2iwu zqA?9OI%XjP^)4nBa}grG-jn;QFW)9$qdoh6XVbAJO(Jt7if>>D6ln$AJurOW)2Q=GVQYMCS?#OV-iUGz zg^PlMjIB4b0ak37=yFqZc!iG(JwoPfSbDbKHm)Lb;S_ard*ka-m{ew{|0Z_#oF;O;mYt>M+>9tCvVwc!T zB=~oVX>cT^T~W(%z^&W0-G4RKSeUG8yjf7#zcp9LUyS~Q5!CygdAa+>=Q`QvidJ-8 zP0&R{m5SPr^zCO~*%`;h93W<i}e$%9xk-({bONRIq%t(yI(hR3YXzIXpO6`t?)YIaH^l z(MRxg#5cqxO}^}3feg67Smt@CycN1f{?N8N6W`aU*_${hgDqBtHE`w>a7aM;;cC7~ z*9A?p%Jpxpz&s|mON{ZRa2vnN2er&_J@@8Vi;Nr0hmOKkVRC20L_}HTAs%0Lkj;`c zrh+!5&9X9^nBLEL-$Jdm==eo73_;0%pjN2r@<`R8n^%gBjg1m*LTYLOAVN}>93x@g z=37^^@5A#D+kvLB)8l{vcXPQJyYk!A_Su3O>APrB&VY@L`)iPmu!UnZe0Hy2*ZO2e zevJ(HWFl2Gx&{r-Mrp{rZZ}vRkzl z^Xp3J>dx|9RNs?~L-7rYQ*k&zN_;s`0+N@Z4*LF@yQF<#2G_1L?I81Fp_VHxr_-?E z=D9uY?Sv<_`;;@tK)uev-q01rNbD-Bx6tFAz7}v3V*u zL$MVm#d+_A@)b#MIKTolXys)TQVEaW>tWNtO9~+gWF)SH2NC%~cQFxxVxf)TVcZ_l zGn{2oqPeGUF(Sj9aEw!i4(O4MY8Zmi+A+j@j^1n&#wDG50G8(O`0ks8`m2dl<<#jx;~yzgJC3X+Wgq$bZDjPKQ}mN{$xVIGa%gwJXOC@w>WU z|MF9@_2(C6J71|T6eHc)m$Gj)`a_flFp()HYbiZ=3&_K;t+9qFSdpQkF?xwB^h+jY z&gbO zG@HVI*`PRNOuf(KC_Gr%mrkIIBlJ^qA*lW4vHq@!r@_D83O?ZWoQL!9to|a2o_Xr{ zg9iwzuNQl-NT4S6(ac`iFBXxSC4s#ESiJRp}Ops(!SvvC7gG9WBy2KL3Os zkIEWI8bfogM`111?L5~x(v=F^i{9+?{Y|y#BLaZN$CUTtH)a?bMIS2Yf!MA)e{R$) z)mD`IhQH@bd*ldd=kS%8O?p#g3g%3iA;XD&)Si|hNlO?m4FZ)2TlX7{5^>9cZnJ7O z<%_4r5u@)O;4Umg`N0_|Wt5cox4+lN>DE-%b0f{p3d7gljLOlc$BAES2#XtOL9UzK z)?+6K(vqP4M2GV8`DHx%HP#r^-QGB2C%1IaGyhR3g38qcpf{;31N^qa_?<)*7S>X~ z1KvU~QB!6IT}5{}QxaktukkQjH0CuHaj~$1nT$C|Ynk%z3yX^y&BMnkZ)oiM1 zY`zCy3Dr>k%+r$p=oftE6?fZ}E!%c0CrOM=$xwd?wuFPly0iBc?~CIXkEiom$^Ov# zYfq@v6K)x*ztgX*AWY**wiC{mX`6NdJ@dBfFrA-`A!s9sjhtP1;h z6jYxR;fZ*XfvLxq6)px&&dk$Izpz;%Lv!}x43merh#o8C>S1R zYHcl#syUwYG~2b`Oh;rqt&4Cw@`io!AOk>q*u-jRBabL+e|Yy+!BR&;OnfQ z$6aBoH~T(Xa0`-oQ0){=!a=7zMTHDxaMN`gWna0!iO|!N@o-YHB(Y83>Ngf#nrxrg z?JR8ga4{GIvs^A44{SkRr^}AeHnl@!k(Td01#!LlZeBPv(x%a=8WR_?l~|gAejgO&gw;W@m*? zGgdJ5(x8kn#o87C{o0s&Kj2d1B7b?&d$6*0RzP=EUd(1mc@Co;Vb65kTEZXe^HlmX;RuVwB<}C$?ceIAg=8EtF3-KQz>R{yZFhPtgl*HZaQl5eJdQj8pNu^R=yz{da#Ub5Ay$+@R{z zj7ikdgR*YJcUkxM=**U4{bnDky(^EroCK9EVt{M<+?K)5hg|> z5*qF`Mn}EVK1ZI4dX|4ot6xr5uJosqu$#EXN2{GiyIeeJI%3`@izhnS9vCe@MvV(w z(8N48iR@=v5|Y_RB(TYmp*bDF9eo8)J}C9@<(lRy8OWn3OE0NeTa)3xB#wM-V7M4j zxa48QI?$23A@T;3vdpLz@x{#fI>1TyY=-A&9?OD%7xuWnb~Dd`WDS@hdmtVT04HxE&;o$od9C!>c0j0nLt zRO@!J_3FGaKq2D3s3-fR({lAd7^PgYfgJ{_gcV`5)+7ra|HBk1<$Uh7@Jp}FcFK0Z z^!cFcB<8m=!)1@Y2mKB=^Lx{QiR!vWStBZ}^-BOA?}g83!;X4LjirgXxpTCLUkqo^ z2|qTUOD*ajJ7PJx2tN*ta`*YQtxzK7MfZIz%I@aF2U#5+e`@?FtEV37e7oxOL=KZW zF0HOt=N>w>u8kIL%Mtu3zjMtkthz}IMmRt4I{1#XBuCp>RNe)YwqKhKFe@3Qas{Ru zGoht@moY^-DTw~;%u&)G#J@9iE;R-1dH!l-V)`>f?$3&SwWeN<)dSL|DYvi@KQ7ps z8E!1ww2Ob^TSPSJUlPpx4?i%O4hw#N&>_%z{l3q{Vik$AF-CEjJ7D-oxW?sur`lhB ziG3#Em&}u+)WAYXTI?N$S0KRt@jO6;m^)Yzn&mG_1*RrHD+x1gY-qp(fEkCtu_*^g zaFU|f6!zx5|Frc6RH{zM$5td$Wj!#fGsq`5*?VkMCF+Cu@)JgU=4HISxIp1W47os9 zQW8-Xw}nmqt*j3+toIRu@ubvD6Yd=P>orG2jEZ*C($sV$pDdAPdXk%$OAsYJW;Dw# zftxE<4KeRa@*NpD6;fw6*1q$%8Si=wo=%{xoujg;73*s5zlm-N_E9omF&oQ z*@{zhWwXOg7F|peNN(uv^QL-q{zYK#t!1QYlO8edG6_G8+43*9tq&sff(KX6Ltn*> z!FlMgH%{J&cToQLPP9^BzVqwp3&>WfS46`zy0rZ7#*@CVbDHVRU}-ICpy$&tSk)iJ zeVSPRAt51Q$XjuJ#4ystfov=BArLsSaTr$yMPhHnJubAPHw>cJMbcz7Xmll}-~5Eo z__ERYBBdtnS$>3d>h)N6UjYdO0wGW|o|Rl=|G71%q>&Kmg^EizZRo>R(!5Ck2a-b6 z$$=yFsvmD6277^S?tp>Xqd0Z0$)^7(yw010S9xULdPjIkPrUlt03XgdBLyTu7$p7G@0lK%@=IRY43{S+{tOQ%fT9`83ZTLKi0gI^> zA$-j%hCl>Kf5$okV7^?Rs_S5o|SIZd9BkX@wMiwK;xK&Ea?-P@zTK zH_*Fo1cPGsfGz}nRFzL6sO7d*ky6ns=*5{WMiDHl})dR)F1IYnLa*xQTDN_c}f5P~G01!)?@B6(#K+c=*QwQCuv~ zGV+KNT{(WUr@PrQSrPpaUXSJ~OA&7U6B{s^Py^B5qNumJYpdk#4S=n2Dva~@`!S+} z_d_On%_n^Oew3_Q;QhjY)}_RX&4m`6I~{xk+vI$Z`ON`jTNCY%cZbp)S`o`nB*;*9 z=4#EW>yIz?V9RpDjZ;p7hJ~OPY@9imt^P>^Br|mC?!zw@s}QZ1UG#G$t@c8X1n!gr-!4ykEen|0eF3f ze%p(|G4VnYfXg|r&JJK8YtZiS{V_-5wH<-z|JT*LeIQF_7tjv@Lx&w<^O{FYY;ifP zpd6(<6eO2wZKopH^M0rHdSVXcydYO`6lp$+pZqK=EpPR&9sW0lfJY>R#T)?I;=L1n z@KeOYE-gKswOBBbStS$-mF#E!E}&kZ%$%)Twb|7Peuanz;Tn-FTZWXzyySKf!8VJR zR3L<{pS*EAk*ojB+Hc(uh}Z!+Gm{l$c<)>((+iGze> zFnY_jtnY`sn2=M55GX9e$ifmi;oK*J{+etbL1X_QsAa)Gr|ng`$6ZW$Qy1h{uWXTs zqb%1gx>_U9qqihH$uPbW{CSJ{iINqaKXE8@?l#?B8>jB^>ONdLFm*EndP^As8E*n8 z#TG%2Lv>6pbkM4R8ZGvp1o>aO$A7|DMw2dNKr?=Y9?s*0c935pSRJ_B&QG;FpF!$}mkPKm+bT9$$m!9WD)tH-7;B0SraU z7$7(;P2ON=05o8l1{Re@fB*B(=l?Z2__9gcKd;i}79u9|CroEFxsTxICs^|~e;wS# zL7+Y{!*fgnhQ?w6Ba?^+l1%s#L3I0NO$Glew*POx5rBaKl02uBb0MmgY=1xHP6OVt z9p;z>Is7f{Wop}~kh=XaApXub9V{D|rwf=CZI^@|@BeM+GXfZQz`k(J*$Dpe-G8Pp zAotdOjJc+~%hrRl$=#ql#PqiM8O;0f<}zqRi!^|DsN(MJMFg6Je0oyBy4BqjAHW6- z$|r)~oUz|i`)?C;g$!7vV6Cs*Vi;uqOwc?XV4l@IFzb0TF2|q;uc{S@Tag1J58WE7 zbmfR-Pc+avN2F4Sd+~A2>pU|QCYTy0wce(zb1^xX;1uEiii&Gai+s#Y+55%H+>p%2Y0&hqD zEfS0d)1HnGrLcRDiO0T!gPBQ07)@E?9=KBRKTSpeGUJ~`)g!=t{2%oF$u0Vxkd-=a z1A-nz?t6o1(Z4@iB?M!i-K|7jL{|O!!6byzy_|R`@XsdxmkBWu`)4bPxkWMj)q>wn z^yAbA4o9mA>Z0>61O78FZ~hF+8HvX5cTedsf(>5ZKQg$%-()QtnEHAx zSnl^{2e+>DRhUk&BjSB~H6Cf4rWwp1e?8Q{%ro^r^ZZV@C*kir-_9~a;H|7_b}plD zA54Xb)vbXXV(xz09Nfv=(@l@YZV3C|HiyEWVN<$;6aKyz$8X-U#k!?CxgkHG_w*ig z~?F2%alk7A`m@fC8I-Iv_oRfe?$A|SwDU$PT_y}ywzaJPSq7ydhU9d^)p`2?DQG4xIh?ecQ7 zYpE+7qznnk!{>6OkRW@lOC~Q~$d^E_5SqRACela=-3fu4XmT^dVKfoFUDmI3Xe%># zDgW3X#(&v~qKKDQG~(fPEsb5&e|aopvcQ}OcOS4jHa9FTnwH-O%S(coC2yW zvrMK-(&MwU%WDCq9%H&OmaAH%Ve_?aM_UL251778D@+GdV`ml2`jH`^lNm*E)uc%v zR6v&-LB3gStmUyT+`TF|dR#a@{;b;@Et=t9&5_C4KZkmaFsAFDZ)DPg*?K5o&8Ne5 zYp6lOPEbG7hmspuXEx+I``H0ApuQ=2L*F{z^3sirZ&jK8fQ>0jis>OIC$Y4&w8_PB zDbQEty|Ha>2DhqaH{&-9@?hy6y59e+8SbFV7P!Q@m>b^yXv0?OzxSH#s|E_{?S}ukU@@fZvP441ofpm=j1DQrsz8k5+q(mOZem3SVU{5rt>J^qd&*5h(Yu zgqIs=2@ia}ppmxs&UMXpYFXCDd0bo8?=>a9P8Ab8hP*=}HHB%4{1;*Se|Lt7+8;ae zkX5VXubaHX5CCdm7^2?>KiZ$mgzT{~(s&Wfk&VLc_AM?_eS@rE7Xr%S<;9-x>29;r zT~^21mz+zzbJb>+a5#r|B#nmzB_^hOdyQZXWi6_9Wff^d>It&^GFQ^>`q~dkt6uXb z5z(P6D*VkD>NT2yN$hC(im73jEe8Dq0|BSq8$4u*(=N5t21o-9&FiVAn59_hEcPovm0_s$#?jvhzmyWm=BsCymlo zuCM=x^PnVs2gQiFBO>|l@r`E$fv*Bb4+)T{5w#^`M`hACC!CGGz~>ik*K9 z+0^n$NlA^pmscV2-~Rf%0kmkECrJU_nb6&Eg&}a0Lc?Yp)khXg z>9$8H8X>}1El*SHf;VezA9N(g_booErxj$;Cu5p>`0;I);l08wQb}YzIW6;$WN}uG zkcbMCeuhp?(;WJWxuebC>gr-1y~e9wKM5OXs8MHSw=D+|fHRzx$NAw;lmi_U{ZXi7 zbH}GyEnYommYm*Wd}GOiWz#vlX=F@La_JjBiV;13L-4=3Vpu2uP-n0@Vq^aJ_kbAi zxAx~}?vj#7_kTxK6PL$%78e?Mr7orj?NIjd-b&uvD}dGTJG8R0vI?&gF0=8?5+i<4 zsvPYq62{8FfJDOmwm|!y?}OwJX!P+~ad}E57dFLl-AI|o_E!vW*gFq)zE&bVbeJpD z`UrT7Jl?;^NZMUi9)mJ3RQCEho?Fw#pyFk$YOA+L?ZMBVKjBv=-#a93F5jnU5#V3? zG%(KbeZXd6c~Pj_M@mUasaqLzDO%y*RtkDd+BcHdZc3i5Yjvur|dHiLuM_7^D1H=EthRXI>a3Rb0mHH4~sw{fJKFODG} zQ3dheb2=?|duy=MXp#>`(x7Am1DoknktLykB)A(4iszl>^wVM zSDJfZM*_+J_%SFv9L;S%H7yOjv9VFLrx;TRUoe0l)Bq^fF88LR=XPtY#Ic_UY83fE zUmVVxAlakYb{+US703v9*R}_e0s|fo>ntiny1?%!lyBo{$~wWrA6IH2)6qE4RA zto+i5Xkn?dUEkEAezkdC>B=ATqjCy(fu11-w4V&L72a|i)7{}ryEojFPYDMhoLk;f z@AZ;9DqmA|f3)gs93wjw+|G4J88v5b6i#r}>?kinJJoOvA6h_+h)@h2lV^2)m*o4j zO+}+CXZl*TR5}5rEx?u-+BJ*uPSh85y~|v)x+^%u{i~b8tCIG4Iy_OsELw3+thy}h z=j`g4zw-Tyy*aKq?)Bxvg`QJ4uJ{)lA{DBAyQjwIYSMS6+RN2nfH`@15Kyx%8lj{V zo<%B6C%~>US@y}($ZiAEsLYa9xEb&G+dv4jCRMJD01Lc$`^g-O)?M`j)4iR(`1FF2 z?Bm?ZdZd~omz3>i8n)t;puuiBGqKHQ#PZE4JIO;5PH11jLyb~BV%LcLfsI1zTdBkK z`4+b;_VfD!7S_`x!h{K5y5D!dxi97ix*ek)MG&j``1s_^P-%1BpaCvBTgt(kWHZKp zv)qB}w@wr6l^8;BXS}`hfk1=o8Q3b=+%~gJV{(8_&*6h&zQ_44K(!`cc{SfjTv)P1 z7be#Tst9y~#Ufd4B$ps!v6q9jWdfFJB&Ai;ZFI~Rnn5x(LN?hVt zSczKAcS;;lpeB%R;fG(gzAwn8rM+=F6Aw*}b0Mahdi9)|u(iECT=PEVJA(D}mATG2 z01^v#nl4EpdI_onlIB?TAKoAK&<4C6E|}B!!srSTYr&sNM9b z*KQbaSVA|Wxy7}knnQ*_ZAokZep&9`5m>|jA$U{=5@tTycF7XNKcLdlQ1KaC6*QhyLm!Wb(1!kX% zn+mXoC?=^F29qtZ7owhpM4W2eSCmcTjA$qdvJ)mzkuze)z3i(y%U1EO4`@mrJT$zo zQsR|ds~urpXrd@!;1hp`;@KkJZJyL}=oG-Qo<#w0#gU=F_%w?OPz@@BK+$L<_PC@S zAH#;nZR?&uLZ&s(<89|aQcgYi>ODp);?A80%8Gh+6wablBvN^l(Po84o|7j*V}qP_ zr7~138#AgLn1`;FXw4J(P!eP#kFE1gKzKtYB@HF6j)-uMh>b;%cXh->N5A9cg+jr0 zpa)V8b9XUN^i(3EVJsHdA)(&_In1ag=jX9(r%UoVs$U*53;Aw-aLsn?=j1NB>-GOE z^WQ%T@jzI4n=yFmg>HkoG+()rApL zQ{!a6I;do<1NA#QK&2wxxj-Z|*u`FZ;*hpMLW-+-X*pCeIk9prjOS_A6!obu=m@RCYRyuD82}2JvT_)!lI$*>cEzK0FYweTp1bHd~&;MQmytn3}r+$_$hdVwoH7H20sYT<9e<#9m&O z;tcIDE@sPpO`nTO1x4+InX$C4la*w>YXt6`ROOrO7k^XDHMmzNaWxwLMyo|94>p>C z@J)4m_8T*@kyE=EQIqFZ?_>X88_&PC?PxP$Y<_z=kYoe6*u&j@Up_ty{JBB!XVJ z6<*E(HAxmfo`Mp1n0oi^rExAB63#&tq1Z*p9f`Mi&88g6v0VZTP12TvFX%@Gf=_0s z2{aF9p%2GCXc0dd9tfQ#9=rTy*duFRrj7{iP9}I6ImNJI3rA# z5@Yr3Y!5&u%G*$J;|@UgK5Rm9O1p`Jya8vl|D1;Z3$h5n1X#tb?z7mP#_PW@fLnD2 zSAxaVbD+8dI9n^!#W_V@^8UecD>rCg>@b*tVgzKP!N4B6e6Y<1wA9;DVhwKVI7;tC z6*yak7&z8?=X7#YD%XVEHV*(*lDm%LiWYGq0!yA+1I5U4APK?vMl$8?o40o=pW}k7 z1eksJe`f#TyG9JOGTB1QOyL{>7r{ayl5pQ@8dt0+Sy_tSUxWg-bMzm7$-{J zZg})ZNlloglhY_rZYX_XRlp;BiHl-1%JG@M=Wi{5$Xuu*0-~^}F&-NY*qU=I+DqNT zPm(F`AnBb+b&(V6UTR-(MIakx_MITGfRdy^+On@Q^mKuJPg>?-#nSCW{IlU3q3oRO zq>rzib#BEaCC`Y{#@n&yxt;}TKlP-0{ryO_^y&^bTH2x}-H1$JDmk@Iv!|GlkO&W! z5pU%tV&g>qPSP?5E0&>j;B@SF|8O8LDiq*@z%x~6W>R~~bz9YdOf&7kHs*i0lOz1I zqp_M|Gyh|E0svflSw=T&`~LYYfLd(0AjC7sEGcKie|b^f#FVs5p8gUf>j=CQ)Mw*Q zfZ!a=r#8iP1U`ca3_7EG393Dt0&<^yvw7dM58Fg_zDu1i&63S?^>oRl7WqK?`ZxJm zLM}n}+^PR~3x^Wb!LP0(T#ia_?KUMlJDj7J@n5Q z`>Lw(afs#X-2kn)6G$l=9`7no6PU_Z-3>OV0^=t+-6E)>18opGxL0><$Sg>;9WGF< zE-<*@rQG-Q(nekBm;sQ5#;Rbtm9yfT_<}qTLL$l&(DQ8xRW*{4ZJ0iG5 z-cRVci?h5EClLs`;Z!b`>eqKpm$n~#AUOMLev{l>UBg8DuyfphPQf@Vs0DvOr zAq_CWQ%W0o&!vzK7}R6ze6c-l*cI6ns1{@M5e2hE7Q_^kXDSsJ>`c9 z>f>q3cD+F{VrBj0{Bxowuj7e*XxO(vJMHoawN=cT)f7?>)c++c;9LV?!O8y>7R29{ ztszj*qLTYhLaD_21379R_lCU(f;BW~{0Wp9Bkesj`dRl#Rx>m~$70~~a3B!4NIE-L zxcY(G$+$GH;0T0><4=?kxidUBcwD}m#(Y&a2Vyj(Y;hz51A~a`uf&K%aV}d zN_MlAqp_94wpZv4{!~ko(}AWKI0Ilro=AU#_ba>s5ZooZrg*LMm;I0xYL)L>(JJO*1s5!-EUJ-LO;QA;L8EHdO`ML<$ihi?^=VEXU#4vodLmmI z2~38`fb8BwsAD-=X8L*+S}{wd_!ER~Ows-a+gr|G$!=}L9ZCuqsis}ID(HmMP&10J zkmT=C+MDU5=?E3SHRNL%tl`^V-#s^Jq7uE zvdQJEmnQ;c2VT@KvquEt(vQPqWdW?Vw(Fs%EHlpXm1y$L2SF%|*BVQFc}2yS8S4~dJz!NNPb7))hYS7tS#l} ziZe1R=iestEDZP(_Y7RV;h4bAw#3NFNKpPFS1Sk4(ebI?vGY}Oj8^H38!K>S&Te+a zhDq*$RX5$*mn;$r0pX!EzTMMXUeZs@Pk6 z1N})3GGp-3ge%FR@NP#d6U2T{+Y)bjenHxuEUUd~(?OSpp*Cc-U!*iOd;nb!_aV8> zv{Cn13x_MtA;vv2H^i{3iO|4# zMsH_#_l-7|#QLtTphWSSXBDr?tS=MWN#%>mB99;bue=&e;OE$q{*qS6*Oasvd7rV#mk3fygtLb#=aq=`zG+9;cKV6}Hl*6m+32wSKaxY~o`^ z*9MemL1w@^H&2{0G+=bQL_;*q;5kH6=d*;my4v;NZ(4g4U?z6I9V&J!WsSlq#hab| z5x8iX^1&-HdM3laVDCODFAXoEJUdYq5yu=&l=9r68}^!)Uz;0>a~o1Kt-)^SjP^iM zstUhIB%93V8Tx>0sBaG%IYM>C7yCOPY)Mjzp(7L1r@n`8;es;zOb$m;>>CHh5A9wS za9BI!qNnN1HcnpN`{7-L9Zhn5s*l2XkA*cuTIKU!L(o558~lPj@g5AwUm#YOkLCP4 zlIxG)g)hw1Ti);1s($s@WE_kozS1r+QwlgY-8}LCo^_vc4KMU~=YRht>t+BQ>tU|S zK|OKOKqG*Zk#OOmUyShChU>o769h|6PT<`Hyr*^ns*5<$xqdjszD33;N$ii> zwipzW>pK_G_uvD#juCO`??^3LC~DcgAhXXRpYPP!=SrI&lkT*JtYQeUh*$gT)6i8C zd|h|WdO83NyU?-zt?9c*Ma<>qFO4^b@Ut=5gX~RU+!8k~%KHUI54^S(6e*q>%uC|3 z-LXOCh(0ZJAbsh4b$7P8mZ5y^yD$3vceEh_Xky-`R*d;g=|x59R~eOcMYTnThtH4R|6GHM`U57NG##DQ#F7)q0>QtbX7cgo1`m?fLg#ij!z- zm@hS;;t+>bMQ3yZQ5014FBi*ZUCPqi9hjUqZr0_vs&m|vLh*WshVH08_i+TDoUFn> z2)D%c#AwuNGW|ezA$@7n zcsag$ec7mDtP~RG>JL=%DG=xsV)zpKC$UO0?xT3^Qvgg!e@dw{GF>aP?M@Qv3>jQ) zc;$|OGa#B4k{uGfAiolh+(JaCXC~wV;w5`3znIn_0OHp zy*MR3Nl~>hOrFsO07;?~%>>xpW|;S<7k#c=Nrl%tMksqu)jz6wCh=$>@eaF1L^hu_ z^8ZnLiqa#g=2oC{|4I;u?x^yjGD8kfEeWV*PiteI&Al=*pyhNo!s-_N^6xxA(tGbx z8F`(CUsr4p#+mXHyvYM9)XeLH(RNM9k#I&OB}1YB`JCIRHL6%PFY=Ah(0PjwzY*k7 zeCGZSQ#z+q)al~cg6vS|Tczg@)VuPsc~@@p$#+9^$xDC&QjT9HVbnca@c&N=JLTmIz8vKk zQwmr}(2?9$kDa)vSrt({w!ebQrHyaeq(bi6= zhTrGp%`jNmOl!`A+iG$tv)7O!Lt6Cu2{z&a|zme_Cm9p_~ zIf)LQb2YyrJG1WWpNUz4A`xpeMo9FdK*^4!@U^Oy(SFdMJxd2;?}etSwvr_&^{2N{ z|EWPgbyRfw=YlmAnT=-)Mj|ycQvJ&So$eb+=M9-jPDfI}ZN@MZ?c4x#O;`?1T}~T0 zN|V%?4F2=4EE!aX3o*+*Dr(19$&eySxsNgNqxyb8bcrfbM3E&{8>oOZ#mhj6NX29A z2xcV6&xQG)3yG#2pikgF&liViPb$AS^EPe7KzrKQbe6&hXCyo!OHuWefL_s1bg)O- zMP_YWR4tV$6h`5H3&B%V1?Nl`^V^m(d(OGWjO5z0s-h+n6S7-82T-S#GGgO}>>2!X zIpgF%^Y=wT)4w^h)1V)wS)i5yTxO(kQ>ZzTmY+8K&!?N%WrrRbenFlssb|Y$H_Fvf zOzTGFc^mqna5!%;JKoa8KvGK&_HEertPq@LSm@$`SS{p zp{Qh^dDX_(h_)`LZ;TrzhT_GE^cJxys<8&qC{WJ4y9I%N$FpCAEsB0F6hZ>Et7nvZ z#UNMfC{Wp0F~Zm4zwMxwi;% zkq;F)r_dXz*Bf-qx{sVUQn8?IMy(NOUO1%JMBJ4}EvJw5^Jv8TqHMpVVjyNN;J3WG zSel;55Ja`n#2-|wZGv^!H zQE@y^3`Cuf`*DiCxjVu2;1;S@c_~>G*mo+<(Guj8Ax#R(f-m^8R`6gk&3IVIpyS%T zgGJpB`T1R2-|ccH+z($BZGMGcs8MbH$ji*f0TPD%@#F;SxOdlt?~|}5aDa+Fid5TG zEXf)1w&T(dra$N`3fdjgmwcY(codudH(k!PYK|Ic?LAf{!ostCOK|Jqc!|^XTQ&tA-v=htdcI?cUrG)?+fSVgLc z;-mA>+Wv8?b=@E*$W&;ya(d zf{`OR4jn^Mp_TxSA+MY_*Kc7H%n;vLZ%GRZrLZ5VXWv-i>TXeiXkK^KnSbynTcwsf zf4uG!COwRE>w1HXN_S!l)HNh+eVBZgo4nK~DK z^hd6RiiDjC-j{=e=?c>)eS??VKSHBfwP-gNIwLtmP9Kboja_kixJ^5}oi3B6G<~a% z#j%r@2g(4t7rx;Apu<|>0qhmG_r7$z{oBTVF$vLk=o81a)@67Uw|EP@&%Pm=i{$7~ zEUV~zTzs6~>wPIt2yhuQbkZO$NP!!Iq@?A|^IZ4p5AW%F3@qB|H6dV}#(jSG*rLtn z?_)W_4-U6hS!$1(IP`~BNbc=7Gw8P~X^8}Hk}i*p@n09TEyFECTsr>dV%ZMvMLRC# z7sM~r(A2EX6{=`Ox3^mkiE`;JF^iQud7jFuRxnZ>>3F%Yrtymk;uQ*XhB&W2$uMb~ ztFrDA2ROuB_8l>EiHqUS7Ig(!)T}E7zof=r!YUvDQKg{8jFPLBAnLI`iAzki>@X1Lr(*QXELltb0hiB>mV#D-TEM1P8k)oxpf ziY<82gae-}P0lS?qK@~IxJ24QOEjl1{BXoiQ~RbDv(tS~$cF#aivTv*t97?&_KlVX z{B~SE4buOqkH|Wv`Hg?>xxpy%0)^D#z22oP39kp1D#$|@CYEB2&O7ZYJL+(H!OY7W z-Kl(rU2`VrVreU2Vl?D3S{0)0`rXg-xV)jy`orTf)!Yt#*!Iq3hc0uE!?-XUU#sQk z*J#Ckwb1K7ImqdT6$TsHwk$B`;D!wjtFpi<8gilH-&GLaNcmKcuer3;V^O^zjd{Lf zygT6r*?1jG^vAGr4VjFfJ2qu0wcwmfkPxYPFF5r}%XVf|(oW-=gAOwULJC+U_byiw zRhXEge1oZ8@oFR4@G0TMaKcFB@Fzjldc5_8qjIY3M{2dbd@_G4Uh~LEwNwfU^mhC9 z%AmS$u*R^#j?Y_5dotf%e3V0@F}+wJQ-jp!Iz!Q_W&TOP15_2@bJlBC##3`7=2y>8 zBN~ZlT;pGt*_ejf(}kCvu(`#ZiyAF!YW=2dz(yzXDp zyEN6d<5YtH=2Js!BWu_*LxX6_Om0EI%^G>@MmLb2Xz|8bftX=CB;y z1l_VbO!k?7SjBA9k>sZ`pgUqfSAf${-5Ie_sI1d;m|}96xI^>53>x=2TGfj`xTpkV z<;GkoDeFtfm?2t0oo~BNdeai!k@!B(F1HV+BVFbV`+FjZ!fuD{A>VGTs;^gX`mU;V zoKAQo1#j=eRoZOOs=SBihQ`fUnkgKrG@pNObbxu+CNY?sw|g_xC7j2t-yC=20}xB- z>saWC@AIDLP%Scz6nS7U_F!qgd5g`CsW~FfAQ$rfYU3gG^I>^>{;yp;eOHoVB>PnA37i zFqWrMB8trvA7Nr_94gCEezz1omi&)ucm?}R4I@#KRnC(IMQTu7aVR1_%SR#U^EaQR z)x~a>^w-{spiW)iN z=uJ@gz@EB*cj|;tCEA8vrV>u=_ttjbe|@x)%Oz0VP5x(gA@d)=E(;!U_j7h(bAUYH zn=)fJ-9;oYA*jw?E}4Rk<{kq1>|I$D12WZ=0_9vzvzaF&Fz!nyJ@0Jf@MX9%9?66j z23bm|X*WkOFB79`)h`$3=WCrzpB^S&ex{3C*^_Y3MsFyW#Ms)iX~@8k5w)_gBLsP2%$?u^osn&Q`LYf}kP|p!SkyL@&Sj+qm0Xfb z*vr@07~cGlmnT%l;>i48!WSF^6b@)rGTNkb=Ktj)P(xQ2|N0&0cLPI1ZQyo(Jp>k!zM82i^_$zvmm*%qc0T}47)Nj;MO-gf zXy?t+ffZ;p=tqTmnDB_-zeGhf6peEr8 z`)2IL4IC{mWQKObwdK9N*F_?WaF?|jmj72YAkmz*{N6Af^lbT=HWp}@#UvSww05r? z-fCPoxcu{ms213gT$t@1uLhuASR}`3OT3Ohs!A@iuVU^Vn6tXtE}n z*iK^AxGh4VKDO(V&tZ;6e1HnHo5enWtt5h|X4kE& zcly!{IpV)Uv|Z_K7CK~d$2|ⅈEjV0(FKLGSzUqk&JI&&KHpE5?nU4_afDD6g#nM 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%0Ach*bYFfd=TYiDbCREgW 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

|jfkj2@UgR) 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 z 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 diff --git a/test/integration/consul-container/test/util/test_debug_configuration.png b/test/integration/consul-container/test/util/test_debug_configuration.png deleted file mode 100644 index 8fa19ba9399855fe8a9b76c203cb0c2ef09c3f0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 294046 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

h?A^(vY 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 F{{U`(riTCk diff --git a/test/integration/consul-container/test/util/test_debug_info.png b/test/integration/consul-container/test/util/test_debug_info.png deleted file mode 100644 index a177999c0d95a407064d4c3953a823fd136a3d35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 622325 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⁡LG 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

ef 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

fUdD_vg!>XZx}O|3ZMo`EyMFc>b)* z5|%VQ)oki)G+LB-28P9i49)*PyvJQ^7OCxm`{$IOVNZFsQ9^DHoHA$ZJD-1@@}sN3 zIFxQ6&;QrQmHhR%_f8+zkwcjs>-qsv`b}b`xz#)ri-iFUIT4Wn2xTmizQTkVo3u2u zI<=iv8iTqsZJ%jnG=4NYM(MdKQ2hQGY3i?ry_G$X{4f7Fgg>T=b^iBAuvf_`FkeTk zR6s2>FdWNwFvqp3br0!=pQC0}h`XC16U%AlygZGAocxqHT(VP9H{AXGE%ptBJp$h} z;<w5wjdaQggj$!)1kaMEsE z*k_t9CT!bL*DwPPE7LJ4eK5cbF0RbAgtmc{&!i=U(xyTZ)qab+AXYtJ zOBz7_cR63?cph%Hgu62bgYW+sdnT724PPCh2R>ll#Hjbr$>lnPT8y0u0iejOI%vz5U)Cm-lp9HuzSgKPxiSOT;$Y*6%M` zx@~vy)|CfEy$4WlnD^0&zG)@=aI3^|WwB1iBt40IPU4Ku^u=fFV!jCN`Ms|ch;VNL z{&Rm`%NJ@Ky_5YZ4?53W0-UaVj(V9F^5&zmf1K&UZl|>VY9*Q|WX_b1mUbRF8_NC?CL;){k zJoB~UHmBA9%V!74-)Y)^dhd=e5FA;j#>bM$0r)A)arJwHwF9Nx>R3hU^5@yMNX85R zes2xydskU^wD(@(<36)I@X~)>rq@A%9E70xo$Vdae`z$T!8H0WkpaIrxRd;I0`}Mc zoa`Tmb{ZI6NwJsG z!zzbj>oIlsZij`@FYC0@0jA(Y4FI(0M9^5|$ZOncun*>3b#4Q7hYV=Y@7f0bq!k8X z>2f%r2DdGu`TYiGuA~1~r|@v`-H1xs>eEF3(%V+7j$W ze^hX@en^#mIM*d8>YlQW#X#kx)l{)b5ID*nA^kecgZ;zp9>l5!n0IR4`}t#zt7d^G zKflLr-s)J52ITFb5}5hi^3WRL{c;Mr*Wok_iB-vvk+ng)EQ22BtqGTvg$b9FY%fI;NM6VDB_>&v?U7(Og2>e_bgBfmFWvq9_$OF`u9>f0eL31H>@j+eW49q1-% zkDw0%Z>4^Fk-jzAWs-iOJ^I1es`v7jS-@r*uMAy&-e<68N$o%b9c{^NbjjB$AIZmeov$Wvty0@f{fb{dbr;}1L)QuN#@hWGSlp4W53kP|JG>bShh|Z| zX1w?s>-kCEhzo9oDR>zP0D_94Qa4LMH^;t1Kayq=xk`H=2uhzj*$ z{>_L@Fn&ev0>N$Ki28GDrMvHWWx!99=LM)#jMIr{m{2e1Nd9L~r4jh$#C3l;@o!B4 zsb*dwlf*{TALt^zI`1~Rlh;+Aml(AGq2p~ot3qb{^XsrU?m+j{hmY{J2NX#F5e9xL zVfw@R#-N72e17l?qU{lJuiZHei5xIh(F`y|1q;flUivI{e5g|3>84twxR;U3N=PMi zuT1;k<++hzkwq~~>4n`^x=<;A?5ecn_bh?V`7p3SR~mRQdW`}dd(;3E6VQu{e2X=h zt=pTl^bH2$nurdzn$FbuVIrb*nYfTLS? z;C&)U2PX7eI#b0M(Gr)P6?mweujQ25tq-RXb^IA-bvT2!Z-vg<0ywJ3nk3!%v?pJ3 zKr-+xbvxJ!hf>BfZ+~v_?)6-vh{e}-hW71(i=I?&KXF?0l7{sXX`-1m2-|*oO_s~+ zxqg(C!Vs1sG)tCb;-MOe%(JNlmBX3xmJhg#*2kz8O9Bp8ThR1z*<&lnk68-I zhQ6K{OW~vKk{%Ju$IjKGkc~<9banYsYThvDnh{~TqVR<^FyGdZ^o)@AaV`E8FB;&8 z`x862zMLbvSCgeG9_XF{IMU(CJA2~}p^nH|%(b200WMEIClrWuxe!v8g(rtgpB}ah zt4fK2iM|#x%Mqp)OJF)~Hd6xp!NCw9d~ihr;+7I2(VUc813of!Q5raXSLvS0fL7{- z&iDrmG#Ed3(qSzw3Jn^lHV~`&tX})5m*6DI-*N#(Q2CtUf2n2Z}z z?X0jkDt)L-7J^O_*QbV-KCai@%fBsDIhDtvi!rSFxJzI^tovTRQmar-g)EA6*67K} z?GEz}^zg76#8!9ECNeV8&)FTbWC!#DQ7g3jt0jtlL$;NI)iZA>(sd8ay72B?uSdrK zj>N0?O}eOSZ=IxK6&Q@!6+q(Hf)U5B{`&4X4EOTci?0>Fq#77vl&yZwc*GYRQ>KX? zHu{P=U%bYyr{lioCf$7kRX94ZFmS%zUueX)hECP@%i=uy{MzRLlKkiMz~1hHLiY;m zoE}A?-W+-O{`RcN=IoOp`qutAqfqYH7{xMmYJ3seI{jrPj{&^Nq)MPin1wu-`}Zgv zriz<4^=M^}0gq@kb-@m37YV8PM{5JB%n_j^-8b>End8K#QyYV|G~IYNpH6QYqwX6x zlsvO!WcsnOv;4q~51x4ND`Pv?&KmbDSN*>E$QBa>+7ul%ktsqy{z-Cgz-H~ah({}X znU6b`MGKe)k}iwM+KP>_Tn%>ffn|jfi_uc^oM@c276RkbK&(piBPS~*f-%LlKNzA& zDPTV@wLN~^ViYQD`ZaK<+Ta2yXji7?Hrd_ITu~G~Qfm%zk}or&lodsVNyoD3$}Kbl zzyIlM0A1%INT)mILTg0&PGa!QJ5xn_>J!JE$E@u;?w>@UVF{gCsRa?h2e3GK0KJeH zMnU+ZB5~_eY?a1C#f4U4ul+u(=Jx&QV1sKD{W9btqrlpGBo9mmoE7k=>ZUyjIgd>? z+^$fdh>hl&_Y#P;up|;6rvgN=)4ZeiW8-|t)Aya`+?91+y$ZG?TP_lKjP)nS9>~!Q zhh7YUizMAZ&(fH!t-+fjkb6NO>DIk(9_rxkQ#`aoTRXXfo!f3dKjP)HyMgQ;@8WW= z(@60`y23=YJsk5xY15E?04^TVvD`;z0w$&j7`!$QP)d`ygw{G#uPS&-00@=15!dA} zk4AR4)%Ul8dKO-}ukU0?v_;tOn~-&KxNMB%Ki-&Z$;%auuGvvR953m6DW~3ch6L?7 zrf8_=-TU_L8X0<@V}GWFASHp{w5~q0=;bz6aWlWU7%E_@GbEO@i|M(gq2S&5Nw4ra zyWZojXG&_&dp}BVD@W_Do$T&99&_7PDl@B9>d4Pv%2r3}SmaCccH=Wi>widp!KX(N zy<2RHY*{rD4&6C5Y3|CDA=hcK;Q$-SklQf}=I{LmLlt=yUcHZN=NA)m{-?6wkoYqm ze#tF`D^IDtuJD7YL7=iXIL&jO0i5Gh{;6H@WQa=GpGY{rXH>bkJQn^)+{)!+vJ3MnXRJhZOXg{9vc)u~$Agw0HAHBXe z;gafzn#UKv%fQf{#9ty`xI1^DxDeXuvy+3zZ8uGmqfwZ$tS_{;F{S9W^CQ#L$|@SutV*WT*bubjx|CJWBwJI`D9! z%rYzI@aNH9y}Ws>CI@F&Jt8!@@M5co$=!ST{c}U{Biuz#O$#0GIt&%Bjw9dZLagLMrFn7yp=v{uAVA^m*_U~GT$X9T z66%Lt@O_LWaxgcmu*TgwOPoQLG_n)wjM*{Y$G}gblTl`{g19(h>J2A-o;%YIeSk7E ze9nUT9fJABTt|ecz84crWWjCvRqkv#`vG5uJWyE;;H6iC8&(Yop%!IeMk z$q>9Zx*Y_?z)&R>@jMv6iyg69u2zL7bpmEKr=nDl6k0HAyIHM<5r9E3G5eP%d3?TS zX;q7iFNS@Lf6j+Qr$*{L=8wr`hQy$T2g8Ecs(-lXo*Ydccl2x>xlHD=O*u^YsVK?Q zmCn|=%+IHiKd$xJx!LZ}6$l*@4+OKAqk-JOOu?ZuE_QI08Y-v68POORP9it3?4vGl z#d+adk}KRn;olwWE3t={&y%oTF`iP2mjt-YR_SS}E5DFuMx!A0){NN%Fir4QbpI$$mYGh zL(*w5n>*JmU1pgZegW)-}@&sry} zt{W3B;}|zBw+$#!HmsP^xG=#t7wjfukXX;LPS0nITb?3AAnuEfr1{TxMGmVOPL{D) zo6w%P*Ysl6Yfcm|5Z*FY2R#W-{S))jxE5+D-tFfQ``Lb{=xl$Q#43kZhM97FTPsSryrrv#yA_^q9#U%$*&q)x7 z0TS9=ix)MJ=sJY`{(?pvbH`A#A0AOQlMi0o1~c*6fC;LUcb*Hvt&As@YJ+H>>oGif z!KQ04FjaGN*xkJZ8pl#)B+HPAWF#(g>y0a+A1v>ewjh!j0x{t6-A*l zQz4+(k9nt|dtWryJILSRW%~-;?w0XV5euY%d3d`)u}Bod$gRC*6uFd6M30gw-=#@C9w9-_NF40{d`;5) zbT<`=aft^vjUE&eap=aeUdJa3oJRVwECrQc)$URW?vg0)=wtf;$dVwbGR!XDtJ9VMjOGsoNK0}ItlZ={oO{i;PVj=D&p%Q0`l+GMco?zA{j4sWvV^Cnla z;CNxnm}F{A9R*>1JerIsPpV?QB;8^u5cW`z53~HCdSEh>VBekMErxP zht#)0ySZXqU_a z1j7QqK!)v+V64ZwcdOdK*w4lbBZr8m4<1q$RLjZtc&aA5r=@yV&I*$qio`tsu70ME zO7BW(&lSAq{*pK@pd#gihOzfI1|oY}=-!I+7}FcvkowR^o7KhfAJAK|@|V;PA4RQ8 zHm`Ml#3rBor?~0|!&%N@b{#+Hx$ljEGlcZ0#EH|gHXp8(LX~eY3lP){qZUH*1hCXh z(gt4VqgnCj$hQ`Vgw4xW*gY?8Kau5liP_;*TZrf|0rO1y3v|b>s1Lmh2ZcmFh0Y+c z?@hTRPNU2ycKu1Yg(MMU3(B$M?5XLMxy%GrARAv0fbNK-B4Vqe5kCCa9M&ZBH zT7h0-(6T;S8ygLkJYTGe#gCI)99>wmUXvyR5~z^eJvUXFz+`vzX0hi8my2o1cvt2*()OSeg`R(T2;9uyTX zhqWtWw5+D;h5b|jC^o;zn8LB5;a#o;WV?-5tR2tHH3U#STsb+~@b2&)F6iogTG(p0 z&dhq^C*Y#nwx8m$9_?N+@Zf-elB;R$7^&fYD-n7mh#If3J$Z5q_PNK2yC4$uj3zRv z@LC@#PkJ3#lU?VJ9-hr*Ph{ zKi<%S)FH|Cr{W(_?YZt0wLs{1)JB>4KN_dj+-o%?~T+ z`p80@GUmW|T3V1%a9T6Sx$3HWZ555}f(9F295!9$V#&P%o3Ymp8OI|db!Li8YOPLe z?yMMbLwA_X(YBgN_g$BDp&W4`_no)Fw>eqGiMh)j@d#nPzZKu$XX@FA;@I|lG({Y9 z8OylZdHBK*24?8$w!c1RYkbgilf_(X4361y7&)rR#drJweM3qA_`)>kYzf$4Yb9@+ zk#Jd>+v%9!i0brFz*%!7Y7Y1(h(PR#qklG_zVy;@tLFyicQ@9l(AD6WKXu$`>nv!d z7fAtXEq4u+U7B9K8oZKVZ`QWAcWO62IkmzdEyZ*NJ*=-`dx4AxLaOhv#;sYk75Pw? z2Vm`bo<*UWu@Mn@%x;}>CA!{y<<{Efut^<+td34zLUB8HSq%Hfr;23w;zhPJP?SSS z<_nQelMh#WXWW34LUadprK8jwAwPJfjyA5LNu#Bnd2oO?1lzVtswk8)Q>m$`T;ps_ zis@CgSW=C?z0+T)FFNvh=3rp`@DfAjdV0#w{)#%`o~x~Fr^zs7&)CZ(Vg<)`3dGP( zsBVqpHOkDM_O!;i$Sk?oslmi@;2j9&%rfAsqf0XZ)Zx25B8jxD1)+uFRzSNK@y4YR zW`Zrx-aH3eOcbm4md(GeAbC+@P2M6HDX_aI-YfFEU!Z_vy0-#K=FaXDJeC+X%{z#! zEP~i^r{M{%7e5RTj>olbTt>}_yAz$;KuagRw=Uf2K$)h=;qCQ?Csb(bZK>tP@woR- zfG0V%5R%3X2v!U3U7>`Lr8JxB7v@qLp^Y<4$v5LmmawF{aw@+$Vtug$TYy7pT%~SxZJGxL} znR?KkDhlsZiS7j((`+*LK?g=ji;T~%f@JWm``iUJlX6R=)q|=)R5k^|yGM83-h}Pf zNi0bIs6}7xv(8E4&!C=?jj3<8_58B!dhVb<)l+G-4BBjsYYaU$Y1g^aCLO3!IC-Br z3eqi?!*ANzVcsq6{gI^|32^D_tZ|G%lX@>w1UHGG-jJXiHcr%()$nlbq}tNJoDgXE z%F__-;k6#Wm*{n<>@{`d@jYN8YS{aEKkD&j5D>ZHat2*PO7SyxW}O z>$z(;d$@n8*tKtLcjETJIAWjA`OC?byz&Hp6KruB3ra+W6}3Svm!QJ6@wE3S;?1aUv6MO z`sr6`y0~yZE_-inAg5&9WeTig(7l?In{cbMewi5zKNgwH(<(82AAFntYyF5&g~r9s zwg&9BL}^f@bn(OYjy<@XWSW^-s<-+tv)6{*T5Yx9cnOdy)ccB396}HO4h?-M1Rx^u zGg`}J*kW^8MnT}q3w=ieNe$`4tq%6J+^%h)cx?kSxNTF|_3Pyz&#Q)7F$6)4|LxZ}Rpx;Y>}cpWb@$)ji2#{s^d!>mNcHHJv7(L^p1 zDH@d&R&;ApJ8Yx~H*avEAE+o^Du^wERnG<0>2vgeOnte_pBEKsE$hucR*M^+RBzrf?udUq1E{DW2MZ} zc*z!?$*)Q&HZT=RlrwCaE3$vDi$_u4cql9D=vk_|!O-e6rW`Mx>dW+~m`Ptxb-vBd zn46>Z6Nu`nIdWSN#2U=hFZE5ezf%y^|IZ*6c64_A>|6J1jglcTz#*#aY@A#mT4k3E zrR+LxFtKm4!`<3BNX6{cyGu(;N7(t30^Yy!HdmDp?Ua@LLamOjAD?d^?H=J6&LP1q z%$P_CX$LC+ee9CBOkn%|x$Bl-NT-Fs*QSRPY`O_ACJjV0n6s}a4~7G9k7#JCSDZ)| z44PG)YVB!jkT?3O-8j<`e>d{+7NCc$eX zFPKWW-KxZ;Aj`m}AhR4HYiO7T@NGdS2h%zHbX#4{60ai+*s`PUwm0FOMWrg*hAMxU z`~&x_4Yt;?;qf;iYmgxK$o36X6dHL9iMO6Xk79S0U5AXT+dWS< zw!!G`E?)gCn+hPP2X^woyPzw9pU%m{1Jd@R?fU(@wv)9Mn1;wLumKIm+v)vaY>gJ4 z2N3FOMMW<+?Q>u-lWtvkv=y~SWTyP!X3C!Xdd@ldy(Yx>)fF_GCFFzMc;(At+YLQL z<2fRcY>^LrU581-DU{L4pa$pdRrTLnKT0zfl&sV1FLdi?cUWvrKqjIw5YVzT-QcH^ zI8f+aQ`=kPg0d{oEHRbwWlrq&6|2O>cHLJ@Oe($0`-JXjIh?K-gNO!A`A9n= zWk|{?ufjVO^z;gK%)%xgZQM`K00q#YRzUPd_{8&IVB?XdFcVAI$30Q6!|Vh?w~W=F zP5~IP{sk3)bXTEZx$?u><%f5n`lz{b-{fg6+t|OL4v}SKk14d?CdmyCWEPmYe4(K2+)L~^IvNm*TYN`N#XZkXY1JETd;kx z?}Dgv`X*}k>hvbuxBOtQd97Nf2j02NPzg3P+3Dj9ZyKqQ4OkZBn~J>NI++UKIlM-sv5Ku^`_j^PF2V9+ z8nC_%`ULMWnBxx<(HVHq#a0+X!HxxxAnYw6&~Jxhbn@o{yg%j&JEH~$gY8F4+o*CM z3miVYLG_0PJr#)&Z=OXq24Y?(QOOJ#U6G{e!T!5fw(@J>?w*hiU0{JIXjYL93^GYc zz+u-w-zw{tBz;sme&#pqB^;^Ap}b*Bl!0WH1-XYjVlB5YMAh~N?-N0#ZfVkVpLpeUya)rb|?pRyyD;dcf6vlQHfY zAPg7CZ85#kNr1pEgK0TQ4dv~tc&Q^~P)`ERfbL!M6tK)!A2d7b?t2}%lfJ1v#w6GW zB%o9Sgm;R;nE3(Tv)bjJGAW*0(j|JKnu;Sw-^lgjEL{Q3oU1>5EQ=3gIsi!&Bj~#f z$I1@MF`=E!(S!9)H%y9Q0y&|%_Zj6A($B_I$IY2KX`?>4`Mx5@Sy>8=Wf&=E8V8*m zX$nAo7X`#uv=?2-d6GUhfx*^VDaz07>pTlGM^>i_ZQszAt2Df%Brd%URKfAEJA?Ti zE+t?K(g|JT8^W@L3=!1lWI_azcU45cP7AZQ5nJ6wC3m|Okw?Qa@-6MYuSm~tEoelO+QP*lmQD~EVRy9v5>e&n@eiI;ryP-sRBr)h zzQDpy^JX03yVoAfOV1l6vxm2NG7a!Eg{J-3Q-nN2M|(TMi7B;`Ebc88f#9uCdO9&C+TlBP#s zT;}muCS%PJnQ_da0@-?U{)(bM#qvuaOM|K^Jt?G?$8|Yb;)94Z0k=LfsQ@C1=U_kC zqb6Fv3sUu-xM~-VxgSIq9`8+9TF5**vMsPRGzssw3VO{B8p?9LGOI<-K&QWWp>5;L?mYh<{Lhg|t>I^Prywh&j`kT6 zD`$;eIQjswGUcPie`m#w?`t5a`)VjzPwYgs$Vg*z?wkcP&(4!JLLWVL^88H;kDm%` zs%Ikz{g9yfI0qKz^0D~aeGB(|5vZOF!C3s$lf#cJtjMrLuM&NBjA?oMXHW<#$*Y35 zlHT}Epft{_53&ig6*lT1XVj6WJ$&Ov^$rRIH6rVPC4-$Y_%vXfz6%U)?ctyhYS5vs zVH!luy$3pV%9^0o^N1~$l25%^nCXTHO1WSUHfiPz#`Qleg>Hg+v7HzaK3525JM2ey z@tU=o#Oj(_MsFhDk+B$q^(8lXjCl(3c8#yu#MFs-~`O4ih3Q-+hj0m1D{-F(7K|v1eUC~dKx1o-+O7= z)U5G1tP87EZXIk4Cwd`HiX{A3fx{yy8TDF6j*Y-~AMzZyyQpffh){X`yoy9CqGtg_ z6aiLcWH=`SuL(~v&laKi(71aJ^5rGy23FZC6OGUI{aI!)VW3_H8E(Y<@TnsJMY9b~ z)&UHXbw|_RCPd~@+91xQHM59I6W!)AF zMPgi9yRS?jKN#3@J2@83ew%M05Pf?*LXOHv#vc&th9rSowWv&mYx(0Zh0_cLTSAGgOYU|7Q82s0z1SBU45HhJV8hX6|=d_g$q znzt+#OnR|!wirP>Fg%cYoR1aG=9+)C-};TBjDSH^`ZC$(BVMYi>>z6P894~!euji2 zf6O%AWd4a2E!G9@MMbe_bk~Nb3-+%aA8okIgBc944TVfw4^ZIr9rVjWyD(2+U!T+_ zBJqV!VRJ&V<%o3mOX-RTpEV*%ssY=xG3@$!kcL*X%<8eU%wRWJd0eo-iQIv8VjN6a z0$bMP;`gdI&&eNo$lMIm(c5jQIhkTyDNov5VoMw!2Ka$Xp+E;-*OM)?9 z&D7s{24)wrRg7;H4%FxK2y|}sNmA!9-(_R5tV73*R2KJFh=g()HQ#Ckz;-*ByKKCq zFr1j9Ibr%fR`Pu9C7=qeExUx~$$CwKb`w~5kJPrUlh;#IwL_9`0vnMhp#SN9e<#bP zSuxJ4JrfSgT<(Vi_OtKW8CC+>h?Q;jm&yXEJUAYY^_CQ7CeusUd@E|eqH5P}a=;w1 zP`y&{0C55>=_Xs3nrPd-%aBak$15xdSz{fF&+x^pNGx6{P~LQLOT9WAi1 zhsNv;TpMS-_*(T#jw=6{cN=N2{tw{fr6%Jz#pN&SK9(;L`JzTi6mW16f>ZYWXF8j%a!7mUBW5cBx;azz4D_u!=@E5!W9|InX)zVzVA9 z*lodtY;h{d^tIC<-f)Urbw0*r!ma|R|KazWnMG!qK- zSh$RSbiw6gqx}MllrT5|FD!=|28ETos4e#N1(NOFZm2ppp@2*Z>_a5_DVYxO2hN2nPH=uX}93dhx!DojY zJ23CdC9QD6g74QA_C+&0abI2Y+*wwxcuxU(-T|U)epU!{2-jGB|4b_%E#V@FY>(r% z(6QYWd^xMAngis;JXMw`=j4i)CKouLnyJ7nK4E(u&W&r?6PSADsa8Mt@n6<_h%-NSjJe#EY zs6%>#j>fz2iM(BJC1#;_Z9wxkOLaoL9_Y@^)a#)XOqX9#-?c#q+4h&_fE6oFK9%-Zgu?5m-i4}ok;zyu-@axTVfKLqqB^5x7|1GE z6jR2FU8N&1QRY-+c3v8jo^y}=hdXx((9TECaVRa=HH%C4zdYKrN$#QzxN?($cc5Nb zx&UfPT2*!>`Bl*<T`)`eHQ&Z~ zT-L;^x|s@39=nAotk!&}E_AwA6b6|0<6~IX3lWc@qa&5=HxvsfnP`(n%!cvUQ0XI$ zgQ|T*7F09^kAc|yd4*<)(cs>EgoVX^(bfWasu`b~?b0W2XH;+5v7P;av!dDeVI~%# zWWOx5!cE?}f3$6!C$_79RWqfrqD%yoRhu(Ss~6|1z+@z9;NZO}L+sL`FSionK|>U@ zVYx(zRE-mQMm8|KrZkAOb8{e1Q&nDaaMF?AteaI6jO!a-KeFB^d%$x+cRDlC2B@Pv zRU$}8A>0MQ@XkT_a&kIM5ZMCOG9~12`iWc=01EwASfj;piujhC3>x6GX3_yk&;8Ns z=t3O6Oye7Z7=kJ9jY!A$D}@?}VWL=|&x7I1f0}23@bi$wxNVcSF2w4y2|SyeZDSN7 z)WlnGG*AFudh!t0RvO4U=K(+gq}n{82ig?J#|O5^{t?K`v%(VJKmeLWJ6n%wb#V!4 zMc)j~?d?CeH)U3SK(b{CgRwYkARIu|B~RX&YMZhmI!n43@12KCjSl7YW_5yM7z^t} z^mcmm>b~~~Lj@0pQ<@je>!4F&fQLqZFSCp-wc1Rt8++K3sy6eTkWv?tHx(x`p{A{X zc*RcK%78-|Q4R4Yk&R)dZ&AD*JIErcOl`++5~BA(>`|3G^vu(fae+KozSr>xGg-Mn zdZr?X6@!-gxaC>E=L_upO0Cy+g!cKqH+_wGlk4Nabll!C( zZ||Yvt{^7%s5zui134`4Tx7PO%lf?v7*n{unkwDO!na9blU$fW4~Y;CW8LxPNlpHm ztRS}btjB@x2TD=jo_Mok8U3lwz&Nqo-rlI`nv~g>;sVO1f+)r?U58i#Y z-2(C7QD1D-1~U&*x?8XUtMIPWRGOect9uH%zid>PsM-IYe9<&3jxD@!7vR-qS5aaq z|A)1=fU0s`yM`4(2?YcRl~#~$=}x7)8)>AwmPiYTAe{md(%m85-7Vd@=vaLBa_{r* zbKbMh_`d&)e+&l0!9dnp&vQRl%xhkAX33@T-5vv~2Yqb|yn7f$zno31f>Xz%86+cs zmK;z)3&IOxBGtpoR?PYw7q6juJh&JFWOvo|-Cw}RdO1s@P~&If^$P%FPXEa4v#WhT za2Ju__YO;koQ_Lzp;C^Px>GL6bn8S%9LXDwc76U#z|XWw&*Zcm{{92yRe$npMb8w^ z0pK1{L#7CrbrQ9w1MzZ8;V%L*+$-tT3;2wjyFRaj8Bf%d@MF4Tu^JFR{9X<}XUZoPos=8pv20%f#$4ayj8r?~6P%qgp} zEvnL^e(wEgy|$$wtEt8H(OQ_FfmL^oen%1-0x=`D@WqFJYatYFVTw zb9A6{eD>rCKClzlGDwV4|iP?n)p z5RsPmlHx%dmJnyF0nC4UkNaLJo!cF6gqJY&DlY`* z$_?kK+l#8^jw&iO4(8Tg#KpvEgJ(+_Y05v-4fwIi=Ez-|#j&ufXtyw%Yi#Y09*-9M z_`SEB})SOyXCyXFDpl(SQhsQX#MCoG9hoIOjSsH(YMvJfid9DX}W4 zl{THrEzI-C^2*7W7lJ7J(+sTmIUD!yybY+a%3lzWh^bbq-@6)7%Hqw)v_C6*Lan6s zELX1()^H7LjH!OVW}RZit#1^KM8>p}3C3;Tvib8O`4TtwJa$q=2;YnXxh00Ze!;Mb z5w}+aPA$?&brc$MhOpcNf|Y&)gPb^`|Jg$F*^zWc_7(Z%s9fEJ8nAJXfWt-r z;7(**dD&Utd$Z>CMuU^xTqlcCLB7R>zJ`E3c>CYQ0lxft0WX}z!)$n|B<_n$j-nr?4%G@bVE(pKqk&9PQRvul{Pfaf^zi_biS_J-S~FY=knml69O{0H+nljOt>y za^cnG|TX%ZmB9PI&u zkWnK6Yp$34R@JMx7hupS^H(G%0jo<<&8vO3IoFzGw{&H7dDWV_EBc9($}sPBWM7Rx z`7`K%KV$f@ELVA~;42XVGuX6`ysTu8Xy!_EIrtXubj-gM^Kf05S>%er=A-8wUQg)p z55;B;sv$3#%ND7#x&2F`YzQf%^B%#~+QR|snoZ*&9Hf(h&eyv6;i^hM6&S|L2D#o1 zzxBH~-L)q^8c%Ik$dK$>lTMh0<#pNoB*`08lo|*PW=S0cOGlmi+|FHuq0fF`Sl_7L z^gfGTMCK~uWM`X~lFo+^vAw^%-AO{Kd!qcjUALz8v3!lNgu=_0N>85PU?PeL$ko(p zav=ptp4G?P=ie;46K;h_EA;GT%lxTYmU^ z*J|46ET@g@K0>d7kW%e!DMuoucH(|&cXZ*KxYBnxDrUFQ(OBw~yHs_tFJ9Fvm6W+q ztsv~)E^-6muPuikh$zv>BC5p++_q^@m$U@RaEweS{^(t&n1a(~Y{b9Zs_y*x?-1mT z?Xl~;63D{*N`Gk>zia3;s<8$mk}DWgWRCtA!T*HiDz)buR3{sRoiP-LzRN*HDY%L7 zv5Sy!B!^qvKenR$O~}U4x03_ZezBtE&UR zv^-_H>_)1_9R}zUexmtar*k!ohh><<&b!lXsU9G|njLR2MKVCV)QvC8%#N<4m5Wxl zZ{O?u>-yYT#D)N#FEOFkQr=mqAD$y_!=y`=r3utO0Pg$l5Y<1D}&v_2D+i_J-eomZC zEV%f@v)!m^-1nkI>;s^Sm`CX17j|pDXPo9Cb>qoAu8Cm7h%zi!r-OTcJS&XPoZ@RH zitQTiA}(7RLT#S$#F%UfU&e!GX%~e>l^I21u@HPwBvf21m8CuTh?iaO*umWpdnH2< zmQCLg@07N6qbtR8r}}6mBdtxR1S8b1Rcx`srP}sNWk!-BLziB5DjA~l2}?b3gP?bG zQ|m!R{^P)Y1NIlTX?)2WloBiHKf(n0Yrs|H3H%!ynGZ4oy1Azm5=yJRk@7}97f+=G z=b=-jiUdQhUi21Ecu=r8Ax`qieI#0Tiu2hrkda7wl30T4T}6>Kli(oR*2aS(<>42W zi9({E9&{XwhD&Qdwaez5NABLp0lYU)nZHGbBzGReeTQC z8P8$Dr&&D-FjESdM6UN-IP_YvwXzUo=XQ&UyvLdSkZ(L-pPWhj5%5v1n$3c71VaHG zSAbk1IWc^QSEV2QYO;-F$qt{Meq~RRL-{&u^k>Kv_eHaD{|rAa>syu*Bx!uMjX+B294 z)%jxl)xP$k5Aty_Mp^e81D9;#eis~OZZ64Y}!w5tUPLs%*mwz2*+uU5fzWgp~ zPi3iOcK-08ceckZUhHGBB#on024Dn=cQ{Sz#qBY3ThZxJIPrsK--oRLEr!8{1CLEH z%bswuLX4y)crLLmh}Ug0FD2~RYoWTlQSJE-@dsypm-4J!6tusHd5!aWRnB(VPj>$H zD3ji$u^3h9e&$4RCn%h%6G|cV@aI9DN~*)%@UA9{S3a?V>QY)Sc-ZN*sxS)@eL9~h z|M@_CNcvE7xA;}-(HkjuM#8z)pdGC0+YjE6%E)pd&0k;1Zh$QhC-1aU4hF@w-sVS8 zM$&h^7D}_pr_h0bZ1+m5X4J8J?(tX@$(RMarD&wzuo$OVc!Fo^T)(!55sS}MzPF!L z{xM9GwtsJ@S6uFVaU4VBK5sZYFIgWE z@(kwZK2B%$ezT1CaLteQ+Y>5@%%fs9*Z5!GkFqpp4b>PG8_moYdc%=M8#m8!{=B;Mq{7&8T8F}9i;mGu# z9QxL+HkL#hbnNwllL^AC(nR)Zy`->Sz7Yt0_Byk2dmN{cWobz8aB2LT;5`n_GPG+f zjhPCz7!^Qd%)EDXCSJ?*t%U?wZ~yZbrZzI7!Fw)DN5lx#cc@1sQV&yQG(^?BtEO5kAU0BX@>Fz3OoRknuUZn zD~j6N_hLD#uqlojhJjf)z-!6#Q7NP%1Fb&srEu5^#Xd=q)UI*LpjOVYV>?og?Yww^ z{_JH>QSb(5sYy>&a)VwI!ln5*WC<@$@cQtjl!tJY;_iHUR&TeX-JF z9m&RozHV4dQ9GOb+5#7J**)2m!=P$OejI2X%-+PuXh|4TC=WREsd>%KTP*>Q;O#SM zDv{Y*>%yXl^ZIjiMyK1H%XXDi9mvfi{ql+rHjm$z243{E>6)&e5|+KcVk=x#=JkeI zzVeM3%Tb9L>rdbgXl_l2OKx7F8d*IfTHlvx3mJUU{!}i<2znmIy zf-nh@L-092p$6hbdO9xbSV>)8o*phQ8SN(T>5e<8ihmm>m8zqY7o!LeAe3Y|q0~3P zN5ftp0FI&$MI!J1X#og95s2M*Lz~GLJKh!qvUYkhZw)s(52{shIj_^nbAB(6OTgyb z{MB^N0hqxyx^)*MsAqQ~L`w=Go{h-zbE>^PR#68#l^IuSjj$RSKzy;^wi>BU2C|BZ z{fV3+jgS`={rK76w3JJ;3pK{5y>r-vwicIv(&t}%onyIdVG-gA6cZr%gguC7okx!- zdYGE#E}wYEH%R{aPFvBQQRkQNh^#k)s)ahKwO;cN+8Lk7yKzV$;$hF;+g@tjpq5za zO8bm*i*7&@6vLpK`4+n)7%xvoY_obL-yV~~?S=2nzg;#C1h{3we47|LvDMVo!$Rw` zCps;A3yreE_h&-P5DT&zCZ5E7(dU~YyY>-HW(2JwqAbJPBU~~)Vd**s(rTwB{h@_%*Ndz76DUl6m zn({U9D8!s;g1D%v?8ePV(El}tfYb1c;Vv?^K2!L*RMo+|C(PDFv=o=_2&DYTAAVc< z#gg99PkT`wODp9-Kvj{3=BCGa$^VP}`|M?!Pe!oY2o>-?9?|g7A zmV4rqfL(>V57-Y+O<=crQ*5wCtG@DTAHa>74sD*-=eF)TBJlTy=bgQDO6DZrVQR>H zclNezB|W(KKe~Z_2nENhSTnY>Adxc<1uerBy4Gxvwp)e_TL5ObilByFY1sqhczIx= z@^OJuu z)ofUy**ECp)WfYm>?{NC!?O_28yCji&U>1FJz$t4@E6G>)(`p5FG3F@^?|8q43NHVeE zhmXG*{~rhEk0bui-vwgv!)wa2ITlcHX-VD%vFR^;L_*VJVp4lR<#l}?$>-UwryS-c z`1=l}Jq4ee5Cfk`iu>p%?w@B7{IOOCgsR)%O>z8X;05}}A^5lN@C#Okf-UUV*4h?~ zD+t8agM~gl`9Y~(@~$a|=;Y(?XHSF$SX*)tG5$W-bbtM+z)eJ(TfC7l#`XvQ@nnS4 zNC6b7hzIfBgVV4w;k)_eMRSz>0X+&P#k11B6n_4C&Blh=YV%bIE&#vUwwwHbt(~bo zb%Nh}ftOex7>6G7{dX@3j#jlDI)=718ZNjUg9Y$cOy8Z!!pM+F65FeDgx-Hd$kxlT zT&e_ty5~LQh974VEci7rpr0g2%<<7a@oLF)scNLDRGp{sH-!@R%57 zUqp`zUh*p;%Nkk$A#fLWoOGH$U~jZ{^{f^0JBlO`6yoj5I+rH>cDo;odpnXv<4+0+34m_=CUo8A}(Vz4C<6Y=t`5Re_lP zA`3?qKshzU(0DBbn2l%}3E7j}clqdnl=3&JIA(?JNUGKAI=2(*n}e1xdGi7{;vl+! zO3p_ht-bwko-FurL=Fx*;`$;KsQ2+Hi4<$*b|F|}xo*#&RscQzOHrHTBm7-M=Mh~G zrg2l%NQneSeI9Z!e0-k*yE)UXafMRsE;ObzH#ctrBXujNSnFr7P%H3Y@1{Utsn!h_{(x4p$VBYqM)7N#2mA(=+9#5dc8r`;(V~31}YsU zb%>uoY>nM&EV|oD%mgZ*DxtbG=hQQF0 znN8s5CO=zsXnM9c*Ls7lbbh|Prqtl!>JG4vB(e$*(34PYc5|v0B(@51Iql{lu*{UK zT9gOL@}rz{$-hJ@^HxvvXMhE6a zWSp$+pMm_p3AGe?Xl_&qm3V(fX7D2{-UywNAAE1B?QhV)7 z&{_75>!zkQUW96%Byt(HJ5WjS0D$}vF<-O&+MCJk++UI?*g&+%d26DuQD2ruiBeWN zfepvtXO+WZGtx6IhgkiFjl@_WMZYy$ja_^Pdbr$i4BCZ}t+7;pVe{E@VYibp)zyYt z=l$UickgWi|15vk@Qt_+g-{1@up-GsQM+70WigyoVc)m2RBMzgODTAbXm|Tf&?l)> zq~|?6FaMYE8U#;usfXJ2A93lmz+>J7PX(q@e|=nYmDpHnWoowzql7WuisMs}D#Qk- zlbj-0Wq?cy-)^xyZp&(4LV!Y+44vplfT&S871nuPIk|IIY@7{CGRT8)6qwIz#{q%y zXxBPvx5F{q=|)In2$WdYHz?5>OnD-y6e)nUQ=_ls98uy5R+V;zc?^a0Gl^Id(zyor z02tQz?&#?PnOdZKOw$J=bJO)*(~5Y;WK%{ zQhV_l6~N{cY>#^M!GdX-%OO^}^PMXt-z(5msxNw-b9Pf+ z9>b?1)%V6 zy4tO5*EsJ#l<3bmboa$#Q`rj)%fIrJfYhrGSB>vqkHGqK#2CO-TyjTX>ARFe zZ(72<=NVz#@p9OeS^L9;p92qk7y1fHVPTT{Ve<9U&G6a zuK4}A+E;m*+F38(M#uqN>pPOj{2?#|8jjKR+8n$DghJo3dQ0ZeHb={w{U)CW$6%=h zjLzN~acK@|0{*pfftGq;7InAVR5NJ+jcUQ9pOa;rd}Yx_Fk|@KZpoE_(`qm7T&7eU z^|mquK+V#$M9T-jJ<*_Y&~k_Yko`{&OAdfknVG}JAgOW)kbMMBUVVJG0O6tUWZr6x34+9C0ir zGMu*;RRq`w66=HY?(F)9tc6m^%toI$Vl3A`&ie!S|Ek_)NGKo&bay|!AN|LN?SDOc zcf3s{KwCQF?ZbG;9~?wVN?HUOA?VX)5yKJ~>Z6-J>)D)jC5T_p&DGggdSi99a=#$-ORXCD_cM+&)Em7+3TLB!2*#HIHe zL6h_c6-30UOcED4v?TT*JuJS{#l?jqU%OVOJ?Yj3i^8}oLi7{Clr&xNidt;jjj?_T zs&(BV7kok2s$|k)z77*!TFn|)R$D#|n|o@1ezBfn28OH5R!&;UB3k$EA6IHd@c==d zzGU7RtMDSg*j1qIY-T3v068f`?<;r9j>T9G`Bk}EAXX)+ZCcbfH2NfMjMCceuz1$g zC(UDQ0fU2#RAtLmd~EZ4WVB55YDGW2>U3Q*BFdUO4S%_^dYs!Rs9@(uu2yiwCZ%hQ z)4J=foB7-)mIGwbYO1Gd8(mgijaPf_251rUAE!V#<+WWxEN+utXFGxF?a$YvsrMLX&F8KfQZvjT+mCh&@{IQyR==GGn9WgD% z{O2(O)IacAozdI_Fs$R+At=IQn7tt&m z!$z~^edZyzyz0jQ<7p;a;)pQ^?jj<)GnLo{kma}A5#S+;aXl_Bel3kF%T*g`HMC?% z4NA7&Mw>;l+7n3{qiSXv`%zSIv#8DveK6)@mPCwfBSzG|b>Wf^r0~mLoe_Tn^mCgM z;UZ@61fronz#uZH8le6|L3dow=7T#b~PFnF?$AWn^X7>*MPhGba z#s~z$##`ytrykiC>eO$xhd%d@!XW08(hz)SVJY!bwaiqW%3v8`hs<>-t*upMrVdFL zNmn9vBfkMSbiI`f>WQX1iyqVGN5i{1-Ig>{$ckRx8_%zuwRY0l6VZ~;>O_#N=ym}$ zeSlZ?qgA{3HbdvV+3+sy8i!N_q$A02&0LjyWfjE~H~vY-*TGVu2(>Q;fWYl+TSt6Y zH6PoHnEAwuF;yD0%IQ#}>b``^LHLHotb}^O&u)UTjvWSY&3_PlKW|x=2i(E$lJA_X z^B?e?S}L>B(#~4hMxJRtP3VuJO9D$&vev_-^D=?b!9mcdd&KTWoRO7R$GCg__G_59 z@+pHrR1G9n$wXS8Kdw8el+yPDl)tLzzmTkd0CWHH6HF<9g^V8B7qSeYKo z0~vcx7RSOJbX9BXfA)}WGAH7(lOXJLN73N%dRb+g|-k{S6>rx1b3vGPHNZxAhy1MW~UpsYM)9t4Zo0$|fTYIh%~ z-mDGik}UT_)J$Ul)B%douVvq3K|MWXZRC2`-j^_%Z^7=)#IkJnYDpnP-E#7WqKW(S z1`&;ND^VlgToZJ#_MHVX&V@oRW7t*zl*yqVjC4E~`D!wyjLX?I(?&ZogV9e)L_a-A zMJJr@`EFfdl|ddH(^(Z&qUF6+8ONE^9k0K?%@gG_3OlHyRm@~v1>5n7nw%LKLgfil z1BskH^uLsESXkJSw!wh|zDr{{Ph$qaC`SPx+V5(to+?*9>mKI-&j8Uen}dGZ7Q1f{ z7v2AdYT~0P{2>TG(XzJ0qo7vpUrf#Y)jb7ODz3l-iO1`o5|3{X*j)H_ygA}tAUD$! zjRUNhLV5j=AYfkn&2p+_YD8%z6Y~m;l*HA7&=lVuji@%oU{RF37F$)AOeHIB`j`tA zl(1@ZjdC4;iU$r^yYQ)HT_aeAk9=*RvWYO=&_cCDE5*tJ4@%+9p;ng;n*>@fxPigp zS8aw;G-GrcmAvm@siU@U`+dMxhjrtP7|_PHNvJm;qXu#5MRkhyyV59rXTuR1Dy=F; z$DK(*ifU|%ttB?yZaX3xd!^8+5rW~X)DF+2EVrlY9B6s~C!wFUjfqTCn;*bMnZjXv zKw}79jqMamzR`E?-)!X>UB7hSuNQx9F}`vi&Vtoi(jK*Xo`Zm#-~k$0orzKg^V3KbV0*<%-(35o2+>An1ULw zFD!*8QxfmiesQY+sp1od-3n#Q9LR3idl0C?T5nv2ktlBqSaLQ6jq&MA5NjHcv8#uH zvC$xKts>uEsC8!Oi(^r3?}_$|i)S?x0*Fe)%=J1jOg!QbrU3mY2DSVWxf|?aov>Bo zw3lpYplTKcF3?LYYPOSBZ8D(acA~QkI*wEf{<0v%v)vi-Qj>v04S$v*O(QHkF{i%1 zYtC#hK#TBmJKK9P5&|nK7paKv)CcGl&=)bTM0j2AQREw>vX=d<^yz6szhaViEeG0@ zDN#1GcaD{tD(!1l4b|JirN+`ffP}5x86fkREi_o0{rmv4gDo^dbo-@Yqdv84PgIey z9X0-L*#8?B{`YH-7z{wTCbI47`ALu$aIq)Agai$b-j{I*>cG?pKi5wGa;|yZPrrdZ zVQjRB>B>s=TBug-Sv`o6Y28t}q_{ccQn7Nlzid-@Tou|qaXc=lrKG-6JSu+8;j{_g zYp$?N=p)bn&| z-7QLIc?UPP&2Y!=5){~=nn5;m9a3!iM>58B%Hjp$u1{5Oez^e+kZLWqoGjaA48Nj7 z?aqezf5G68!b36*u zw+rY%jA7atfaG`-2)fq0ntb?&;A+eXmh*ha&;eH0;di{XA+;95C(oNj@ZP=o-__}V z1n)7C5db3Wb7w4o8U%EC02e&cehU>AB9S`Q?~m<905B5UKVT&L9RB83@W?9wUg$f& zQe#h1AitfYzY6AL89>ka&E525QpsrAVTmPhRZiYLHIal^9)`657PBz;ag?q0LAi0C z23&$e${Dtt%g6+p{n0F0YjuxX*bS@a<-@0{;~SIadH`ui%8i);vhOb{jI(MhR|$>V zS7lnqfNAUS63N7Kq6Yu*0_`68fS-oh3aiR-U_Z=k5y8FE69Q_dY*4M*x!=O>8F;Xz zrtTiFceP&4Wg}}J?JOT)Zi$9&XDt2?sev;WmC+iV zLivX|H-F>h7R}|U=7jx%_VZ6PzCr!I#gG2q)9XWcdiBXUmHq-}7Dqx12!n|e& zu$$h#e=cdl=^Eg1Qsen=3F-u6T)NH0@`;=g5cOVZ4+5s%B>nX^P}g%vgM>8Z<-Rr4=blm=kMPWS!yQ6;Elx;P(?dm{E3J70sK#!gd)Gs7! z${QTIhTd0{2y`SZ!k`>VopCI$9JlAAuv%qFzD~Y|USFUEc4R!LAec&P>uBAz{k1#= zM^JEO;F+Cgd}rFFJMxDE=;yDzKG#9}xsNZm%Z;Xi9cLgNg`EvMTQzhlMGpl#zgM1S z$1^S~ids1>Q<^^l5w80P2UZ<$3hWnM+E8&eg!O}%1wSGl1McI&>6uKF7^yQyClu00wBqy-w!yl)wfw6RT)Wd(hu+ z1~at3VIQFVY!K|lZap8lXT+dWN4dSsFA>{`0ARa@@+^A*8ML;hi8u)-@wnPmhi&7( zHfPnYcT=`1)eG@6Bmkfm-KCSjX;?lA0I)v;2!vkLtxgw@BAzgY`!U|cLbbh#0knX? zg=eSz?EDbBH5x1U36<0iMf|;5nmvGz25%IB_@Gp%qfKSC;^C197tx^gzdBpUYBo2b zP!}(G*X2^_aCN;J!?M{K{=!c4X6UNP5jcM)sC|fKG88k&jRgh*-#KiT20_bjx-)6( z094!5M@J@==9;i5>~4(LDPur6i~(;!23ALZyx&WVqZ(jY11*xLnQN)dqR`ScwE%!% z*Y^g&?zHLNtSfUrr1vwp-v-tz>Mub(&gybN;;NJ5ncUixJgryop6`7|PSdOZ=W5^% zG9r9-E-1WRYyhxijTBJ+{y{ZxOQgef0)5BBfxjM7fZVi6q;-6rH zHQ>~vd$*9ciKGPBH3AS|zbJqXnVKnix>&#Ez5!kfHKl&q^y#td*`BsWg(Z*>+5v=VNe=%N1`{2^jjFiyLQXIqI#RFTrJw?CjoS_^g4CE07%y_ z(^O;jNSb%c{jB}VIQH$!`C8{N6Z7 zCq}({lUK~L;MNN5RPcCS9;5or43wJm4+n<7AUsVVOkn6}O-(geJaABCpraLb?{1=rp3{lbmQZ3ozxFeyCMBgz^4CvaTV5>YWm|K%&d8tOD(uyuYtNSv@ouQ{+R6Kk50r_%^WF=LJPdw5na z)xS@Ce~aBsx~6dSq$^|Wt&Hj-s0z#M*XbA2-0LOm&RIdfkvrsJZz?e3ax&IE3e2_R znsFsSFP^sR7~*EJeEb9ZGtxg#PX49C`@6PJkmQcO0p_<$IU{(Vv7c?xEMzuc2YT&| zmPDo~BoOB;J+F>am41wLCIPdDZ>cT*Pfa|cx2(OwqL9o?rb-ylQVq-($zuJ?RX0|; zzM`vOg~s=NA@zCkwB+ZfxyPly-d5jb>n_ZyKOUA;=xoD%s?LZX^0T=Nl$H|g!xM$K zq5=u5Zb6q2qi6zolEi*>>O@bB*lvlh8kOy8i<>t#7=2zrjXVxo3 z(g$H$FjK-mZ(Rudy#nq_F!?9&JU=B3`ofBgeTz*2P)T_A+*czNS0V@JIVtmQA^pK~ zGDb{`XFRN4FOhHXxFBx>Y@}g7v~?eeGNm8Gk>JQowU1=o4g=*zpJ^g$c5xEJb}6MQ zo5z)YVFa8~ss-1ZPLOx|$SSupWjBcuG4yl+&LBT+&F8c5g5*;Y@cjLB$A$Hc9PnF8 z0cZeu9)?jSNT(c1Rn`kcVNfQnfdx>-Du$~gp&?IA%IB8YZnRny`X#dED-|) z;+Ppm?59c|69>R2iz$$688EfVw3sNk9Mvl}XxsF|)A(rn5Y(^>F!kyD-L+ z+B)+laf!$E(2qc88*=cA51@Y&7JM{M^FHgACjoREjCd36paV3JK>J^T(>TWi0$Pop zyZj4~gR?6B#oo9Phr=ZXt6;TFh*Av<7?6AcIi0%W0{m_GgY9qldFLX9+nK04`39+_ zVKWFo)!*l8oj2doA9k);mwP6kxwcv7ub1-5p0)8VUqIJ4&WqC>mfIi26xT=|IKyxu zKR`+JbzIvKeG_y$2NxPUa)TX@$fZ2a55hfuh~v~c-}2FEn!9s+8y+f5}pV2@bL;B z-d^oLCs9^hP&7-(4^0u>c5Wb+=>_lOGag7_g={j1pjN*k zs9GK<|4`^l_G=^cAZ`N_8*W??0g~y*fg2~arVl!Qw0NK2Sgf8^Dms%Hu`pll)7

  • |1$jBK)ZpE=6g^VQg)*8h_i5+h{H`%SO zMM1o_>5O1|&qb|sO&+(l3mZx$Ve=r9D|ttyA42l_h9+70eOTr|PF^p63JIxV2p|p` ztPn_m;M3eHr_W@2m?jEZ35#c$vMKUBtRcjCTk;IQs~iE=7nozdLCU!*S?$vCZ$9a# zrj{8?tH}jYNJodnv%R;%bF_VN3%g?Q98PnUn-{KmI1TtL@t=bNdWJ|@Essf!`Ys80U5|VzWbpA)!A=G-{wxDZYSR@l zDXD_(d*?8;q28?FEkq6^(et-U6WbK-L zOV;5njaoLNC$LRAzJ^X|*Yqy!^d+zj*Em{eo&G??eZgir`KInpxGeb;KQT&px5}c7 z-B?bP6;h_k^aQc*)brPYTJ>&GKqtk#sKYH{?2!9RZ}1!Gk=C!{3sR`*)v0v2c*Z}p z0N(ejBQy|pZdVrG?DOk=!_;%bi`w$hZt!^ee!5CfHo}(X24nQ3BSVn_8%)Ke@7+g# zj3K4a?Y;rV+#|9w7ucS+BpCk7lRVET2Nh^JhkX7;?AVg!e6&UunTc*xo-} zXTH5ZUE<0@r`s@UvqL?!b4~c#EhM!_W-J#%uf~`%S#DkQ5sN|x%+wnOmnFFYxAcYA zx%HC*-CM~(?t$Tt7tjp3LCUZ~Xi5*z5dS3h8GlW#5A+9AS7>{F<=6Ga@>VF+bLz1LWVBQU(i>xJ}zWtsdR2Y#7i^ z)aC{@FF$4htB6~|TejoIF#7268POql?7``N7Pv574@(>3g+XJ8{ZaS~w`J_+1zr^>R~+|7 zoAi@>byWZ!osc&$cauIF#Gi?Lyfqhdw9@rrqF1w=wSvnk#{k=}*Xve24nk2AL^c%r zJMA5iNYRos1?20z1!J~WPJsGSOHj1pBmbEyeY;FgzwgLYRu za{8cxkwY69dn(FS=~2@bWOv$nP*bQVj!_@sg2aBbb5S10Te8vZY*QR8YEyW{PSq&4 z(v|$WcIJGNi8X1Uczf4}QuNb`RgXJ1g;?c9&-f=0nRgE6ns8&5I>KJzIpPF@4T4X^ zWu)dK2P`FPjrt~OZ^?p-Ty5Dv>vc-R?{dISE)h8>__79&KAA)WYfv`@B2#?r#0J+@SUOg%)cAdl<~||SyI+U57g>EL z%3$OTxZ~a;Lq9Rzu^`9jyXkEct)}o|hHZf=;WQNks48K927NATiv2eX_QA0+1y0O^1sR&d-UhsC26D5KD?1mfPnXOs7hcWaz z-@)d%1X>1|Zu>#opF2|8E{WLPf|-o($q#AzWo49brd#Eip_5YgFr7$#h}V=St`)6L znOse`bTSX;n0ppq{pD7!f?kV3o8Y~xTD5JU{=Es3aR2j}%X05I zTgYJ>{${*_iBY*HE?ef40-7XYgu|=4iw-(?_h>iKQ11@*`5BT*)#od?yz1}qtb;mR z#*!(_H53?V1)7CupKq<^wVoKZo~Ttrpp~~f{;zG9Zd-F_y>>OqS6lEumtw9@JBl-5 z)vDBc-8|cmZZf~U=XxXWS#qRaX3Au~kedDksT3)+$>%;t$VByCXYy_6bBKs??$m5& ziKFcLKF!zyB$$`=&Wmu(OWycxrt&LsMK0 ztY?&tkIT-{=_=t-JPQxqyJ3I!mEX);WAZFZI`I}Zc$8Qv=p&|-ZY&*V7LFNM%*aIX z!0Q8(e)G$#rQM%*JvRXv7G2ouWQ_V)e#Dr0_lsKD$x0dz^ID^@N&3|NU}6f{IO+>s zJcJ_H&E+7F#v%|qbge~K0)|X+?P)E*bA)?GbsfxKft<}7$Th6C1?D`TFKgYPE}mH| z*^ASRQ;6zqsymheDZ$C<*RE0UMyP1}0)}3Jt}OFSq7lgp60_asNi%>sOQ8_byy@<= zp9z?coF*ve6-c8V z%&O4$`nOf`XY3*?*Vae!ETkm4WVIYXP`A;yEWD2&a~Fe{DT3LgpDe%ibbn%^ZPf;J z|C=rC(l1lM1bWzfaaadKWvx&rOg@ngGLf$-yLSnvUo@W=i%lU!8;izvlFg#;^4o7n zQj>Ck8iX<9ts%C#^VVe3Dog;6;&f}wN3Ci{Rt~IXv0J0CyX|U!0zgmPCtMne5j;9A zfdvmJe*n+cc^nP}P&-co1OAuW?{dHN)6ejqe>x*f4b8H%LtB zV~YRPz%Q25Q6Z4y6MW^vJ+ITQ_V-N}ZvBZBz%XKkib#2!*l^@xeRKMg=N?MY)v?nq zcjrU*vz^q!hIp!F#mxRM(IXehk^9o2A8Q~=SCg7=DhrZ!&Z_^@QH%q#9arL3+uzxr(8T?fYi+J6e023Xqie1_7u#0+(nKm8jOc#_fdb{mf}- z8UE<^F7XI0wQL*l^7b)8oc(v~B-V8o6h>V~iGf++xX;d|8|_U7u=wTN&kwAHFRxp; zjJijk5LHaWFw4aU<{#5bvCcqVQ_|~7s%`5#19i0T;VNB|8W@_{2QM)Vf|)jfOnpM7 z6;^Gn$Hi)ik{pjIn78dXob|uI1mLV`-?U93MlV>d5Q*|b4$wBBkWCg+`$1OYyq{b& z?JQj5#Nn{cMWF{mjlo==elkb3P|y$fL2W_;+d48N@oHDz zrtsZ+jnzSAHCuIDSftU~{NBmY;t81{OylXTruA4xBB#AXt}z}1Oz4_0lGaS&@~u{` z+K1C=i`N^gz;Ezmr>v;GQjTYGqEY<#!N&GD>QKA6_>jNB_g3P5>tu1ii^5BMLjGVJ z8nE>06rsIPZ-Lhr2aW1sr2Yh)o{48>n;~@lVW2aZf&v)ZmqI$3T3d#Q+f7MLq)ff8 z!~`>(b*a{2rwWA`Am#U1jgCaFta5i}XzV^61V0AE^2i@11IekjhK)9lwYYGY%FP_F z-O|-d`NY8{Tx4{X`gfLZ5Mn@R&rBw#JQUDwyf+46X%;CxOHnE0?|+ZyDVqdGhpXB^QCaH48tHBzd>s`@IU9wYb(yj63LYcaKj@E_pRFb}M z0A`AHgTDautXw+^lyWG38O@t4#uC9LJXS=F_P-YH`rMxxh5%GD{$(ES7OC8Niq5N! ziw47=KbwX%UhwY_usJY-9;Ay?Q=sx5ozzNy{foTQ2K5dK%aofj+88L+WOM6L^Rxa} z19^)cz%&;%z&a{^q<(L^hDFhf+Yo))3jFIqf1v=wdy>L zjQHLL_cMBfU=cA=ifb6N{mp9weTu%`OJQgjf2z^|twL!A931W|GJ|Q$0a>1E>w$UR zJ^p|FOvP+zFuO`LpUI-Oza=mTnA~YLk4GnPB(7gGG6w{bE4qJ#>RV`w~o=q z%dk^j>yDihZsv>a8+Lox*6KZ5nCRNc%+7g!-Yp}4?&=s5qx}u?yQ>^xW4;sjvV6_T z;btV#lKA3fitZTmN$k!KcW)l%s+>XKWcD+@iYtm6KUQ78AmfXtPTeADar@TwPjhe9 zkBpObFUX`;7Dzx|h?(OB@PXRELaMWNdtV~N`y961p5MzK<4r;;1_$fx(BYg5Tv}86 zRf2B#$met5TYT|P{Cb>BWNPWZd4qv9h-AXC=kkhP9BS%(BqLo#Z9-nL@+yJC9Pnjf zpEl?1Mh0!K%~j>Ze5$@{yZcGFRw7CF_z`d1dW;`PQaz@VDjS9n4bT`|pYVpH%mwzv zUu0lXY1Wp#LV^`PbhStP z{WPf2y{R5Ti!v&Kl+)8sV9=HVyLVrL^t*og{h*y3$CW_+`|iE3L{BfQ9bu*TaRdD5 z*T3SlC)$JY29N@Wg!TFMUG-_qhF>z@s+JlL>m2@)#;9rI#0~!Z{LIhOIkPv8N-^`+ zH{i&HbHQKfyMLHHH5PF>X#xx@Vwz>Cbb8oq6S#pfvH zZ~YvO(@z%*{c&kg*u^ZiqhwU0oJurTJ5|^suMf-R6YG%0EsUg7m2tZ1-5l|^B6AFW ze2b0CGc{I<3bxWRfHZPv-&}L^0s%WN43zycZ~eFx*SEvQPL=tOLAd6_U07#JWvUf6 zIs4Xxb*@g>IB$K!1yD7+=_>vD25!?o;{%{`s$5#1TrPXafp(vq$cnw}Rq362iFkVf>mq8tn6G5zvd%V1y)x zfA_OJv%tnG7kLWXG!a0&e#GUv?+H9ZCzG%3)491JK>(bUmc3$cDOk~?>TyY~XcbkyJuL8NHgvS9TUSq!eJpSy{ z-hz}rT0)DHGv{w>jY}K*S!1x=(>$%l`~%h9Tv?WFXRYy_i`?l)qZfGU6V^1#l_jv2 z>%8c7u3jB}gdx60j!g@f^Nq)Ic>||`dT8@tDXEJs{v3E;XSQJB z(C<&kAh@ppilUJ>f*y6{`Itgu(PWZ}AGDQ_T;sgcg>L9Q>t+!))}az*3s-A5(A!pf z?OlJ2nSwH4ES|Alt_HE(aj0()L)`&c@fSwW9Wu{^ zK4;%l)mMKJS~T0CVl#R+xi9qnwUXN0f$_zM|3lkbM^)MNYoi7Vh)M}aHz+M3(nuqv zA}t-#9a3wFfV6;0gGdNScf(RrKtQ@#(%rdObtXQK&%5`2_x{fQ#yID%HDIi`?|IMp z%jpnOXvyOcelBN=4Rej)Ji&-x={$z|6TBD!Ks#|Z z7qYW8Me~G!dO$1D`sj3x?+2HC^Ifi608K7mqR_n5P1xl}%(lO`!7$wfGBDLq7ognb zf-#Ig39uIlqZf6>>p;zUdSmiq06?$dLF7uH+k?A>P!3_{KIEl3+Sv2hq=dH+0|pD` zQK$s9Qm#si117sr>s(xy`qG2~9k_+Ul!lB}+nXQd&@qxXgiY z^x8%wugLIbfna z13bp`V(!*X#?vE)YUkW$*QU2F4>7HOV~dcQthRB0y;1m#NCy>I(=?8x2PeF?5+@S2 zRgF8`hy+avh-xC=TL`(#MY6*y1BNa0^V1^5R7aQX z9TjAUjW?4mV!mkG}q_L2T8(B%=s3r(*IhNa?ItOsa^f(fp ze2c3XIQ83tjci1_O`V}}cg#)I==aP5D}3EnTpMTV+;ljeXNOK#fr*?w?Y-w&_H;vq zeNX|k)8FNQgt1fkK+*FCRhqL+IO9)H#` zimj?>SoC&#F%|stb5EnHeJls4a_x)Rwe6a=ygn8Q1hXs%Q7Eknx<;$?u_+*ls(2o< zn9zN8ytZZXE0M|>aD21cvSP0%5&XsKmAN+y?#AmX7 zBMILJ(=ZqM!dWPXDHGOlXF(w`uVa1Vh1@k#?q}`4sQE1Ge7RZz_{bfE?6f^j4m48N>f-2U*qa+D=IeD(~}}- z+pE||j;-(PNCO3qPSv=wNoaBB`q9)isL;)$FUD9uk0tvh)RO0AZ_FBcr5;^}T|rsB z9@#U{!_Hy!xt*5Ih(nKG{796?CuKdv2XbxxipG73%kL5-*j3Z+%jRtK>jGI$t}((H z@Atnhtz-5m$~-+43gbW_UTvBg&AffZx64Bk*qQ>=^Q#LlUdQb?Id%-MTDEXF!9$^6K35bdNZGxsLIS=|x`Nl){&bxi7vcLiKnlbrmrveu0=OT)I zf^r3al|{><07p((o{QJksBHb)g<~+>!p?p0r5d2?m?+RA)tD^3&ufI9<0H2Xjy30H z$(Q%$IU6XJOP#-60>V{$AxZg)*vc~#wUQo#X{gtcg;_!PV=`sKbeJ7ffDdC9oxT%LTo-LRuff%6;|TTr9X z7I?PbPd7}h2YdY6y5t?yh++?e9~x8KPik;`tnCc!%DT2!YLUY3RP9U~qHFt`ckH{O zCNOO>k|9!XpjcAql@9p;2Jp-->TGCp9~u%+WYxd5^6{dh^XmO~SK4ZiyMqX}v`24`b;FJ4;kP z);_7mtK_3AV_Xqo>4@^j9rW2T@%*gumw}KLelw30%eH%2iUR;~Vo`HIAbc?6J6?!W zmS+y~d7jn*!!{q^m-Lhe>4xKi_QOj0y-R)YCSMJ_JIxtCe`+0<-PzFEd|J_)%e}Qm zQ>H(gQGUT`H`7I9Z}5_V*rH37)7WUn6=qX90IMR8Ep3h zB(&Fb5?6xr(ClZP@L6e(DLV;_5$y5=HuM(T)w8qKF%C#fhLNjFbn)Uha%Gqy|Gq$6l_pI$iv@d`=e%~w84STs4UT5eu z6=0oiEIzjbB{y~XMbXeaTdr&mW8flh=DH%{XA}|=GC;KlPx!TiSb3i77-qhmI#Fpi zroO`UaN@1K={#WPSe=7Iso#PD3Oo1H-F_bA)oWg36UHwC#;LlWGjc2u=`=p;8}(C( z<6tf6N$r4bDO|77E1Pp51Lj4+%an=0sUSRLjpno=g8Np%R~Xdyc%6AB%x&`2#oX}i zMT6_ydga+%Esn{s)O)QwMvF%gZ)Hphxb9NnlbR3y4rbaXH*-ghaF1sCw<>gQc=YF< zwQgTC_APod{TzTlij1nBZoNy_o*Ls6aQkCa{A=nVxzTXd>GiX~W{9~JT6L!)X(2a3 z$Hf?m&0omvM(nSlkW=fZlh0~i-j@cT1!GQG&4_MzU18FZ80QLa4gL26UjAaZcBhji zIs~D|4FXKlDzr2nX;LeYKD}dvdRgh&ONB&xPW4Mt&^Z|0B7YrC=_5Ap3c{HgiIC8Q zfzuOa*pG~6&L+?e*k6#;#n*2ZB9e!Yo=tv_pgG9u#4oR=4&{iQSa%@&#?pndD7A|ujHN? zD@4+8&jgeQf7+fACAj#_FeJyI%5h;J?%<~>bDKehUa)+WVhfp`a6=WLR+sM%RJzIz z#v?4DC;t?I7+Mb$YT|KnDM0HGRET3{o9ZKQBZO&^{Tdu4e2`o9{M_zGw)zeCr%hoT z{Q$py-OJgg*QUNSj6M}~;{x7qJv6@kyxRS)!))U~b2KwPDch~l4tu9f;2JyI_rvtZ zLyLhi?bHadv@+G?Et$t~73K#=iM5D67Iwi%kZemHerk}hBwgmx9}FBpWQ|!`n#z`R z+KMyvLkkX!jmHIjn3K7`MbZgq>knAi@oh;uExcwABqBZ{BM9d*v5K7qIGoibe#@*K66DT6SJKSHg6^#cj_g6_MD+u*}CO|Nh2aRzf5`Q z9;A946k(6)8rsJ`SgIua95Z&>OXPhlhOUF))?bK*O5@`g0(##ii#>sULWl|MRnvwZBYeYmBmnkmYjFB9<4Xh9wg=6PKR;hX zx?#TXuWQ!)@&gnLR6?$`=U|2J-cvh* z>|fql2eF)t`_{WhP{tog1-mZF!A&g$7&a4g@w z95iPCfLUyLBCE5^6_lBN3sA8*G4)WAp%4}o5fqENFQ^;50fl8wfvSL zd$nGi+FUZfapDM?=JKf-dnihbdoc|pGNMtT5#aROld+ML%r1NkhuQ_Tw;>MZx<%%# z==3lB1(F%T8NQ(;_b~Cke~x?W=JvN9YNyc*FL)7egSo}MJ=i`h99Q_Qqh~FVl)Jep zeh46Pet*0@!M*SibBZ+C%F5{t@`%OKIZ}mE4k<8~%H0-m!y*+~ zdd@=fa`%-iod&h7DKmd?Sgbe7{k|3X{UfmI{VnT&%Ivdz%t4DhoM z2wfUa0C)-iR>4cTk67&$So4K;C$WwAZ47lkG=6-t2KhrC z)r&Cl{>(3AhbiM~A<+Bs^z(=9wei=3G2bpJ^{UKikB1}O*HSH=jEV;l!En&^ia)xIz9)u_THj|asw85lvOy;O z@Bv6z(}`_{Cd^sN{&W!|@qK=$;oTc^tv5(k8WT-h@)E5rBnyRP&1$f56O?(P;TA!HO|Z zY~@n*ylI8pc^*A^ymCexiYf3!2xJC_0o$;;uq)Je^2RUv`?rbt+qnp4RY5Uq9c@Jh zs9b!ul;**X9l@*t;r5^_k5ff~Y&F%p{Rx#8fgBCDB-rnE%0cUDbg;?_Nk12CZ(Qq_ zn-8L#wbCDXKW_18DE&aAB(g}j{CnJv#Hr6c+eJK4-{Z)Sta*Eh9I60hOi*b83C*B( z1eFhk7CFpKHN=lcFvwTkRdLgn2NGR;bg{*$H^e@%u8*2TL9qGAE6twnTa(J1HWBL^ z6bdbEiMz-i%b&!FCLU4iZOukldEqWz^&2h^suB_5I+=byzoiyrIBiC3`bT#vbuM3lfbE5fz39L)Fxqk z?S`g~rtI*oUB}naFs`ir}GgaLF@@e`*l<$3u@{2 zN9HVT(~?HO>Ty1XLw(Xh17E3w;pH@iw)Qw4hHB8mH#0lO^4XL165+!Pg6#B-BMTu%2xA6La&Dxufv zA0Ny;{jqt}zkWLL?&mHs^XGy`o?^gcKH+JZ0{E?`Bl*=7vg29<*LF6j=VyA8nA1Ts@@a_RJ!Y2vEGw0M_gJvR9q4T)Ue0CKR^AZ+nOAbJpLTU>2 zt6ut>O!@cOrUt`8xpnf+v0}0o>t_%7pjOftV^ zAD6r^P(z9%q^xn8VhdVl%vX+1Z~h4FivwL3)N7m&PnfDzbuZ z!*J`H=onrhrKeQJdiR{!^W3S=<_82v8WlP(_ov`#7y&o z9!tX=?6WrBy1P56@E_HKSK6#hncNJh=^il>u_Y(T+`0TW?iO=?#4!niIx=WJ*OOKw zzAp|D9l7o4&#tLc32hEfAI=>I)3)^%o|99|a zKJFnD60rErFk>D~Egb)rRwA>U8lrI6Vzf0D%(o|z!sjxW9d$BEda@2`{DWHWYW-8d`su5I0zvXn zbJIn_Sg)X}RpHzgX%y!`GV_Qz-D9w;)vbV{CH`N4mRk&6`oa5xvv=poh*T!(Ml zT-gFp&z70bTa3XUJMFPYqKCC5V>{AE#!h1VL1EJnhGMC+2Yz82E7eC~90;w{~Z8h2frfV7`G!HRlzZUTXYczJLbpaf>9-rfKx z0yzw1d-_Y0$~o6g^em9+NWu(#3lvmtOw7dn?KT@lJ!W&BebMZ(ns1M=tI4Ax3l6g< z+sR_tldo5 zz32JbZ|)s;u-De0@^j|&+i!bqk@-&rPO#b#81DQ@v@Lw|ERCvRLZe_qXZEZgUhvUq za|G$Id9IEOZU+Z zRoK~XU+NSRHmW6aUhXE}qe|ZkeBD`-!jmhhR_>TJ?@LGM+_A6+c&j*OnV>}9*7ZTu zgKE!gj-|EAR-;9(+0!56?K?NHe$``jH(i)HO^;#z5d~37a2TrP#p*g)C74vwRlVMp zEkpY^WbxN|ac(c3_c3yWkl9OWGYbq2TqAH=IMJ>FMu1$QkY_U=11jsOkHS(G!R*{) zFhm^08W8zG(1xVSpkA4Zd3sT#fnSS&I`*z=rPrWb8#NS~FId56_Y5XQPyp&!OM~w% zRUB6qyGT9v-q{L2J_y-};2@y3qATR2!vHK5HsJX8N)^73>Hr22 z#jU9-kJ&8`vBU$o-2zi!4f2JTha3*n%fYRlcT236gUrzrFvcuAWi?Qz5p}Pvd^KNi zh26Mcs;P`l0y)m@1{AguK|xCoPRqELct$z%S}Jy2t0ADIn?N*I~Ew|5B+t?x$gz%5! zl1+rL=o>`b!d`Yk-(R(9=Cq&D@prlIc*zvtVLY9l>gC(vCWg3^KftH zOMjz=VaYGiBs^#kQoX|&0bG)Y@&-ml?G>Na(+EkYJ*G@~0(Ww3O`rgpgjb~W2p03sbICz?Z zwu^jCVv_BbMWC78EeasBv{(DljT)o4I8*0(yd+!nQyWW;Q_9LrmBh^61`I<~bRc?=cS#3j$Ky!L*7cM(l)B)ERl@D9FCh+;_J84VQzV)2?#GOQ& zbnaL!NL6^@_E!u&pbETM|E!3h!d*C!hfttWfi+A&_C~u^duLyghLM|NQ)QC6k`2QAhyLdp z*y-;nrs>RSzr)QLy%6+8R&jaI~gc27hl0Fo8JUG+2$FmxPGyT^* zvE3@3>Jo+V`cv;nz@BoO4u~#1k1)MwanCd^IdA~|UJH^>AAmVLLQdIY zNA?7es7LsufFS`ChbE0omR7jI$Y&Ny|8?0PNocZjmU*Jsb=bs4w2{p}H6m%%TWtHM zx?r+c{{GcDE_Fc?w)IRoa+ZCk9+Rt|3BVvHK*W$cZ8H8nEiElae4aOseDo=uQ%@X~ zuKiH>q#|eYEePx-RL$m8bKe#h7rr#zUm#EazK>$|E`QI-ndNeZH0jN|X*^VT3_VQb z4f1HY{`7%`AOxKO2Nc~l6NBwH4J+zPHy$T_Q*dFtZ3D2z({7uqPtN8EQi$X%w}xuc z-N`yLgZn3|UA#**|3+#7>YU=m!{FW$tKMutTApY1`q&0Ev}p-`pHo^<`yisXR-Zw& zO18FiJ;SRr_a(!M#xuR~(BD0!n)=c%T);ZVHQeAOwN|Z);rl2a)(sF+08Sn2_N$W~ z`pHH!_hlO487fWEp9;N;_A=_ZZMl11@P#ta{h&O8{hc4Xjscjz&D?9EEPEasaB>^m zxx(2OdlI50oyKC{v8r(R+Om9d7RIUK^IiTyNhSGX!~w8CyvThR=&%O%b1s6hcssne z+8E58txtb0*qj9IJh_>J=k08!4Q90GufgK$@Oi=B(ekPdy^+nrmIbKwG)< zfUU1`%cJzBxTB*pTHq|NfFb^kXyM{MBx3fAc8+6I(d9_t-&n&)!QgMa08(kQ1lv*cnaDSu`p# zMoB!iZiJbv+8Ay!c#)ob=!xwCn~U8waTj`Ad}%g(9!X#SupS2|R)OdWsl5EHC*Mvv z!!sEkd3i~Q%4cs7UwRZW$Y9CLLHj7&y#|9y7f8@s-kzaus5qHDseN&}yS=&DmbBB? zr|!3sYAQPi8uMfj1p9Q`IqyO1FUHoknt^;Hpx6*76TD3}f1T>V1<&n6Ys1)mA?xw+ z+qn8R<(m_nH$i_2cdX1o(0(^o)e04VSCc%s#`!u6W$OH-2KE0})wqu7_I6t7hkG7aa39VmhcZ zM=dfkDL9Hs%b#T+F<(mSkIBog7GGrTCXTi?PH z$BPXW?`StBDq#_kl%=*K*X9zSqVAiQpUh&cRA=Tn!2{IiY)yq8uvhzN9mx zk$(TiXrbPcR=GYFfRI}{ZfrDdZ}4mmwk4{{U=*#4JKr8pJbNZYhrvua@!5|PmF!Cu z!-<5==!s21|NK=jfnx!4Zu?WFU?P{dG𝔙IQl(pr5cWq}+E50<6ad@@_(^?Z!3e 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�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 diff --git a/test/integration/consul-container/test/util/test_debug_remote_configuration.png b/test/integration/consul-container/test/util/test_debug_remote_configuration.png deleted file mode 100644 index 01b14eada6d9a561bbb4a8b9243babd9463f136d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 285715 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 JFm^Z#- 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 m)zhrk)>uU_ah3=92qa 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 ../../sdk diff --git a/testing/deployer/go.sum b/testing/deployer/go.sum deleted file mode 100644 index 1db52e2ddbbda..0000000000000 --- a/testing/deployer/go.sum +++ /dev/null @@ -1,245 +0,0 @@ -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= -github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= -github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/hashicorp/consul/api v1.24.0 h1:u2XyStA2j0jnCiVUU7Qyrt8idjRn4ORhK6DlvZ3bWhA= -github.com/hashicorp/consul/api v1.24.0/go.mod h1:NZJGRFYruc/80wYowkPFCp1LbGmJC9L8izrwfyVx/Wg= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v1.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/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= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= -github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl/v2 v2.16.2 h1:mpkHZh/Tv+xet3sy3F9Ld4FyI2tUpWe9x3XtPx9f1a0= -github.com/hashicorp/hcl/v2 v2.16.2/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= -github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= -github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= -github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -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/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -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= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -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= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/rboyer/safeio v0.2.2 h1:XhtqyUTRleMYGyBt3ni4j2BtEh669U2ry2INnnd+B4k= -github.com/rboyer/safeio v0.2.2/go.mod h1:pSnr2LFXyn/c/fotxotyOdYy7pP/XSh6MpBmzXPjiNc= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.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= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= -github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -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-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/testing/deployer/sprawl/acl.go b/testing/deployer/sprawl/acl.go deleted file mode 100644 index 6196d94d46f9f..0000000000000 --- a/testing/deployer/sprawl/acl.go +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "fmt" - "strings" - "time" - - "github.com/hashicorp/consul/api" - - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" - "github.com/hashicorp/consul/testing/deployer/topology" -) - -// TODO: fix this by checking that a token/policy works on ALL servers before -// returning from create. -func isACLNotFound(err error) bool { - if err == nil { - return false - } - return strings.Contains(err.Error(), `ACL not found`) -} - -func (s *Sprawl) bootstrapACLs(cluster string) error { - var ( - client = s.clients[cluster] - logger = s.logger.With("cluster", cluster) - mgmtToken = s.secrets.ReadGeneric(cluster, secrets.BootstrapToken) - ) - - ac := client.ACL() - - if mgmtToken != "" { - NOT_BOOTED: - ready, err := s.isACLBootstrapped(cluster, client) - if err != nil { - return fmt.Errorf("error checking if the acl system is bootstrapped: %w", err) - } else if !ready { - logger.Warn("ACL system is not ready yet") - time.Sleep(250 * time.Millisecond) - goto NOT_BOOTED - } - - TRYAGAIN: - // check to see if it works - _, _, err = ac.TokenReadSelf(&api.QueryOptions{Token: mgmtToken}) - if err != nil { - if isACLNotBootstrapped(err) { - logger.Warn("system is rebooting", "error", err) - time.Sleep(250 * time.Millisecond) - goto TRYAGAIN - } - - return fmt.Errorf("management token no longer works: %w", err) - } - - logger.Debug("current management token", "token", mgmtToken) - return nil - } - -TRYAGAIN2: - logger.Info("bootstrapping ACLs") - tok, _, err := ac.Bootstrap() - if err != nil { - if isACLNotBootstrapped(err) { - logger.Debug("system is rebooting", "error", err) - time.Sleep(250 * time.Millisecond) - goto TRYAGAIN2 - } - return err - } - mgmtToken = tok.SecretID - s.secrets.SaveGeneric(cluster, secrets.BootstrapToken, mgmtToken) - - logger.Debug("current management token", "token", mgmtToken) - - return nil - -} - -func isACLNotBootstrapped(err error) bool { - switch { - case strings.Contains(err.Error(), "ACL system must be bootstrapped before making any requests that require authorization"): - return true - case strings.Contains(err.Error(), "The ACL system is currently in legacy mode"): - return true - } - return false -} - -func (s *Sprawl) isACLBootstrapped(cluster string, client *api.Client) (bool, error) { - policy, _, err := client.ACL().PolicyReadByName("global-management", &api.QueryOptions{ - Token: s.secrets.ReadGeneric(cluster, secrets.BootstrapToken), - }) - if err != nil { - if strings.Contains(err.Error(), "Unexpected response code: 403 (ACL not found)") { - return false, nil - } else if isACLNotBootstrapped(err) { - return false, nil - } - return false, err - } - return policy != nil, nil -} - -func (s *Sprawl) createAnonymousToken(cluster *topology.Cluster) error { - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - if err := s.createAnonymousPolicy(cluster); err != nil { - return err - } - - token, err := CreateOrUpdateToken(client, anonymousToken()) - if err != nil { - return err - } - - logger.Debug("created anonymous token", - "token", token.SecretID, - ) - - return nil -} - -func (s *Sprawl) createAnonymousPolicy(cluster *topology.Cluster) error { - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - op, err := CreateOrUpdatePolicy(client, anonymousPolicy(cluster.Enterprise)) - if err != nil { - return err - } - - logger.Debug("created anonymous policy", - "policy-name", op.Name, - "policy-id", op.ID, - ) - - return nil -} - -func (s *Sprawl) createAgentTokens(cluster *topology.Cluster) error { - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - for _, node := range cluster.Nodes { - // NOTE: always create tokens even for disabled nodes. - if !node.IsAgent() { - continue - } - - if tok := s.secrets.ReadAgentToken(cluster.Name, node.ID()); tok == "" { - token, err := CreateOrUpdateToken(client, tokenForNode(node, cluster.Enterprise)) - if err != nil { - return err - } - - logger.Debug("created agent token", - "node", node.ID(), - "token", token.SecretID, - ) - - s.secrets.SaveAgentToken(cluster.Name, node.ID(), token.SecretID) - } - } - - return nil -} - -// Create a policy to allow super permissive catalog reads across namespace -// boundaries. -func (s *Sprawl) createCrossNamespaceCatalogReadPolicies(cluster *topology.Cluster, partition string) error { - if !cluster.Enterprise { - return nil - } - - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - op, err := CreateOrUpdatePolicy(client, policyForCrossNamespaceRead(partition)) - if err != nil { - return err - } - - logger.Debug("created cross-ns-catalog-read policy", - "policy-name", op.Name, - "policy-id", op.ID, - "partition", partition, - ) - - return nil -} - -func (s *Sprawl) createAllServiceTokens() error { - for _, cluster := range s.topology.Clusters { - if err := s.createServiceTokens(cluster); err != nil { - return fmt.Errorf("createServiceTokens[%s]: %w", cluster.Name, err) - } - } - return nil -} - -func (s *Sprawl) createServiceTokens(cluster *topology.Cluster) error { - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - sids := make(map[topology.ServiceID]struct{}) - for _, node := range cluster.Nodes { - if !node.RunsWorkloads() || len(node.Services) == 0 || node.Disabled { - continue - } - - for _, svc := range node.Services { - sid := svc.ID - - if _, done := sids[sid]; done { - continue - } - - var overridePolicy *api.ACLPolicy - if svc.IsMeshGateway { - var err error - overridePolicy, err = CreateOrUpdatePolicy(client, policyForMeshGateway(svc, cluster.Enterprise)) - if err != nil { - return fmt.Errorf("could not create policy: %w", err) - } - } - - token, err := CreateOrUpdateToken(client, tokenForService(svc, overridePolicy, cluster.Enterprise)) - if err != nil { - return fmt.Errorf("could not create token: %w", err) - } - - logger.Debug("created service token", - "service", svc.ID.Name, - "namespace", svc.ID.Namespace, - "partition", svc.ID.Partition, - "token", token.SecretID, - ) - - s.secrets.SaveServiceToken(cluster.Name, sid, token.SecretID) - - sids[sid] = struct{}{} - } - } - - return nil -} - -func CreateOrUpdateToken(client *api.Client, t *api.ACLToken) (*api.ACLToken, error) { - ac := client.ACL() - - currentToken, err := getTokenByDescription(client, t.Description, &api.QueryOptions{ - Partition: t.Partition, - Namespace: t.Namespace, - }) - if err != nil { - return nil, err - } else if currentToken != nil { - t.AccessorID = currentToken.AccessorID - t.SecretID = currentToken.SecretID - } - - if t.AccessorID != "" { - t, _, err = ac.TokenUpdate(t, nil) - } else { - t, _, err = ac.TokenCreate(t, nil) - } - if err != nil { - return nil, err - } - return t, nil -} - -func getTokenByDescription(client *api.Client, description string, opts *api.QueryOptions) (*api.ACLToken, error) { - ac := client.ACL() - tokens, _, err := ac.TokenList(opts) - if err != nil { - return nil, err - } - - for _, tokenEntry := range tokens { - if tokenEntry.Description == description { - token, _, err := ac.TokenRead(tokenEntry.AccessorID, opts) - if err != nil { - return nil, err - } - - return token, nil - } - } - return nil, nil -} - -func CreateOrUpdatePolicy(client *api.Client, p *api.ACLPolicy) (*api.ACLPolicy, error) { - ac := client.ACL() - - currentPolicy, _, err := ac.PolicyReadByName(p.Name, &api.QueryOptions{ - Partition: p.Partition, - Namespace: p.Namespace, - }) - - // There is a quirk about Consul 1.14.x, where: if reading a policy yields - // an empty result, we return "ACL not found". It's safe to ignore this here, - // because if the Client's ACL token truly doesn't exist, then the create fails below. - if err != nil && !strings.Contains(err.Error(), "ACL not found") { - return nil, err - } else if currentPolicy != nil { - p.ID = currentPolicy.ID - } - - if p.ID != "" { - p, _, err = ac.PolicyUpdate(p, nil) - } else { - p, _, err = ac.PolicyCreate(p, nil) - } - - if err != nil { - return nil, err - } - return p, nil -} diff --git a/testing/deployer/sprawl/acl_rules.go b/testing/deployer/sprawl/acl_rules.go deleted file mode 100644 index 7c360d85f6103..0000000000000 --- a/testing/deployer/sprawl/acl_rules.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "fmt" - - "github.com/hashicorp/consul/api" - - "github.com/hashicorp/consul/testing/deployer/topology" -) - -func policyForCrossNamespaceRead(partition string) *api.ACLPolicy { - return &api.ACLPolicy{ - Name: "cross-ns-catalog-read", - Description: "cross-ns-catalog-read", - Partition: partition, - Rules: fmt.Sprintf(` -partition %[1]q { - namespace_prefix "" { - node_prefix "" { policy = "read" } - service_prefix "" { policy = "read" } - } -} -`, partition), - } -} - -const anonymousTokenAccessorID = "00000000-0000-0000-0000-000000000002" - -func anonymousToken() *api.ACLToken { - return &api.ACLToken{ - AccessorID: anonymousTokenAccessorID, - // SecretID: "anonymous", - Description: "anonymous", - Local: false, - Policies: []*api.ACLTokenPolicyLink{ - { - Name: "anonymous", - }, - }, - } -} - -func anonymousPolicy(enterprise bool) *api.ACLPolicy { - p := &api.ACLPolicy{ - Name: "anonymous", - Description: "anonymous", - } - if enterprise { - p.Rules = ` -partition_prefix "" { - namespace_prefix "" { - node_prefix "" { policy = "read" } - service_prefix "" { policy = "read" } - } -} -` - } else { - p.Rules = ` -node_prefix "" { policy = "read" } -service_prefix "" { policy = "read" } -` - } - return p -} - -func tokenForNode(node *topology.Node, enterprise bool) *api.ACLToken { - nid := node.ID() - - tokenName := "agent--" + nid.ACLString() - - token := &api.ACLToken{ - Description: tokenName, - Local: false, - NodeIdentities: []*api.ACLNodeIdentity{{ - NodeName: node.PodName(), - Datacenter: node.Datacenter, - }}, - } - if enterprise { - token.Partition = node.Partition - token.Namespace = "default" - } - return token -} - -func tokenForService(svc *topology.Service, overridePolicy *api.ACLPolicy, enterprise bool) *api.ACLToken { - token := &api.ACLToken{ - Description: "service--" + svc.ID.ACLString(), - Local: false, - } - if overridePolicy != nil { - token.Policies = []*api.ACLTokenPolicyLink{{ID: overridePolicy.ID}} - } else { - token.ServiceIdentities = []*api.ACLServiceIdentity{{ - ServiceName: svc.ID.Name, - }} - } - - if enterprise { - token.Namespace = svc.ID.Namespace - token.Partition = svc.ID.Partition - } - - return token -} - -const ( - meshGatewayCommunityRules = ` -service "mesh-gateway" { - policy = "write" -} -service_prefix "" { - policy = "read" -} -node_prefix "" { - policy = "read" -} -agent_prefix "" { - policy = "read" -} -# for peering -mesh = "write" -peering = "read" -` - - meshGatewayEntDefaultRules = ` -namespace_prefix "" { - service "mesh-gateway" { - policy = "write" - } - service_prefix "" { - policy = "read" - } - node_prefix "" { - policy = "read" - } -} -agent_prefix "" { - policy = "read" -} -# for peering -mesh = "write" - -partition_prefix "" { - peering = "read" -} -` - - meshGatewayEntNonDefaultRules = ` -namespace_prefix "" { - service "mesh-gateway" { - policy = "write" - } - service_prefix "" { - policy = "read" - } - node_prefix "" { - policy = "read" - } -} -agent_prefix "" { - policy = "read" -} -# for peering -mesh = "write" -` -) - -func policyForMeshGateway(svc *topology.Service, enterprise bool) *api.ACLPolicy { - policyName := "mesh-gateway--" + svc.ID.ACLString() - - policy := &api.ACLPolicy{ - Name: policyName, - Description: policyName, - } - if enterprise { - policy.Partition = svc.ID.Partition - policy.Namespace = "default" - } - - if enterprise { - if svc.ID.Partition == "default" { - policy.Rules = meshGatewayEntDefaultRules - } else { - policy.Rules = meshGatewayEntNonDefaultRules - } - } else { - policy.Rules = meshGatewayCommunityRules - } - - return policy -} diff --git a/testing/deployer/sprawl/boot.go b/testing/deployer/sprawl/boot.go deleted file mode 100644 index 37656ca0ad873..0000000000000 --- a/testing/deployer/sprawl/boot.go +++ /dev/null @@ -1,524 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "context" - "crypto/rand" - "encoding/base64" - "errors" - "fmt" - "strings" - "time" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/build" - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/tfgen" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/consul/testing/deployer/util" -) - -const ( - sharedBootstrapToken = "root" - // sharedBootstrapToken = "ec59aa56-1996-4ff1-911a-f5d782552a13" - - sharedAgentRecoveryToken = "22082b05-05c9-4a0a-b3da-b9685ac1d688" -) - -func (s *Sprawl) launch() error { - return s.launchType(true) -} -func (s *Sprawl) relaunch() error { - return s.launchType(false) -} -func (s *Sprawl) launchType(firstTime bool) (launchErr error) { - if err := build.DockerImages(s.logger, s.runner, s.topology); err != nil { - return fmt.Errorf("build.DockerImages: %w", err) - } - - if firstTime { - // Initialize secrets the easy way for now (same in all clusters). - gossipKey, err := newGossipKey() - if err != nil { - return fmt.Errorf("newGossipKey: %w", err) - } - for _, cluster := range s.topology.Clusters { - s.secrets.SaveGeneric(cluster.Name, secrets.BootstrapToken, sharedBootstrapToken) - s.secrets.SaveGeneric(cluster.Name, secrets.AgentRecovery, sharedAgentRecoveryToken) - s.secrets.SaveGeneric(cluster.Name, secrets.GossipKey, gossipKey) - - // Give servers a copy of the bootstrap token for use as their agent tokens - // to avoid complicating the chicken/egg situation for startup. - for _, node := range cluster.Nodes { - if node.IsServer() { // include disabled - s.secrets.SaveAgentToken(cluster.Name, node.ID(), sharedBootstrapToken) - } - } - } - } - - var cleanupFuncs []func() - defer func() { - for i := len(cleanupFuncs) - 1; i >= 0; i-- { - cleanupFuncs[i]() - } - }() - - if firstTime { - var err error - s.generator, err = tfgen.NewGenerator( - s.logger.Named("tfgen"), - s.runner, - s.topology, - &s.secrets, - s.workdir, - s.license, - ) - if err != nil { - return err - } - } else { - s.generator.SetTopology(s.topology) - } - cleanupFuncs = append(cleanupFuncs, func() { - // Log the error before the cleanup so you don't have to wait to see - // the cause. - if launchErr != nil { - s.logger.Error("fatal error during launch", "error", launchErr) - } - - _ = s.generator.DestroyAllQuietly() - }) - - if firstTime { - // The networking phase is special. We have to pick a random subnet and - // hope. Once we have this established once it is immutable for future - // runs. - if err := s.initNetworkingAndVolumes(); err != nil { - return fmt.Errorf("initNetworkingAndVolumes: %w", err) - } - } - - if err := s.assignIPAddresses(); err != nil { - return fmt.Errorf("assignIPAddresses: %w", err) - } - - // The previous terraform run should have made the special volume for us. - if err := s.initTLS(context.TODO()); err != nil { - return fmt.Errorf("initTLS: %w", err) - } - - if firstTime { - if err := s.createFirstTime(); err != nil { - return err - } - - s.generator.MarkLaunched() - } else { - if err := s.updateExisting(); err != nil { - return err - } - } - - if err := s.waitForPeeringEstablishment(); err != nil { - return fmt.Errorf("waitForPeeringEstablishment: %w", err) - } - - cleanupFuncs = nil // reset - - return nil -} - -func (s *Sprawl) Stop() error { - var merr error - if s.generator != nil { - if err := s.generator.DestroyAllQuietly(); err != nil { - merr = multierror.Append(merr, err) - } - } - return merr -} - -const dockerOutOfNetworksErrorMessage = `Unable to create network: Error response from daemon: Pool overlaps with other one on this address space` - -var ErrDockerNetworkCollision = errors.New("could not create one or more docker networks for use due to subnet collision") - -func (s *Sprawl) initNetworkingAndVolumes() error { - var lastErr error - for attempts := 0; attempts < 5; attempts++ { - err := s.generator.Generate(tfgen.StepNetworks) - if err != nil && strings.Contains(err.Error(), dockerOutOfNetworksErrorMessage) { - lastErr = ErrDockerNetworkCollision - s.logger.Warn(ErrDockerNetworkCollision.Error()+"; retrying", "attempt", attempts+1) - time.Sleep(1 * time.Second) - continue - } else if err != nil { - return fmt.Errorf("generator[networks]: %w", err) - } - return nil - } - - return lastErr -} - -func (s *Sprawl) assignIPAddresses() error { - // assign ips now that we have network ips known to us - for _, net := range s.topology.Networks { - if len(net.IPPool) == 0 { - return fmt.Errorf("network %q does not have any ip assignments", net.Name) - } - } - for _, cluster := range s.topology.Clusters { - for _, node := range cluster.Nodes { - for _, addr := range node.Addresses { - net, ok := s.topology.Networks[addr.Network] - if !ok { - return fmt.Errorf("unknown network %q", addr.Network) - } - addr.IPAddress = net.IPByIndex(node.Index) - s.logger.Info("assign addr", "node", node.Name, "addr", addr.IPAddress) - } - } - } - - return nil -} - -func (s *Sprawl) initConsulServers() error { - if err := s.generator.Generate(tfgen.StepServers); err != nil { - return fmt.Errorf("generator[servers]: %w", err) - } - - // s.logger.Info("ALL", "t", jd(s.topology)) // TODO - - // Create token-less api clients first. - for _, cluster := range s.topology.Clusters { - node := cluster.FirstServer() - - var err error - s.clients[cluster.Name], err = util.ProxyAPIClient( - node.LocalProxyPort(), - node.LocalAddress(), - 8500, - "", /*no token yet*/ - ) - if err != nil { - return fmt.Errorf("error creating initial bootstrap client for cluster=%s: %w", cluster.Name, err) - } - } - - if err := s.rejoinAllConsulServers(); err != nil { - return err - } - - for _, cluster := range s.topology.Clusters { - err := s.bootstrapACLs(cluster.Name) - if err != nil { - return fmt.Errorf("bootstrap[%s]: %w", cluster.Name, err) - } - - mgmtToken := s.secrets.ReadGeneric(cluster.Name, secrets.BootstrapToken) - - // Reconfigure the clients to use a management token. - node := cluster.FirstServer() - s.clients[cluster.Name], err = util.ProxyAPIClient( - node.LocalProxyPort(), - node.LocalAddress(), - 8500, - mgmtToken, - ) - if err != nil { - return fmt.Errorf("error creating final client for cluster=%s: %v", cluster.Name, err) - } - - // For some reason the grpc resolver stuff for partitions takes some - // time to get ready. - s.waitForLocalWrites(cluster, mgmtToken) - - // Create tenancies so that the ACL tokens and clients have somewhere to go. - if cluster.Enterprise { - if err := s.initTenancies(cluster); err != nil { - return fmt.Errorf("initTenancies[%s]: %w", cluster.Name, err) - } - } - - if err := s.populateInitialConfigEntries(cluster); err != nil { - return fmt.Errorf("populateInitialConfigEntries[%s]: %w", cluster.Name, err) - } - - if err := s.createAnonymousToken(cluster); err != nil { - return fmt.Errorf("createAnonymousToken[%s]: %w", cluster.Name, err) - } - - // Create tokens for all of the agents to use for anti-entropy. - // - // NOTE: this will cause the servers to roll to pick up the change to - // the acl{tokens{agent=XXX}}} section. - if err := s.createAgentTokens(cluster); err != nil { - return fmt.Errorf("createAgentTokens[%s]: %w", cluster.Name, err) - } - } - - return nil -} - -func (s *Sprawl) createFirstTime() error { - if err := s.initConsulServers(); err != nil { - return fmt.Errorf("initConsulServers: %w", err) - } - - if err := s.generator.Generate(tfgen.StepAgents); err != nil { - return fmt.Errorf("generator[agents]: %w", err) - } - for _, cluster := range s.topology.Clusters { - if err := s.waitForClientAntiEntropyOnce(cluster); err != nil { - return fmt.Errorf("waitForClientAntiEntropyOnce[%s]: %w", cluster.Name, err) - } - } - - // Ideally we start services WITH a token initially, so we pre-create them - // before running terraform for them. - if err := s.createAllServiceTokens(); err != nil { - return fmt.Errorf("createAllServiceTokens: %w", err) - } - - if err := s.registerAllServicesForDataplaneInstances(); err != nil { - return fmt.Errorf("registerAllServicesForDataplaneInstances: %w", err) - } - - // We can do this ahead, because we've incrementally run terraform as - // we went. - if err := s.registerAllServicesToAgents(); err != nil { - return fmt.Errorf("registerAllServicesToAgents: %w", err) - } - - // NOTE: start services WITH token initially - if err := s.generator.Generate(tfgen.StepServices); err != nil { - return fmt.Errorf("generator[services]: %w", err) - } - - if err := s.initPeerings(); err != nil { - return fmt.Errorf("initPeerings: %w", err) - } - return nil -} - -func (s *Sprawl) updateExisting() error { - if err := s.preRegenTasks(); err != nil { - return fmt.Errorf("preRegenTasks: %w", err) - } - - // We save all of the terraform to the end. Some of the containers will - // be a little broken until we can do stuff like register services to - // new agents, which we cannot do until they come up. - if err := s.generator.Generate(tfgen.StepRelaunch); err != nil { - return fmt.Errorf("generator[relaunch]: %w", err) - } - - if err := s.postRegenTasks(); err != nil { - return fmt.Errorf("postRegenTasks: %w", err) - } - - // TODO: enforce that peering relationships cannot change - // TODO: include a fixup version of new peerings? - - return nil -} - -func (s *Sprawl) preRegenTasks() error { - for _, cluster := range s.topology.Clusters { - // Create tenancies so that the ACL tokens and clients have somewhere to go. - if cluster.Enterprise { - if err := s.initTenancies(cluster); err != nil { - return fmt.Errorf("initTenancies[%s]: %w", cluster.Name, err) - } - } - - if err := s.populateInitialConfigEntries(cluster); err != nil { - return fmt.Errorf("populateInitialConfigEntries[%s]: %w", cluster.Name, err) - } - - // Create tokens for all of the agents to use for anti-entropy. - if err := s.createAgentTokens(cluster); err != nil { - return fmt.Errorf("createAgentTokens[%s]: %w", cluster.Name, err) - } - } - - // Ideally we start services WITH a token initially, so we pre-create them - // before running terraform for them. - if err := s.createAllServiceTokens(); err != nil { - return fmt.Errorf("createAllServiceTokens: %w", err) - } - - if err := s.registerAllServicesForDataplaneInstances(); err != nil { - return fmt.Errorf("registerAllServicesForDataplaneInstances: %w", err) - } - - return nil -} - -func (s *Sprawl) postRegenTasks() error { - if err := s.rejoinAllConsulServers(); err != nil { - return err - } - - for _, cluster := range s.topology.Clusters { - var err error - - mgmtToken := s.secrets.ReadGeneric(cluster.Name, secrets.BootstrapToken) - - // Reconfigure the clients to use a management token. - node := cluster.FirstServer() - s.clients[cluster.Name], err = util.ProxyAPIClient( - node.LocalProxyPort(), - node.LocalAddress(), - 8500, - mgmtToken, - ) - if err != nil { - return fmt.Errorf("error creating final client for cluster=%s: %v", cluster.Name, err) - } - - s.waitForLeader(cluster) - - // For some reason the grpc resolver stuff for partitions takes some - // time to get ready. - s.waitForLocalWrites(cluster, mgmtToken) - } - - for _, cluster := range s.topology.Clusters { - if err := s.waitForClientAntiEntropyOnce(cluster); err != nil { - return fmt.Errorf("waitForClientAntiEntropyOnce[%s]: %w", cluster.Name, err) - } - } - - if err := s.registerAllServicesToAgents(); err != nil { - return fmt.Errorf("registerAllServicesToAgents: %w", err) - } - - return nil -} - -func (s *Sprawl) waitForLocalWrites(cluster *topology.Cluster, token string) { - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - tryKV := func() error { - _, err := client.KV().Put(&api.KVPair{ - Key: "local-test", - Value: []byte("payload-for-local-test-in-" + cluster.Name), - }, nil) - return err - } - tryAP := func() error { - if !cluster.Enterprise { - return nil - } - _, _, err := client.Partitions().Create(context.Background(), &api.Partition{ - Name: "placeholder", - }, &api.WriteOptions{Token: token}) - return err - } - - start := time.Now() - for attempts := 0; ; attempts++ { - if err := tryKV(); err != nil { - logger.Debug("local kv write failed; something is not ready yet", "error", err) - time.Sleep(500 * time.Millisecond) - continue - } else { - dur := time.Since(start) - logger.Debug("local kv write success", "elapsed", dur, "retries", attempts) - } - - break - } - - if cluster.Enterprise { - start = time.Now() - for attempts := 0; ; attempts++ { - if err := tryAP(); err != nil { - logger.Debug("local partition write failed; something is not ready yet", "error", err) - time.Sleep(500 * time.Millisecond) - continue - } else { - dur := time.Since(start) - logger.Debug("local partition write success", "elapsed", dur, "retries", attempts) - } - - break - } - } -} - -func (s *Sprawl) waitForClientAntiEntropyOnce(cluster *topology.Cluster) error { - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - var ( - queryOptionList = cluster.PartitionQueryOptionsList() - start = time.Now() - cc = client.Catalog() - ) - for { - // Enumerate all of the nodes that are currently in the catalog. This - // will overmatch including things like fake nodes for agentless but - // that's ok. - current := make(map[topology.NodeID]*api.Node) - for _, queryOpts := range queryOptionList { - nodes, _, err := cc.Nodes(queryOpts) - if err != nil { - return err - } - for _, node := range nodes { - nid := topology.NewNodeID(node.Node, node.Partition) - current[nid] = node - } - } - - // See if we have them all. - var stragglers []topology.NodeID - for _, node := range cluster.Nodes { - if !node.IsAgent() || node.Disabled { - continue - } - nid := node.CatalogID() - - got, ok := current[nid] - if ok && len(got.TaggedAddresses) > 0 { - // this is a field that is not updated just due to serf reconcile - continue - } - - stragglers = append(stragglers, nid) - } - - if len(stragglers) == 0 { - dur := time.Since(start) - logger.Debug("all nodes have posted node updates, so first anti-entropy has happened", "elapsed", dur) - return nil - } - logger.Debug("not all nodes have posted node updates yet", "nodes", stragglers) - - time.Sleep(1 * time.Second) - } -} - -func newGossipKey() (string, error) { - key := make([]byte, 16) - n, err := rand.Reader.Read(key) - if err != nil { - return "", fmt.Errorf("error reading random data: %s", err) - } - if n != 16 { - return "", fmt.Errorf("couldn't read enough entropy. Generate more entropy") - } - return base64.StdEncoding.EncodeToString(key), nil -} diff --git a/testing/deployer/sprawl/catalog.go b/testing/deployer/sprawl/catalog.go deleted file mode 100644 index fc5d2dbc399d5..0000000000000 --- a/testing/deployer/sprawl/catalog.go +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "fmt" - "net/http" - "time" - - "github.com/hashicorp/consul/api" - - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/consul/testing/deployer/util" -) - -func (s *Sprawl) registerAllServicesToAgents() error { - for _, cluster := range s.topology.Clusters { - if err := s.registerServicesToAgents(cluster); err != nil { - return fmt.Errorf("registerServicesToAgents[%s]: %w", cluster.Name, err) - } - } - return nil -} - -func (s *Sprawl) registerAllServicesForDataplaneInstances() error { - for _, cluster := range s.topology.Clusters { - if err := s.registerServicesForDataplaneInstances(cluster); err != nil { - return fmt.Errorf("registerServicesForDataplaneInstances[%s]: %w", cluster.Name, err) - } - } - return nil -} - -func (s *Sprawl) registerServicesToAgents(cluster *topology.Cluster) error { - for _, node := range cluster.Nodes { - if !node.RunsWorkloads() || len(node.Services) == 0 || node.Disabled { - continue - } - - if !node.IsAgent() { - continue - } - - agentClient, err := util.ProxyAPIClient( - node.LocalProxyPort(), - node.LocalAddress(), - 8500, - "", /*token will be in request*/ - ) - if err != nil { - return err - } - - for _, svc := range node.Services { - if err := s.registerAgentService(agentClient, cluster, node, svc); err != nil { - return err - } - } - } - - return nil -} - -func (s *Sprawl) registerAgentService( - agentClient *api.Client, - cluster *topology.Cluster, - node *topology.Node, - svc *topology.Service, -) error { - if !node.IsAgent() { - panic("called wrong method type") - } - - if svc.IsMeshGateway { - return nil // handled at startup time for agent-full, but won't be for agent-less - } - - var ( - logger = s.logger.With("cluster", cluster.Name) - ) - - reg := &api.AgentServiceRegistration{ - ID: svc.ID.Name, - Name: svc.ID.Name, - Port: svc.Port, - Meta: svc.Meta, - } - if cluster.Enterprise { - reg.Namespace = svc.ID.Namespace - reg.Partition = svc.ID.Partition - } - - if !svc.DisableServiceMesh { - var upstreams []api.Upstream - for _, u := range svc.Upstreams { - uAPI := api.Upstream{ - DestinationPeer: u.Peer, - DestinationName: u.ID.Name, - LocalBindAddress: u.LocalAddress, - LocalBindPort: u.LocalPort, - // Config map[string]interface{} `json:",omitempty" bexpr:"-"` - // MeshGateway MeshGatewayConfig `json:",omitempty"` - } - if cluster.Enterprise { - uAPI.DestinationNamespace = u.ID.Namespace - if u.Peer == "" { - uAPI.DestinationPartition = u.ID.Partition - } - } - upstreams = append(upstreams, uAPI) - } - reg.Connect = &api.AgentServiceConnect{ - SidecarService: &api.AgentServiceRegistration{ - Proxy: &api.AgentServiceConnectProxyConfig{ - Upstreams: upstreams, - }, - }, - } - } - - switch { - case svc.CheckTCP != "": - chk := &api.AgentServiceCheck{ - Name: "up", - TCP: svc.CheckTCP, - Interval: "5s", - Timeout: "1s", - } - reg.Checks = append(reg.Checks, chk) - case svc.CheckHTTP != "": - chk := &api.AgentServiceCheck{ - Name: "up", - HTTP: svc.CheckHTTP, - Method: "GET", - Interval: "5s", - Timeout: "1s", - } - reg.Checks = append(reg.Checks, chk) - } - - // Switch token for every request. - hdr := make(http.Header) - hdr.Set("X-Consul-Token", s.secrets.ReadServiceToken(cluster.Name, svc.ID)) - agentClient.SetHeaders(hdr) - -RETRY: - if err := agentClient.Agent().ServiceRegister(reg); err != nil { - if isACLNotFound(err) { - time.Sleep(50 * time.Millisecond) - goto RETRY - } - return fmt.Errorf("failed to register service %q to node %q: %w", svc.ID, node.ID(), err) - } - - logger.Debug("registered service to client agent", - "service", svc.ID.Name, - "node", node.Name, - "namespace", svc.ID.Namespace, - "partition", svc.ID.Partition, - ) - - return nil -} - -func (s *Sprawl) registerServicesForDataplaneInstances(cluster *topology.Cluster) error { - for _, node := range cluster.Nodes { - if !node.RunsWorkloads() || len(node.Services) == 0 || node.Disabled { - continue - } - - if !node.IsDataplane() { - continue - } - - if err := s.registerCatalogNode(cluster, node); err != nil { - return fmt.Errorf("error registering virtual node: %w", err) - } - - for _, svc := range node.Services { - if err := s.registerCatalogService(cluster, node, svc); err != nil { - return fmt.Errorf("error registering service: %w", err) - } - if !svc.DisableServiceMesh { - if err := s.registerCatalogSidecarService(cluster, node, svc); err != nil { - return fmt.Errorf("error registering sidecar service: %w", err) - } - } - } - } - - return nil -} - -func (s *Sprawl) registerCatalogNode( - cluster *topology.Cluster, - node *topology.Node, -) error { - if !node.IsDataplane() { - panic("called wrong method type") - } - - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - reg := &api.CatalogRegistration{ - Node: node.PodName(), - Address: node.LocalAddress(), - NodeMeta: map[string]string{ - "dataplane-faux": "1", - }, - } - if cluster.Enterprise { - reg.Partition = node.Partition - } - - // register synthetic node -RETRY: - if _, err := client.Catalog().Register(reg, nil); err != nil { - if isACLNotFound(err) { - time.Sleep(50 * time.Millisecond) - goto RETRY - } - return fmt.Errorf("error registering virtual node %s: %w", node.ID(), err) - } - - logger.Debug("virtual node created", - "node", node.ID(), - ) - - return nil -} - -func (s *Sprawl) registerCatalogService( - cluster *topology.Cluster, - node *topology.Node, - svc *topology.Service, -) error { - if !node.IsDataplane() { - panic("called wrong method type") - } - - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - reg := serviceToCatalogRegistration(cluster, node, svc) - -RETRY: - if _, err := client.Catalog().Register(reg, nil); err != nil { - if isACLNotFound(err) { - time.Sleep(50 * time.Millisecond) - goto RETRY - } - return fmt.Errorf("error registering service %s to node %s: %w", svc.ID, node.ID(), err) - } - - logger.Debug("dataplane service created", - "service", svc.ID, - "node", node.ID(), - ) - - return nil -} - -func (s *Sprawl) registerCatalogSidecarService( - cluster *topology.Cluster, - node *topology.Node, - svc *topology.Service, -) error { - if !node.IsDataplane() { - panic("called wrong method type") - } - if svc.DisableServiceMesh { - panic("not valid") - } - - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - pid, reg := serviceToSidecarCatalogRegistration(cluster, node, svc) -RETRY: - if _, err := client.Catalog().Register(reg, nil); err != nil { - if isACLNotFound(err) { - time.Sleep(50 * time.Millisecond) - goto RETRY - } - return fmt.Errorf("error registering service %s to node %s: %w", svc.ID, node.ID(), err) - } - - logger.Debug("dataplane sidecar service created", - "service", pid, - "node", node.ID(), - ) - - return nil -} - -func serviceToCatalogRegistration( - cluster *topology.Cluster, - node *topology.Node, - svc *topology.Service, -) *api.CatalogRegistration { - reg := &api.CatalogRegistration{ - Node: node.PodName(), - SkipNodeUpdate: true, - Service: &api.AgentService{ - Kind: api.ServiceKindTypical, - ID: svc.ID.Name, - Service: svc.ID.Name, - Meta: svc.Meta, - Port: svc.Port, - Address: node.LocalAddress(), - }, - } - if svc.IsMeshGateway { - reg.Service.Kind = api.ServiceKindMeshGateway - reg.Service.Proxy = &api.AgentServiceConnectProxyConfig{ - Config: map[string]interface{}{ - "envoy_gateway_no_default_bind": true, - "envoy_gateway_bind_tagged_addresses": true, - }, - MeshGateway: api.MeshGatewayConfig{ - Mode: api.MeshGatewayModeLocal, - }, - } - } - if node.HasPublicAddress() { - reg.TaggedAddresses = map[string]string{ - "lan": node.LocalAddress(), - "lan_ipv4": node.LocalAddress(), - "wan": node.PublicAddress(), - "wan_ipv4": node.PublicAddress(), - } - // TODO: not sure what the difference is between these, but with just the - // top-level set, it appeared to not get set in either :/ - reg.Service.TaggedAddresses = map[string]api.ServiceAddress{ - "lan": { - Address: node.LocalAddress(), - Port: svc.Port, - }, - "lan_ipv4": { - Address: node.LocalAddress(), - Port: svc.Port, - }, - "wan": { - Address: node.PublicAddress(), - Port: svc.Port, - }, - "wan_ipv4": { - Address: node.PublicAddress(), - Port: svc.Port, - }, - } - } - if cluster.Enterprise { - reg.Partition = svc.ID.Partition - reg.Service.Namespace = svc.ID.Namespace - reg.Service.Partition = svc.ID.Partition - } - - if svc.HasCheck() { - chk := &api.HealthCheck{ - Name: "external sync", - // Type: "external-sync", - Status: "passing", // TODO - ServiceID: svc.ID.Name, - ServiceName: svc.ID.Name, - Output: "", - } - if cluster.Enterprise { - chk.Namespace = svc.ID.Namespace - chk.Partition = svc.ID.Partition - } - switch { - case svc.CheckTCP != "": - chk.Definition.TCP = svc.CheckTCP - case svc.CheckHTTP != "": - chk.Definition.HTTP = svc.CheckHTTP - chk.Definition.Method = "GET" - } - reg.Checks = append(reg.Checks, chk) - } - return reg -} - -func serviceToSidecarCatalogRegistration( - cluster *topology.Cluster, - node *topology.Node, - svc *topology.Service, -) (topology.ServiceID, *api.CatalogRegistration) { - pid := svc.ID - pid.Name += "-sidecar-proxy" - reg := &api.CatalogRegistration{ - Node: node.PodName(), - SkipNodeUpdate: true, - Service: &api.AgentService{ - Kind: api.ServiceKindConnectProxy, - ID: pid.Name, - Service: pid.Name, - Meta: svc.Meta, - Port: svc.EnvoyPublicListenerPort, - Address: node.LocalAddress(), - Proxy: &api.AgentServiceConnectProxyConfig{ - DestinationServiceName: svc.ID.Name, - DestinationServiceID: svc.ID.Name, - LocalServicePort: svc.Port, - }, - }, - Checks: []*api.HealthCheck{{ - Name: "external sync", - // Type: "external-sync", - Status: "passing", // TODO - ServiceID: pid.Name, - ServiceName: pid.Name, - Definition: api.HealthCheckDefinition{ - TCP: fmt.Sprintf("%s:%d", node.LocalAddress(), svc.EnvoyPublicListenerPort), - }, - Output: "", - }}, - } - if node.HasPublicAddress() { - reg.TaggedAddresses = map[string]string{ - "lan": node.LocalAddress(), - "lan_ipv4": node.LocalAddress(), - "wan": node.PublicAddress(), - "wan_ipv4": node.PublicAddress(), - } - } - if cluster.Enterprise { - reg.Partition = pid.Partition - reg.Service.Namespace = pid.Namespace - reg.Service.Partition = pid.Partition - reg.Checks[0].Namespace = pid.Namespace - reg.Checks[0].Partition = pid.Partition - } - - for _, u := range svc.Upstreams { - pu := api.Upstream{ - DestinationName: u.ID.Name, - DestinationPeer: u.Peer, - LocalBindAddress: u.LocalAddress, - LocalBindPort: u.LocalPort, - } - if cluster.Enterprise { - pu.DestinationNamespace = u.ID.Namespace - if u.Peer == "" { - pu.DestinationPartition = u.ID.Partition - } - } - reg.Service.Proxy.Upstreams = append(reg.Service.Proxy.Upstreams, pu) - } - - return pid, reg -} diff --git a/testing/deployer/sprawl/configentries.go b/testing/deployer/sprawl/configentries.go deleted file mode 100644 index b22a22aeaecf9..0000000000000 --- a/testing/deployer/sprawl/configentries.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "fmt" - "strings" - "time" - - "github.com/hashicorp/consul/api" - - "github.com/hashicorp/consul/testing/deployer/topology" -) - -func (s *Sprawl) populateInitialConfigEntries(cluster *topology.Cluster) error { - if len(cluster.InitialConfigEntries) == 0 { - return nil - } - - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - for _, ce := range cluster.InitialConfigEntries { - _, _, err := client.ConfigEntries().Set(ce, nil) - if err != nil { - if ce.GetKind() == api.ServiceIntentions && strings.Contains(err.Error(), intentionsMigrationError) { - logger.Warn("known error writing initial config entry; trying again", - "kind", ce.GetKind(), - "name", ce.GetName(), - "namespace", ce.GetNamespace(), - "partition", ce.GetPartition(), - "error", err, - ) - - time.Sleep(500 * time.Millisecond) - continue - } - return fmt.Errorf( - "error persisting config entry kind=%q name=%q namespace=%q partition=%q: %w", - ce.GetKind(), - ce.GetName(), - ce.GetNamespace(), - ce.GetPartition(), - err, - ) - } - logger.Debug("wrote initial config entry", - "kind", ce.GetKind(), - "name", ce.GetName(), - "namespace", ce.GetNamespace(), - "partition", ce.GetPartition(), - ) - } - - return nil -} - -const intentionsMigrationError = `Intentions are read only while being upgraded to config entries` diff --git a/testing/deployer/sprawl/consul.go b/testing/deployer/sprawl/consul.go deleted file mode 100644 index 2693135784153..0000000000000 --- a/testing/deployer/sprawl/consul.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "errors" - "fmt" - "time" - - "github.com/hashicorp/consul/api" - - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/consul/testing/deployer/util" -) - -func getLeader(client *api.Client) (string, error) { - leaderAdd, err := client.Status().Leader() - if err != nil { - return "", fmt.Errorf("could not query leader: %w", err) - } - if leaderAdd == "" { - return "", errors.New("no leader available") - } - return leaderAdd, nil -} - -func (s *Sprawl) waitForLeader(cluster *topology.Cluster) { - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - logger.Info("waiting for cluster to elect leader") - for { - leader, err := client.Status().Leader() - if leader != "" && err == nil { - logger.Info("cluster has leader", "leader_addr", leader) - return - } - logger.Debug("cluster has no leader yet", "error", err) - time.Sleep(500 * time.Millisecond) - } -} - -func (s *Sprawl) rejoinAllConsulServers() error { - // Join the servers together. - for _, cluster := range s.topology.Clusters { - if err := s.rejoinServers(cluster); err != nil { - return fmt.Errorf("rejoinServers[%s]: %w", cluster.Name, err) - } - s.waitForLeader(cluster) - } - return nil -} - -func (s *Sprawl) rejoinServers(cluster *topology.Cluster) error { - var ( - // client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - servers := cluster.ServerNodes() - - recoveryToken := s.secrets.ReadGeneric(cluster.Name, secrets.AgentRecovery) - - node0, rest := servers[0], servers[1:] - client, err := util.ProxyNotPooledAPIClient( - node0.LocalProxyPort(), - node0.LocalAddress(), - 8500, - recoveryToken, - ) - if err != nil { - return fmt.Errorf("could not get client for %q: %w", node0.ID(), err) - } - - logger.Info("joining servers together", - "from", node0.ID(), - "rest", nodeSliceToNodeIDSlice(rest), - ) - for _, node := range rest { - for { - err = client.Agent().Join(node.LocalAddress(), false) - if err == nil { - break - } - logger.Warn("could not join", "from", node0.ID(), "to", node.ID(), "error", err) - time.Sleep(500 * time.Millisecond) - } - } - - return nil -} - -func nodeSliceToNodeIDSlice(nodes []*topology.Node) []topology.NodeID { - var out []topology.NodeID - for _, node := range nodes { - out = append(out, node.ID()) - } - return out -} diff --git a/testing/deployer/sprawl/debug.go b/testing/deployer/sprawl/debug.go deleted file mode 100644 index df11f96c3c8b6..0000000000000 --- a/testing/deployer/sprawl/debug.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import "encoding/json" - -func jd(v any) string { - b, _ := json.MarshalIndent(v, "", " ") - return string(b) -} diff --git a/testing/deployer/sprawl/details.go b/testing/deployer/sprawl/details.go deleted file mode 100644 index c463d310d873c..0000000000000 --- a/testing/deployer/sprawl/details.go +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "bytes" - "fmt" - "sort" - "strconv" - "strings" - "text/tabwriter" -) - -// PrintDetails will dump relevant addressing and naming data to the logger for -// human interaction purposes. -func (s *Sprawl) PrintDetails() error { - det := logDetails{ - TopologyID: s.topology.ID, - } - - for _, cluster := range s.topology.Clusters { - client := s.clients[cluster.Name] - - cfg, err := client.Operator().RaftGetConfiguration(nil) - if err != nil { - return fmt.Errorf("could not get raft config for cluster %q: %w", cluster.Name, err) - } - - var leaderNode string - for _, svr := range cfg.Servers { - if svr.Leader { - leaderNode = strings.TrimSuffix(svr.Node, "-pod") - } - } - - cd := clusterDetails{ - Name: cluster.Name, - Leader: leaderNode, - } - - for _, node := range cluster.Nodes { - if node.Disabled { - continue - } - - var addrs []string - for _, addr := range node.Addresses { - addrs = append(addrs, addr.Network+"="+addr.IPAddress) - } - sort.Strings(addrs) - - if node.IsServer() { - cd.Apps = append(cd.Apps, appDetail{ - Type: "server", - Container: node.DockerName(), - Addresses: addrs, - ExposedPort: node.ExposedPort(8500), - }) - } - - for _, svc := range node.Services { - if svc.IsMeshGateway { - cd.Apps = append(cd.Apps, appDetail{ - Type: "mesh-gateway", - Container: node.DockerName(), - ExposedPort: node.ExposedPort(svc.Port), - ExposedEnvoyAdminPort: node.ExposedPort(svc.EnvoyAdminPort), - Addresses: addrs, - Service: svc.ID.String(), - }) - } else { - cd.Apps = append(cd.Apps, appDetail{ - Type: "app", - Container: node.DockerName(), - ExposedPort: node.ExposedPort(svc.Port), - ExposedEnvoyAdminPort: node.ExposedPort(svc.EnvoyAdminPort), - Addresses: addrs, - Service: svc.ID.String(), - }) - } - } - } - - det.Clusters = append(det.Clusters, cd) - } - - var buf bytes.Buffer - w := tabwriter.NewWriter(&buf, 0, 0, 3, ' ', tabwriter.Debug) - - score := map[string]int{ - "server": 0, - "mesh-gateway": 1, - "app": 2, - } - - for _, cluster := range det.Clusters { - fmt.Fprintf(w, "CLUSTER\tTYPE\tCONTAINER\tNAME\tADDRS\tPORTS\t\n") - sort.Slice(cluster.Apps, func(i, j int) bool { - a := cluster.Apps[i] - b := cluster.Apps[j] - - asc := score[a.Type] - bsc := score[b.Type] - - if asc < bsc { - return true - } else if asc > bsc { - return false - } - - if a.Container < b.Container { - return true - } else if a.Container > b.Container { - return false - } - - if a.Service < b.Service { - return true - } else if a.Service > b.Service { - return false - } - - return a.ExposedPort < b.ExposedPort - }) - for _, d := range cluster.Apps { - if d.Type == "server" && d.Container == cluster.Leader { - d.Type = "leader" - } - portStr := "app=" + strconv.Itoa(d.ExposedPort) - if d.ExposedEnvoyAdminPort > 0 { - portStr += " envoy=" + strconv.Itoa(d.ExposedEnvoyAdminPort) - } - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t\n", - cluster.Name, - d.Type, - d.Container, - d.Service, - strings.Join(d.Addresses, ", "), - portStr, - ) - } - fmt.Fprintf(w, "\t\t\t\t\t\n") - } - - w.Flush() - - s.logger.Debug("CURRENT SPRAWL DETAILS", "details", buf.String()) - - return nil -} - -type logDetails struct { - TopologyID string - Clusters []clusterDetails -} - -type clusterDetails struct { - Name string - - Leader string - Apps []appDetail -} - -type appDetail struct { - Type string // server|mesh-gateway|app - Container string - Addresses []string - ExposedPort int `json:",omitempty"` - ExposedEnvoyAdminPort int `json:",omitempty"` - // just services - Service string `json:",omitempty"` -} diff --git a/testing/deployer/sprawl/ent.go b/testing/deployer/sprawl/ent.go deleted file mode 100644 index fcff5fa7a0049..0000000000000 --- a/testing/deployer/sprawl/ent.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "bytes" - "context" - "fmt" - "os" - "strings" - "time" - - "github.com/hashicorp/consul/api" - - "github.com/hashicorp/consul/testing/deployer/topology" -) - -func (s *Sprawl) ensureLicense() error { - if s.license != "" { - return nil - } - v, err := readLicense() - if err != nil { - return err - } - s.license = v - return nil -} - -func readLicense() (string, error) { - if license := os.Getenv("CONSUL_LICENSE"); license != "" { - return license, nil - } - - licensePath := os.Getenv("CONSUL_LICENSE_PATH") - if licensePath == "" { - return "", nil - } - - licenseBytes, err := os.ReadFile(licensePath) - if err != nil { - return "", err - } - return strings.TrimSpace(string(licenseBytes)), nil -} - -func (s *Sprawl) initTenancies(cluster *topology.Cluster) error { - var ( - client = s.clients[cluster.Name] - logger = s.logger.With("cluster", cluster.Name) - ) - - // TODO: change this to UPSERT - - var ( - partClient = client.Partitions() - nsClient = client.Namespaces() - - partitionNameList []string - ) - for _, ap := range cluster.Partitions { - if ap.Name != "default" { - old, _, err := partClient.Read(context.Background(), ap.Name, nil) - if err != nil { - return fmt.Errorf("error reading partition %q: %w", ap.Name, err) - } - if old == nil { - obj := &api.Partition{ - Name: ap.Name, - } - - _, _, err := partClient.Create(context.Background(), obj, nil) - if err != nil { - return fmt.Errorf("error creating partition %q: %w", ap.Name, err) - } - logger.Debug("created partition", "partition", ap.Name) - } - - partitionNameList = append(partitionNameList, ap.Name) - } - - if err := s.createCrossNamespaceCatalogReadPolicies(cluster, ap.Name); err != nil { - return fmt.Errorf("createCrossNamespaceCatalogReadPolicies[%s]: %w", ap.Name, err) - } - - for _, ns := range ap.Namespaces { - old, _, err := nsClient.Read(ns, &api.QueryOptions{Partition: ap.Name}) - if err != nil { - return err - } - - if old == nil { - obj := &api.Namespace{ - Partition: ap.Name, - Name: ns, - ACLs: &api.NamespaceACLConfig{ - PolicyDefaults: []api.ACLLink{ - {Name: "cross-ns-catalog-read"}, - }, - }, - } - if ns == "default" { - _, _, err := nsClient.Update(obj, nil) - if err != nil { - return err - } - logger.Debug("updated namespace", "namespace", ns, "partition", ap.Name) - } else { - _, _, err := nsClient.Create(obj, nil) - if err != nil { - return err - } - logger.Debug("created namespace", "namespace", ns, "partition", ap.Name) - } - } - } - } - - if err := s.waitUntilPartitionedSerfIsReady(context.TODO(), cluster, partitionNameList); err != nil { - return fmt.Errorf("waitUntilPartitionedSerfIsReady: %w", err) - } - - return nil -} - -func (s *Sprawl) waitUntilPartitionedSerfIsReady(ctx context.Context, cluster *topology.Cluster, partitions []string) error { - var ( - logger = s.logger.With("cluster", cluster.Name) - ) - - readyLogs := make(map[string]string) - for _, partition := range partitions { - readyLogs[partition] = `agent.server: Added serf partition to gossip network: partition=` + partition - } - - start := time.Now() - logger.Info("waiting for partitioned serf to be ready on all servers", "partitions", partitions) - for _, node := range cluster.Nodes { - if !node.IsServer() || node.Disabled { - continue - } - - var buf bytes.Buffer - for { - buf.Reset() - - err := s.runner.DockerExec(ctx, []string{ - "logs", node.DockerName(), - }, &buf, nil) - if err != nil { - return fmt.Errorf("could not fetch docker logs from node %q: %w", node.ID(), err) - } - - var ( - body = buf.String() - found []string - ) - - for partition, readyLog := range readyLogs { - if strings.Contains(body, readyLog) { - found = append(found, partition) - } - } - - if len(found) == len(readyLogs) { - break - } - } - - time.Sleep(500 * time.Millisecond) - } - - logger.Info("partitioned serf is ready on all servers", "partitions", partitions, "elapsed", time.Since(start)) - - return nil -} diff --git a/testing/deployer/sprawl/helpers.go b/testing/deployer/sprawl/helpers.go deleted file mode 100644 index 941311a1c1183..0000000000000 --- a/testing/deployer/sprawl/helpers.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -// Deprecated: remove -func TruncateSquidError(err error) error { - return err -} - -// Deprecated: remove -func IsSquid503(err error) bool { - return false -} diff --git a/testing/deployer/sprawl/internal/build/docker.go b/testing/deployer/sprawl/internal/build/docker.go deleted file mode 100644 index ac1976dad4eec..0000000000000 --- a/testing/deployer/sprawl/internal/build/docker.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package build - -import ( - "context" - "strings" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/runner" - "github.com/hashicorp/consul/testing/deployer/topology" -) - -const dockerfileEnvoy = ` -ARG CONSUL_IMAGE -ARG ENVOY_IMAGE -FROM ${CONSUL_IMAGE} -FROM ${ENVOY_IMAGE} -COPY --from=0 /bin/consul /bin/consul -` - -// FROM hashicorp/consul-dataplane:latest -// COPY --from=busybox:uclibc /bin/sh /bin/sh -// TODO: busybox:latest doesn't work, see https://hashicorp.slack.com/archives/C03EUN3QF1C/p1691784078972959 -const dockerfileDataplane = ` -ARG DATAPLANE_IMAGE -FROM busybox:1.34 -FROM ${DATAPLANE_IMAGE} -COPY --from=0 /bin/busybox /bin/busybox -USER 0:0 -RUN ["busybox", "--install", "/bin", "-s"] -USER 100:0 -ENTRYPOINT [] -` - -func DockerImages( - logger hclog.Logger, - run *runner.Runner, - t *topology.Topology, -) error { - logw := logger.Named("docker").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug}) - - built := make(map[string]struct{}) - for _, c := range t.Clusters { - for _, n := range c.Nodes { - joint := n.Images.EnvoyConsulImage() - if _, ok := built[joint]; joint != "" && !ok { - logger.Info("building image", "image", joint) - err := run.DockerExec(context.TODO(), []string{ - "build", - "--build-arg", - "CONSUL_IMAGE=" + n.Images.Consul, - "--build-arg", - "ENVOY_IMAGE=" + n.Images.Envoy, - "-t", joint, - "-", - }, logw, strings.NewReader(dockerfileEnvoy)) - if err != nil { - return err - } - - built[joint] = struct{}{} - } - - cdp := n.Images.LocalDataplaneImage() - if _, ok := built[cdp]; cdp != "" && !ok { - logger.Info("building image", "image", cdp) - err := run.DockerExec(context.TODO(), []string{ - "build", - "--build-arg", - "DATAPLANE_IMAGE=" + n.Images.Dataplane, - "-t", cdp, - "-", - }, logw, strings.NewReader(dockerfileDataplane)) - if err != nil { - return err - } - - built[cdp] = struct{}{} - } - } - } - - return nil -} diff --git a/testing/deployer/sprawl/internal/runner/exec.go b/testing/deployer/sprawl/internal/runner/exec.go deleted file mode 100644 index 1c2a8a1d311b4..0000000000000 --- a/testing/deployer/sprawl/internal/runner/exec.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package runner - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "os" - "os/exec" - - "github.com/hashicorp/go-hclog" -) - -type Runner struct { - logger hclog.Logger - - tfBin string - dockerBin string -} - -func Load(logger hclog.Logger) (*Runner, error) { - r := &Runner{ - logger: logger, - } - - type item struct { - name string - dest *string - warn string // optional - } - lookup := []item{ - {"docker", &r.dockerBin, ""}, - {"terraform", &r.tfBin, ""}, - } - - var ( - bins []string - err error - ) - for _, i := range lookup { - *i.dest, err = exec.LookPath(i.name) - if err != nil { - if errors.Is(err, exec.ErrNotFound) { - if i.warn != "" { - return nil, fmt.Errorf("Could not find %q on path (%s): %w", i.name, i.warn, err) - } else { - return nil, fmt.Errorf("Could not find %q on path: %w", i.name, err) - } - } - return nil, fmt.Errorf("Unexpected failure looking for %q on path: %w", i.name, err) - } - bins = append(bins, *i.dest) - } - r.logger.Trace("using binaries", "paths", bins) - - return r, nil -} - -func (r *Runner) DockerExec(ctx context.Context, args []string, stdout io.Writer, stdin io.Reader) error { - return cmdExec(ctx, "docker", r.dockerBin, args, stdout, nil, stdin, "") -} - -func (r *Runner) DockerExecWithStderr(ctx context.Context, args []string, stdout, stderr io.Writer, stdin io.Reader) error { - return cmdExec(ctx, "docker", r.dockerBin, args, stdout, stderr, stdin, "") -} - -func (r *Runner) TerraformExec(ctx context.Context, args []string, stdout io.Writer, workdir string) error { - return cmdExec(ctx, "terraform", r.tfBin, args, stdout, nil, nil, workdir) -} - -func cmdExec(ctx context.Context, name, binary string, args []string, stdout, stderr io.Writer, stdin io.Reader, dir string) error { - if binary == "" { - panic("binary named " + name + " was not detected") - } - var errWriter bytes.Buffer - - if stdout == nil { - stdout = os.Stdout // TODO: wrap logs - } - - cmd := exec.CommandContext(ctx, binary, args...) - if dir != "" { - cmd.Dir = dir - } - cmd.Stdout = stdout - cmd.Stderr = &errWriter - if stderr != nil { - cmd.Stderr = io.MultiWriter(stderr, cmd.Stderr) - } - cmd.Stdin = stdin - if err := cmd.Run(); err != nil { - return &ExecError{ - BinaryName: name, - Err: err, - ErrorOutput: errWriter.String(), - } - } - - return nil -} - -type ExecError struct { - BinaryName string - ErrorOutput string - Err error -} - -func (e *ExecError) Unwrap() error { - return e.Err -} - -func (e *ExecError) Error() string { - return fmt.Sprintf( - "could not invoke %q: %v : %s", - e.BinaryName, - e.Err, - e.ErrorOutput, - ) -} diff --git a/testing/deployer/sprawl/internal/secrets/store.go b/testing/deployer/sprawl/internal/secrets/store.go deleted file mode 100644 index 0cacf88b256eb..0000000000000 --- a/testing/deployer/sprawl/internal/secrets/store.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package secrets - -import ( - "net/url" - "strings" - - "github.com/hashicorp/consul/testing/deployer/topology" -) - -type Store struct { - m map[string]string -} - -const ( - GossipKey = "gossip" - BootstrapToken = "bootstrap-token" - AgentRecovery = "agent-recovery" -) - -func (s *Store) SaveGeneric(cluster, name, value string) { - s.save(encode(cluster, "generic", name), value) -} - -func (s *Store) ReadGeneric(cluster, name string) string { - return s.read(encode(cluster, "generic", name)) -} - -func (s *Store) SaveAgentToken(cluster string, nid topology.NodeID, value string) { - s.save(encode(cluster, "agent", nid.String()), value) -} - -func (s *Store) ReadAgentToken(cluster string, nid topology.NodeID) string { - return s.read(encode(cluster, "agent", nid.String())) -} - -func (s *Store) SaveServiceToken(cluster string, sid topology.ServiceID, value string) { - s.save(encode(cluster, "service", sid.String()), value) -} - -func (s *Store) ReadServiceToken(cluster string, sid topology.ServiceID) string { - return s.read(encode(cluster, "service", sid.String())) -} - -func (s *Store) save(key, value string) { - if s.m == nil { - s.m = make(map[string]string) - } - - s.m[key] = value -} - -func (s *Store) read(key string) string { - if s.m == nil { - return "" - } - - v, ok := s.m[key] - if !ok { - return "" - } - return v -} - -func encode(parts ...string) string { - var out []string - for _, p := range parts { - out = append(out, url.QueryEscape(p)) - } - return strings.Join(out, "/") -} diff --git a/testing/deployer/sprawl/internal/tfgen/agent.go b/testing/deployer/sprawl/internal/tfgen/agent.go deleted file mode 100644 index 00e7276783538..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/agent.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "fmt" - "strings" - - "github.com/hashicorp/hcl/v2/hclwrite" - - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" - "github.com/hashicorp/consul/testing/deployer/topology" -) - -func (g *Generator) generateAgentHCL(node *topology.Node) string { - if !node.IsAgent() { - panic("generateAgentHCL only applies to agents") - } - - cluster, ok := g.topology.Clusters[node.Cluster] - if !ok { - panic(fmt.Sprintf("no such cluster: %s", node.Cluster)) - } - - var b HCLBuilder - - b.add("server", node.IsServer()) - b.add("bind_addr", "0.0.0.0") - b.add("client_addr", "0.0.0.0") - b.add("advertise_addr", `{{ GetInterfaceIP "eth0" }}`) - b.add("datacenter", node.Datacenter) - b.add("disable_update_check", true) - b.add("log_level", "trace") - b.add("enable_debug", true) - b.add("use_streaming_backend", true) - - // speed up leaves - b.addBlock("performance", func() { - b.add("leave_drain_time", "50ms") - }) - - b.add("primary_datacenter", node.Datacenter) - - // Using retry_join here is bad because changing server membership will - // destroy and recreate all of the servers - // if !node.IsServer() { - b.addSlice("retry_join", []string{"server." + node.Cluster + "-consulcluster.lan"}) - b.add("retry_interval", "1s") - // } - - if node.IsServer() { - b.addBlock("peering", func() { - b.add("enabled", true) - }) - } - - b.addBlock("ui_config", func() { - b.add("enabled", true) - }) - - b.addBlock("telemetry", func() { - b.add("disable_hostname", true) - b.add("prometheus_retention_time", "168h") - }) - - b.add("encrypt", g.sec.ReadGeneric(node.Cluster, secrets.GossipKey)) - - { - var ( - root = "/consul/config/certs" - caFile = root + "/consul-agent-ca.pem" - certFile = root + "/" + node.TLSCertPrefix + ".pem" - certKey = root + "/" + node.TLSCertPrefix + "-key.pem" - ) - - b.addBlock("tls", func() { - b.addBlock("internal_rpc", func() { - b.add("ca_file", caFile) - b.add("cert_file", certFile) - b.add("key_file", certKey) - b.add("verify_incoming", true) - b.add("verify_server_hostname", true) - b.add("verify_outgoing", true) - }) - // if cfg.EncryptionTLSAPI { - // b.addBlock("https", func() { - // b.add("ca_file", caFile) - // b.add("cert_file", certFile) - // b.add("key_file", certKey) - // // b.add("verify_incoming", true) - // }) - // } - if node.IsServer() { - b.addBlock("grpc", func() { - b.add("ca_file", caFile) - b.add("cert_file", certFile) - b.add("key_file", certKey) - // b.add("verify_incoming", true) - }) - } - }) - } - - b.addBlock("ports", func() { - if node.IsServer() { - b.add("grpc_tls", 8503) - b.add("grpc", -1) - } else { - b.add("grpc", 8502) - b.add("grpc_tls", -1) - } - b.add("http", 8500) - b.add("dns", 8600) - }) - - b.addSlice("recursors", []string{"8.8.8.8"}) - - b.addBlock("acl", func() { - b.add("enabled", true) - b.add("default_policy", "deny") - b.add("down_policy", "extend-cache") - b.add("enable_token_persistence", true) - b.addBlock("tokens", func() { - if node.IsServer() { - b.add("initial_management", g.sec.ReadGeneric(node.Cluster, secrets.BootstrapToken)) - } - b.add("agent_recovery", g.sec.ReadGeneric(node.Cluster, secrets.AgentRecovery)) - b.add("agent", g.sec.ReadAgentToken(node.Cluster, node.ID())) - }) - }) - - if node.IsServer() { - b.add("bootstrap_expect", len(cluster.ServerNodes())) - // b.add("translate_wan_addrs", true) - b.addBlock("rpc", func() { - b.add("enable_streaming", true) - }) - if node.HasPublicAddress() { - b.add("advertise_addr_wan", `{{ GetInterfaceIP "eth1" }}`) // note: can't use 'node.PublicAddress()' b/c we don't know that yet - } - - // Exercise config entry bootstrap - // b.addBlock("config_entries", func() { - // b.addBlock("bootstrap", func() { - // b.add("kind", "service-defaults") - // b.add("name", "placeholder") - // b.add("protocol", "grpc") - // }) - // b.addBlock("bootstrap", func() { - // b.add("kind", "service-intentions") - // b.add("name", "placeholder") - // b.addBlock("sources", func() { - // b.add("name", "placeholder-client") - // b.add("action", "allow") - // }) - // }) - // }) - - b.addBlock("connect", func() { - b.add("enabled", true) - }) - - } else { - if cluster.Enterprise { - b.add("partition", node.Partition) - } - } - - return b.String() -} - -type HCLBuilder struct { - parts []string -} - -func (b *HCLBuilder) format(s string, a ...any) { - if len(a) == 0 { - b.parts = append(b.parts, s) - } else { - b.parts = append(b.parts, fmt.Sprintf(s, a...)) - } -} - -func (b *HCLBuilder) add(k string, v any) { - switch x := v.(type) { - case string: - if x != "" { - b.format("%s = %q", k, x) - } - case int: - b.format("%s = %d", k, x) - case bool: - b.format("%s = %v", k, x) - default: - panic(fmt.Sprintf("unexpected type %T", v)) - } -} - -func (b *HCLBuilder) addBlock(block string, fn func()) { - b.format(block + "{") - fn() - b.format("}") -} - -func (b *HCLBuilder) addSlice(name string, vals []string) { - b.format(name + " = [") - for _, v := range vals { - b.format("%q,", v) - } - b.format("]") -} - -func (b *HCLBuilder) String() string { - joined := strings.Join(b.parts, "\n") - // Ensure it looks tidy - return string(hclwrite.Format([]byte(joined))) -} diff --git a/testing/deployer/sprawl/internal/tfgen/digest.go b/testing/deployer/sprawl/internal/tfgen/digest.go deleted file mode 100644 index 297def0fae81d..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/digest.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "fmt" -) - -// digestOutputs takes the data extracted from terraform output variables and -// updates various fields on the topology.Topology with that data. -func (g *Generator) digestOutputs(out *Outputs) error { - for clusterName, nodeMap := range out.Nodes { - cluster, ok := g.topology.Clusters[clusterName] - if !ok { - return fmt.Errorf("found output cluster that does not exist: %s", clusterName) - } - for nid, nodeOut := range nodeMap { - node := cluster.NodeByID(nid) - if node == nil { - return fmt.Errorf("found output node that does not exist in cluster %q: %s", nid, clusterName) - } - - if node.DigestExposedPorts(nodeOut.Ports) { - g.logger.Debug("discovered exposed port mappings", - "cluster", clusterName, - "node", nid.String(), - "ports", nodeOut.Ports, - ) - } - } - } - - for netName, proxyPort := range out.ProxyPorts { - changed, err := g.topology.DigestExposedProxyPort(netName, proxyPort) - if err != nil { - return err - } - if changed { - g.logger.Debug("discovered exposed forward proxy port", - "network", netName, - "port", proxyPort, - ) - } - } - - return nil -} diff --git a/testing/deployer/sprawl/internal/tfgen/dns.go b/testing/deployer/sprawl/internal/tfgen/dns.go deleted file mode 100644 index 20dca878ebf39..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/dns.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/consul/testing/deployer/util" -) - -func (g *Generator) getCoreDNSContainer( - net *topology.Network, - ipAddress string, - hashes []string, -) Resource { - var env []string - for i, hv := range hashes { - env = append(env, fmt.Sprintf("HASH_FILE_%d_VALUE=%s", i, hv)) - } - coredns := struct { - Name string - DockerNetworkName string - IPAddress string - HashValues string - Env []string - }{ - Name: net.Name, - DockerNetworkName: net.DockerName, - IPAddress: ipAddress, - Env: env, - } - return Eval(tfCorednsT, &coredns) -} - -func (g *Generator) writeCoreDNSFiles(net *topology.Network, dnsIPAddress string) (bool, []string, error) { - if net.IsPublic() { - return false, nil, fmt.Errorf("coredns only runs on local networks") - } - - rootdir := filepath.Join(g.workdir, "terraform", "coredns-config-"+net.Name) - if err := os.MkdirAll(rootdir, 0755); err != nil { - return false, nil, err - } - - for _, cluster := range g.topology.Clusters { - if cluster.NetworkName != net.Name { - continue - } - var addrs []string - for _, node := range cluster.SortedNodes() { - if node.Kind != topology.NodeKindServer || node.Disabled { - continue - } - addr := node.AddressByNetwork(net.Name) - if addr.IPAddress != "" { - addrs = append(addrs, addr.IPAddress) - } - } - - var ( - clusterDNSName = cluster.Name + "-consulcluster.lan" - ) - - corefilePath := filepath.Join(rootdir, "Corefile") - zonefilePath := filepath.Join(rootdir, "servers") - - _, err := UpdateFileIfDifferent( - g.logger, - generateCoreDNSConfigFile( - clusterDNSName, - addrs, - ), - corefilePath, - 0644, - ) - if err != nil { - return false, nil, fmt.Errorf("error writing %q: %w", corefilePath, err) - } - corefileHash, err := util.HashFile(corefilePath) - if err != nil { - return false, nil, fmt.Errorf("error hashing %q: %w", corefilePath, err) - } - - _, err = UpdateFileIfDifferent( - g.logger, - generateCoreDNSZoneFile( - dnsIPAddress, - clusterDNSName, - addrs, - ), - zonefilePath, - 0644, - ) - if err != nil { - return false, nil, fmt.Errorf("error writing %q: %w", zonefilePath, err) - } - zonefileHash, err := util.HashFile(zonefilePath) - if err != nil { - return false, nil, fmt.Errorf("error hashing %q: %w", zonefilePath, err) - } - - return true, []string{corefileHash, zonefileHash}, nil - } - - return false, nil, nil -} - -func generateCoreDNSConfigFile( - clusterDNSName string, - addrs []string, -) []byte { - serverPart := "" - if len(addrs) > 0 { - var servers []string - for _, addr := range addrs { - servers = append(servers, addr+":8600") - } - serverPart = fmt.Sprintf(` -consul:53 { - forward . %s - log - errors - whoami -} -`, strings.Join(servers, " ")) - } - - return []byte(fmt.Sprintf(` -%[1]s:53 { - file /config/servers %[1]s - log - errors - whoami -} - -%[2]s - -.:53 { - forward . 8.8.8.8:53 - log - errors - whoami -} -`, clusterDNSName, serverPart)) -} - -func generateCoreDNSZoneFile( - dnsIPAddress string, - clusterDNSName string, - addrs []string, -) []byte { - var buf bytes.Buffer - buf.WriteString(fmt.Sprintf(` -$TTL 60 -$ORIGIN %[1]s. -@ IN SOA ns.%[1]s. webmaster.%[1]s. ( - 2017042745 ; serial - 7200 ; refresh (2 hours) - 3600 ; retry (1 hour) - 1209600 ; expire (2 weeks) - 3600 ; minimum (1 hour) - ) -@ IN NS ns.%[1]s. ; Name server -ns IN A %[2]s ; self -`, clusterDNSName, dnsIPAddress)) - - for _, addr := range addrs { - buf.WriteString(fmt.Sprintf(` -server IN A %s ; Consul server -`, addr)) - } - - return buf.Bytes() -} diff --git a/testing/deployer/sprawl/internal/tfgen/docker.go b/testing/deployer/sprawl/internal/tfgen/docker.go deleted file mode 100644 index 63f628c15a330..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/docker.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "fmt" - "regexp" -) - -var invalidResourceName = regexp.MustCompile(`[^a-z0-9-]+`) - -func DockerImageResourceName(image string) string { - if image == "" { - panic(`image must not be ""`) - } - return invalidResourceName.ReplaceAllLiteralString(image, "-") -} - -func DockerNetwork(name, subnet string) Resource { - return Text(fmt.Sprintf(` -resource "docker_network" %[1]q { - name = %[1]q - attachable = true - ipam_config { - subnet = %[2]q - } -} -`, name, subnet)) -} - -func DockerVolume(name string) Resource { - return Text(fmt.Sprintf(` -resource "docker_volume" %[1]q { - name = %[1]q -}`, name)) -} - -func DockerImage(name, image string) Resource { - return Text(fmt.Sprintf(` -resource "docker_image" %[1]q { - name = %[2]q - keep_locally = true -}`, name, image)) -} diff --git a/testing/deployer/sprawl/internal/tfgen/docker_test.go b/testing/deployer/sprawl/internal/tfgen/docker_test.go deleted file mode 100644 index 942b87189fca5..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/docker_test.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestDockerImageResourceName(t *testing.T) { - fn := DockerImageResourceName - - assert.Equal(t, "", fn("")) - assert.Equal(t, "abcdefghijklmnopqrstuvwxyz0123456789-", fn("abcdefghijklmnopqrstuvwxyz0123456789-")) - assert.Equal(t, "hashicorp-consul-1-15-0", fn("hashicorp/consul:1.15.0")) -} diff --git a/testing/deployer/sprawl/internal/tfgen/gen.go b/testing/deployer/sprawl/internal/tfgen/gen.go deleted file mode 100644 index f64d7b6a254b0..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/gen.go +++ /dev/null @@ -1,476 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/runner" - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/consul/testing/deployer/util" -) - -type Generator struct { - logger hclog.Logger - runner *runner.Runner - topology *topology.Topology - sec *secrets.Store - workdir string - license string - - tfLogger io.Writer - - // set during network phase - remainingSubnets map[string]struct{} - - launched bool -} - -func NewGenerator( - logger hclog.Logger, - runner *runner.Runner, - topo *topology.Topology, - sec *secrets.Store, - workdir string, - license string, -) (*Generator, error) { - if logger == nil { - panic("logger is required") - } - if runner == nil { - panic("runner is required") - } - if topo == nil { - panic("topology is required") - } - if sec == nil { - panic("secrets store is required") - } - if workdir == "" { - panic("workdir is required") - } - - g := &Generator{ - logger: logger, - runner: runner, - sec: sec, - workdir: workdir, - license: license, - - tfLogger: logger.Named("terraform").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug}), - } - g.SetTopology(topo) - - _ = g.terraformDestroy(context.Background(), true) // cleanup prior run - - return g, nil -} - -func (g *Generator) MarkLaunched() { - g.launched = true -} - -func (g *Generator) SetTopology(topo *topology.Topology) { - if topo == nil { - panic("topology is required") - } - g.topology = topo -} - -type Step int - -const ( - StepAll Step = 0 - StepNetworks Step = 1 - StepServers Step = 2 - StepAgents Step = 3 - StepServices Step = 4 - // StepPeering Step = XXX5 - StepRelaunch Step = 5 -) - -func (s Step) String() string { - switch s { - case StepAll: - return "all" - case StepNetworks: - return "networks" - case StepServers: - return "servers" - case StepAgents: - return "agents" - case StepServices: - return "services" - case StepRelaunch: - return "relaunch" - // case StepPeering: - // return "peering" - default: - return "UNKNOWN--" + strconv.Itoa(int(s)) - } -} - -func (s Step) StartServers() bool { return s >= StepServers } -func (s Step) StartAgents() bool { return s >= StepAgents } -func (s Step) StartServices() bool { return s >= StepServices } - -// func (s Step) InitiatePeering() bool { return s >= StepPeering } - -func (g *Generator) Regenerate() error { - return g.Generate(StepRelaunch) -} - -func (g *Generator) Generate(step Step) error { - if g.launched && step != StepRelaunch { - return fmt.Errorf("cannot use step %q after successful launch; see Regenerate()", step) - } - - g.logger.Info("generating and creating resources", "step", step.String()) - var ( - networks []Resource - volumes []Resource - images []Resource - containers []Resource - - imageNames = make(map[string]string) - ) - - addVolume := func(name string) { - volumes = append(volumes, DockerVolume(name)) - } - addImage := func(name, image string) { - if image == "" { - return - } - if _, ok := imageNames[image]; ok { - return - } - - if name == "" { - name = DockerImageResourceName(image) - } - - imageNames[image] = name - - g.logger.Debug("registering image", "resource", name, "image", image) - - images = append(images, DockerImage(name, image)) - } - - if g.remainingSubnets == nil { - g.remainingSubnets = util.GetPossibleDockerNetworkSubnets() - } - if len(g.remainingSubnets) == 0 { - return fmt.Errorf("exhausted all docker networks") - } - - addImage("nginx", "nginx:latest") - addImage("coredns", "coredns/coredns:latest") - for _, net := range g.topology.SortedNetworks() { - if net.Subnet == "" { - // Because this harness runs on a linux or macos host, we can't - // directly invoke the moby libnetwork calls to check for free - // subnets as it would have to cross into the docker desktop vm on - // mac. - // - // Instead rely on map iteration order being random to avoid - // collisions, but detect the terraform failure and retry until - // success. - - var ipnet string - for ipnet = range g.remainingSubnets { - } - if ipnet == "" { - return fmt.Errorf("could not get a free docker network") - } - delete(g.remainingSubnets, ipnet) - - if _, err := net.SetSubnet(ipnet); err != nil { - return fmt.Errorf("assigned subnet is invalid %q: %w", ipnet, err) - } - } - networks = append(networks, DockerNetwork(net.DockerName, net.Subnet)) - - var ( - // We always ask for a /24, so just blindly pick x.x.x.252 as our - // proxy address. There's an offset of 2 in the list of available - // addresses here because we removed x.x.x.0 and x.x.x.1 from the - // pool. - proxyIPAddress = net.IPByIndex(250) - // Grab x.x.x.253 for the dns server - dnsIPAddress = net.IPByIndex(251) - ) - - { - // wrote, hashes, err := g.write - } - - { // nginx forward proxy - _, hash, err := g.writeNginxConfig(net) - if err != nil { - return fmt.Errorf("writeNginxConfig[%s]: %w", net.Name, err) - } - - containers = append(containers, g.getForwardProxyContainer(net, proxyIPAddress, hash)) - - } - - net.ProxyAddress = proxyIPAddress - net.DNSAddress = "" - - if net.IsLocal() { - wrote, hashes, err := g.writeCoreDNSFiles(net, dnsIPAddress) - if err != nil { - return fmt.Errorf("writeCoreDNSFiles[%s]: %w", net.Name, err) - } - if wrote { - net.DNSAddress = dnsIPAddress - containers = append(containers, g.getCoreDNSContainer(net, dnsIPAddress, hashes)) - } - } - } - - for _, c := range g.topology.SortedClusters() { - if c.TLSVolumeName == "" { - c.TLSVolumeName = c.Name + "-tls-material-" + g.topology.ID - } - addVolume(c.TLSVolumeName) - } - - addImage("pause", "registry.k8s.io/pause:3.3") - - if step.StartServers() { - for _, c := range g.topology.SortedClusters() { - for _, node := range c.SortedNodes() { - if node.Disabled { - continue - } - addImage("", node.Images.Consul) - addImage("", node.Images.EnvoyConsulImage()) - addImage("", node.Images.LocalDataplaneImage()) - - if node.IsAgent() { - addVolume(node.DockerName()) - } - - for _, svc := range node.Services { - addImage("", svc.Image) - } - - myContainers, err := g.generateNodeContainers(step, c, node) - if err != nil { - return err - } - - containers = append(containers, myContainers...) - } - } - } - - tfpath := func(p string) string { - return filepath.Join(g.workdir, "terraform", p) - } - - if _, err := WriteHCLResourceFile(g.logger, []Resource{Text(terraformPrelude)}, tfpath("init.tf"), 0644); err != nil { - return err - } - if netResult, err := WriteHCLResourceFile(g.logger, networks, tfpath("networks.tf"), 0644); err != nil { - return err - } else if netResult == UpdateResultModified { - if step != StepNetworks { - return fmt.Errorf("cannot change networking details after they are established") - } - } - if _, err := WriteHCLResourceFile(g.logger, volumes, tfpath("volumes.tf"), 0644); err != nil { - return err - } - if _, err := WriteHCLResourceFile(g.logger, images, tfpath("images.tf"), 0644); err != nil { - return err - } - if _, err := WriteHCLResourceFile(g.logger, containers, tfpath("containers.tf"), 0644); err != nil { - return err - } - - if err := g.terraformApply(context.TODO()); err != nil { - return err - } - - out, err := g.terraformOutputs(context.TODO()) - if err != nil { - return err - } - - return g.digestOutputs(out) -} - -func (g *Generator) DestroyAll() error { - return g.terraformDestroy(context.TODO(), false) -} - -func (g *Generator) DestroyAllQuietly() error { - return g.terraformDestroy(context.TODO(), true) -} - -func (g *Generator) terraformApply(ctx context.Context) error { - tfdir := filepath.Join(g.workdir, "terraform") - - if _, err := os.Stat(filepath.Join(tfdir, ".terraform")); err != nil { - if !os.IsNotExist(err) { - return err - } - - // On the fly init - g.logger.Info("Running 'terraform init'...") - if err := g.runner.TerraformExec(ctx, []string{"init", "-input=false"}, g.tfLogger, tfdir); err != nil { - return err - } - } - - g.logger.Info("Running 'terraform apply'...") - return g.runner.TerraformExec(ctx, []string{"apply", "-input=false", "-auto-approve"}, g.tfLogger, tfdir) -} - -func (g *Generator) terraformDestroy(ctx context.Context, quiet bool) error { - g.logger.Info("Running 'terraform destroy'...") - - var out io.Writer - if quiet { - out = io.Discard - } else { - out = g.tfLogger - } - - tfdir := filepath.Join(g.workdir, "terraform") - return g.runner.TerraformExec(ctx, []string{ - "destroy", "-input=false", "-auto-approve", "-refresh=false", - }, out, tfdir) -} - -func (g *Generator) terraformOutputs(ctx context.Context) (*Outputs, error) { - tfdir := filepath.Join(g.workdir, "terraform") - - var buf bytes.Buffer - err := g.runner.TerraformExec(ctx, []string{ - "output", "-json", - }, &buf, tfdir) - if err != nil { - return nil, err - } - - type outputVar struct { - // may be map[string]any - Value any `json:"value"` - } - - raw := make(map[string]*outputVar) - dec := json.NewDecoder(&buf) - if err := dec.Decode(&raw); err != nil { - return nil, err - } - - out := &Outputs{} - - for key, rv := range raw { - switch { - case strings.HasPrefix(key, "ports_"): - cluster, nid, ok := extractNodeOutputKey("ports_", key) - if !ok { - return nil, fmt.Errorf("unexpected output var: %s", key) - } - - ports := make(map[int]int) - for k, v := range rv.Value.(map[string]any) { - ki, err := strconv.Atoi(k) - if err != nil { - return nil, fmt.Errorf("unexpected port value %q: %w", k, err) - } - ports[ki] = int(v.(float64)) - } - out.SetNodePorts(cluster, nid, ports) - case strings.HasPrefix(key, "forwardproxyport_"): - netname := strings.TrimPrefix(key, "forwardproxyport_") - - found := rv.Value.(map[string]any) - if len(found) != 1 { - return nil, fmt.Errorf("found unexpected ports: %v", found) - } - got, ok := found[strconv.Itoa(proxyInternalPort)] - if !ok { - return nil, fmt.Errorf("found unexpected ports: %v", found) - } - - out.SetProxyPort(netname, int(got.(float64))) - } - } - - return out, nil -} - -func extractNodeOutputKey(prefix, key string) (string, topology.NodeID, bool) { - clusterNode := strings.TrimPrefix(key, prefix) - - cluster, nodeid, ok := strings.Cut(clusterNode, "_") - if !ok { - return "", topology.NodeID{}, false - } - - partition, node, ok := strings.Cut(nodeid, "_") - if !ok { - return "", topology.NodeID{}, false - } - - nid := topology.NewNodeID(node, partition) - return cluster, nid, true -} - -type Outputs struct { - ProxyPorts map[string]int // net -> exposed port - Nodes map[string]map[topology.NodeID]*NodeOutput // clusterID -> node -> stuff -} - -func (o *Outputs) SetNodePorts(cluster string, nid topology.NodeID, ports map[int]int) { - nodeOut := o.getNode(cluster, nid) - nodeOut.Ports = ports -} - -func (o *Outputs) SetProxyPort(net string, port int) { - if o.ProxyPorts == nil { - o.ProxyPorts = make(map[string]int) - } - o.ProxyPorts[net] = port -} - -func (o *Outputs) getNode(cluster string, nid topology.NodeID) *NodeOutput { - if o.Nodes == nil { - o.Nodes = make(map[string]map[topology.NodeID]*NodeOutput) - } - cnodes, ok := o.Nodes[cluster] - if !ok { - cnodes = make(map[topology.NodeID]*NodeOutput) - o.Nodes[cluster] = cnodes - } - - nodeOut, ok := cnodes[nid] - if !ok { - nodeOut = &NodeOutput{} - cnodes[nid] = nodeOut - } - - return nodeOut -} - -type NodeOutput struct { - Ports map[int]int `json:",omitempty"` -} diff --git a/testing/deployer/sprawl/internal/tfgen/io.go b/testing/deployer/sprawl/internal/tfgen/io.go deleted file mode 100644 index a64d6918efaa8..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/io.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "bytes" - "os" - "strings" - - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/hcl/v2/hclwrite" - "github.com/rboyer/safeio" -) - -func WriteHCLResourceFile( - logger hclog.Logger, - res []Resource, - path string, - perm os.FileMode, -) (UpdateResult, error) { - var text []string - for _, r := range res { - val, err := r.Render() - if err != nil { - return UpdateResultNone, err - } - text = append(text, strings.TrimSpace(val)) - } - - body := strings.Join(text, "\n\n") - - // Ensure it looks tidy - out := hclwrite.Format(bytes.TrimSpace([]byte(body))) - - return UpdateFileIfDifferent(logger, out, path, perm) -} - -type UpdateResult int - -const ( - UpdateResultNone UpdateResult = iota - UpdateResultCreated - UpdateResultModified -) - -func UpdateFileIfDifferent( - logger hclog.Logger, - body []byte, - path string, - perm os.FileMode, -) (UpdateResult, error) { - prev, err := os.ReadFile(path) - - result := UpdateResultNone - if err != nil { - if !os.IsNotExist(err) { - return result, err - } - logger.Debug("writing new file", "path", path) - result = UpdateResultCreated - } else { - // loaded - if bytes.Equal(body, prev) { - return result, nil - } - logger.Debug("file has changed", "path", path) - result = UpdateResultModified - } - - _, err = safeio.WriteToFile(bytes.NewReader(body), path, perm) - return result, err -} diff --git a/testing/deployer/sprawl/internal/tfgen/nodes.go b/testing/deployer/sprawl/internal/tfgen/nodes.go deleted file mode 100644 index 33a820a3e32e7..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/nodes.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "fmt" - - "github.com/hashicorp/consul/testing/deployer/topology" -) - -type terraformPod struct { - PodName string - Node *topology.Node - Ports []int - Labels map[string]string - TLSVolumeName string - DNSAddress string - DockerNetworkName string -} - -func (g *Generator) generateNodeContainers( - step Step, - cluster *topology.Cluster, - node *topology.Node, -) ([]Resource, error) { - if node.Disabled { - return nil, fmt.Errorf("cannot generate containers for a disabled node") - } - - pod := terraformPod{ - PodName: node.PodName(), - Node: node, - Labels: map[string]string{ - "consulcluster-topology-id": g.topology.ID, - "consulcluster-cluster-name": node.Cluster, - }, - TLSVolumeName: cluster.TLSVolumeName, - DNSAddress: "8.8.8.8", - } - - cluster, ok := g.topology.Clusters[node.Cluster] - if !ok { - return nil, fmt.Errorf("no such cluster: %s", node.Cluster) - } - - net, ok := g.topology.Networks[cluster.NetworkName] - if !ok { - return nil, fmt.Errorf("no local network: %s", cluster.NetworkName) - } - if net.DNSAddress != "" { - pod.DNSAddress = net.DNSAddress - } - pod.DockerNetworkName = net.DockerName - - containers := []Resource{} - - if node.IsAgent() { - switch { - case node.IsServer() && step.StartServers(), - !node.IsServer() && step.StartAgents(): - containers = append(containers, Eval(tfConsulT, struct { - terraformPod - ImageResource string - HCL string - EnterpriseLicense string - }{ - terraformPod: pod, - ImageResource: DockerImageResourceName(node.Images.Consul), - HCL: g.generateAgentHCL(node), - EnterpriseLicense: g.license, - })) - } - } - - svcContainers := []Resource{} - for _, svc := range node.SortedServices() { - token := g.sec.ReadServiceToken(node.Cluster, svc.ID) - switch { - case svc.IsMeshGateway && !node.IsDataplane(): - svcContainers = append(svcContainers, Eval(tfMeshGatewayT, struct { - terraformPod - ImageResource string - Enterprise bool - Service *topology.Service - Token string - }{ - terraformPod: pod, - ImageResource: DockerImageResourceName(node.Images.EnvoyConsulImage()), - Enterprise: cluster.Enterprise, - Service: svc, - Token: token, - })) - case svc.IsMeshGateway && node.IsDataplane(): - svcContainers = append(svcContainers, Eval(tfMeshGatewayDataplaneT, &struct { - terraformPod - ImageResource string - Enterprise bool - Service *topology.Service - Token string - }{ - terraformPod: pod, - ImageResource: DockerImageResourceName(node.Images.LocalDataplaneImage()), - Enterprise: cluster.Enterprise, - Service: svc, - Token: token, - })) - - case !svc.IsMeshGateway: - svcContainers = append(svcContainers, Eval(tfAppT, struct { - terraformPod - ImageResource string - Service *topology.Service - }{ - terraformPod: pod, - ImageResource: DockerImageResourceName(svc.Image), - Service: svc, - })) - - if svc.DisableServiceMesh { - break - } - - tmpl := tfAppSidecarT - var img string - if node.IsDataplane() { - tmpl = tfAppDataplaneT - img = DockerImageResourceName(node.Images.LocalDataplaneImage()) - } else { - img = DockerImageResourceName(node.Images.EnvoyConsulImage()) - } - svcContainers = append(svcContainers, Eval(tmpl, struct { - terraformPod - ImageResource string - Service *topology.Service - Token string - Enterprise bool - }{ - terraformPod: pod, - ImageResource: img, - Service: svc, - Token: token, - Enterprise: cluster.Enterprise, - })) - } - - if step.StartServices() { - containers = append(containers, svcContainers...) - } - } - - // Wait until the very end to render the pod so we know all of the ports. - pod.Ports = node.SortedPorts() - - // pod placeholder container - containers = append(containers, Eval(tfPauseT, &pod)) - - return containers, nil -} diff --git a/testing/deployer/sprawl/internal/tfgen/prelude.go b/testing/deployer/sprawl/internal/tfgen/prelude.go deleted file mode 100644 index 2e9a01cb08058..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/prelude.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -const terraformPrelude = `provider "docker" { - host = "unix:///var/run/docker.sock" -} - -terraform { - required_providers { - docker = { - source = "kreuzwerker/docker" - version = "~> 2.0" - } - } - required_version = ">= 0.13" -} -` diff --git a/testing/deployer/sprawl/internal/tfgen/proxy.go b/testing/deployer/sprawl/internal/tfgen/proxy.go deleted file mode 100644 index 0fcaf841ee27c..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/proxy.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/consul/testing/deployer/util" -) - -const proxyInternalPort = 80 - -func (g *Generator) writeNginxConfig(net *topology.Network) (bool, string, error) { - rootdir := filepath.Join(g.workdir, "terraform", "nginx-config-"+net.Name) - if err := os.MkdirAll(rootdir, 0755); err != nil { - return false, "", err - } - - configFile := filepath.Join(rootdir, "nginx.conf") - - body := fmt.Sprintf(` -server { - listen %d; - - location / { - resolver 8.8.8.8; - ############## - # Relevant config knobs are here: https://nginx.org/en/docs/http/ngx_http_proxy_module.html - ############## - proxy_pass http://$http_host$uri$is_args$args; - proxy_cache off; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_connect_timeout 5s; - proxy_read_timeout 5s; - proxy_send_timeout 5s; - proxy_request_buffering off; - proxy_buffering off; - } -} -`, proxyInternalPort) - - _, err := UpdateFileIfDifferent( - g.logger, - []byte(body), - configFile, - 0644, - ) - if err != nil { - return false, "", fmt.Errorf("error writing %q: %w", configFile, err) - } - - hash, err := util.HashFile(configFile) - if err != nil { - return false, "", fmt.Errorf("error hashing %q: %w", configFile, err) - } - - return true, hash, err -} - -func (g *Generator) getForwardProxyContainer( - net *topology.Network, - ipAddress string, - hash string, -) Resource { - env := []string{"HASH_FILE_VALUE=" + hash} - proxy := struct { - Name string - DockerNetworkName string - InternalPort int - IPAddress string - Env []string - }{ - Name: net.Name, - DockerNetworkName: net.DockerName, - InternalPort: proxyInternalPort, - IPAddress: ipAddress, - Env: env, - } - - return Eval(tfForwardProxyT, &proxy) -} diff --git a/testing/deployer/sprawl/internal/tfgen/res.go b/testing/deployer/sprawl/internal/tfgen/res.go deleted file mode 100644 index a45c460793d22..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/res.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "bytes" - "text/template" - - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/hcl/v2/hclwrite" -) - -type FileResource struct { - name string - res Resource -} - -func (r *FileResource) Name() string { return r.name } - -func (r *FileResource) Commit(logger hclog.Logger) error { - val, err := r.res.Render() - if err != nil { - return err - } - _, err = UpdateFileIfDifferent(logger, []byte(val), r.name, 0644) - return err -} - -func File(name string, res Resource) *FileResource { - return &FileResource{name: name, res: res} -} - -func Text(s string) Resource { - return &textResource{text: s} -} - -func Embed(name string) Resource { - return &embedResource{name: name} -} - -func Eval(t *template.Template, data any) Resource { - return &evalResource{template: t, data: data, hcl: false} -} - -func HCL(t *template.Template, data any) Resource { - return &evalResource{template: t, data: data, hcl: true} -} - -type Resource interface { - Render() (string, error) -} - -type embedResource struct { - name string -} - -func (r *embedResource) Render() (string, error) { - val, err := content.ReadFile(r.name) - if err != nil { - return "", err - } - return string(val), nil -} - -type textResource struct { - text string -} - -func (r *textResource) Render() (string, error) { - return r.text, nil -} - -type evalResource struct { - template *template.Template - data any - hcl bool -} - -func (r *evalResource) Render() (string, error) { - out, err := StringTemplate(r.template, r.data) - if err != nil { - return "", err - } - - if r.hcl { - return string(hclwrite.Format([]byte(out))), nil - } - return out, nil -} - -func StringTemplate(t *template.Template, data any) (string, error) { - var res bytes.Buffer - if err := t.Execute(&res, data); err != nil { - return "", err - } - return res.String(), nil -} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl deleted file mode 100644 index 040cabbf11601..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl +++ /dev/null @@ -1,44 +0,0 @@ -resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" { - name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" - network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest - restart = "on-failure" - -{{- range $k, $v := .Labels }} - labels { - label = "{{ $k }}" - value = "{{ $v }}" - } -{{- end }} - - volumes { - volume_name = "{{.TLSVolumeName}}" - container_path = "/consul/config/certs" - read_only = true - } - - env = [ - "DP_CONSUL_ADDRESSES=server.{{.Node.Cluster}}-consulcluster.lan", - "DP_SERVICE_NODE_NAME={{.Node.PodName}}", - "DP_PROXY_SERVICE_ID={{.Service.ID.Name}}-sidecar-proxy", - {{ if .Enterprise }} - "DP_SERVICE_NAMESPACE={{.Service.ID.Namespace}}", - "DP_SERVICE_PARTITION={{.Service.ID.Partition}}", - {{ end }} - {{ if .Token }} - "DP_CREDENTIAL_TYPE=static", - "DP_CREDENTIAL_STATIC_TOKEN={{.Token}}", - {{ end }} - // for demo purposes - "DP_ENVOY_ADMIN_BIND_ADDRESS=0.0.0.0", - "DP_ENVOY_ADMIN_BIND_PORT=19000", - "DP_LOG_LEVEL=trace", - "DP_CA_CERTS=/consul/config/certs/consul-agent-ca.pem", - "DP_CONSUL_GRPC_PORT=8503", - "DP_TLS_SERVER_NAME=server.{{.Node.Datacenter}}.consul", - ] - - command = [ - "/usr/local/bin/consul-dataplane", - ] -} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-app-sidecar.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-app-sidecar.tf.tmpl deleted file mode 100644 index 15a5f6922691f..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-app-sidecar.tf.tmpl +++ /dev/null @@ -1,37 +0,0 @@ -resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" { - name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" - network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest - restart = "on-failure" - -{{- range $k, $v := .Labels }} - labels { - label = "{{ $k }}" - value = "{{ $v }}" - } -{{- end }} - - volumes { - volume_name = "{{.TLSVolumeName}}" - container_path = "/consul/config/certs" - read_only = true - } - - command = [ - "consul", "connect", "envoy", - "-sidecar-for={{.Service.ID.Name}}", - "-grpc-addr=http://127.0.0.1:8502", - // for demo purposes (TODO: huh?) - "-admin-bind=0.0.0.0:{{.Service.EnvoyAdminPort}}", - {{if .Enterprise}} - "-partition={{.Service.ID.Partition}}", - "-namespace={{.Service.ID.Namespace}}", - {{end}} - {{if .Token }} - "-token={{.Token}}", - {{end}} - "--", - "-l", - "trace", - ] -} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-app.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-app.tf.tmpl deleted file mode 100644 index d6033587b1ead..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-app.tf.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" { - name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}" - network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest - restart = "on-failure" - -{{- range $k, $v := .Labels }} - labels { - label = "{{ $k }}" - value = "{{ $v }}" - } -{{- end }} - - env = [ -{{- range .Service.Env }} - "{{.}}", -{{- end}} - ] - - command = [ -{{- range .Service.Command }} - "{{.}}", -{{- end }} - ] -} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-consul.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-consul.tf.tmpl deleted file mode 100644 index fac148f29c2b6..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-consul.tf.tmpl +++ /dev/null @@ -1,37 +0,0 @@ -resource "docker_container" "{{.Node.DockerName}}" { - name = "{{.Node.DockerName}}" - network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest - restart = "always" - - env = [ - "CONSUL_UID=0", - "CONSUL_GID=0", - "CONSUL_LICENSE={{.EnterpriseLicense}}", - ] - -{{- range $k, $v := .Labels }} - labels { - label = "{{ $k }}" - value = "{{ $v }}" - } -{{- end }} - - command = [ - "agent", - "-hcl", - <<-EOT -{{ .HCL }} -EOT - ] - - volumes { - volume_name = "{{.Node.DockerName}}" - container_path = "/consul/data" - } - - volumes { - volume_name = "{{.TLSVolumeName}}" - container_path = "/consul/config/certs" - } -} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl deleted file mode 100644 index 7789376a98f10..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl +++ /dev/null @@ -1,28 +0,0 @@ -resource "docker_container" "{{.DockerNetworkName}}-coredns" { - name = "{{.DockerNetworkName}}-coredns" - image = docker_image.coredns.latest - restart = "always" - dns = ["8.8.8.8"] - - networks_advanced { - name = docker_network.{{.DockerNetworkName}}.name - ipv4_address = "{{.IPAddress}}" - } - - env = [ -{{- range .Env }} - "{{.}}", -{{- end}} - ] - - volumes { - host_path = abspath("coredns-config-{{.Name}}") - container_path = "/config" - read_only = true - } - - command = [ - "-conf", - "/config/Corefile", - ] -} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-mgw-dataplane.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-mgw-dataplane.tf.tmpl deleted file mode 100644 index 18152e68eb6d6..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-mgw-dataplane.tf.tmpl +++ /dev/null @@ -1,45 +0,0 @@ -resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" { - name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}" - network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest - restart = "on-failure" - -{{- range $k, $v := .Labels }} - labels { - label = "{{ $k }}" - value = "{{ $v }}" - } -{{- end }} - - volumes { - volume_name = "{{.TLSVolumeName}}" - container_path = "/consul/config/certs" - read_only = true - } - - env = [ - "DP_CONSUL_ADDRESSES=server.{{.Node.Cluster}}-consulcluster.lan", - "DP_SERVICE_NODE_NAME={{.Node.PodName}}", - "DP_PROXY_SERVICE_ID={{.Service.ID.Name}}", - {{ if .Enterprise }} - "DP_SERVICE_NAMESPACE={{.Service.ID.Namespace}}", - "DP_SERVICE_PARTITION={{.Service.ID.Partition}}", - {{ end }} - {{ if .Token }} - "DP_CREDENTIAL_TYPE=static", - "DP_CREDENTIAL_STATIC_TOKEN={{.Token}}", - {{ end }} - // for demo purposes - "DP_ENVOY_ADMIN_BIND_ADDRESS=0.0.0.0", - "DP_ENVOY_ADMIN_BIND_PORT=19000", - "DP_LOG_LEVEL=trace", - "DP_CA_CERTS=/consul/config/certs/consul-agent-ca.pem", - "DP_CONSUL_GRPC_PORT=8503", - "DP_TLS_SERVER_NAME=server.{{.Node.Datacenter}}.consul", - ] - - command = [ - "/usr/local/bin/consul-dataplane", - ] -} - diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-mgw.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-mgw.tf.tmpl deleted file mode 100644 index 78c4abe8dfa42..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-mgw.tf.tmpl +++ /dev/null @@ -1,39 +0,0 @@ -resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" { - name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}" - network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest - restart = "on-failure" - -{{- range $k, $v := .Labels }} - labels { - label = "{{ $k }}" - value = "{{ $v }}" - } -{{- end }} - - volumes { - volume_name = "{{.TLSVolumeName}}" - container_path = "/consul/config/certs" - read_only = true - } - - command = [ - "consul", "connect", "envoy", - "-register", - "-mesh-gateway", - "-address={{`{{ GetInterfaceIP \"eth0\" }}`}}:{{.Service.Port}}", - "-wan-address={{`{{ GetInterfaceIP \"eth1\" }}`}}:{{.Service.Port}}", - "-grpc-addr=http://127.0.0.1:8502", - // for demo purposes (TODO: huh?) - "-admin-bind=0.0.0.0:{{.Service.EnvoyAdminPort}}", - {{ if .Enterprise }} - "-partition={{.Service.ID.Partition}}", - {{end}} - {{ if .Token }} - "-token={{.Token}}", - {{end}} - "--", - "-l", - "trace", - ] -} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl deleted file mode 100644 index 1f1627b0719bd..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl +++ /dev/null @@ -1,38 +0,0 @@ -resource "docker_container" "{{.PodName}}" { - name = "{{.PodName}}" - image = docker_image.pause.latest - hostname = "{{.PodName}}" - restart = "always" - dns = ["{{.DNSAddress}}"] - -{{- range $k, $v := .Labels }} - labels { - label = "{{ $k }}" - value = "{{ $v }}" - } -{{- end }} - -depends_on = [ - docker_container.{{.DockerNetworkName}}-coredns, - docker_container.{{.DockerNetworkName}}-forwardproxy, -] - -{{- range .Ports }} -ports { - internal = {{.}} -} -{{- end }} - -{{- range .Node.Addresses }} -networks_advanced { - name = docker_network.{{.DockerNetworkName}}.name - ipv4_address = "{{.IPAddress}}" -} -{{- end }} -} - -output "ports_{{.Node.Cluster}}_{{.Node.Partition}}_{{.Node.Name}}" { - value = { - for port in docker_container.{{.PodName}}.ports : port.internal => port.external - } -} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl deleted file mode 100644 index ed44d8343fe8b..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl +++ /dev/null @@ -1,33 +0,0 @@ -resource "docker_container" "{{.DockerNetworkName}}-forwardproxy" { - name = "{{.DockerNetworkName}}-forwardproxy" - image = docker_image.nginx.latest - restart = "always" - dns = ["8.8.8.8"] - - ports { - internal = {{.InternalPort}} - } - - networks_advanced { - name = docker_network.{{.DockerNetworkName}}.name - ipv4_address = "{{.IPAddress}}" - } - - env = [ -{{- range .Env }} - "{{.}}", -{{- end}} - ] - - volumes { - host_path = abspath("nginx-config-{{.Name}}/nginx.conf") - container_path = "/etc/nginx/conf.d/default.conf" - read_only = true - } -} - -output "forwardproxyport_{{.Name}}" { - value = { - for port in docker_container.{{.DockerNetworkName}}-forwardproxy.ports : port.internal => port.external - } -} diff --git a/testing/deployer/sprawl/internal/tfgen/tfgen.go b/testing/deployer/sprawl/internal/tfgen/tfgen.go deleted file mode 100644 index 6df36dcb2d6d2..0000000000000 --- a/testing/deployer/sprawl/internal/tfgen/tfgen.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tfgen - -import ( - "embed" - "text/template" -) - -//go:embed templates/container-app-dataplane.tf.tmpl -//go:embed templates/container-app-sidecar.tf.tmpl -//go:embed templates/container-app.tf.tmpl -//go:embed templates/container-consul.tf.tmpl -//go:embed templates/container-mgw.tf.tmpl -//go:embed templates/container-mgw-dataplane.tf.tmpl -//go:embed templates/container-pause.tf.tmpl -//go:embed templates/container-proxy.tf.tmpl -//go:embed templates/container-coredns.tf.tmpl -var content embed.FS - -var ( - tfAppDataplaneT = template.Must(template.ParseFS(content, "templates/container-app-dataplane.tf.tmpl")) - tfAppSidecarT = template.Must(template.ParseFS(content, "templates/container-app-sidecar.tf.tmpl")) - tfAppT = template.Must(template.ParseFS(content, "templates/container-app.tf.tmpl")) - tfConsulT = template.Must(template.ParseFS(content, "templates/container-consul.tf.tmpl")) - tfMeshGatewayT = template.Must(template.ParseFS(content, "templates/container-mgw.tf.tmpl")) - tfMeshGatewayDataplaneT = template.Must(template.ParseFS(content, "templates/container-mgw-dataplane.tf.tmpl")) - tfPauseT = template.Must(template.ParseFS(content, "templates/container-pause.tf.tmpl")) - tfForwardProxyT = template.Must(template.ParseFS(content, "templates/container-proxy.tf.tmpl")) - tfCorednsT = template.Must(template.ParseFS(content, "templates/container-coredns.tf.tmpl")) -) diff --git a/testing/deployer/sprawl/peering.go b/testing/deployer/sprawl/peering.go deleted file mode 100644 index dd280cc49a295..0000000000000 --- a/testing/deployer/sprawl/peering.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "context" - "errors" - "fmt" - "net/http" - "strings" - "time" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/go-hclog" - - "github.com/hashicorp/consul/testing/deployer/topology" -) - -// TODO: this is definitely a grpc resolver/balancer issue to look into -const grpcWeirdError = `transport: Error while dialing failed to find Consul server for global address` - -func isWeirdGRPCError(err error) bool { - if err == nil { - return false - } - return strings.Contains(err.Error(), grpcWeirdError) -} - -func (s *Sprawl) initPeerings() error { - // TODO: wait until services are healthy? wait until mesh gateways work? - // if err := s.generator.Generate(tfgen.StepPeering); err != nil { - // return fmt.Errorf("generator[peering]: %w", err) - // } - - var ( - logger = s.logger.Named("peering") - _ = logger - ) - - for _, peering := range s.topology.Peerings { - dialingCluster, ok := s.topology.Clusters[peering.Dialing.Name] - if !ok { - return fmt.Errorf("peering references dialing cluster that does not exist: %s", peering.String()) - } - acceptingCluster, ok := s.topology.Clusters[peering.Accepting.Name] - if !ok { - return fmt.Errorf("peering references accepting cluster that does not exist: %s", peering.String()) - } - - var ( - dialingClient = s.clients[dialingCluster.Name] - acceptingClient = s.clients[acceptingCluster.Name] - ) - - // TODO: allow for use of ServerExternalAddresses - - req1 := api.PeeringGenerateTokenRequest{ - PeerName: peering.Accepting.PeerName, - } - if acceptingCluster.Enterprise { - req1.Partition = peering.Accepting.Partition - } - - GENTOKEN: - resp, _, err := acceptingClient.Peerings().GenerateToken(context.Background(), req1, nil) - if err != nil { - if isWeirdGRPCError(err) { - time.Sleep(50 * time.Millisecond) - goto GENTOKEN - } - return fmt.Errorf("error generating peering token for %q: %w", peering.String(), err) - } - - peeringToken := resp.PeeringToken - logger.Debug("generated peering token", "peering", peering.String()) - - req2 := api.PeeringEstablishRequest{ - PeerName: peering.Dialing.PeerName, - PeeringToken: peeringToken, - } - if dialingCluster.Enterprise { - req2.Partition = peering.Dialing.Partition - } - - logger.Info("registering peering with token", "peering", peering.String()) - ESTABLISH: - _, _, err = dialingClient.Peerings().Establish(context.Background(), req2, nil) - if err != nil { - if isWeirdGRPCError(err) { - time.Sleep(50 * time.Millisecond) - goto ESTABLISH - } - // Establish and friends return an api.StatusError value, not pointer - // not sure if this is weird - var asStatusError api.StatusError - if errors.As(err, &asStatusError) && asStatusError.Code == http.StatusGatewayTimeout { - time.Sleep(50 * time.Millisecond) - goto ESTABLISH - } - return fmt.Errorf("error establishing peering with token for %q: %#v", peering.String(), err) - } - - logger.Info("peering registered", "peering", peering.String()) - } - - return nil -} - -func (s *Sprawl) waitForPeeringEstablishment() error { - var ( - logger = s.logger.Named("peering") - ) - logger.Info("awaiting peering establishment") - startTimeTotal := time.Now() - - for _, peering := range s.topology.Peerings { - dialingCluster, ok := s.topology.Clusters[peering.Dialing.Name] - if !ok { - return fmt.Errorf("peering references dialing cluster that does not exist: %s", peering.String()) - } - acceptingCluster, ok := s.topology.Clusters[peering.Accepting.Name] - if !ok { - return fmt.Errorf("peering references accepting cluster that does not exist: %s", peering.String()) - } - - var ( - dialingClient = s.clients[dialingCluster.Name] - acceptingClient = s.clients[acceptingCluster.Name] - - dialingLogger = logger.With( - "cluster", dialingCluster.Name, - "peering", peering.String(), - ) - acceptingLogger = logger.With( - "cluster", acceptingCluster.Name, - "peering", peering.String(), - ) - ) - - s.checkPeeringDirection(dialingLogger, dialingClient, peering.Dialing, dialingCluster.Enterprise) - s.checkPeeringDirection(acceptingLogger, acceptingClient, peering.Accepting, acceptingCluster.Enterprise) - } - logger.Info("peering established", "dur", time.Since(startTimeTotal).Round(time.Second)) - return nil -} - -func (s *Sprawl) checkPeeringDirection(logger hclog.Logger, client *api.Client, pc topology.PeerCluster, enterprise bool) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - startTime := time.Now() - - for { - opts := &api.QueryOptions{} - logger2 := logger.With("dur", time.Since(startTime).Round(time.Second)) - if enterprise { - opts.Partition = pc.Partition - } - res, _, err := client.Peerings().Read(ctx, pc.PeerName, opts) - if isWeirdGRPCError(err) { - time.Sleep(50 * time.Millisecond) - continue - } - if err != nil { - logger2.Debug("error looking up peering", "error", err) - time.Sleep(100 * time.Millisecond) - continue - } - if res == nil { - logger2.Debug("peering not found") - time.Sleep(100 * time.Millisecond) - continue - } - - if res.State == api.PeeringStateActive { - break - } - logger2.Debug("peering not active yet", "state", res.State) - time.Sleep(500 * time.Millisecond) - } - logger.Debug("peering is active", "dur", time.Since(startTime).Round(time.Second)) -} diff --git a/testing/deployer/sprawl/sprawl.go b/testing/deployer/sprawl/sprawl.go deleted file mode 100644 index 16743b8b7b234..0000000000000 --- a/testing/deployer/sprawl/sprawl.go +++ /dev/null @@ -1,508 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "bufio" - "bytes" - "context" - "fmt" - "io" - "net/http" - "os" - "path/filepath" - "strings" - "time" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-multierror" - "github.com/mitchellh/copystructure" - - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/runner" - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/tfgen" - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/consul/testing/deployer/util" -) - -// TODO: manage workdir externally without chdir - -// Sprawl is the definition of a complete running Consul deployment topology. -type Sprawl struct { - logger hclog.Logger - runner *runner.Runner - license string - secrets secrets.Store - - workdir string - - // set during Run - config *topology.Config - topology *topology.Topology - generator *tfgen.Generator - - clients map[string]*api.Client // one per cluster -} - -// Topology allows access to the topology that defines the resources. Do not -// write to any of these fields. -func (s *Sprawl) Topology() *topology.Topology { - return s.topology -} - -func (s *Sprawl) Config() *topology.Config { - c2, err := copyConfig(s.config) - if err != nil { - panic(err) - } - return c2 -} - -func (s *Sprawl) HTTPClientForCluster(clusterName string) (*http.Client, error) { - cluster, ok := s.topology.Clusters[clusterName] - if !ok { - return nil, fmt.Errorf("no such cluster: %s", clusterName) - } - - // grab the local network for the cluster - network, ok := s.topology.Networks[cluster.NetworkName] - if !ok { - return nil, fmt.Errorf("no such network: %s", cluster.NetworkName) - } - - transport, err := util.ProxyHTTPTransport(network.ProxyPort) - if err != nil { - return nil, err - } - - return &http.Client{Transport: transport}, nil -} - -// APIClientForNode gets a pooled api.Client connected to the agent running on -// the provided node. -// -// Passing an empty token will assume the bootstrap token. If you want to -// actually use the anonymous token say "-". -func (s *Sprawl) APIClientForNode(clusterName string, nid topology.NodeID, token string) (*api.Client, error) { - cluster, ok := s.topology.Clusters[clusterName] - if !ok { - return nil, fmt.Errorf("no such cluster: %s", clusterName) - } - - nid.Normalize() - - node := cluster.NodeByID(nid) - if !node.IsAgent() { - return nil, fmt.Errorf("node is not an agent") - } - - switch token { - case "": - token = s.secrets.ReadGeneric(clusterName, secrets.BootstrapToken) - case "-": - token = "" - } - - return util.ProxyAPIClient( - node.LocalProxyPort(), - node.LocalAddress(), - 8500, - token, - ) -} - -// APIClientForCluster is a convenience wrapper for APIClientForNode that returns -// an API client for an agent node in the cluster, preferring clients, then servers -func (s *Sprawl) APIClientForCluster(clusterName, token string) (*api.Client, error) { - clu := s.topology.Clusters[clusterName] - // TODO: this always goes to the first client, but we might want to balance this - firstAgent := clu.FirstClient() - if firstAgent == nil { - firstAgent = clu.FirstServer() - } - if firstAgent == nil { - return nil, fmt.Errorf("failed to find agent in cluster %s", clusterName) - } - return s.APIClientForNode(clusterName, firstAgent.ID(), token) -} - -func copyConfig(cfg *topology.Config) (*topology.Config, error) { - dup, err := copystructure.Copy(cfg) - if err != nil { - return nil, err - } - return dup.(*topology.Config), nil -} - -// Launch will create the topology defined by the provided configuration and -// bring up all of the relevant clusters. Once created the Stop method must be -// called to destroy everything. -func Launch( - logger hclog.Logger, - workdir string, - cfg *topology.Config, -) (*Sprawl, error) { - if logger == nil { - panic("logger is required") - } - if workdir == "" { - panic("workdir is required") - } - - if err := os.MkdirAll(filepath.Join(workdir, "terraform"), 0755); err != nil { - return nil, err - } - - runner, err := runner.Load(logger) - if err != nil { - return nil, err - } - - // Copy this to avoid leakage. - cfg, err = copyConfig(cfg) - if err != nil { - return nil, err - } - - s := &Sprawl{ - logger: logger, - runner: runner, - workdir: workdir, - clients: make(map[string]*api.Client), - } - - if err := s.ensureLicense(); err != nil { - return nil, err - } - - // Copy this AGAIN, BEFORE compiling so we capture the original definition, without denorms. - s.config, err = copyConfig(cfg) - if err != nil { - return nil, err - } - - s.topology, err = topology.Compile(logger.Named("compile"), cfg) - if err != nil { - return nil, fmt.Errorf("topology.Compile: %w", err) - } - - s.logger.Debug("compiled topology", "ct", jd(s.topology)) // TODO - - start := time.Now() - if err := s.launch(); err != nil { - return nil, err - } - s.logger.Info("topology is ready for use", "elapsed", time.Since(start)) - - if err := s.PrintDetails(); err != nil { - return nil, fmt.Errorf("error gathering diagnostic details: %w", err) - } - - return s, nil -} - -func (s *Sprawl) Relaunch( - cfg *topology.Config, -) error { - // Copy this BEFORE compiling so we capture the original definition, without denorms. - var err error - s.config, err = copyConfig(cfg) - if err != nil { - return err - } - - newTopology, err := topology.Recompile(s.logger.Named("recompile"), cfg, s.topology) - if err != nil { - return fmt.Errorf("topology.Compile: %w", err) - } - - s.topology = newTopology - - s.logger.Debug("compiled replacement topology", "ct", jd(s.topology)) // TODO - - start := time.Now() - if err := s.relaunch(); err != nil { - return err - } - s.logger.Info("topology is ready for use", "elapsed", time.Since(start)) - - if err := s.PrintDetails(); err != nil { - return fmt.Errorf("error gathering diagnostic details: %w", err) - } - - return nil -} - -// SnapshotSave saves a snapshot of a cluster and restore with the snapshot -func (s *Sprawl) SnapshotSave(clusterName string) error { - cluster, ok := s.topology.Clusters[clusterName] - if !ok { - return fmt.Errorf("no such cluster: %s", clusterName) - } - var ( - client = s.clients[cluster.Name] - ) - snapshot := client.Snapshot() - snap, _, err := snapshot.Save(nil) - if err != nil { - return fmt.Errorf("error saving snapshot: %w", err) - } - s.logger.Info("snapshot saved") - time.Sleep(3 * time.Second) - defer snap.Close() - - // Restore the snapshot. - if err := snapshot.Restore(nil, snap); err != nil { - return fmt.Errorf("error restoring snapshot: %w", err) - } - s.logger.Info("snapshot restored") - return nil -} - -// Leader returns the cluster leader agent, or an error if no leader is -// available. -func (s *Sprawl) Leader(clusterName string) (*topology.Node, error) { - cluster, ok := s.topology.Clusters[clusterName] - if !ok { - return nil, fmt.Errorf("no such cluster: %s", clusterName) - } - - var ( - client = s.clients[cluster.Name] - // logger = s.logger.With("cluster", cluster.Name) - ) - - leaderAddr, err := getLeader(client) - if err != nil { - return nil, err - } - - for _, node := range cluster.Nodes { - if !node.IsServer() || node.Disabled { - continue - } - if strings.HasPrefix(leaderAddr, node.LocalAddress()+":") { - return node, nil - } - } - - return nil, fmt.Errorf("leader not found") -} - -// Followers returns the cluster following servers. -func (s *Sprawl) Followers(clusterName string) ([]*topology.Node, error) { - cluster, ok := s.topology.Clusters[clusterName] - if !ok { - return nil, fmt.Errorf("no such cluster: %s", clusterName) - } - - leaderNode, err := s.Leader(clusterName) - if err != nil { - return nil, fmt.Errorf("could not determine leader: %w", err) - } - - var followers []*topology.Node - - for _, node := range cluster.Nodes { - if !node.IsServer() || node.Disabled { - continue - } - if node.ID() != leaderNode.ID() { - followers = append(followers, node) - } - } - - return followers, nil -} - -func (s *Sprawl) DisabledServers(clusterName string) ([]*topology.Node, error) { - cluster, ok := s.topology.Clusters[clusterName] - if !ok { - return nil, fmt.Errorf("no such cluster: %s", clusterName) - } - - var servers []*topology.Node - - for _, node := range cluster.Nodes { - if !node.IsServer() || !node.Disabled { - continue - } - servers = append(servers, node) - } - - return servers, nil -} - -func (s *Sprawl) StopContainer(ctx context.Context, containerName string) error { - return s.runner.DockerExec(ctx, []string{"stop", containerName}, nil, nil) -} - -func (s *Sprawl) SnapshotEnvoy(ctx context.Context) error { - snapDir := filepath.Join(s.workdir, "envoy-snapshots") - if err := os.MkdirAll(snapDir, 0755); err != nil { - return fmt.Errorf("could not create envoy snapshot output dir %s: %w", snapDir, err) - } - - targets := map[string]string{ - "config_dump.json": "config_dump", - "clusters.json": "clusters?format=json", - "stats.txt": "stats", - "stats_prometheus.txt": "stats/prometheus", - } - - var merr error - for _, c := range s.topology.Clusters { - client, err := s.HTTPClientForCluster(c.Name) - if err != nil { - return fmt.Errorf("could not get http client for cluster %q: %w", c.Name, err) - } - - for _, n := range c.Nodes { - if n.Disabled { - continue - } - for _, s := range n.Services { - if s.Disabled || s.EnvoyAdminPort <= 0 { - continue - } - prefix := fmt.Sprintf("http://%s:%d", n.LocalAddress(), s.EnvoyAdminPort) - - for fn, target := range targets { - u := prefix + "/" + target - - body, err := scrapeURL(client, u) - if err != nil { - merr = multierror.Append(merr, fmt.Errorf("could not scrape %q for %s on %s: %w", - target, s.ID.String(), n.ID().String(), err, - )) - continue - } - - outFn := filepath.Join(snapDir, n.DockerName()+"--"+s.ID.TFString()+"."+fn) - - if err := os.WriteFile(outFn+".tmp", body, 0644); err != nil { - merr = multierror.Append(merr, fmt.Errorf("could not write output %q for %s on %s: %w", - target, s.ID.String(), n.ID().String(), err, - )) - continue - } - - if err := os.Rename(outFn+".tmp", outFn); err != nil { - merr = multierror.Append(merr, fmt.Errorf("could not write output %q for %s on %s: %w", - target, s.ID.String(), n.ID().String(), err, - )) - continue - } - } - } - } - } - return merr -} - -func scrapeURL(client *http.Client, url string) ([]byte, error) { - res, err := client.Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - - body, err := io.ReadAll(res.Body) - if err != nil { - return nil, err - } - return body, nil -} - -func (s *Sprawl) CaptureLogs(ctx context.Context) error { - logDir := filepath.Join(s.workdir, "logs") - if err := os.MkdirAll(logDir, 0755); err != nil { - return fmt.Errorf("could not create log output dir %s: %w", logDir, err) - } - - containers, err := s.listContainers(ctx) - if err != nil { - return err - } - - s.logger.Debug("Capturing logs") - - var merr error - for _, container := range containers { - if err := s.dumpContainerLogs(ctx, container, logDir); err != nil { - merr = multierror.Append(merr, fmt.Errorf("could not dump logs for container %s: %w", container, err)) - } - } - - return merr -} - -// Dump known containers out of terraform state file. -func (s *Sprawl) listContainers(ctx context.Context) ([]string, error) { - tfdir := filepath.Join(s.workdir, "terraform") - - var buf bytes.Buffer - if err := s.runner.TerraformExec(ctx, []string{"state", "list"}, &buf, tfdir); err != nil { - return nil, fmt.Errorf("error listing containers in terraform state file: %w", err) - } - - var ( - scan = bufio.NewScanner(&buf) - containers []string - ) - for scan.Scan() { - line := strings.TrimSpace(scan.Text()) - - name := strings.TrimPrefix(line, "docker_container.") - if name != line { - containers = append(containers, name) - continue - } - } - if err := scan.Err(); err != nil { - return nil, err - } - - return containers, nil -} - -func (s *Sprawl) dumpContainerLogs(ctx context.Context, containerName, outputRoot string) error { - path := filepath.Join(outputRoot, containerName+".log") - - f, err := os.Create(path + ".tmp") - if err != nil { - return err - } - keep := false - defer func() { - _ = f.Close() - if !keep { - _ = os.Remove(path + ".tmp") - _ = os.Remove(path) - } - }() - - err = s.runner.DockerExecWithStderr( - ctx, - []string{"logs", containerName}, - f, - f, - nil, - ) - if err != nil { - return err - } - - if err := f.Close(); err != nil { - return err - } - - if err := os.Rename(path+".tmp", path); err != nil { - return err - } - - keep = true - return nil -} diff --git a/testing/deployer/sprawl/sprawltest/sprawltest.go b/testing/deployer/sprawl/sprawltest/sprawltest.go deleted file mode 100644 index 7b1e0493d751e..0000000000000 --- a/testing/deployer/sprawl/sprawltest/sprawltest.go +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawltest - -import ( - "context" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - "sync" - "testing" - - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-multierror" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/testing/deployer/sprawl" - "github.com/hashicorp/consul/testing/deployer/sprawl/internal/runner" - "github.com/hashicorp/consul/testing/deployer/topology" -) - -// TODO(rb): move comments to doc.go - -var ( - // set SPRAWL_WORKDIR_ROOT in the environment to have the test output - // coalesced in here. By default it uses a directory called "workdir" in - // each package. - workdirRoot string - - // set SPRAWL_KEEP_WORKDIR=1 in the environment to keep the workdir output - // intact. Files are all destroyed by default. - keepWorkdirOnFail bool - - // set SPRAWL_KEEP_RUNNING=1 in the environment to keep the workdir output - // intact and also refrain from tearing anything down. Things are all - // destroyed by default. - // - // SPRAWL_KEEP_RUNNING=1 implies SPRAWL_KEEP_WORKDIR=1 - keepRunningOnFail bool - - // set SPRAWL_SKIP_OLD_CLEANUP to prevent the library from tearing down and - // removing anything found in the working directory at init time. The - // default behavior is to do this. - skipOldCleanup bool -) - -var cleanupPriorRunOnce sync.Once - -func init() { - if root := os.Getenv("SPRAWL_WORKDIR_ROOT"); root != "" { - fmt.Fprintf(os.Stdout, "INFO: sprawltest: SPRAWL_WORKDIR_ROOT set; using %q as output root\n", root) - workdirRoot = root - } else { - workdirRoot = "workdir" - } - - if os.Getenv("SPRAWL_KEEP_WORKDIR") == "1" { - keepWorkdirOnFail = true - fmt.Fprintf(os.Stdout, "INFO: sprawltest: SPRAWL_KEEP_WORKDIR set; not destroying workdir on failure\n") - } - - if os.Getenv("SPRAWL_KEEP_RUNNING") == "1" { - keepRunningOnFail = true - keepWorkdirOnFail = true - fmt.Fprintf(os.Stdout, "INFO: sprawltest: SPRAWL_KEEP_RUNNING set; not tearing down resources on failure\n") - } - - if os.Getenv("SPRAWL_SKIP_OLD_CLEANUP") == "1" { - skipOldCleanup = true - fmt.Fprintf(os.Stdout, "INFO: sprawltest: SPRAWL_SKIP_OLD_CLEANUP set; not cleaning up anything found in %q\n", workdirRoot) - } - - if !skipOldCleanup { - cleanupPriorRunOnce.Do(func() { - fmt.Fprintf(os.Stdout, "INFO: sprawltest: triggering cleanup of any prior test runs\n") - CleanupWorkingDirectories() - }) - } -} - -// Launch will create the topology defined by the provided configuration and -// bring up all of the relevant clusters. -// -// - Logs will be routed to (*testing.T).Logf. -// -// - By default everything will be stopped and removed via -// (*testing.T).Cleanup. For failed tests, this can be skipped by setting the -// environment variable SKIP_TEARDOWN=1. -func Launch(t *testing.T, cfg *topology.Config) *sprawl.Sprawl { - SkipIfTerraformNotPresent(t) - logger := testutil.Logger(t) - // IMO default level for tests should be info, not warn - logger.SetLevel(testutil.TestLogLevelWithDefault(hclog.Info)) - sp, err := sprawl.Launch( - logger, - initWorkingDirectory(t), - cfg, - ) - require.NoError(t, err) - stopOnCleanup(t, sp) - return sp -} - -func initWorkingDirectory(t *testing.T) string { - // TODO(rb): figure out how to get the calling package which we can put in - // the middle here, which is likely 2 call frames away so maybe - // runtime.Callers can help - scratchDir := filepath.Join(workdirRoot, t.Name()) - _ = os.RemoveAll(scratchDir) // cleanup prior runs - if err := os.MkdirAll(scratchDir, 0755); err != nil { - t.Fatalf("error: %v", err) - } - - t.Cleanup(func() { - if t.Failed() && keepWorkdirOnFail { - t.Logf("test failed; leaving sprawl terraform definitions in: %s", scratchDir) - } else { - _ = os.RemoveAll(scratchDir) - } - }) - - return scratchDir -} - -func stopOnCleanup(t *testing.T, sp *sprawl.Sprawl) { - t.Cleanup(func() { - if t.Failed() && keepWorkdirOnFail { - // It's only worth it to capture the logs if we aren't going to - // immediately discard them. - if err := sp.CaptureLogs(context.Background()); err != nil { - t.Logf("log capture encountered failures: %v", err) - } - if err := sp.SnapshotEnvoy(context.Background()); err != nil { - t.Logf("envoy snapshot capture encountered failures: %v", err) - } - } - - if t.Failed() && keepRunningOnFail { - t.Log("test failed; leaving sprawl running") - } else { - //nolint:errcheck - sp.Stop() - } - }) -} - -// CleanupWorkingDirectories is meant to run in an init() once at the start of -// any tests. -func CleanupWorkingDirectories() { - fi, err := os.ReadDir(workdirRoot) - if os.IsNotExist(err) { - return - } else if err != nil { - fmt.Fprintf(os.Stderr, "WARN: sprawltest: unable to scan 'workdir' for prior runs to cleanup\n") - return - } else if len(fi) == 0 { - fmt.Fprintf(os.Stdout, "INFO: sprawltest: no prior tests to clean up\n") - return - } - - r, err := runner.Load(hclog.NewNullLogger()) - if err != nil { - fmt.Fprintf(os.Stderr, "WARN: sprawltest: unable to look for 'terraform' and 'docker' binaries\n") - return - } - - ctx := context.Background() - - for _, d := range fi { - if !d.IsDir() { - continue - } - path := filepath.Join(workdirRoot, d.Name(), "terraform") - - fmt.Fprintf(os.Stdout, "INFO: sprawltest: cleaning up failed prior run in: %s\n", path) - - err := r.TerraformExec(ctx, []string{ - "init", "-input=false", - }, io.Discard, path) - - err2 := r.TerraformExec(ctx, []string{ - "destroy", "-input=false", "-auto-approve", "-refresh=false", - }, io.Discard, path) - - if err2 != nil { - err = multierror.Append(err, err2) - } - - if err != nil { - fmt.Fprintf(os.Stderr, "WARN: sprawltest: could not clean up failed prior run in: %s: %v\n", path, err) - } else { - _ = os.RemoveAll(path) - } - } -} - -func SkipIfTerraformNotPresent(t *testing.T) { - const terraformBinaryName = "terraform" - - path, err := exec.LookPath(terraformBinaryName) - if err != nil || path == "" { - t.Skipf("%q not found on $PATH - download and install to run this test", terraformBinaryName) - } -} diff --git a/testing/deployer/sprawl/sprawltest/test_test.go b/testing/deployer/sprawl/sprawltest/test_test.go deleted file mode 100644 index 1bb69ea77efee..0000000000000 --- a/testing/deployer/sprawl/sprawltest/test_test.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawltest_test - -import ( - "strconv" - "testing" - - "github.com/hashicorp/consul/api" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" - "github.com/hashicorp/consul/testing/deployer/topology" -) - -func TestSprawl(t *testing.T) { - serversDC1 := newTopologyServerSet("dc1-server", 3, []string{"dc1", "wan"}, nil) - serversDC2 := newTopologyServerSet("dc2-server", 3, []string{"dc2", "wan"}, nil) - - cfg := &topology.Config{ - Networks: []*topology.Network{ - {Name: "dc1"}, - {Name: "dc2"}, - {Name: "wan", Type: "wan"}, - }, - Clusters: []*topology.Cluster{ - { - Name: "dc1", - Nodes: topology.MergeSlices(serversDC1, []*topology.Node{ - { - Kind: topology.NodeKindClient, - Name: "dc1-client1", - Services: []*topology.Service{ - { - ID: topology.ServiceID{Name: "mesh-gateway"}, - Port: 8443, - EnvoyAdminPort: 19000, - IsMeshGateway: true, - }, - }, - }, - { - Kind: topology.NodeKindClient, - Name: "dc1-client2", - Services: []*topology.Service{ - { - ID: topology.ServiceID{Name: "ping"}, - Image: "rboyer/pingpong:latest", - Port: 8080, - EnvoyAdminPort: 19000, - Command: []string{ - "-bind", "0.0.0.0:8080", - "-dial", "127.0.0.1:9090", - "-pong-chaos", - "-dialfreq", "250ms", - "-name", "ping", - }, - Upstreams: []*topology.Upstream{{ - ID: topology.ServiceID{Name: "pong"}, - LocalPort: 9090, - Peer: "peer-dc2-default", - }}, - }, - }, - }, - }), - InitialConfigEntries: []api.ConfigEntry{ - &api.ExportedServicesConfigEntry{ - Name: "default", - Services: []api.ExportedService{{ - Name: "ping", - Consumers: []api.ServiceConsumer{{ - Peer: "peer-dc2-default", - }}, - }}, - }, - }, - }, - { - Name: "dc2", - Nodes: topology.MergeSlices(serversDC2, []*topology.Node{ - { - Kind: topology.NodeKindClient, - Name: "dc2-client1", - Services: []*topology.Service{ - { - ID: topology.ServiceID{Name: "mesh-gateway"}, - Port: 8443, - EnvoyAdminPort: 19000, - IsMeshGateway: true, - }, - }, - }, - { - Kind: topology.NodeKindDataplane, - Name: "dc2-client2", - Services: []*topology.Service{ - { - ID: topology.ServiceID{Name: "pong"}, - Image: "rboyer/pingpong:latest", - Port: 8080, - EnvoyAdminPort: 19000, - Command: []string{ - "-bind", "0.0.0.0:8080", - "-dial", "127.0.0.1:9090", - "-pong-chaos", - "-dialfreq", "250ms", - "-name", "pong", - }, - Upstreams: []*topology.Upstream{{ - ID: topology.ServiceID{Name: "ping"}, - LocalPort: 9090, - Peer: "peer-dc1-default", - }}, - }, - }, - }, - }), - InitialConfigEntries: []api.ConfigEntry{ - &api.ExportedServicesConfigEntry{ - Name: "default", - Services: []api.ExportedService{{ - Name: "ping", - Consumers: []api.ServiceConsumer{{ - Peer: "peer-dc2-default", - }}, - }}, - }, - }, - }, - }, - Peerings: []*topology.Peering{{ - Dialing: topology.PeerCluster{ - Name: "dc1", - }, - Accepting: topology.PeerCluster{ - Name: "dc2", - }, - }}, - } - - sp := sprawltest.Launch(t, cfg) - - for _, cluster := range sp.Topology().Clusters { - leader, err := sp.Leader(cluster.Name) - require.NoError(t, err) - t.Logf("%s: leader = %s", cluster.Name, leader.ID()) - - followers, err := sp.Followers(cluster.Name) - require.NoError(t, err) - for _, f := range followers { - t.Logf("%s: follower = %s", cluster.Name, f.ID()) - } - } -} - -func newTopologyServerSet( - namePrefix string, - num int, - networks []string, - mutateFn func(i int, node *topology.Node), -) []*topology.Node { - var out []*topology.Node - for i := 1; i <= num; i++ { - name := namePrefix + strconv.Itoa(i) - - node := &topology.Node{ - Kind: topology.NodeKindServer, - Name: name, - } - for _, net := range networks { - node.Addresses = append(node.Addresses, &topology.Address{Network: net}) - } - - if mutateFn != nil { - mutateFn(i, node) - } - - out = append(out, node) - } - return out -} diff --git a/testing/deployer/sprawl/tls.go b/testing/deployer/sprawl/tls.go deleted file mode 100644 index bc5489206c7be..0000000000000 --- a/testing/deployer/sprawl/tls.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package sprawl - -import ( - "bytes" - "context" - "fmt" - "io" - - "github.com/hashicorp/consul/testing/deployer/topology" -) - -const ( - consulUID = "100" - consulGID = "1000" - consulUserArg = consulUID + ":" + consulGID -) - -func tlsPrefixFromNode(node *topology.Node) string { - switch node.Kind { - case topology.NodeKindServer: - return node.Partition + "." + node.Name + ".server" - case topology.NodeKindClient: - return node.Partition + "." + node.Name + ".client" - default: - return "" - } -} - -func tlsCertCreateCommand(node *topology.Node) string { - if node.IsServer() { - return fmt.Sprintf(`consul tls cert create -server -dc=%s -node=%s`, node.Datacenter, node.PodName()) - } else { - return fmt.Sprintf(`consul tls cert create -client -dc=%s`, node.Datacenter) - } -} - -func (s *Sprawl) initTLS(ctx context.Context) error { - for _, cluster := range s.topology.Clusters { - - var buf bytes.Buffer - - // Create the CA if not already done, and proceed to do all of the - // consul CLI calls inside of a throwaway temp directory. - buf.WriteString(` -if [[ ! -f consul-agent-ca-key.pem || ! -f consul-agent-ca.pem ]]; then - consul tls ca create -fi -rm -rf tmp -mkdir -p tmp -cp -a consul-agent-ca-key.pem consul-agent-ca.pem tmp -cd tmp -`) - - for _, node := range cluster.Nodes { - if !node.IsAgent() || node.Disabled { - continue - } - - node.TLSCertPrefix = tlsPrefixFromNode(node) - if node.TLSCertPrefix == "" { - continue - } - - expectPrefix := cluster.Datacenter + "-" + string(node.Kind) + "-consul-0" - - // Conditionally generate these in isolation and rename them to - // not rely upon the numerical indexing. - buf.WriteString(fmt.Sprintf(` -if [[ ! -f %[1]s || ! -f %[2]s ]]; then - rm -f %[3]s %[4]s - %[5]s - mv -f %[3]s %[1]s - mv -f %[4]s %[2]s -fi -`, - "../"+node.TLSCertPrefix+"-key.pem", "../"+node.TLSCertPrefix+".pem", - expectPrefix+"-key.pem", expectPrefix+".pem", - tlsCertCreateCommand(node), - )) - } - - err := s.runner.DockerExec(ctx, []string{ - "run", - "--rm", - "-i", - "--net=none", - "-v", cluster.TLSVolumeName + ":/data", - // TODO: latest busted? - // https://hashicorp.slack.com/archives/C03EUN3QF1C/p1691784078972959 - "busybox:1.34", - "sh", "-c", - // Need this so the permissions stick; docker seems to treat unused volumes differently. - `touch /data/VOLUME_PLACEHOLDER && chown -R ` + consulUserArg + ` /data`, - }, io.Discard, nil) - if err != nil { - return fmt.Errorf("could not initialize docker volume for cert data %q: %w", cluster.TLSVolumeName, err) - } - - err = s.runner.DockerExec(ctx, []string{"run", - "--rm", - "-i", - "--net=none", - "-u", consulUserArg, - "-v", cluster.TLSVolumeName + ":/data", - "-w", "/data", - "--entrypoint", "", - cluster.Images.Consul, - "/bin/sh", "-ec", buf.String(), - }, io.Discard, nil) - if err != nil { - return fmt.Errorf("could not create all necessary TLS certificates in docker volume: %v", err) - } - } - - return nil -} diff --git a/testing/deployer/topology/compile.go b/testing/deployer/topology/compile.go deleted file mode 100644 index 7faf74d01a0ee..0000000000000 --- a/testing/deployer/topology/compile.go +++ /dev/null @@ -1,678 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -import ( - crand "crypto/rand" - "encoding/hex" - "errors" - "fmt" - "reflect" - "regexp" - "sort" - - "github.com/google/go-cmp/cmp" - "github.com/hashicorp/go-hclog" -) - -const DockerPrefix = "consulcluster" - -func Compile(logger hclog.Logger, raw *Config) (*Topology, error) { - return compile(logger, raw, nil) -} - -func Recompile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error) { - if prev == nil { - return nil, errors.New("missing previous topology") - } - return compile(logger, raw, prev) -} - -func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error) { - var id string - if prev == nil { - var err error - id, err = newTopologyID() - if err != nil { - return nil, err - } - } else { - id = prev.ID - } - - images := DefaultImages().OverrideWith(raw.Images) - if images.Consul != "" { - return nil, fmt.Errorf("topology.images.consul cannot be set at this level") - } - - if len(raw.Networks) == 0 { - return nil, fmt.Errorf("topology.networks is empty") - } - - networks := make(map[string]*Network) - for _, net := range raw.Networks { - if net.DockerName != "" { - return nil, fmt.Errorf("network %q should not specify DockerName", net.Name) - } - if !IsValidLabel(net.Name) { - return nil, fmt.Errorf("network name is not valid: %s", net.Name) - } - if _, exists := networks[net.Name]; exists { - return nil, fmt.Errorf("cannot have two networks with the same name %q", net.Name) - } - - switch net.Type { - case "": - net.Type = "lan" - case "wan", "lan": - default: - return nil, fmt.Errorf("network %q has unknown type %q", net.Name, net.Type) - } - - networks[net.Name] = net - net.DockerName = DockerPrefix + "-" + net.Name + "-" + id - } - - if len(raw.Clusters) == 0 { - return nil, fmt.Errorf("topology.clusters is empty") - } - - var ( - clusters = make(map[string]*Cluster) - nextIndex int // use a global index so any shared networks work properly with assignments - ) - - foundPeerNames := make(map[string]map[string]struct{}) - for _, c := range raw.Clusters { - if c.Name == "" { - return nil, fmt.Errorf("cluster has no name") - } - - foundPeerNames[c.Name] = make(map[string]struct{}) - - if !IsValidLabel(c.Name) { - return nil, fmt.Errorf("cluster name is not valid: %s", c.Name) - } - - if _, exists := clusters[c.Name]; exists { - return nil, fmt.Errorf("cannot have two clusters with the same name %q; use unique names and override the Datacenter field if that's what you want", c.Name) - } - - if c.Datacenter == "" { - c.Datacenter = c.Name - } else { - if !IsValidLabel(c.Datacenter) { - return nil, fmt.Errorf("datacenter name is not valid: %s", c.Datacenter) - } - } - - clusters[c.Name] = c - if c.NetworkName == "" { - c.NetworkName = c.Name - } - - c.Images = images.OverrideWith(c.Images).ChooseConsul(c.Enterprise) - - if _, ok := networks[c.NetworkName]; !ok { - return nil, fmt.Errorf("cluster %q uses network name %q that does not exist", c.Name, c.NetworkName) - } - - if len(c.Nodes) == 0 { - return nil, fmt.Errorf("cluster %q has no nodes", c.Name) - } - - if c.TLSVolumeName != "" { - return nil, fmt.Errorf("user cannot specify the TLSVolumeName field") - } - - tenancies := make(map[string]map[string]struct{}) - addTenancy := func(partition, namespace string) { - partition = PartitionOrDefault(partition) - namespace = NamespaceOrDefault(namespace) - m, ok := tenancies[partition] - if !ok { - m = make(map[string]struct{}) - tenancies[partition] = m - } - m[namespace] = struct{}{} - } - - for _, ap := range c.Partitions { - addTenancy(ap.Name, "default") - for _, ns := range ap.Namespaces { - addTenancy(ap.Name, ns) - } - } - - for _, ce := range c.InitialConfigEntries { - addTenancy(ce.GetPartition(), ce.GetNamespace()) - } - - seenNodes := make(map[NodeID]struct{}) - for _, n := range c.Nodes { - if n.Name == "" { - return nil, fmt.Errorf("cluster %q node has no name", c.Name) - } - if !IsValidLabel(n.Name) { - return nil, fmt.Errorf("node name is not valid: %s", n.Name) - } - - switch n.Kind { - case NodeKindServer, NodeKindClient, NodeKindDataplane: - default: - return nil, fmt.Errorf("cluster %q node %q has invalid kind: %s", c.Name, n.Name, n.Kind) - } - - n.Partition = PartitionOrDefault(n.Partition) - if !IsValidLabel(n.Partition) { - return nil, fmt.Errorf("node partition is not valid: %s", n.Partition) - } - addTenancy(n.Partition, "default") - - if _, exists := seenNodes[n.ID()]; exists { - return nil, fmt.Errorf("cannot have two nodes in the same cluster %q with the same name %q", c.Name, n.ID()) - } - seenNodes[n.ID()] = struct{}{} - - if len(n.usedPorts) != 0 { - return nil, fmt.Errorf("user cannot specify the usedPorts field") - } - n.usedPorts = make(map[int]int) - exposePort := func(v int) bool { - if _, ok := n.usedPorts[v]; ok { - return false - } - n.usedPorts[v] = 0 - return true - } - - if n.IsAgent() { - // TODO: the ux here is awful; we should be able to examine the topology to guess properly - exposePort(8500) - if n.IsServer() { - exposePort(8503) - } else { - exposePort(8502) - } - } - - if n.Index != 0 { - return nil, fmt.Errorf("user cannot specify the node index") - } - n.Index = nextIndex - nextIndex++ - - n.Images = c.Images.OverrideWith(n.Images.ChooseConsul(c.Enterprise)).ChooseNode(n.Kind) - - n.Cluster = c.Name - n.Datacenter = c.Datacenter - n.dockerName = DockerPrefix + "-" + n.Name + "-" + id - - if len(n.Addresses) == 0 { - n.Addresses = append(n.Addresses, &Address{Network: c.NetworkName}) - } - var ( - numPublic int - numLocal int - ) - for _, addr := range n.Addresses { - if addr.Network == "" { - return nil, fmt.Errorf("cluster %q node %q has invalid address", c.Name, n.Name) - } - - if addr.Type != "" { - return nil, fmt.Errorf("user cannot specify the address type directly") - } - - net, ok := networks[addr.Network] - if !ok { - return nil, fmt.Errorf("cluster %q node %q uses network name %q that does not exist", c.Name, n.Name, addr.Network) - } - - if net.IsPublic() { - numPublic++ - } else if net.IsLocal() { - numLocal++ - } - addr.Type = net.Type - - addr.DockerNetworkName = net.DockerName - } - - if numLocal == 0 { - return nil, fmt.Errorf("cluster %q node %q has no local addresses", c.Name, n.Name) - } - if numPublic > 1 { - return nil, fmt.Errorf("cluster %q node %q has more than one public address", c.Name, n.Name) - } - - seenServices := make(map[ServiceID]struct{}) - for _, svc := range n.Services { - if n.IsAgent() { - // Default to that of the enclosing node. - svc.ID.Partition = n.Partition - } - svc.ID.Normalize() - - // Denormalize - svc.Node = n - - if !IsValidLabel(svc.ID.Partition) { - return nil, fmt.Errorf("service partition is not valid: %s", svc.ID.Partition) - } - if !IsValidLabel(svc.ID.Namespace) { - return nil, fmt.Errorf("service namespace is not valid: %s", svc.ID.Namespace) - } - if !IsValidLabel(svc.ID.Name) { - return nil, fmt.Errorf("service name is not valid: %s", svc.ID.Name) - } - if svc.ID.Partition != n.Partition { - return nil, fmt.Errorf("service %s on node %s has mismatched partitions: %s != %s", - svc.ID.Name, n.Name, svc.ID.Partition, n.Partition) - } - addTenancy(svc.ID.Partition, svc.ID.Namespace) - - if _, exists := seenServices[svc.ID]; exists { - return nil, fmt.Errorf("cannot have two services on the same node %q in the same cluster %q with the same name %q", n.ID(), c.Name, svc.ID) - } - seenServices[svc.ID] = struct{}{} - - if !svc.DisableServiceMesh && n.IsDataplane() { - if svc.EnvoyPublicListenerPort <= 0 { - if _, ok := n.usedPorts[20000]; !ok { - // For convenience the FIRST service on a node can get 20000 for free. - svc.EnvoyPublicListenerPort = 20000 - } else { - return nil, fmt.Errorf("envoy public listener port is required") - } - } - } - - // add all of the service ports - for _, port := range svc.ports() { - if ok := exposePort(port); !ok { - return nil, fmt.Errorf("port used more than once on cluster %q node %q: %d", c.Name, n.ID(), port) - } - } - - // TODO(rb): re-expose? - // switch svc.Protocol { - // case "": - // svc.Protocol = "tcp" - // fallthrough - // case "tcp": - // if svc.CheckHTTP != "" { - // return nil, fmt.Errorf("cannot set CheckHTTP for tcp service") - // } - // case "http": - // if svc.CheckTCP != "" { - // return nil, fmt.Errorf("cannot set CheckTCP for tcp service") - // } - // default: - // return nil, fmt.Errorf("service has invalid protocol: %s", svc.Protocol) - // } - - for _, u := range svc.Upstreams { - // Default to that of the enclosing service. - if u.Peer == "" { - if u.ID.Partition == "" { - u.ID.Partition = svc.ID.Partition - } - if u.ID.Namespace == "" { - u.ID.Namespace = svc.ID.Namespace - } - } else { - if u.ID.Partition != "" { - u.ID.Partition = "" // irrelevant here; we'll set it to the value of the OTHER side for plumbing purposes in tests - } - u.ID.Namespace = NamespaceOrDefault(u.ID.Namespace) - foundPeerNames[c.Name][u.Peer] = struct{}{} - } - - if u.ID.Name == "" { - return nil, fmt.Errorf("upstream service name is required") - } - addTenancy(u.ID.Partition, u.ID.Namespace) - } - - if err := svc.Validate(); err != nil { - return nil, fmt.Errorf("cluster %q node %q service %q is not valid: %w", c.Name, n.Name, svc.ID.String(), err) - } - } - } - - // Explode this into the explicit list based on stray references made. - c.Partitions = nil - for ap, nsMap := range tenancies { - p := &Partition{ - Name: ap, - } - for ns := range nsMap { - p.Namespaces = append(p.Namespaces, ns) - } - sort.Strings(p.Namespaces) - c.Partitions = append(c.Partitions, p) - } - sort.Slice(c.Partitions, func(i, j int) bool { - return c.Partitions[i].Name < c.Partitions[j].Name - }) - - if !c.Enterprise { - expect := []*Partition{{Name: "default", Namespaces: []string{"default"}}} - if !reflect.DeepEqual(c.Partitions, expect) { - return nil, fmt.Errorf("cluster %q references non-default partitions or namespaces but is CE", c.Name) - } - } - } - - clusteredPeerings := make(map[string]map[string]*PeerCluster) // local-cluster -> local-peer -> info - addPeerMapEntry := func(pc PeerCluster) { - pm, ok := clusteredPeerings[pc.Name] - if !ok { - pm = make(map[string]*PeerCluster) - clusteredPeerings[pc.Name] = pm - } - pm[pc.PeerName] = &pc - } - for _, p := range raw.Peerings { - dialingCluster, ok := clusters[p.Dialing.Name] - if !ok { - return nil, fmt.Errorf("peering references a dialing cluster that does not exist: %s", p.Dialing.Name) - } - acceptingCluster, ok := clusters[p.Accepting.Name] - if !ok { - return nil, fmt.Errorf("peering references an accepting cluster that does not exist: %s", p.Accepting.Name) - } - if p.Dialing.Name == p.Accepting.Name { - return nil, fmt.Errorf("self peerings are not allowed: %s", p.Dialing.Name) - } - - p.Dialing.Partition = PartitionOrDefault(p.Dialing.Partition) - p.Accepting.Partition = PartitionOrDefault(p.Accepting.Partition) - - if dialingCluster.Enterprise { - if !dialingCluster.hasPartition(p.Dialing.Partition) { - return nil, fmt.Errorf("dialing side of peering cannot reference a partition that does not exist: %s", p.Dialing.Partition) - } - } else { - if p.Dialing.Partition != "default" { - return nil, fmt.Errorf("dialing side of peering cannot reference a partition when CE") - } - } - if acceptingCluster.Enterprise { - if !acceptingCluster.hasPartition(p.Accepting.Partition) { - return nil, fmt.Errorf("accepting side of peering cannot reference a partition that does not exist: %s", p.Accepting.Partition) - } - } else { - if p.Accepting.Partition != "default" { - return nil, fmt.Errorf("accepting side of peering cannot reference a partition when CE") - } - } - - if p.Dialing.PeerName == "" { - p.Dialing.PeerName = "peer-" + p.Accepting.Name + "-" + p.Accepting.Partition - } - if p.Accepting.PeerName == "" { - p.Accepting.PeerName = "peer-" + p.Dialing.Name + "-" + p.Dialing.Partition - } - - { // Ensure the link fields do not have recursive links. - p.Dialing.Link = nil - p.Accepting.Link = nil - - // Copy the un-linked data before setting the link - pa := p.Accepting - pd := p.Dialing - - p.Accepting.Link = &pd - p.Dialing.Link = &pa - } - - addPeerMapEntry(p.Accepting) - addPeerMapEntry(p.Dialing) - - delete(foundPeerNames[p.Accepting.Name], p.Accepting.PeerName) - delete(foundPeerNames[p.Dialing.Name], p.Dialing.PeerName) - } - - for cluster, peers := range foundPeerNames { - if len(peers) > 0 { - var pretty []string - for name := range peers { - pretty = append(pretty, name) - } - sort.Strings(pretty) - return nil, fmt.Errorf("cluster[%s] found topology references to peerings that do not exist: %v", cluster, pretty) - } - } - - // after we decoded the peering stuff, we can fill in some computed data in the upstreams - for _, c := range clusters { - c.Peerings = clusteredPeerings[c.Name] - for _, n := range c.Nodes { - for _, svc := range n.Services { - for _, u := range svc.Upstreams { - if u.Peer == "" { - u.Cluster = c.Name - u.Peering = nil - continue - } - remotePeer, ok := c.Peerings[u.Peer] - if !ok { - return nil, fmt.Errorf("not possible") - } - u.Cluster = remotePeer.Link.Name - u.Peering = remotePeer.Link - // this helps in generating fortio assertions; otherwise field is ignored - u.ID.Partition = remotePeer.Link.Partition - } - } - } - } - - t := &Topology{ - ID: id, - Networks: networks, - Clusters: clusters, - Images: images, - Peerings: raw.Peerings, - } - - if prev != nil { - // networks cannot change - if !sameKeys(prev.Networks, t.Networks) { - return nil, fmt.Errorf("cannot create or destroy networks") - } - - for _, newNetwork := range t.Networks { - oldNetwork := prev.Networks[newNetwork.Name] - - // Carryover - newNetwork.inheritFromExisting(oldNetwork) - - if err := isSame(oldNetwork, newNetwork); err != nil { - return nil, fmt.Errorf("networks cannot change: %w", err) - } - - } - - // cannot add or remove an entire cluster - if !sameKeys(prev.Clusters, t.Clusters) { - return nil, fmt.Errorf("cannot create or destroy clusters") - } - - for _, newCluster := range t.Clusters { - oldCluster := prev.Clusters[newCluster.Name] - - // Carryover - newCluster.inheritFromExisting(oldCluster) - - if newCluster.Name != oldCluster.Name || - newCluster.NetworkName != oldCluster.NetworkName || - newCluster.Datacenter != oldCluster.Datacenter || - newCluster.Enterprise != oldCluster.Enterprise { - return nil, fmt.Errorf("cannot edit some cluster fields for %q", newCluster.Name) - } - - // WARN on presence of some things. - if len(newCluster.InitialConfigEntries) > 0 { - logger.Warn("initial config entries were provided, but are skipped on recompile") - } - - // Check NODES - if err := inheritAndValidateNodes(oldCluster.Nodes, newCluster.Nodes); err != nil { - return nil, fmt.Errorf("some immutable aspects of nodes were changed in cluster %q: %w", newCluster.Name, err) - } - } - } - - return t, nil -} - -const permutedWarning = "use the disabled node kind if you want to ignore a node" - -func inheritAndValidateNodes( - prev, curr []*Node, -) error { - nodeMap := mapifyNodes(curr) - - for prevIdx, node := range prev { - currNode, ok := nodeMap[node.ID()] - if !ok { - return fmt.Errorf("node %q has vanished; "+permutedWarning, node.ID()) - } - // Ensure it hasn't been permuted. - if currNode.Pos != prevIdx { - return fmt.Errorf( - "node %q has been shuffled %d -> %d; "+permutedWarning, - node.ID(), - prevIdx, - currNode.Pos, - ) - } - - if currNode.Node.Kind != node.Kind || - currNode.Node.Partition != node.Partition || - currNode.Node.Name != node.Name || - currNode.Node.Index != node.Index || - len(currNode.Node.Addresses) != len(node.Addresses) || - !sameKeys(currNode.Node.usedPorts, node.usedPorts) { - return fmt.Errorf("cannot edit some node fields for %q", node.ID()) - } - - currNode.Node.inheritFromExisting(node) - - for i := 0; i < len(currNode.Node.Addresses); i++ { - prevAddr := node.Addresses[i] - currAddr := currNode.Node.Addresses[i] - - if prevAddr.Network != currAddr.Network { - return fmt.Errorf("addresses were shuffled for node %q", node.ID()) - } - - if prevAddr.Type != currAddr.Type { - return fmt.Errorf("cannot edit some address fields for %q", node.ID()) - } - - currAddr.inheritFromExisting(prevAddr) - } - - svcMap := mapifyServices(currNode.Node.Services) - - for _, svc := range node.Services { - currSvc, ok := svcMap[svc.ID] - if !ok { - continue // service has vanished, this is ok - } - // don't care about index permutation - - if currSvc.ID != svc.ID || - currSvc.Port != svc.Port || - currSvc.EnvoyAdminPort != svc.EnvoyAdminPort || - currSvc.EnvoyPublicListenerPort != svc.EnvoyPublicListenerPort || - isSame(currSvc.Command, svc.Command) != nil || - isSame(currSvc.Env, svc.Env) != nil { - return fmt.Errorf("cannot edit some address fields for %q", svc.ID) - } - - currSvc.inheritFromExisting(svc) - } - } - return nil -} - -func newTopologyID() (string, error) { - const n = 16 - id := make([]byte, n) - if _, err := crand.Read(id[:]); err != nil { - return "", err - } - return hex.EncodeToString(id)[:n], nil -} - -// matches valid DNS labels according to RFC 1123, should be at most 63 -// characters according to the RFC -var validLabel = regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?$`) - -// IsValidLabel returns true if the string given is a valid DNS label (RFC 1123). -// Note: the only difference between RFC 1035 and RFC 1123 labels is that in -// RFC 1123 labels can begin with a number. -func IsValidLabel(name string) bool { - return validLabel.MatchString(name) -} - -// ValidateLabel is similar to IsValidLabel except it returns an error -// instead of false when name is not a valid DNS label. The error will contain -// reference to what constitutes a valid DNS label. -func ValidateLabel(name string) error { - if !IsValidLabel(name) { - return errors.New("a valid DNS label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character") - } - return nil -} - -func isSame(x, y any) error { - diff := cmp.Diff(x, y) - if diff != "" { - return fmt.Errorf("values are not equal\n--- expected\n+++ actual\n%v", diff) - } - return nil -} - -func sameKeys[K comparable, V any](x, y map[K]V) bool { - if len(x) != len(y) { - return false - } - - for kx := range x { - if _, ok := y[kx]; !ok { - return false - } - } - return true -} - -func mapifyNodes(nodes []*Node) map[NodeID]nodeWithPosition { - m := make(map[NodeID]nodeWithPosition) - for i, node := range nodes { - m[node.ID()] = nodeWithPosition{ - Pos: i, - Node: node, - } - } - return m -} - -type nodeWithPosition struct { - Pos int - Node *Node -} - -func mapifyServices(services []*Service) map[ServiceID]*Service { - m := make(map[ServiceID]*Service) - for _, svc := range services { - m[svc.ID] = svc - } - return m -} diff --git a/testing/deployer/topology/default_cdp.go b/testing/deployer/topology/default_cdp.go deleted file mode 100644 index f20df3d1a9ccb..0000000000000 --- a/testing/deployer/topology/default_cdp.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -const DefaultDataplaneImage = "hashicorp/consul-dataplane:1.2.1" diff --git a/testing/deployer/topology/default_consul.go b/testing/deployer/topology/default_consul.go deleted file mode 100644 index 3a259d12d4705..0000000000000 --- a/testing/deployer/topology/default_consul.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -const DefaultConsulImage = "hashicorp/consul:1.16.2" -const DefaultConsulEnterpriseImage = "hashicorp/consul-enterprise:1.16.2-ent" diff --git a/testing/deployer/topology/default_envoy.go b/testing/deployer/topology/default_envoy.go deleted file mode 100644 index c557a318a17fd..0000000000000 --- a/testing/deployer/topology/default_envoy.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -const DefaultEnvoyImage = "envoyproxy/envoy:v1.25.1" diff --git a/testing/deployer/topology/ids.go b/testing/deployer/topology/ids.go deleted file mode 100644 index 3f964b12548e6..0000000000000 --- a/testing/deployer/topology/ids.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -import ( - "fmt" - - "github.com/hashicorp/consul/api" -) - -type NodeServiceID struct { - Node string - Service string `json:",omitempty"` - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` -} - -func NewNodeServiceID(node, service, namespace, partition string) NodeServiceID { - id := NodeServiceID{ - Node: node, - Service: service, - Namespace: namespace, - Partition: partition, - } - id.Normalize() - return id -} - -func (id NodeServiceID) NodeID() NodeID { - return NewNodeID(id.Node, id.Partition) -} - -func (id NodeServiceID) ServiceID() ServiceID { - return NewServiceID(id.Service, id.Namespace, id.Partition) -} - -func (id *NodeServiceID) Normalize() { - id.Namespace = NamespaceOrDefault(id.Namespace) - id.Partition = PartitionOrDefault(id.Partition) -} - -func (id NodeServiceID) String() string { - return fmt.Sprintf("%s/%s/%s/%s", id.Partition, id.Node, id.Namespace, id.Service) -} - -type NodeID struct { - Name string `json:",omitempty"` - Partition string `json:",omitempty"` -} - -func NewNodeID(name, partition string) NodeID { - id := NodeID{ - Name: name, - Partition: partition, - } - id.Normalize() - return id -} - -func (id *NodeID) Normalize() { - id.Partition = PartitionOrDefault(id.Partition) -} - -func (id NodeID) String() string { - return fmt.Sprintf("%s/%s", id.Partition, id.Name) -} - -func (id NodeID) ACLString() string { - return fmt.Sprintf("%s--%s", id.Partition, id.Name) -} -func (id NodeID) TFString() string { - return id.ACLString() -} - -type ServiceID struct { - Name string `json:",omitempty"` - Namespace string `json:",omitempty"` - Partition string `json:",omitempty"` -} - -func NewServiceID(name, namespace, partition string) ServiceID { - id := ServiceID{ - Name: name, - Namespace: namespace, - Partition: partition, - } - id.Normalize() - return id -} - -func (id ServiceID) Less(other ServiceID) bool { - if id.Partition != other.Partition { - return id.Partition < other.Partition - } - if id.Namespace != other.Namespace { - return id.Namespace < other.Namespace - } - return id.Name < other.Name -} - -func (id *ServiceID) Normalize() { - id.Namespace = NamespaceOrDefault(id.Namespace) - id.Partition = PartitionOrDefault(id.Partition) -} - -func (id ServiceID) String() string { - return fmt.Sprintf("%s/%s/%s", id.Partition, id.Namespace, id.Name) -} - -func (id ServiceID) ACLString() string { - return fmt.Sprintf("%s--%s--%s", id.Partition, id.Namespace, id.Name) -} -func (id ServiceID) TFString() string { - return id.ACLString() -} - -func PartitionOrDefault(name string) string { - if name == "" { - return "default" - } - return name -} -func NamespaceOrDefault(name string) string { - if name == "" { - return "default" - } - return name -} - -func DefaultToEmpty(name string) string { - if name == "default" { - return "" - } - return name -} - -// PartitionQueryOptions returns an *api.QueryOptions with the given partition -// field set only if the partition is non-default. This helps when writing -// tests for joint use in CE and ENT. -func PartitionQueryOptions(partition string) *api.QueryOptions { - return &api.QueryOptions{ - Partition: DefaultToEmpty(partition), - } -} diff --git a/testing/deployer/topology/images.go b/testing/deployer/topology/images.go deleted file mode 100644 index 7adb8d3f7ee65..0000000000000 --- a/testing/deployer/topology/images.go +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -import ( - "strings" -) - -type Images struct { - // Consul is the image used for creating the container, - // Use ChooseConsul() to control which image (ConsulCE or ConsulEnterprise) assign to Consul - Consul string `json:",omitempty"` - // ConsulCE sets the CE image - ConsulCE string `json:",omitempty"` - // ConsulEnterprise sets the ent image - ConsulEnterprise string `json:",omitempty"` - Envoy string - Dataplane string -} - -func (i Images) LocalDataplaneImage() string { - if i.Dataplane == "" { - return "" - } - - img, tag, ok := strings.Cut(i.Dataplane, ":") - if !ok { - tag = "latest" - } - - repo, name, ok := strings.Cut(img, "/") - if ok { - name = repo + "-" + name - } - - // ex: local/hashicorp-consul-dataplane:1.1.0 - return "local/" + name + ":" + tag -} - -func (i Images) EnvoyConsulImage() string { - if i.Consul == "" || i.Envoy == "" { - return "" - } - - img1, tag1, ok1 := strings.Cut(i.Consul, ":") - img2, tag2, ok2 := strings.Cut(i.Envoy, ":") - if !ok1 { - tag1 = "latest" - } - if !ok2 { - tag2 = "latest" - } - - repo1, name1, ok1 := strings.Cut(img1, "/") - repo2, name2, ok2 := strings.Cut(img2, "/") - - if ok1 { - name1 = repo1 + "-" + name1 - } else { - name1 = repo1 - } - if ok2 { - name2 = repo2 + "-" + name2 - } else { - name2 = repo2 - } - - // ex: local/hashicorp-consul-and-envoyproxy-envoy:1.15.0-with-v1.26.2 - return "local/" + name1 + "-and-" + name2 + ":" + tag1 + "-with-" + tag2 -} - -// TODO: what is this for and why do we need to do this and why is it named this? -func (i Images) ChooseNode(kind NodeKind) Images { - switch kind { - case NodeKindServer: - i.Envoy = "" - i.Dataplane = "" - case NodeKindClient: - i.Dataplane = "" - case NodeKindDataplane: - i.Envoy = "" - default: - // do nothing - } - return i -} - -// ChooseConsul controls which image assigns to Consul -func (i Images) ChooseConsul(enterprise bool) Images { - if enterprise { - i.Consul = i.ConsulEnterprise - } else { - i.Consul = i.ConsulCE - } - i.ConsulEnterprise = "" - i.ConsulCE = "" - return i -} - -func (i Images) OverrideWith(i2 Images) Images { - if i2.Consul != "" { - i.Consul = i2.Consul - } - if i2.ConsulCE != "" { - i.ConsulCE = i2.ConsulCE - } - if i2.ConsulEnterprise != "" { - i.ConsulEnterprise = i2.ConsulEnterprise - } - if i2.Envoy != "" { - i.Envoy = i2.Envoy - } - if i2.Dataplane != "" { - i.Dataplane = i2.Dataplane - } - return i -} - -// DefaultImages controls which specific docker images are used as default -// values for topology components that do not specify values. -// -// These can be bulk-updated using the make target 'make update-defaults' -func DefaultImages() Images { - return Images{ - Consul: "", - ConsulCE: DefaultConsulImage, - ConsulEnterprise: DefaultConsulEnterpriseImage, - Envoy: DefaultEnvoyImage, - Dataplane: DefaultDataplaneImage, - } -} diff --git a/testing/deployer/topology/images_test.go b/testing/deployer/topology/images_test.go deleted file mode 100644 index d3ea2136e260c..0000000000000 --- a/testing/deployer/topology/images_test.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -import ( - "strconv" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestImages_EnvoyConsulImage(t *testing.T) { - type testcase struct { - consul, envoy string - expect string - } - - run := func(t *testing.T, tc testcase) { - i := Images{Consul: tc.consul, Envoy: tc.envoy} - j := i.EnvoyConsulImage() - require.Equal(t, tc.expect, j) - } - - cases := []testcase{ - { - consul: "", - envoy: "", - expect: "", - }, - { - consul: "consul", - envoy: "", - expect: "", - }, - { - consul: "", - envoy: "envoy", - expect: "", - }, - { - consul: "consul", - envoy: "envoy", - expect: "local/consul-and-envoy:latest-with-latest", - }, - // repos - { - consul: "hashicorp/consul", - envoy: "envoy", - expect: "local/hashicorp-consul-and-envoy:latest-with-latest", - }, - { - consul: "consul", - envoy: "envoyproxy/envoy", - expect: "local/consul-and-envoyproxy-envoy:latest-with-latest", - }, - { - consul: "hashicorp/consul", - envoy: "envoyproxy/envoy", - expect: "local/hashicorp-consul-and-envoyproxy-envoy:latest-with-latest", - }, - // tags - { - consul: "consul:1.15.0", - envoy: "envoy", - expect: "local/consul-and-envoy:1.15.0-with-latest", - }, - { - consul: "consul", - envoy: "envoy:v1.26.1", - expect: "local/consul-and-envoy:latest-with-v1.26.1", - }, - { - consul: "consul:1.15.0", - envoy: "envoy:v1.26.1", - expect: "local/consul-and-envoy:1.15.0-with-v1.26.1", - }, - // repos+tags - { - consul: "hashicorp/consul:1.15.0", - envoy: "envoy:v1.26.1", - expect: "local/hashicorp-consul-and-envoy:1.15.0-with-v1.26.1", - }, - { - consul: "consul:1.15.0", - envoy: "envoyproxy/envoy:v1.26.1", - expect: "local/consul-and-envoyproxy-envoy:1.15.0-with-v1.26.1", - }, - { - consul: "hashicorp/consul:1.15.0", - envoy: "envoyproxy/envoy:v1.26.1", - expect: "local/hashicorp-consul-and-envoyproxy-envoy:1.15.0-with-v1.26.1", - }, - } - - for i, tc := range cases { - t.Run(strconv.Itoa(i), func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/testing/deployer/topology/topology.go b/testing/deployer/topology/topology.go deleted file mode 100644 index 2662329aee734..0000000000000 --- a/testing/deployer/topology/topology.go +++ /dev/null @@ -1,788 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -import ( - "errors" - "fmt" - "net" - "net/netip" - "reflect" - "sort" - - "github.com/hashicorp/consul/api" -) - -type Topology struct { - ID string - - // Images controls which specific docker images are used when running this - // node. Non-empty fields here override non-empty fields inherited from the - // general default values from DefaultImages(). - Images Images - - // Networks is the list of networks to create for this set of clusters. - Networks map[string]*Network - - // Clusters defines the list of Consul clusters that should be created, and - // their associated workloads. - Clusters map[string]*Cluster - - // Peerings defines the list of pairwise peerings that should be established - // between clusters. - Peerings []*Peering `json:",omitempty"` -} - -func (t *Topology) DigestExposedProxyPort(netName string, proxyPort int) (bool, error) { - net, ok := t.Networks[netName] - if !ok { - return false, fmt.Errorf("found output network that does not exist: %s", netName) - } - if net.ProxyPort == proxyPort { - return false, nil - } - - net.ProxyPort = proxyPort - - // Denormalize for UX. - for _, cluster := range t.Clusters { - for _, node := range cluster.Nodes { - for _, addr := range node.Addresses { - if addr.Network == netName { - addr.ProxyPort = proxyPort - } - } - } - } - - return true, nil -} - -func (t *Topology) SortedNetworks() []*Network { - var out []*Network - for _, n := range t.Networks { - out = append(out, n) - } - sort.Slice(out, func(i, j int) bool { - return out[i].Name < out[j].Name - }) - return out -} - -func (t *Topology) SortedClusters() []*Cluster { - var out []*Cluster - for _, c := range t.Clusters { - out = append(out, c) - } - sort.Slice(out, func(i, j int) bool { - return out[i].Name < out[j].Name - }) - return out -} - -type Config struct { - // Images controls which specific docker images are used when running this - // node. Non-empty fields here override non-empty fields inherited from the - // general default values from DefaultImages(). - Images Images - - // Networks is the list of networks to create for this set of clusters. - Networks []*Network - - // Clusters defines the list of Consul clusters that should be created, and - // their associated workloads. - Clusters []*Cluster - - // Peerings defines the list of pairwise peerings that should be established - // between clusters. - Peerings []*Peering -} - -func (c *Config) Cluster(name string) *Cluster { - for _, cluster := range c.Clusters { - if cluster.Name == name { - return cluster - } - } - return nil -} - -type Network struct { - Type string // lan/wan ; empty means lan - Name string // logical name - - // computed at topology compile - DockerName string - // generated during network-and-tls - Subnet string - IPPool []string `json:"-"` - // generated during network-and-tls - ProxyAddress string `json:",omitempty"` - DNSAddress string `json:",omitempty"` - // filled in from terraform outputs after network-and-tls - ProxyPort int `json:",omitempty"` -} - -func (n *Network) IsLocal() bool { - return n.Type == "" || n.Type == "lan" -} - -func (n *Network) IsPublic() bool { - return n.Type == "wan" -} - -func (n *Network) inheritFromExisting(existing *Network) { - n.Subnet = existing.Subnet - n.IPPool = existing.IPPool - n.ProxyAddress = existing.ProxyAddress - n.DNSAddress = existing.DNSAddress - n.ProxyPort = existing.ProxyPort -} - -func (n *Network) IPByIndex(index int) string { - if index >= len(n.IPPool) { - panic(fmt.Sprintf( - "not enough ips on this network to assign index %d: %d", - len(n.IPPool), index, - )) - } - return n.IPPool[index] -} - -func (n *Network) SetSubnet(subnet string) (bool, error) { - if n.Subnet == subnet { - return false, nil - } - - p, err := netip.ParsePrefix(subnet) - if err != nil { - return false, err - } - if !p.IsValid() { - return false, errors.New("not valid") - } - p = p.Masked() - - var ipPool []string - - addr := p.Addr() - for { - if !p.Contains(addr) { - break - } - ipPool = append(ipPool, addr.String()) - addr = addr.Next() - } - - ipPool = ipPool[2:] // skip the x.x.x.{0,1} - - n.Subnet = subnet - n.IPPool = ipPool - return true, nil -} - -// Cluster represents a single standalone install of Consul. This is the unit -// of what is peered when using cluster peering. Older consul installs would -// call this a datacenter. -type Cluster struct { - Name string - NetworkName string // empty assumes same as Name - - // Images controls which specific docker images are used when running this - // cluster. Non-empty fields here override non-empty fields inherited from - // the enclosing Topology. - Images Images - - // Enterprise marks this cluster as desiring to run Consul Enterprise - // components. - Enterprise bool `json:",omitempty"` - - // Nodes is the definition of the nodes (agent-less and agent-ful). - Nodes []*Node - - // Partitions is a list of tenancy configurations that should be created - // after the servers come up but before the clients and the rest of the - // topology starts. - // - // Enterprise Only. - Partitions []*Partition `json:",omitempty"` - - // Datacenter defaults to "Name" if left unspecified. It lets you possibly - // create multiple peer clusters with identical datacenter names. - Datacenter string - - // InitialConfigEntries is a convenience function to have some config - // entries created after the servers start up but before the rest of the - // topology comes up. - InitialConfigEntries []api.ConfigEntry `json:",omitempty"` - - // TLSVolumeName is the docker volume name containing the various certs - // generated by 'consul tls cert create' - // - // This is generated during the networking phase and is not user specified. - TLSVolumeName string `json:",omitempty"` - - // Peerings is a map of peering names to information about that peering in this cluster - // - // Denormalized during compile. - Peerings map[string]*PeerCluster `json:",omitempty"` -} - -func (c *Cluster) inheritFromExisting(existing *Cluster) { - c.TLSVolumeName = existing.TLSVolumeName -} - -type Partition struct { - Name string - Namespaces []string -} - -func (c *Cluster) hasPartition(p string) bool { - for _, partition := range c.Partitions { - if partition.Name == p { - return true - } - } - return false -} - -func (c *Cluster) PartitionQueryOptionsList() []*api.QueryOptions { - if !c.Enterprise { - return []*api.QueryOptions{{}} - } - - var out []*api.QueryOptions - for _, p := range c.Partitions { - out = append(out, &api.QueryOptions{Partition: p.Name}) - } - return out -} - -func (c *Cluster) ServerNodes() []*Node { - var out []*Node - for _, node := range c.SortedNodes() { - if node.Kind != NodeKindServer || node.Disabled { - continue - } - out = append(out, node) - } - return out -} - -func (c *Cluster) ServerByAddr(addr string) *Node { - expect, _, err := net.SplitHostPort(addr) - if err != nil { - return nil - } - - for _, node := range c.Nodes { - if node.Kind != NodeKindServer || node.Disabled { - continue - } - if node.LocalAddress() == expect { - return node - } - } - - return nil -} - -func (c *Cluster) FirstServer() *Node { - for _, node := range c.Nodes { - // TODO: not sure why we check that it has 8500 exposed? - if node.IsServer() && !node.Disabled && node.ExposedPort(8500) > 0 { - return node - } - } - return nil -} - -func (c *Cluster) FirstClient() *Node { - for _, node := range c.Nodes { - if node.Kind != NodeKindClient || node.Disabled { - continue - } - return node - } - return nil -} - -func (c *Cluster) ActiveNodes() []*Node { - var out []*Node - for _, node := range c.Nodes { - if !node.Disabled { - out = append(out, node) - } - } - return out -} - -func (c *Cluster) SortedNodes() []*Node { - var out []*Node - out = append(out, c.Nodes...) - - kindOrder := map[NodeKind]int{ - NodeKindServer: 1, - NodeKindClient: 2, - NodeKindDataplane: 2, - } - sort.Slice(out, func(i, j int) bool { - ni, nj := out[i], out[j] - - // servers before clients/dataplanes - ki, kj := kindOrder[ni.Kind], kindOrder[nj.Kind] - if ki < kj { - return true - } else if ki > kj { - return false - } - - // lex sort by partition - if ni.Partition < nj.Partition { - return true - } else if ni.Partition > nj.Partition { - return false - } - - // lex sort by name - return ni.Name < nj.Name - }) - return out -} - -func (c *Cluster) FindService(id NodeServiceID) *Service { - id.Normalize() - - nid := id.NodeID() - sid := id.ServiceID() - return c.ServiceByID(nid, sid) -} - -func (c *Cluster) ServiceByID(nid NodeID, sid ServiceID) *Service { - return c.NodeByID(nid).ServiceByID(sid) -} - -func (c *Cluster) ServicesByID(sid ServiceID) []*Service { - sid.Normalize() - - var out []*Service - for _, n := range c.Nodes { - for _, svc := range n.Services { - if svc.ID == sid { - out = append(out, svc) - } - } - } - return out -} - -func (c *Cluster) NodeByID(nid NodeID) *Node { - nid.Normalize() - for _, n := range c.Nodes { - if n.ID() == nid { - return n - } - } - panic("node not found: " + nid.String()) -} - -type Address struct { - Network string - - // denormalized at topology compile - Type string - // denormalized at topology compile - DockerNetworkName string - // generated after network-and-tls - IPAddress string - // denormalized from terraform outputs stored in the Network - ProxyPort int `json:",omitempty"` -} - -func (a *Address) inheritFromExisting(existing *Address) { - a.IPAddress = existing.IPAddress - a.ProxyPort = existing.ProxyPort -} - -func (a Address) IsLocal() bool { - return a.Type == "" || a.Type == "lan" -} - -func (a Address) IsPublic() bool { - return a.Type == "wan" -} - -type NodeKind string - -const ( - NodeKindUnknown NodeKind = "" - NodeKindServer NodeKind = "server" - NodeKindClient NodeKind = "client" - NodeKindDataplane NodeKind = "dataplane" -) - -// TODO: rename pod -type Node struct { - Kind NodeKind - Partition string // will be not empty - Name string // logical name - - // Images controls which specific docker images are used when running this - // node. Non-empty fields here override non-empty fields inherited from - // the enclosing Cluster. - Images Images - - Disabled bool `json:",omitempty"` - - Addresses []*Address - Services []*Service - - // denormalized at topology compile - Cluster string - Datacenter string - - // computed at topology compile - Index int - - // generated during network-and-tls - TLSCertPrefix string `json:",omitempty"` - - // dockerName is computed at topology compile - dockerName string - - // usedPorts has keys that are computed at topology compile (internal - // ports) and values initialized to zero until terraform creates the pods - // and extracts the exposed port values from output variables. - usedPorts map[int]int // keys are from compile / values are from terraform output vars -} - -func (n *Node) DockerName() string { - return n.dockerName -} - -func (n *Node) ExposedPort(internalPort int) int { - return n.usedPorts[internalPort] -} - -func (n *Node) SortedPorts() []int { - var out []int - for internalPort := range n.usedPorts { - out = append(out, internalPort) - } - sort.Ints(out) - return out -} - -func (n *Node) inheritFromExisting(existing *Node) { - n.TLSCertPrefix = existing.TLSCertPrefix - - merged := existing.usedPorts - for k, vNew := range n.usedPorts { - if _, present := merged[k]; !present { - merged[k] = vNew - } - } - n.usedPorts = merged -} - -func (n *Node) String() string { - return n.ID().String() -} - -func (n *Node) ID() NodeID { - return NewNodeID(n.Name, n.Partition) -} - -func (n *Node) CatalogID() NodeID { - return NewNodeID(n.PodName(), n.Partition) -} - -func (n *Node) PodName() string { - return n.dockerName + "-pod" -} - -func (n *Node) AddressByNetwork(name string) *Address { - for _, a := range n.Addresses { - if a.Network == name { - return a - } - } - return nil -} - -func (n *Node) LocalAddress() string { - for _, a := range n.Addresses { - if a.IsLocal() { - if a.IPAddress == "" { - panic("node has no assigned local address: " + n.Name) - } - return a.IPAddress - } - } - panic("node has no local network") -} - -func (n *Node) HasPublicAddress() bool { - for _, a := range n.Addresses { - if a.IsPublic() { - return true - } - } - return false -} - -func (n *Node) LocalProxyPort() int { - for _, a := range n.Addresses { - if a.IsLocal() { - if a.ProxyPort > 0 { - return a.ProxyPort - } - panic("node has no assigned local address: " + n.Name) - } - } - panic("node has no local network") -} - -func (n *Node) PublicAddress() string { - for _, a := range n.Addresses { - if a.IsPublic() { - if a.IPAddress == "" { - panic("node has no assigned public address") - } - return a.IPAddress - } - } - panic("node has no public network") -} - -func (n *Node) PublicProxyPort() int { - for _, a := range n.Addresses { - if a.IsPublic() { - if a.ProxyPort > 0 { - return a.ProxyPort - } - panic("node has no assigned public address") - } - } - panic("node has no public network") -} - -func (n *Node) IsServer() bool { - return n.Kind == NodeKindServer -} - -func (n *Node) IsAgent() bool { - return n.Kind == NodeKindServer || n.Kind == NodeKindClient -} - -func (n *Node) RunsWorkloads() bool { - return n.IsAgent() || n.IsDataplane() -} - -func (n *Node) IsDataplane() bool { - return n.Kind == NodeKindDataplane -} - -func (n *Node) SortedServices() []*Service { - var out []*Service - out = append(out, n.Services...) - sort.Slice(out, func(i, j int) bool { - mi := out[i].IsMeshGateway - mj := out[j].IsMeshGateway - if mi && !mi { - return false - } else if !mi && mj { - return true - } - return out[i].ID.Less(out[j].ID) - }) - return out -} - -// DigestExposedPorts returns true if it was changed. -func (n *Node) DigestExposedPorts(ports map[int]int) bool { - if reflect.DeepEqual(n.usedPorts, ports) { - return false - } - for internalPort := range n.usedPorts { - if v, ok := ports[internalPort]; ok { - n.usedPorts[internalPort] = v - } else { - panic(fmt.Sprintf( - "cluster %q node %q port %d not found in exposed list", - n.Cluster, - n.ID(), - internalPort, - )) - } - } - for _, svc := range n.Services { - svc.DigestExposedPorts(ports) - } - - return true -} - -func (n *Node) ServiceByID(sid ServiceID) *Service { - sid.Normalize() - for _, svc := range n.Services { - if svc.ID == sid { - return svc - } - } - panic("service not found: " + sid.String()) -} - -type ServiceAndNode struct { - Service *Service - Node *Node -} - -type Service struct { - ID ServiceID - Image string - Port int - ExposedPort int `json:",omitempty"` - - Disabled bool `json:",omitempty"` // TODO - - // TODO: expose extra port here? - - Meta map[string]string `json:",omitempty"` - - // TODO(rb): re-expose this perhaps? Protocol string `json:",omitempty"` // tcp|http (empty == tcp) - CheckHTTP string `json:",omitempty"` // url; will do a GET - CheckTCP string `json:",omitempty"` // addr; will do a socket open/close - - EnvoyAdminPort int - ExposedEnvoyAdminPort int `json:",omitempty"` - EnvoyPublicListenerPort int `json:",omitempty"` // agentless - - Command []string `json:",omitempty"` // optional - Env []string `json:",omitempty"` // optional - - DisableServiceMesh bool `json:",omitempty"` - IsMeshGateway bool `json:",omitempty"` - Upstreams []*Upstream - - // denormalized at topology compile - Node *Node `json:"-"` -} - -func (s *Service) inheritFromExisting(existing *Service) { - s.ExposedPort = existing.ExposedPort - s.ExposedEnvoyAdminPort = existing.ExposedEnvoyAdminPort -} - -func (s *Service) ports() []int { - var out []int - if s.Port > 0 { - out = append(out, s.Port) - } - if s.EnvoyAdminPort > 0 { - out = append(out, s.EnvoyAdminPort) - } - if s.EnvoyPublicListenerPort > 0 { - out = append(out, s.EnvoyPublicListenerPort) - } - for _, u := range s.Upstreams { - if u.LocalPort > 0 { - out = append(out, u.LocalPort) - } - } - return out -} - -func (s *Service) HasCheck() bool { - return s.CheckTCP != "" || s.CheckHTTP != "" -} - -func (s *Service) DigestExposedPorts(ports map[int]int) { - s.ExposedPort = ports[s.Port] - if s.EnvoyAdminPort > 0 { - s.ExposedEnvoyAdminPort = ports[s.EnvoyAdminPort] - } else { - s.ExposedEnvoyAdminPort = 0 - } -} - -func (s *Service) Validate() error { - if s.ID.Name == "" { - return fmt.Errorf("service name is required") - } - if s.Image == "" && !s.IsMeshGateway { - return fmt.Errorf("service image is required") - } - if s.Port <= 0 { - return fmt.Errorf("service has invalid port") - } - if s.DisableServiceMesh && s.IsMeshGateway { - return fmt.Errorf("cannot disable service mesh and still run a mesh gateway") - } - if s.DisableServiceMesh && len(s.Upstreams) > 0 { - return fmt.Errorf("cannot disable service mesh and configure upstreams") - } - - if s.DisableServiceMesh { - if s.EnvoyAdminPort != 0 { - return fmt.Errorf("cannot use envoy admin port without a service mesh") - } - } else { - if s.EnvoyAdminPort <= 0 { - return fmt.Errorf("envoy admin port is required") - } - } - - for _, u := range s.Upstreams { - if u.ID.Name == "" { - return fmt.Errorf("upstream service name is required") - } - if u.LocalPort <= 0 { - return fmt.Errorf("upstream local port is required") - } - - if u.LocalAddress != "" { - ip := net.ParseIP(u.LocalAddress) - if ip == nil { - return fmt.Errorf("upstream local address is invalid: %s", u.LocalAddress) - } - } - } - - return nil -} - -type Upstream struct { - ID ServiceID - LocalAddress string `json:",omitempty"` // defaults to 127.0.0.1 - LocalPort int - Peer string `json:",omitempty"` - // TODO: what about mesh gateway mode overrides? - - // computed at topology compile - Cluster string `json:",omitempty"` - Peering *PeerCluster `json:",omitempty"` // this will have Link!=nil -} - -type Peering struct { - Dialing PeerCluster - Accepting PeerCluster -} - -type PeerCluster struct { - Name string - Partition string - PeerName string // name to call it on this side; defaults if not specified - - // computed at topology compile (pointer so it can be empty in json) - Link *PeerCluster `json:",omitempty"` -} - -func (c PeerCluster) String() string { - return c.Name + ":" + c.Partition -} - -func (p *Peering) String() string { - return "(" + p.Dialing.String() + ")->(" + p.Accepting.String() + ")" -} diff --git a/testing/deployer/topology/util.go b/testing/deployer/topology/util.go deleted file mode 100644 index a6d6670c2655c..0000000000000 --- a/testing/deployer/topology/util.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -func MergeSlices[V any](x, y []V) []V { - switch { - case len(x) == 0 && len(y) == 0: - return nil - case len(x) == 0: - return y - case len(y) == 0: - return x - } - - out := make([]V, 0, len(x)+len(y)) - out = append(out, x...) - out = append(out, y...) - return out -} diff --git a/testing/deployer/topology/util_test.go b/testing/deployer/topology/util_test.go deleted file mode 100644 index a858a4e698149..0000000000000 --- a/testing/deployer/topology/util_test.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestMergeSlices(t *testing.T) { - require.Nil(t, MergeSlices[int](nil, nil)) -} diff --git a/testing/deployer/util/consul.go b/testing/deployer/util/consul.go deleted file mode 100644 index d3ebc037a9fed..0000000000000 --- a/testing/deployer/util/consul.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package util - -import ( - "fmt" - "net/http" - "net/url" - "strconv" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/go-cleanhttp" -) - -func ProxyNotPooledAPIClient(proxyPort int, containerIP string, containerPort int, token string) (*api.Client, error) { - return proxyAPIClient(cleanhttp.DefaultTransport(), proxyPort, containerIP, containerPort, token) -} - -func ProxyAPIClient(proxyPort int, containerIP string, containerPort int, token string) (*api.Client, error) { - return proxyAPIClient(cleanhttp.DefaultPooledTransport(), proxyPort, containerIP, containerPort, token) -} - -func proxyAPIClient(baseTransport *http.Transport, proxyPort int, containerIP string, containerPort int, token string) (*api.Client, error) { - if proxyPort <= 0 { - return nil, fmt.Errorf("cannot use an http proxy on port %d", proxyPort) - } - if containerIP == "" { - return nil, fmt.Errorf("container IP is required") - } - if containerPort <= 0 { - return nil, fmt.Errorf("cannot dial api client on port %d", containerPort) - } - - proxyURL, err := url.Parse("http://127.0.0.1:" + strconv.Itoa(proxyPort)) - if err != nil { - return nil, err - } - - cfg := api.DefaultConfig() - cfg.Transport = baseTransport - cfg.Transport.Proxy = http.ProxyURL(proxyURL) - cfg.Address = fmt.Sprintf("http://%s:%d", containerIP, containerPort) - cfg.Token = token - return api.NewClient(cfg) -} - -func ProxyNotPooledHTTPTransport(proxyPort int) (*http.Transport, error) { - return proxyHTTPTransport(cleanhttp.DefaultTransport(), proxyPort) -} - -func ProxyHTTPTransport(proxyPort int) (*http.Transport, error) { - return proxyHTTPTransport(cleanhttp.DefaultPooledTransport(), proxyPort) -} - -func proxyHTTPTransport(baseTransport *http.Transport, proxyPort int) (*http.Transport, error) { - if proxyPort <= 0 { - return nil, fmt.Errorf("cannot use an http proxy on port %d", proxyPort) - } - proxyURL, err := url.Parse("http://127.0.0.1:" + strconv.Itoa(proxyPort)) - if err != nil { - return nil, err - } - baseTransport.Proxy = http.ProxyURL(proxyURL) - return baseTransport, nil -} diff --git a/testing/deployer/util/files.go b/testing/deployer/util/files.go deleted file mode 100644 index 5929f227e501a..0000000000000 --- a/testing/deployer/util/files.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package util - -import ( - "fmt" - "io" - "os" - "path/filepath" - - "golang.org/x/crypto/blake2b" -) - -func FilesExist(parent string, paths ...string) (bool, error) { - for _, p := range paths { - ok, err := FileExists(filepath.Join(parent, p)) - if err != nil { - return false, err - } - if !ok { - return false, nil - } - } - return true, nil -} - -func FileExists(path string) (bool, error) { - _, err := os.Stat(path) - if os.IsNotExist(err) { - return false, nil - } else if err != nil { - return false, err - } else { - return true, nil - } -} - -func HashFile(path string) (string, error) { - hash, err := blake2b.New256(nil) - if err != nil { - return "", err - } - - if err := AddFileToHash(path, hash); err != nil { - return "", err - } - - return fmt.Sprintf("%x", hash.Sum(nil)), nil -} - -func AddFileToHash(path string, w io.Writer) error { - f, err := os.Open(path) - if err != nil { - return err - } - defer f.Close() - _, err = io.Copy(w, f) - return err -} diff --git a/testing/deployer/util/internal/ipamutils/doc.go b/testing/deployer/util/internal/ipamutils/doc.go deleted file mode 100644 index 7820e3776201b..0000000000000 --- a/testing/deployer/util/internal/ipamutils/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015 Docker Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Originally from: -// https://github.com/moby/moby/blob/7489b51f610104ab5acc43f4e77142927e7b522e/libnetwork/ipamutils -// -// The only changes were to remove dead code from the package that we did not -// need, and to edit the tests to use github.com/stretchr/testify to avoid an -// extra dependency. -package ipamutils diff --git a/testing/deployer/util/internal/ipamutils/utils.go b/testing/deployer/util/internal/ipamutils/utils.go deleted file mode 100644 index 11367cc176bbf..0000000000000 --- a/testing/deployer/util/internal/ipamutils/utils.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Package ipamutils provides utility functions for ipam management -package ipamutils - -import ( - "fmt" - "net" - "sync" -) - -var ( - // predefinedLocalScopeDefaultNetworks contains a list of 31 IPv4 private networks with host size 16 and 12 - // (172.17-31.x.x/16, 192.168.x.x/20) which do not overlap with the networks in `PredefinedGlobalScopeDefaultNetworks` - predefinedLocalScopeDefaultNetworks []*net.IPNet - // predefinedGlobalScopeDefaultNetworks contains a list of 64K IPv4 private networks with host size 8 - // (10.x.x.x/24) which do not overlap with the networks in `PredefinedLocalScopeDefaultNetworks` - predefinedGlobalScopeDefaultNetworks []*net.IPNet - mutex sync.Mutex - localScopeDefaultNetworks = []*NetworkToSplit{{"172.17.0.0/16", 16}, {"172.18.0.0/16", 16}, {"172.19.0.0/16", 16}, - {"172.20.0.0/14", 16}, {"172.24.0.0/14", 16}, {"172.28.0.0/14", 16}, - {"192.168.0.0/16", 20}} - globalScopeDefaultNetworks = []*NetworkToSplit{{"10.0.0.0/8", 24}} -) - -// NetworkToSplit represent a network that has to be split in chunks with mask length Size. -// Each subnet in the set is derived from the Base pool. Base is to be passed -// in CIDR format. -// Example: a Base "10.10.0.0/16 with Size 24 will define the set of 256 -// 10.10.[0-255].0/24 address pools -type NetworkToSplit struct { - Base string `json:"base"` - Size int `json:"size"` -} - -func init() { - var err error - if predefinedGlobalScopeDefaultNetworks, err = SplitNetworks(globalScopeDefaultNetworks); err != nil { - panic("failed to initialize the global scope default address pool: " + err.Error()) - } - - if predefinedLocalScopeDefaultNetworks, err = SplitNetworks(localScopeDefaultNetworks); err != nil { - panic("failed to initialize the local scope default address pool: " + err.Error()) - } -} - -// ConfigGlobalScopeDefaultNetworks configures global default pool. -// Ideally this will be called from SwarmKit as part of swarm init -func ConfigGlobalScopeDefaultNetworks(defaultAddressPool []*NetworkToSplit) error { - if defaultAddressPool == nil { - return nil - } - mutex.Lock() - defer mutex.Unlock() - defaultNetworks, err := SplitNetworks(defaultAddressPool) - if err != nil { - return err - } - predefinedGlobalScopeDefaultNetworks = defaultNetworks - return nil -} - -// GetGlobalScopeDefaultNetworks returns a copy of the global-sopce network list. -func GetGlobalScopeDefaultNetworks() []*net.IPNet { - mutex.Lock() - defer mutex.Unlock() - return append([]*net.IPNet(nil), predefinedGlobalScopeDefaultNetworks...) -} - -// GetLocalScopeDefaultNetworks returns a copy of the default local-scope network list. -func GetLocalScopeDefaultNetworks() []*net.IPNet { - return append([]*net.IPNet(nil), predefinedLocalScopeDefaultNetworks...) -} - -// SplitNetworks takes a slice of networks, split them accordingly and returns them -func SplitNetworks(list []*NetworkToSplit) ([]*net.IPNet, error) { - localPools := make([]*net.IPNet, 0, len(list)) - - for _, p := range list { - _, b, err := net.ParseCIDR(p.Base) - if err != nil { - return nil, fmt.Errorf("invalid base pool %q: %v", p.Base, err) - } - ones, _ := b.Mask.Size() - if p.Size <= 0 || p.Size < ones { - return nil, fmt.Errorf("invalid pools size: %d", p.Size) - } - localPools = append(localPools, splitNetwork(p.Size, b)...) - } - return localPools, nil -} - -func splitNetwork(size int, base *net.IPNet) []*net.IPNet { - one, bits := base.Mask.Size() - mask := net.CIDRMask(size, bits) - n := 1 << uint(size-one) - s := uint(bits - size) - list := make([]*net.IPNet, 0, n) - - for i := 0; i < n; i++ { - ip := copyIP(base.IP) - addIntToIP(ip, uint(i<= 0; i-- { - array[i] |= (byte)(ordinal & 0xff) - ordinal >>= 8 - } -} diff --git a/testing/deployer/util/internal/ipamutils/utils_test.go b/testing/deployer/util/internal/ipamutils/utils_test.go deleted file mode 100644 index e91ae258cb913..0000000000000 --- a/testing/deployer/util/internal/ipamutils/utils_test.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package ipamutils - -import ( - "net" - "testing" - - "github.com/stretchr/testify/assert" -) - -func initBroadPredefinedNetworks() []*net.IPNet { - pl := make([]*net.IPNet, 0, 31) - mask := []byte{255, 255, 0, 0} - for i := 17; i < 32; i++ { - pl = append(pl, &net.IPNet{IP: []byte{172, byte(i), 0, 0}, Mask: mask}) - } - mask20 := []byte{255, 255, 240, 0} - for i := 0; i < 16; i++ { - pl = append(pl, &net.IPNet{IP: []byte{192, 168, byte(i << 4), 0}, Mask: mask20}) - } - return pl -} - -func initGranularPredefinedNetworks() []*net.IPNet { - pl := make([]*net.IPNet, 0, 256*256) - mask := []byte{255, 255, 255, 0} - for i := 0; i < 256; i++ { - for j := 0; j < 256; j++ { - pl = append(pl, &net.IPNet{IP: []byte{10, byte(i), byte(j), 0}, Mask: mask}) - } - } - return pl -} - -func initGlobalScopeNetworks() []*net.IPNet { - pl := make([]*net.IPNet, 0, 256*256) - mask := []byte{255, 255, 255, 0} - for i := 0; i < 256; i++ { - for j := 0; j < 256; j++ { - pl = append(pl, &net.IPNet{IP: []byte{30, byte(i), byte(j), 0}, Mask: mask}) - } - } - return pl -} - -func TestDefaultNetwork(t *testing.T) { - for _, nw := range GetGlobalScopeDefaultNetworks() { - if ones, bits := nw.Mask.Size(); bits != 32 || ones != 24 { - t.Fatalf("Unexpected size for network in granular list: %v", nw) - } - } - - for _, nw := range GetLocalScopeDefaultNetworks() { - if ones, bits := nw.Mask.Size(); bits != 32 || (ones != 20 && ones != 16) { - t.Fatalf("Unexpected size for network in broad list: %v", nw) - } - } - - originalBroadNets := initBroadPredefinedNetworks() - m := make(map[string]bool) - for _, v := range originalBroadNets { - m[v.String()] = true - } - for _, nw := range GetLocalScopeDefaultNetworks() { - _, ok := m[nw.String()] - assert.True(t, ok) - delete(m, nw.String()) - } - - assert.Empty(t, m) - - originalGranularNets := initGranularPredefinedNetworks() - - m = make(map[string]bool) - for _, v := range originalGranularNets { - m[v.String()] = true - } - for _, nw := range GetGlobalScopeDefaultNetworks() { - _, ok := m[nw.String()] - assert.True(t, ok) - delete(m, nw.String()) - } - - assert.Empty(t, m) -} - -func TestConfigGlobalScopeDefaultNetworks(t *testing.T) { - err := ConfigGlobalScopeDefaultNetworks([]*NetworkToSplit{{"30.0.0.0/8", 24}}) - assert.NoError(t, err) - - originalGlobalScopeNetworks := initGlobalScopeNetworks() - m := make(map[string]bool) - for _, v := range originalGlobalScopeNetworks { - m[v.String()] = true - } - for _, nw := range GetGlobalScopeDefaultNetworks() { - _, ok := m[nw.String()] - assert.True(t, ok) - delete(m, nw.String()) - } - - assert.Empty(t, m) -} diff --git a/testing/deployer/util/net.go b/testing/deployer/util/net.go deleted file mode 100644 index 83ca01761b48c..0000000000000 --- a/testing/deployer/util/net.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package util - -import ( - "github.com/hashicorp/consul/testing/deployer/util/internal/ipamutils" -) - -// GetPossibleDockerNetworkSubnets returns a copy of the global-scope network list. -func GetPossibleDockerNetworkSubnets() map[string]struct{} { - list := ipamutils.GetGlobalScopeDefaultNetworks() - - out := make(map[string]struct{}) - for _, ipnet := range list { - subnet := ipnet.String() - out[subnet] = struct{}{} - } - return out -} diff --git a/testrpc/wait.go b/testrpc/wait.go index ca315d28539e4..acd9524d78f30 100644 --- a/testrpc/wait.go +++ b/testrpc/wait.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package testrpc diff --git a/tlsutil/config.go b/tlsutil/config.go index 5cba2597f19d7..5cdaf7633eca5 100644 --- a/tlsutil/config.go +++ b/tlsutil/config.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tlsutil @@ -857,23 +857,10 @@ func (c *Configurator) IncomingHTTPSConfig() *tls.Config { return config } -// OutgoingTLSConfigForCheck creates a client *tls.Config for executing checks. -// It is RECOMMENDED that the serverName be left unspecified. The crypto/tls -// client will deduce the ServerName (for SNI) from the check address unless -// it's an IP (RFC 6066, Section 3). However, there are two instances where -// supplying a serverName is useful: -// -// 1. When the check address is an IP, a serverName can be supplied for SNI. -// Note: setting serverName will also override the hostname used to verify -// the certificate presented by the server being checked. -// -// 2. When the hostname in the check address won't be present in the SAN -// (Subject Alternative Name) field of the certificate presented by the -// server being checked. Note: setting serverName will also override the -// ServerName used for SNI. -// -// Setting skipVerify will disable verification of the server's certificate -// chain and hostname, which is generally not suitable for production use. +// OutgoingTLSConfigForCheck generates a *tls.Config for outgoing TLS connections +// for checks. This function is separated because there is an extra flag to +// consider for checks. EnableAgentTLSForChecks and InsecureSkipVerify has to +// be checked for checks. func (c *Configurator) OutgoingTLSConfigForCheck(skipVerify bool, serverName string) *tls.Config { c.log("OutgoingTLSConfigForCheck") @@ -888,9 +875,13 @@ func (c *Configurator) OutgoingTLSConfigForCheck(skipVerify bool, serverName str } } + if serverName == "" { + serverName = c.serverNameOrNodeName() + } config := c.internalRPCTLSConfig(false) config.InsecureSkipVerify = skipVerify config.ServerName = serverName + return config } diff --git a/tlsutil/config_test.go b/tlsutil/config_test.go index bc2ee36068a41..30ebd62c206b7 100644 --- a/tlsutil/config_test.go +++ b/tlsutil/config_test.go @@ -1,6 +1,7 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 //go:build !fips +// +build !fips package tlsutil @@ -1375,7 +1376,7 @@ func TestConfigurator_OutgoingTLSConfigForCheck(t *testing.T) { }, }, { - name: "agent tls, default consul server name, no override", + name: "agent tls, default server name", conf: func() (*Configurator, error) { return NewConfigurator(Config{ InternalRPC: ProtocolConfig{ @@ -1388,11 +1389,11 @@ func TestConfigurator_OutgoingTLSConfigForCheck(t *testing.T) { }, expected: &tls.Config{ MinVersion: tls.VersionTLS12, - ServerName: "", + ServerName: "servername", }, }, { - name: "agent tls, skip verify, consul node name for server name, no override", + name: "agent tls, skip verify, node name for server name", conf: func() (*Configurator, error) { return NewConfigurator(Config{ InternalRPC: ProtocolConfig{ @@ -1406,7 +1407,7 @@ func TestConfigurator_OutgoingTLSConfigForCheck(t *testing.T) { expected: &tls.Config{ InsecureSkipVerify: true, MinVersion: tls.VersionTLS12, - ServerName: "", + ServerName: "nodename", }, }, { diff --git a/tlsutil/generate.go b/tlsutil/generate.go index 907d7ba99694f..a92f76f9201c8 100644 --- a/tlsutil/generate.go +++ b/tlsutil/generate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tlsutil diff --git a/tlsutil/generate_test.go b/tlsutil/generate_test.go index da3fd29af1f9c..ddceefe2cd5ae 100644 --- a/tlsutil/generate_test.go +++ b/tlsutil/generate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package tlsutil diff --git a/tools/internal-grpc-proxy/main.go b/tools/internal-grpc-proxy/main.go index 5a4218e8fa466..fda3d2f044464 100644 --- a/tools/internal-grpc-proxy/main.go +++ b/tools/internal-grpc-proxy/main.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package main diff --git a/troubleshoot/go.mod b/troubleshoot/go.mod index 4845f60518835..f5645a50f4b3e 100644 --- a/troubleshoot/go.mod +++ b/troubleshoot/go.mod @@ -6,8 +6,6 @@ replace github.com/hashicorp/consul/api => ../api replace github.com/hashicorp/consul/envoyextensions => ../envoyextensions -replace github.com/hashicorp/consul/proto-public => ../proto-public - exclude ( github.com/hashicorp/go-msgpack v1.1.5 // has breaking changes and must be avoided github.com/hashicorp/go-msgpack v1.1.6 // contains retractions but same as v1.1.5 @@ -39,16 +37,14 @@ require ( github.com/hashicorp/go-version v1.2.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/serf v0.10.1 // indirect - github.com/kr/pretty v0.3.0 // indirect github.com/mattn/go-colorable v0.1.13 // 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.4.0 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // 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 @@ -56,6 +52,5 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e // indirect google.golang.org/grpc v1.56.3 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/troubleshoot/go.sum b/troubleshoot/go.sum index 49e800a36eadc..ef0e795c4caf4 100644 --- a/troubleshoot/go.sum +++ b/troubleshoot/go.sum @@ -70,7 +70,6 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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= @@ -210,14 +209,11 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V 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/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -275,9 +271,6 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -324,8 +317,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= -golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -593,9 +586,8 @@ google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/troubleshoot/proxy/certs.go b/troubleshoot/proxy/certs.go index 8f0c09b0293e9..083f1873b528f 100644 --- a/troubleshoot/proxy/certs.go +++ b/troubleshoot/proxy/certs.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/proxy/certs_test.go b/troubleshoot/proxy/certs_test.go index e3db4dc009c5a..ec3ead7e02275 100644 --- a/troubleshoot/proxy/certs_test.go +++ b/troubleshoot/proxy/certs_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/proxy/stats.go b/troubleshoot/proxy/stats.go index 249dce07db040..0ae4f68c8d102 100644 --- a/troubleshoot/proxy/stats.go +++ b/troubleshoot/proxy/stats.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/proxy/troubleshoot_proxy.go b/troubleshoot/proxy/troubleshoot_proxy.go index 4cd422b0d4b89..5dac26752e439 100644 --- a/troubleshoot/proxy/troubleshoot_proxy.go +++ b/troubleshoot/proxy/troubleshoot_proxy.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/proxy/upstreams.go b/troubleshoot/proxy/upstreams.go index 62f08572059a3..c42f6b9716650 100644 --- a/troubleshoot/proxy/upstreams.go +++ b/troubleshoot/proxy/upstreams.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/proxy/upstreams_test.go b/troubleshoot/proxy/upstreams_test.go index a2f0bf60b08e0..a000738acde0b 100644 --- a/troubleshoot/proxy/upstreams_test.go +++ b/troubleshoot/proxy/upstreams_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/proxy/utils.go b/troubleshoot/proxy/utils.go index 78fadaed119e2..b812272942c69 100644 --- a/troubleshoot/proxy/utils.go +++ b/troubleshoot/proxy/utils.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/proxy/validateupstream.go b/troubleshoot/proxy/validateupstream.go index 02c355f40e705..64be9d02e1723 100644 --- a/troubleshoot/proxy/validateupstream.go +++ b/troubleshoot/proxy/validateupstream.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/proxy/validateupstream_test.go b/troubleshoot/proxy/validateupstream_test.go index ddeca9b1cd72a..8709c42d9212c 100644 --- a/troubleshoot/proxy/validateupstream_test.go +++ b/troubleshoot/proxy/validateupstream_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package troubleshoot diff --git a/troubleshoot/validate/validate.go b/troubleshoot/validate/validate.go index 93d26bb42ed12..f7c6299f99848 100644 --- a/troubleshoot/validate/validate.go +++ b/troubleshoot/validate/validate.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package validate diff --git a/troubleshoot/validate/validate_test.go b/troubleshoot/validate/validate_test.go index b9e2aeed611f5..9d779c48f466e 100644 --- a/troubleshoot/validate/validate_test.go +++ b/troubleshoot/validate/validate_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package validate diff --git a/types/area.go b/types/area.go index 7cd0af35fb5c0..30207cd2c388d 100644 --- a/types/area.go +++ b/types/area.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types diff --git a/types/checks.go b/types/checks.go index d119319f413e7..172330267db6d 100644 --- a/types/checks.go +++ b/types/checks.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types diff --git a/types/node_id.go b/types/node_id.go index 868dbf52a9a0d..c404b02bea353 100644 --- a/types/node_id.go +++ b/types/node_id.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types diff --git a/types/tls.go b/types/tls.go index e4788819b8c3a..b113c29030a7c 100644 --- a/types/tls.go +++ b/types/tls.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types diff --git a/types/tls_test.go b/types/tls_test.go index a988cfbc9fb7c..a41817af32cd3 100644 --- a/types/tls_test.go +++ b/types/tls_test.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 package types diff --git a/ui/.nvmrc b/ui/.nvmrc index 3c032078a4a21..b6a7d89c68e0c 100644 --- a/ui/.nvmrc +++ b/ui/.nvmrc @@ -1 +1 @@ -18 +16 diff --git a/ui/package.json b/ui/package.json index 7ed39b1595ac3..5a161e4e691bb 100644 --- a/ui/package.json +++ b/ui/package.json @@ -24,6 +24,6 @@ "ember-basic-dropdown": "3.0.21" }, "engines": { - "node": "18" + "node": ">=14 <=16" } } diff --git a/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs b/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs index a13efa37c19d4..afee0962633f4 100644 --- a/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs +++ b/ui/packages/consul-acls/app/components/consul/acl/selector/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}

    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 diff --git a/test/integration/consul-container/test/util/test_debug_resume_program.png b/test/integration/consul-container/test/util/test_debug_resume_program.png deleted file mode 100644 index 99c2899019bb54c55fe29d26a4939dbaf2684f74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51972 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

  • routes({ diff --git a/ui/packages/consul-acls/vendor/consul-acls/services.js b/ui/packages/consul-acls/vendor/consul-acls/services.js index 1654b41eeea71..74e67ac3a2b82 100644 --- a/ui/packages/consul-acls/vendor/consul-acls/services.js +++ b/ui/packages/consul-acls/vendor/consul-acls/services.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ (services => services({ diff --git a/ui/packages/consul-hcp/app/components/consul/hcp/home/index.hbs b/ui/packages/consul-hcp/app/components/consul/hcp/home/index.hbs index bb5a1fc32a983..55c6531d2be47 100644 --- a/ui/packages/consul-hcp/app/components/consul/hcp/home/index.hbs +++ b/ui/packages/consul-hcp/app/components/consul/hcp/home/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    routes({ diff --git a/ui/packages/consul-hcp/vendor/consul-hcp/services.js b/ui/packages/consul-hcp/vendor/consul-hcp/services.js index d1c7820f7da51..c95daf828c763 100644 --- a/ui/packages/consul-hcp/vendor/consul-hcp/services.js +++ b/ui/packages/consul-hcp/vendor/consul-hcp/services.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ (services => services({ diff --git a/ui/packages/consul-lock-sessions/app/components/consul/lock-session/form/index.hbs b/ui/packages/consul-lock-sessions/app/components/consul/lock-session/form/index.hbs index d84292c72fba9..f7cffddd8b771 100644 --- a/ui/packages/consul-lock-sessions/app/components/consul/lock-session/form/index.hbs +++ b/ui/packages/consul-lock-sessions/app/components/consul/lock-session/form/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    {{else}} {{item.ID}} - @@ -28,7 +28,7 @@ as |item index|> ID
    - diff --git a/ui/packages/consul-lock-sessions/app/components/consul/lock-session/list/index.scss b/ui/packages/consul-lock-sessions/app/components/consul/lock-session/list/index.scss index 503e5192f4730..5182136a3b534 100644 --- a/ui/packages/consul-lock-sessions/app/components/consul/lock-session/list/index.scss +++ b/ui/packages/consul-lock-sessions/app/components/consul/lock-session/list/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ .consul-lock-session-list ul > li:not(:first-child) { diff --git a/ui/packages/consul-lock-sessions/app/components/consul/lock-session/notifications/index.hbs b/ui/packages/consul-lock-sessions/app/components/consul/lock-session/notifications/index.hbs index 12c1391161b92..5f2847d11f014 100644 --- a/ui/packages/consul-lock-sessions/app/components/consul/lock-session/notifications/index.hbs +++ b/ui/packages/consul-lock-sessions/app/components/consul/lock-session/notifications/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} {{#if (eq @type 'remove')}} diff --git a/ui/packages/consul-lock-sessions/app/templates/dc/nodes/show/sessions.hbs b/ui/packages/consul-lock-sessions/app/templates/dc/nodes/show/sessions.hbs index 61c679aa2f1f9..6f18f84b2885d 100644 --- a/ui/packages/consul-lock-sessions/app/templates/dc/nodes/show/sessions.hbs +++ b/ui/packages/consul-lock-sessions/app/templates/dc/nodes/show/sessions.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} routes({ diff --git a/ui/packages/consul-lock-sessions/vendor/consul-lock-sessions/services.js b/ui/packages/consul-lock-sessions/vendor/consul-lock-sessions/services.js index 1654b41eeea71..74e67ac3a2b82 100644 --- a/ui/packages/consul-lock-sessions/vendor/consul-lock-sessions/services.js +++ b/ui/packages/consul-lock-sessions/vendor/consul-lock-sessions/services.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ (services => services({ diff --git a/ui/packages/consul-nspaces/app/components/consul/nspace/form/index.hbs b/ui/packages/consul-nspaces/app/components/consul/nspace/form/index.hbs index 52b39bd9df59f..6621cf73f8eaf 100644 --- a/ui/packages/consul-nspaces/app/components/consul/nspace/form/index.hbs +++ b/ui/packages/consul-nspaces/app/components/consul/nspace/form/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    diff --git a/ui/packages/consul-nspaces/app/components/consul/nspace/form/index.js b/ui/packages/consul-nspaces/app/components/consul/nspace/form/index.js index df8978572e59b..42fb75ecdbd90 100644 --- a/ui/packages/consul-nspaces/app/components/consul/nspace/form/index.js +++ b/ui/packages/consul-nspaces/app/components/consul/nspace/form/index.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Component from "@glimmer/component"; diff --git a/ui/packages/consul-nspaces/app/components/consul/nspace/list/index.hbs b/ui/packages/consul-nspaces/app/components/consul/nspace/list/index.hbs index b503aefa0efd3..b1677012e108b 100644 --- a/ui/packages/consul-nspaces/app/components/consul/nspace/list/index.hbs +++ b/ui/packages/consul-nspaces/app/components/consul/nspace/list/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} () => { diff --git a/ui/packages/consul-nspaces/app/components/consul/nspace/notifications/index.hbs b/ui/packages/consul-nspaces/app/components/consul/nspace/notifications/index.hbs index 67d44210f2073..4f8269aa52a54 100644 --- a/ui/packages/consul-nspaces/app/components/consul/nspace/notifications/index.hbs +++ b/ui/packages/consul-nspaces/app/components/consul/nspace/notifications/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} {{#if (eq @type 'remove')}} diff --git a/ui/packages/consul-nspaces/app/components/consul/nspace/search-bar/index.hbs b/ui/packages/consul-nspaces/app/components/consul/nspace/search-bar/index.hbs index f438d18dce2a2..49819ebb9b91d 100644 --- a/ui/packages/consul-nspaces/app/components/consul/nspace/search-bar/index.hbs +++ b/ui/packages/consul-nspaces/app/components/consul/nspace/search-bar/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} routes({ diff --git a/ui/packages/consul-nspaces/vendor/consul-nspaces/services.js b/ui/packages/consul-nspaces/vendor/consul-nspaces/services.js index 1654b41eeea71..74e67ac3a2b82 100644 --- a/ui/packages/consul-nspaces/vendor/consul-nspaces/services.js +++ b/ui/packages/consul-nspaces/vendor/consul-nspaces/services.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ (services => services({ diff --git a/ui/packages/consul-partitions/app/components/consul/partition/form/index.hbs b/ui/packages/consul-partitions/app/components/consul/partition/form/index.hbs index 03119b64106dd..b9e16298a014c 100644 --- a/ui/packages/consul-partitions/app/components/consul/partition/form/index.hbs +++ b/ui/packages/consul-partitions/app/components/consul/partition/form/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    ({ diff --git a/ui/packages/consul-partitions/app/components/consul/partition/notifications/index.hbs b/ui/packages/consul-partitions/app/components/consul/partition/notifications/index.hbs index d97ff184f965e..082fcf652cfb7 100644 --- a/ui/packages/consul-partitions/app/components/consul/partition/notifications/index.hbs +++ b/ui/packages/consul-partitions/app/components/consul/partition/notifications/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} {{#if (eq @type 'remove')}} diff --git a/ui/packages/consul-partitions/app/components/consul/partition/search-bar/index.hbs b/ui/packages/consul-partitions/app/components/consul/partition/search-bar/index.hbs index 56fa44084a7b8..77e4d6b27d215 100644 --- a/ui/packages/consul-partitions/app/components/consul/partition/search-bar/index.hbs +++ b/ui/packages/consul-partitions/app/components/consul/partition/search-bar/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} routes({ diff --git a/ui/packages/consul-partitions/vendor/consul-partitions/services.js b/ui/packages/consul-partitions/vendor/consul-partitions/services.js index 1cf59ee066ca7..8c9440bce3cd1 100644 --- a/ui/packages/consul-partitions/vendor/consul-partitions/services.js +++ b/ui/packages/consul-partitions/vendor/consul-partitions/services.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ (services => services({ diff --git a/ui/packages/consul-peerings/app/components/consul/peer/address/list/index.hbs b/ui/packages/consul-peerings/app/components/consul/peer/address/list/index.hbs index aabada41ad101..eccac17174b64 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/address/list/index.hbs +++ b/ui/packages/consul-peerings/app/components/consul/peer/address/list/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} @@ -18,7 +18,7 @@
    {{address}}
    - diff --git a/ui/packages/consul-peerings/app/components/consul/peer/components.scss b/ui/packages/consul-peerings/app/components/consul/peer/components.scss index ad5f5cd296917..1e20d8b236fe6 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/components.scss +++ b/ui/packages/consul-peerings/app/components/consul/peer/components.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %pill-pending::before, diff --git a/ui/packages/consul-peerings/app/components/consul/peer/form/chart.xstate.js b/ui/packages/consul-peerings/app/components/consul/peer/form/chart.xstate.js index 2380c523b4cee..af8a7570225a3 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/form/chart.xstate.js +++ b/ui/packages/consul-peerings/app/components/consul/peer/form/chart.xstate.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ export default { diff --git a/ui/packages/consul-peerings/app/components/consul/peer/form/generate/actions/index.hbs b/ui/packages/consul-peerings/app/components/consul/peer/form/generate/actions/index.hbs index 1c16d1d533dc3..f5f66960bb486 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/form/generate/actions/index.hbs +++ b/ui/packages/consul-peerings/app/components/consul/peer/form/generate/actions/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-peerings/app/components/consul/peer/form/generate/fieldsets/index.js b/ui/packages/consul-peerings/app/components/consul/peer/form/generate/fieldsets/index.js index a037015d1d85d..708b52fd8b114 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/form/generate/fieldsets/index.js +++ b/ui/packages/consul-peerings/app/components/consul/peer/form/generate/fieldsets/index.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Component from '@glimmer/component'; diff --git a/ui/packages/consul-peerings/app/components/consul/peer/form/generate/index.hbs b/ui/packages/consul-peerings/app/components/consul/peer/form/generate/index.hbs index d6493c895c6d0..217818abd2a30 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/form/generate/index.hbs +++ b/ui/packages/consul-peerings/app/components/consul/peer/form/generate/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    diff --git a/ui/packages/consul-peerings/app/components/consul/peer/form/index.hbs b/ui/packages/consul-peerings/app/components/consul/peer/form/index.hbs index 031ffead3ccca..a0e151f2f64e2 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/form/index.hbs +++ b/ui/packages/consul-peerings/app/components/consul/peer/form/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    diff --git a/ui/packages/consul-peerings/app/components/consul/peer/form/index.scss b/ui/packages/consul-peerings/app/components/consul/peer/form/index.scss index 830cced098ae0..bca9acedd661a 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/form/index.scss +++ b/ui/packages/consul-peerings/app/components/consul/peer/form/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ .consul-peer-form { diff --git a/ui/packages/consul-peerings/app/components/consul/peer/form/initiate/actions/index.hbs b/ui/packages/consul-peerings/app/components/consul/peer/form/initiate/actions/index.hbs index f5f4c4864f4b4..2aba71c1a0b00 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/form/initiate/actions/index.hbs +++ b/ui/packages/consul-peerings/app/components/consul/peer/form/initiate/actions/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-peerings/app/components/consul/peer/form/token/actions/index.hbs b/ui/packages/consul-peerings/app/components/consul/peer/form/token/actions/index.hbs index feb85bf4a25ea..b3f455833a4ec 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/form/token/actions/index.hbs +++ b/ui/packages/consul-peerings/app/components/consul/peer/form/token/actions/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
  • Switch to the peer
    - Someone on your team should log into the Datacenter (Community) or Admin Partition (Enterprise) that you want this one to connect with. + Someone on your team should log into the Datacenter (CE) or Admin Partition (Enterprise) that you want this one to connect with.
  • Initiate the peering
    diff --git a/ui/packages/consul-peerings/app/components/consul/peer/index.scss b/ui/packages/consul-peerings/app/components/consul/peer/index.scss index c7e6b20eaf06e..db9d677688a4a 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/index.scss +++ b/ui/packages/consul-peerings/app/components/consul/peer/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ @import './components'; diff --git a/ui/packages/consul-peerings/app/components/consul/peer/list/index.hbs b/ui/packages/consul-peerings/app/components/consul/peer/list/index.hbs index b0d10e1f8a741..a1af71ce11eb4 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/list/index.hbs +++ b/ui/packages/consul-peerings/app/components/consul/peer/list/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-peerings/app/templates/dc/peers/show.hbs b/ui/packages/consul-peerings/app/templates/dc/peers/show.hbs index 843c54adf8ef4..93df6f79c7a14 100644 --- a/ui/packages/consul-peerings/app/templates/dc/peers/show.hbs +++ b/ui/packages/consul-peerings/app/templates/dc/peers/show.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-peerings/app/templates/dc/peers/show/addresses.hbs b/ui/packages/consul-peerings/app/templates/dc/peers/show/addresses.hbs index 5845f97f5456e..a8d46aeee7dd5 100644 --- a/ui/packages/consul-peerings/app/templates/dc/peers/show/addresses.hbs +++ b/ui/packages/consul-peerings/app/templates/dc/peers/show/addresses.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-peerings/app/templates/dc/peers/show/exported.hbs b/ui/packages/consul-peerings/app/templates/dc/peers/show/exported.hbs index 35198bfe8df3b..b25af6128fd6a 100644 --- a/ui/packages/consul-peerings/app/templates/dc/peers/show/exported.hbs +++ b/ui/packages/consul-peerings/app/templates/dc/peers/show/exported.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-peerings/app/templates/dc/peers/show/imported.hbs b/ui/packages/consul-peerings/app/templates/dc/peers/show/imported.hbs index c7d32b3b16dba..05832b1c5480e 100644 --- a/ui/packages/consul-peerings/app/templates/dc/peers/show/imported.hbs +++ b/ui/packages/consul-peerings/app/templates/dc/peers/show/imported.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-peerings/app/templates/dc/peers/show/index.hbs b/ui/packages/consul-peerings/app/templates/dc/peers/show/index.hbs index 9a077304e400a..acdf7641c14aa 100644 --- a/ui/packages/consul-peerings/app/templates/dc/peers/show/index.hbs +++ b/ui/packages/consul-peerings/app/templates/dc/peers/show/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-peerings/vendor/consul-peerings/routes.js b/ui/packages/consul-peerings/vendor/consul-peerings/routes.js index 4ce314ba540db..a8748cec3a3e3 100644 --- a/ui/packages/consul-peerings/vendor/consul-peerings/routes.js +++ b/ui/packages/consul-peerings/vendor/consul-peerings/routes.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ ((routes) => diff --git a/ui/packages/consul-peerings/vendor/consul-peerings/services.js b/ui/packages/consul-peerings/vendor/consul-peerings/services.js index afad1c0e84462..2601489b0bcf5 100644 --- a/ui/packages/consul-peerings/vendor/consul-peerings/services.js +++ b/ui/packages/consul-peerings/vendor/consul-peerings/services.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ (services => services({ diff --git a/ui/packages/consul-ui/.docfy-config.js b/ui/packages/consul-ui/.docfy-config.js index 65bfd7401ff5d..c8308a5854c21 100644 --- a/ui/packages/consul-ui/.docfy-config.js +++ b/ui/packages/consul-ui/.docfy-config.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ const path = require('path'); diff --git a/ui/packages/consul-ui/.eslintrc.js b/ui/packages/consul-ui/.eslintrc.js index 114ea2c2f7d37..c8397263b5eaf 100644 --- a/ui/packages/consul-ui/.eslintrc.js +++ b/ui/packages/consul-ui/.eslintrc.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ module.exports = { diff --git a/ui/packages/consul-ui/.istanbul.yml b/ui/packages/consul-ui/.istanbul.yml index 636bf0e77b0a6..45e59c85a1076 100644 --- a/ui/packages/consul-ui/.istanbul.yml +++ b/ui/packages/consul-ui/.istanbul.yml @@ -1,5 +1,5 @@ # Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 +# SPDX-License-Identifier: MPL-2.0 instrumentation: excludes: [ diff --git a/ui/packages/consul-ui/.prettierrc.js b/ui/packages/consul-ui/.prettierrc.js index 4833e3531de51..cd0cb10db33aa 100644 --- a/ui/packages/consul-ui/.prettierrc.js +++ b/ui/packages/consul-ui/.prettierrc.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ 'use strict'; diff --git a/ui/packages/consul-ui/.template-lintrc.js b/ui/packages/consul-ui/.template-lintrc.js index 868e880ed35a8..2acbc36ee99fb 100644 --- a/ui/packages/consul-ui/.template-lintrc.js +++ b/ui/packages/consul-ui/.template-lintrc.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ 'use strict'; diff --git a/ui/packages/consul-ui/README.md b/ui/packages/consul-ui/README.md index cb4615bee9376..a54c4e2603a48 100644 --- a/ui/packages/consul-ui/README.md +++ b/ui/packages/consul-ui/README.md @@ -112,7 +112,7 @@ See [./docs/index.mdx](./docs/index.mdx#environment-variables) We follow a `ui/**/**` branch naming pattern. This branch naming pattern allows front-end focused builds, such as FE tests, to run automatically in Pull Requests. Please note this only works if you are a member of the HashiCorp -GitHub Org. If you are an external contributor, these tests won't run and will +GitHub Org. If you are an external contributor these tests won't run and will instead be run by a member of our team during review. Examples: diff --git a/ui/packages/consul-ui/app/abilities/acl.js b/ui/packages/consul-ui/app/abilities/acl.js index 32701965184f5..c8667d6e72d01 100644 --- a/ui/packages/consul-ui/app/abilities/acl.js +++ b/ui/packages/consul-ui/app/abilities/acl.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/auth-method.js b/ui/packages/consul-ui/app/abilities/auth-method.js index de92c39c259dd..92e805cc7d262 100644 --- a/ui/packages/consul-ui/app/abilities/auth-method.js +++ b/ui/packages/consul-ui/app/abilities/auth-method.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/base.js b/ui/packages/consul-ui/app/abilities/base.js index c2f58ab7b4851..663b107d63926 100644 --- a/ui/packages/consul-ui/app/abilities/base.js +++ b/ui/packages/consul-ui/app/abilities/base.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import { inject as service } from '@ember/service'; diff --git a/ui/packages/consul-ui/app/abilities/intention.js b/ui/packages/consul-ui/app/abilities/intention.js index 27c7dc50c3e73..0ae68551b9227 100644 --- a/ui/packages/consul-ui/app/abilities/intention.js +++ b/ui/packages/consul-ui/app/abilities/intention.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/kv.js b/ui/packages/consul-ui/app/abilities/kv.js index bfcaca43fd9a2..7b32d1b4d9ca0 100644 --- a/ui/packages/consul-ui/app/abilities/kv.js +++ b/ui/packages/consul-ui/app/abilities/kv.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility, { ACCESS_LIST } from './base'; diff --git a/ui/packages/consul-ui/app/abilities/license.js b/ui/packages/consul-ui/app/abilities/license.js index 82affe7cff2c5..a1cd4f96982a4 100644 --- a/ui/packages/consul-ui/app/abilities/license.js +++ b/ui/packages/consul-ui/app/abilities/license.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/node.js b/ui/packages/consul-ui/app/abilities/node.js index 51b92aa131f2c..aaf63243d52f9 100644 --- a/ui/packages/consul-ui/app/abilities/node.js +++ b/ui/packages/consul-ui/app/abilities/node.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/nspace.js b/ui/packages/consul-ui/app/abilities/nspace.js index 994b51f41de32..b561700b18db2 100644 --- a/ui/packages/consul-ui/app/abilities/nspace.js +++ b/ui/packages/consul-ui/app/abilities/nspace.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/overview.js b/ui/packages/consul-ui/app/abilities/overview.js index 4381ecf537aef..cbd6ecd8606a0 100644 --- a/ui/packages/consul-ui/app/abilities/overview.js +++ b/ui/packages/consul-ui/app/abilities/overview.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/partition.js b/ui/packages/consul-ui/app/abilities/partition.js index b884e058498a3..3dade71b77148 100644 --- a/ui/packages/consul-ui/app/abilities/partition.js +++ b/ui/packages/consul-ui/app/abilities/partition.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from 'consul-ui/abilities/base'; diff --git a/ui/packages/consul-ui/app/abilities/peer.js b/ui/packages/consul-ui/app/abilities/peer.js index 7a52ed4300919..b564c731d5b60 100644 --- a/ui/packages/consul-ui/app/abilities/peer.js +++ b/ui/packages/consul-ui/app/abilities/peer.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from 'consul-ui/abilities/base'; diff --git a/ui/packages/consul-ui/app/abilities/permission.js b/ui/packages/consul-ui/app/abilities/permission.js index 41b2e5a7076ff..8856b4c1bc195 100644 --- a/ui/packages/consul-ui/app/abilities/permission.js +++ b/ui/packages/consul-ui/app/abilities/permission.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/policy.js b/ui/packages/consul-ui/app/abilities/policy.js index b8d274f7b6fa5..c4add1ce8bac5 100644 --- a/ui/packages/consul-ui/app/abilities/policy.js +++ b/ui/packages/consul-ui/app/abilities/policy.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/role.js b/ui/packages/consul-ui/app/abilities/role.js index 457fb1bea9cc5..19ab731169ac1 100644 --- a/ui/packages/consul-ui/app/abilities/role.js +++ b/ui/packages/consul-ui/app/abilities/role.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/server.js b/ui/packages/consul-ui/app/abilities/server.js index b6acef100cc7d..55cee3bbd04c5 100644 --- a/ui/packages/consul-ui/app/abilities/server.js +++ b/ui/packages/consul-ui/app/abilities/server.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/service-instance.js b/ui/packages/consul-ui/app/abilities/service-instance.js index 2f00b9857fcbf..e424bb608f744 100644 --- a/ui/packages/consul-ui/app/abilities/service-instance.js +++ b/ui/packages/consul-ui/app/abilities/service-instance.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility, { ACCESS_READ, ACCESS_WRITE } from './base'; diff --git a/ui/packages/consul-ui/app/abilities/session.js b/ui/packages/consul-ui/app/abilities/session.js index dd505eea2d06b..6a9554ae902b2 100644 --- a/ui/packages/consul-ui/app/abilities/session.js +++ b/ui/packages/consul-ui/app/abilities/session.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/token.js b/ui/packages/consul-ui/app/abilities/token.js index e8880daf6c439..d09692e42f5fb 100644 --- a/ui/packages/consul-ui/app/abilities/token.js +++ b/ui/packages/consul-ui/app/abilities/token.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/upstream.js b/ui/packages/consul-ui/app/abilities/upstream.js index 55cf1d0d0ebc8..d8e5090b505c0 100644 --- a/ui/packages/consul-ui/app/abilities/upstream.js +++ b/ui/packages/consul-ui/app/abilities/upstream.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/zervice.js b/ui/packages/consul-ui/app/abilities/zervice.js index 0fadbcb7c6e7a..0b143c5b8fbc8 100644 --- a/ui/packages/consul-ui/app/abilities/zervice.js +++ b/ui/packages/consul-ui/app/abilities/zervice.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/abilities/zone.js b/ui/packages/consul-ui/app/abilities/zone.js index 3f141319f9117..18a1bf4d71b99 100644 --- a/ui/packages/consul-ui/app/abilities/zone.js +++ b/ui/packages/consul-ui/app/abilities/zone.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import BaseAbility from './base'; diff --git a/ui/packages/consul-ui/app/adapters/application.js b/ui/packages/consul-ui/app/adapters/application.js index d0010c784b3aa..1154b24732786 100644 --- a/ui/packages/consul-ui/app/adapters/application.js +++ b/ui/packages/consul-ui/app/adapters/application.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './http'; diff --git a/ui/packages/consul-ui/app/adapters/auth-method.js b/ui/packages/consul-ui/app/adapters/auth-method.js index 97153a3fcbe8f..6d3fbfeb2bf81 100644 --- a/ui/packages/consul-ui/app/adapters/auth-method.js +++ b/ui/packages/consul-ui/app/adapters/auth-method.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/binding-rule.js b/ui/packages/consul-ui/app/adapters/binding-rule.js index 49029ce7a7240..026674c7584c0 100644 --- a/ui/packages/consul-ui/app/adapters/binding-rule.js +++ b/ui/packages/consul-ui/app/adapters/binding-rule.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/coordinate.js b/ui/packages/consul-ui/app/adapters/coordinate.js index fc5eba788cc73..a7a0b286c862e 100644 --- a/ui/packages/consul-ui/app/adapters/coordinate.js +++ b/ui/packages/consul-ui/app/adapters/coordinate.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/discovery-chain.js b/ui/packages/consul-ui/app/adapters/discovery-chain.js index 6ce0020c6e85a..37879323b20c9 100644 --- a/ui/packages/consul-ui/app/adapters/discovery-chain.js +++ b/ui/packages/consul-ui/app/adapters/discovery-chain.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/http.js b/ui/packages/consul-ui/app/adapters/http.js index 5e9acc62fec87..89b7f11da4b7a 100644 --- a/ui/packages/consul-ui/app/adapters/http.js +++ b/ui/packages/consul-ui/app/adapters/http.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import { inject as service } from '@ember/service'; diff --git a/ui/packages/consul-ui/app/adapters/intention.js b/ui/packages/consul-ui/app/adapters/intention.js index b47d179b84462..3ea6925470ae2 100644 --- a/ui/packages/consul-ui/app/adapters/intention.js +++ b/ui/packages/consul-ui/app/adapters/intention.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/kv.js b/ui/packages/consul-ui/app/adapters/kv.js index bb29fff4d9698..e512723702e52 100644 --- a/ui/packages/consul-ui/app/adapters/kv.js +++ b/ui/packages/consul-ui/app/adapters/kv.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/node.js b/ui/packages/consul-ui/app/adapters/node.js index 5ac1a936005a6..be0799a10d6d9 100644 --- a/ui/packages/consul-ui/app/adapters/node.js +++ b/ui/packages/consul-ui/app/adapters/node.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/nspace.js b/ui/packages/consul-ui/app/adapters/nspace.js index 6e9f27dde0a72..3636a363c6551 100644 --- a/ui/packages/consul-ui/app/adapters/nspace.js +++ b/ui/packages/consul-ui/app/adapters/nspace.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/oidc-provider.js b/ui/packages/consul-ui/app/adapters/oidc-provider.js index 6fafe51a85695..c758a49dcd0ac 100644 --- a/ui/packages/consul-ui/app/adapters/oidc-provider.js +++ b/ui/packages/consul-ui/app/adapters/oidc-provider.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/partition.js b/ui/packages/consul-ui/app/adapters/partition.js index b2ec2178de14c..4ba23078afb6f 100644 --- a/ui/packages/consul-ui/app/adapters/partition.js +++ b/ui/packages/consul-ui/app/adapters/partition.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/permission.js b/ui/packages/consul-ui/app/adapters/permission.js index 806ed5a3c3043..23b5a2725075c 100644 --- a/ui/packages/consul-ui/app/adapters/permission.js +++ b/ui/packages/consul-ui/app/adapters/permission.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/policy.js b/ui/packages/consul-ui/app/adapters/policy.js index 6c959df2d8a4d..9d1415f3a3499 100644 --- a/ui/packages/consul-ui/app/adapters/policy.js +++ b/ui/packages/consul-ui/app/adapters/policy.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/proxy.js b/ui/packages/consul-ui/app/adapters/proxy.js index 6f37be6540119..782c9e1b7db95 100644 --- a/ui/packages/consul-ui/app/adapters/proxy.js +++ b/ui/packages/consul-ui/app/adapters/proxy.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/role.js b/ui/packages/consul-ui/app/adapters/role.js index 8773fddeac174..a64d3db366d26 100644 --- a/ui/packages/consul-ui/app/adapters/role.js +++ b/ui/packages/consul-ui/app/adapters/role.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/service-instance.js b/ui/packages/consul-ui/app/adapters/service-instance.js index e61efc8188032..d02295d898de8 100644 --- a/ui/packages/consul-ui/app/adapters/service-instance.js +++ b/ui/packages/consul-ui/app/adapters/service-instance.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/service.js b/ui/packages/consul-ui/app/adapters/service.js index c8e6adf82698e..c3acb927e0ddc 100644 --- a/ui/packages/consul-ui/app/adapters/service.js +++ b/ui/packages/consul-ui/app/adapters/service.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/session.js b/ui/packages/consul-ui/app/adapters/session.js index 3f42ac4bb97c7..c0c2c5437c8a5 100644 --- a/ui/packages/consul-ui/app/adapters/session.js +++ b/ui/packages/consul-ui/app/adapters/session.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/token.js b/ui/packages/consul-ui/app/adapters/token.js index 7e8e46dacb1b3..555b334e5e5b7 100644 --- a/ui/packages/consul-ui/app/adapters/token.js +++ b/ui/packages/consul-ui/app/adapters/token.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/adapters/topology.js b/ui/packages/consul-ui/app/adapters/topology.js index 8ed49fea40fd7..b12ffc3f9dbf3 100644 --- a/ui/packages/consul-ui/app/adapters/topology.js +++ b/ui/packages/consul-ui/app/adapters/topology.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Adapter from './application'; diff --git a/ui/packages/consul-ui/app/app.js b/ui/packages/consul-ui/app/app.js index 43db29bdd35e5..de6711919bb83 100644 --- a/ui/packages/consul-ui/app/app.js +++ b/ui/packages/consul-ui/app/app.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Application from '@ember/application'; diff --git a/ui/packages/consul-ui/app/components/action/index.hbs b/ui/packages/consul-ui/app/components/action/index.hbs index ad405278bfc7e..97119fdd477a2 100644 --- a/ui/packages/consul-ui/app/components/action/index.hbs +++ b/ui/packages/consul-ui/app/components/action/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} {{#if @for~}} diff --git a/ui/packages/consul-ui/app/components/anchors/index.scss b/ui/packages/consul-ui/app/components/anchors/index.scss index 0de89716dbe15..9fe7e5079d42f 100644 --- a/ui/packages/consul-ui/app/components/anchors/index.scss +++ b/ui/packages/consul-ui/app/components/anchors/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ @import './skin'; diff --git a/ui/packages/consul-ui/app/components/anchors/skin.scss b/ui/packages/consul-ui/app/components/anchors/skin.scss index 53fb0d94617ab..a34e5becc9e44 100644 --- a/ui/packages/consul-ui/app/components/anchors/skin.scss +++ b/ui/packages/consul-ui/app/components/anchors/skin.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %anchor-decoration, diff --git a/ui/packages/consul-ui/app/components/anonymous/index.hbs b/ui/packages/consul-ui/app/components/anonymous/index.hbs index 8709fc4b8b770..0566ddf99b461 100644 --- a/ui/packages/consul-ui/app/components/anonymous/index.hbs +++ b/ui/packages/consul-ui/app/components/anonymous/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} {{yield}} \ No newline at end of file diff --git a/ui/packages/consul-ui/app/components/anonymous/index.js b/ui/packages/consul-ui/app/components/anonymous/index.js index d99599ac30397..8f027b69f0e03 100644 --- a/ui/packages/consul-ui/app/components/anonymous/index.js +++ b/ui/packages/consul-ui/app/components/anonymous/index.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Component from '@ember/component'; diff --git a/ui/packages/consul-ui/app/components/app-error/index.hbs b/ui/packages/consul-ui/app/components/app-error/index.hbs index ca65502f59392..0c087cdd4d979 100644 --- a/ui/packages/consul-ui/app/components/app-error/index.hbs +++ b/ui/packages/consul-ui/app/components/app-error/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-ui/app/components/app-view/index.hbs b/ui/packages/consul-ui/app/components/app-view/index.hbs index 3b6ebb26e1383..53cf7113b247a 100644 --- a/ui/packages/consul-ui/app/components/app-view/index.hbs +++ b/ui/packages/consul-ui/app/components/app-view/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    diff --git a/ui/packages/consul-ui/app/components/auth-form/index.js b/ui/packages/consul-ui/app/components/auth-form/index.js index 0cd05cc4c29b2..4c861ad527cb0 100644 --- a/ui/packages/consul-ui/app/components/auth-form/index.js +++ b/ui/packages/consul-ui/app/components/auth-form/index.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Component from '@glimmer/component'; diff --git a/ui/packages/consul-ui/app/components/auth-form/index.scss b/ui/packages/consul-ui/app/components/auth-form/index.scss index 1a5c5afff9884..49051008b08db 100644 --- a/ui/packages/consul-ui/app/components/auth-form/index.scss +++ b/ui/packages/consul-ui/app/components/auth-form/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ @import './skin'; diff --git a/ui/packages/consul-ui/app/components/auth-form/layout.scss b/ui/packages/consul-ui/app/components/auth-form/layout.scss index 60ea16642b5a0..2889b700d09d3 100644 --- a/ui/packages/consul-ui/app/components/auth-form/layout.scss +++ b/ui/packages/consul-ui/app/components/auth-form/layout.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %auth-form { diff --git a/ui/packages/consul-ui/app/components/auth-form/pageobject.js b/ui/packages/consul-ui/app/components/auth-form/pageobject.js index f3812d638f900..3ad553f2ad10d 100644 --- a/ui/packages/consul-ui/app/components/auth-form/pageobject.js +++ b/ui/packages/consul-ui/app/components/auth-form/pageobject.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ export default (submitable, clickable, attribute) => diff --git a/ui/packages/consul-ui/app/components/auth-form/skin.scss b/ui/packages/consul-ui/app/components/auth-form/skin.scss index 341c0928fc8c8..18ff35fead26d 100644 --- a/ui/packages/consul-ui/app/components/auth-form/skin.scss +++ b/ui/packages/consul-ui/app/components/auth-form/skin.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %auth-form em { diff --git a/ui/packages/consul-ui/app/components/auth-form/tabs.xstate.js b/ui/packages/consul-ui/app/components/auth-form/tabs.xstate.js index e25cc0d3e7196..c0fcf889a92c8 100644 --- a/ui/packages/consul-ui/app/components/auth-form/tabs.xstate.js +++ b/ui/packages/consul-ui/app/components/auth-form/tabs.xstate.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ export default { diff --git a/ui/packages/consul-ui/app/components/auth-modal/index.scss b/ui/packages/consul-ui/app/components/auth-modal/index.scss index 24f3ba363a488..c9d0eac524602 100644 --- a/ui/packages/consul-ui/app/components/auth-modal/index.scss +++ b/ui/packages/consul-ui/app/components/auth-modal/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ /*TODO: This is a different style of modal dialog */ diff --git a/ui/packages/consul-ui/app/components/auth-modal/layout.scss b/ui/packages/consul-ui/app/components/auth-modal/layout.scss index 0f38371bbaa28..dcdcede010720 100644 --- a/ui/packages/consul-ui/app/components/auth-modal/layout.scss +++ b/ui/packages/consul-ui/app/components/auth-modal/layout.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %auth-modal footer { diff --git a/ui/packages/consul-ui/app/components/auth-modal/skin.scss b/ui/packages/consul-ui/app/components/auth-modal/skin.scss index ac930a2dd6193..b88fad1e54c60 100644 --- a/ui/packages/consul-ui/app/components/auth-modal/skin.scss +++ b/ui/packages/consul-ui/app/components/auth-modal/skin.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %auth-modal footer button::after { diff --git a/ui/packages/consul-ui/app/components/auth-profile/index.hbs b/ui/packages/consul-ui/app/components/auth-profile/index.hbs index 324a657bbe433..3a7f4e5256b6d 100644 --- a/ui/packages/consul-ui/app/components/auth-profile/index.hbs +++ b/ui/packages/consul-ui/app/components/auth-profile/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    @@ -23,7 +23,7 @@ {{mode.name}}
    - diff --git a/ui/packages/consul-ui/app/components/code-editor/index.js b/ui/packages/consul-ui/app/components/code-editor/index.js index 65566d159b763..52203ac22a0e8 100644 --- a/ui/packages/consul-ui/app/components/code-editor/index.js +++ b/ui/packages/consul-ui/app/components/code-editor/index.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Component from '@ember/component'; @@ -36,24 +36,22 @@ export default Component.extend({ } }, setMode: function (mode) { - if (!this.isDestroying && !this.isDestroyed) { - let options = { - ...DEFAULTS, - mode: mode.mime, - readOnly: this.readonly, - }; - if (mode.name === 'XML') { - options.htmlMode = mode.htmlMode; - options.matchClosing = mode.matchClosing; - options.alignCDATA = mode.alignCDATA; - } - set(this, 'options', options); - - const editor = this.editor; - editor.setOption('mode', mode.mime); - this.helper.lint(editor, mode.mode); - set(this, 'mode', mode); + let options = { + ...DEFAULTS, + mode: mode.mime, + readOnly: this.readonly, + }; + if (mode.name === 'XML') { + options.htmlMode = mode.htmlMode; + options.matchClosing = mode.matchClosing; + options.alignCDATA = mode.alignCDATA; } + set(this, 'options', options); + + const editor = this.editor; + editor.setOption('mode', mode.mime); + this.helper.lint(editor, mode.mode); + set(this, 'mode', mode); }, willDestroyElement: function () { this._super(...arguments); diff --git a/ui/packages/consul-ui/app/components/code-editor/index.scss b/ui/packages/consul-ui/app/components/code-editor/index.scss index 58c7c66596cc4..559533e42a849 100644 --- a/ui/packages/consul-ui/app/components/code-editor/index.scss +++ b/ui/packages/consul-ui/app/components/code-editor/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ @import './skin'; diff --git a/ui/packages/consul-ui/app/components/code-editor/layout.scss b/ui/packages/consul-ui/app/components/code-editor/layout.scss index b8194d850bc94..285fda57a35f6 100644 --- a/ui/packages/consul-ui/app/components/code-editor/layout.scss +++ b/ui/packages/consul-ui/app/components/code-editor/layout.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %code-editor { diff --git a/ui/packages/consul-ui/app/components/code-editor/skin.scss b/ui/packages/consul-ui/app/components/code-editor/skin.scss index 0a8dafc65dde5..db0f52bc0d297 100644 --- a/ui/packages/consul-ui/app/components/code-editor/skin.scss +++ b/ui/packages/consul-ui/app/components/code-editor/skin.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ $syntax-consul: #69499a; diff --git a/ui/packages/consul-ui/app/components/composite-row/index.scss b/ui/packages/consul-ui/app/components/composite-row/index.scss index e9db145da19d9..255a2a67c6ca6 100644 --- a/ui/packages/consul-ui/app/components/composite-row/index.scss +++ b/ui/packages/consul-ui/app/components/composite-row/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ @import './layout'; diff --git a/ui/packages/consul-ui/app/components/composite-row/layout.scss b/ui/packages/consul-ui/app/components/composite-row/layout.scss index 819c41f9504f0..dfc3860b501fc 100644 --- a/ui/packages/consul-ui/app/components/composite-row/layout.scss +++ b/ui/packages/consul-ui/app/components/composite-row/layout.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %composite-row { diff --git a/ui/packages/consul-ui/app/components/confirmation-alert/index.hbs b/ui/packages/consul-ui/app/components/confirmation-alert/index.hbs index 95f243a89233e..cf5a0c403c674 100644 --- a/ui/packages/consul-ui/app/components/confirmation-alert/index.hbs +++ b/ui/packages/consul-ui/app/components/confirmation-alert/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} {{yield}} diff --git a/ui/packages/consul-ui/app/components/confirmation-alert/index.js b/ui/packages/consul-ui/app/components/confirmation-alert/index.js index d99599ac30397..8f027b69f0e03 100644 --- a/ui/packages/consul-ui/app/components/confirmation-alert/index.js +++ b/ui/packages/consul-ui/app/components/confirmation-alert/index.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Component from '@ember/component'; diff --git a/ui/packages/consul-ui/app/components/confirmation-dialog/index.hbs b/ui/packages/consul-ui/app/components/confirmation-dialog/index.hbs index da4c7660efbf4..07826204afe45 100644 --- a/ui/packages/consul-ui/app/components/confirmation-dialog/index.hbs +++ b/ui/packages/consul-ui/app/components/confirmation-dialog/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    diff --git a/ui/packages/consul-ui/app/components/confirmation-dialog/index.js b/ui/packages/consul-ui/app/components/confirmation-dialog/index.js index e10782f579d44..b60850d50a264 100644 --- a/ui/packages/consul-ui/app/components/confirmation-dialog/index.js +++ b/ui/packages/consul-ui/app/components/confirmation-dialog/index.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ /*eslint ember/closure-actions: "warn"*/ diff --git a/ui/packages/consul-ui/app/components/confirmation-dialog/index.scss b/ui/packages/consul-ui/app/components/confirmation-dialog/index.scss index 65914fb025766..67ae530a98eaa 100644 --- a/ui/packages/consul-ui/app/components/confirmation-dialog/index.scss +++ b/ui/packages/consul-ui/app/components/confirmation-dialog/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ @import './skin'; diff --git a/ui/packages/consul-ui/app/components/confirmation-dialog/layout.scss b/ui/packages/consul-ui/app/components/confirmation-dialog/layout.scss index 9538794833b1a..82773a342339e 100644 --- a/ui/packages/consul-ui/app/components/confirmation-dialog/layout.scss +++ b/ui/packages/consul-ui/app/components/confirmation-dialog/layout.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %confirmation-dialog { diff --git a/ui/packages/consul-ui/app/components/confirmation-dialog/skin.scss b/ui/packages/consul-ui/app/components/confirmation-dialog/skin.scss index 4509c4b3fdc52..248c7c9950e7d 100644 --- a/ui/packages/consul-ui/app/components/confirmation-dialog/skin.scss +++ b/ui/packages/consul-ui/app/components/confirmation-dialog/skin.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ table div.with-confirmation.confirming { diff --git a/ui/packages/consul-ui/app/components/consul/acl/disabled/index.hbs b/ui/packages/consul-ui/app/components/consul/acl/disabled/index.hbs index 23e6271820d2f..77e8dba8fecc1 100644 --- a/ui/packages/consul-ui/app/components/consul/acl/disabled/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/acl/disabled/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-ui/app/components/consul/auth-method/binding-list/index.hbs b/ui/packages/consul-ui/app/components/consul/auth-method/binding-list/index.hbs index 44e351e452844..d0ab9b8ae62a1 100644 --- a/ui/packages/consul-ui/app/components/consul/auth-method/binding-list/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/auth-method/binding-list/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    diff --git a/ui/packages/consul-ui/app/components/consul/auth-method/index.scss b/ui/packages/consul-ui/app/components/consul/auth-method/index.scss index 7e6ffe2de8c03..266174687f49a 100644 --- a/ui/packages/consul-ui/app/components/consul/auth-method/index.scss +++ b/ui/packages/consul-ui/app/components/consul/auth-method/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ // List diff --git a/ui/packages/consul-ui/app/components/consul/auth-method/list/index.hbs b/ui/packages/consul-ui/app/components/consul/auth-method/list/index.hbs index 160e38bd9ce5c..2f15936b42cfb 100644 --- a/ui/packages/consul-ui/app/components/consul/auth-method/list/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/auth-method/list/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} () => { diff --git a/ui/packages/consul-ui/app/components/consul/auth-method/nspace-list/index.hbs b/ui/packages/consul-ui/app/components/consul/auth-method/nspace-list/index.hbs index cb617ad0660f2..ec47712ec380a 100644 --- a/ui/packages/consul-ui/app/components/consul/auth-method/nspace-list/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/auth-method/nspace-list/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    diff --git a/ui/packages/consul-ui/app/components/consul/auth-method/search-bar/index.hbs b/ui/packages/consul-ui/app/components/consul/auth-method/search-bar/index.hbs index 63e9f11be2f68..5a0a5949a571e 100644 --- a/ui/packages/consul-ui/app/components/consul/auth-method/search-bar/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/auth-method/search-bar/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} diff --git a/ui/packages/consul-ui/app/components/consul/auth-method/type/index.hbs b/ui/packages/consul-ui/app/components/consul/auth-method/type/index.hbs index a21db4f39264a..b28adf8460540 100644 --- a/ui/packages/consul-ui/app/components/consul/auth-method/type/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/auth-method/type/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} {{#let (icon-mapping @item.Type) as |flightIcon|}} diff --git a/ui/packages/consul-ui/app/components/consul/auth-method/view/index.hbs b/ui/packages/consul-ui/app/components/consul/auth-method/view/index.hbs index eab0fa48399c2..00b0169679fc6 100644 --- a/ui/packages/consul-ui/app/components/consul/auth-method/view/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/auth-method/view/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
    diff --git a/ui/packages/consul-ui/app/components/consul/bucket/list/index.hbs b/ui/packages/consul-ui/app/components/consul/bucket/list/index.hbs index 21d598d64ff5f..0c82141ca5b07 100644 --- a/ui/packages/consul-ui/app/components/consul/bucket/list/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/bucket/list/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }} {{#if this.itemsToDisplay.length}} diff --git a/ui/packages/consul-ui/app/components/consul/bucket/list/index.js b/ui/packages/consul-ui/app/components/consul/bucket/list/index.js index 0268cb6d22efd..387d04f1721f4 100644 --- a/ui/packages/consul-ui/app/components/consul/bucket/list/index.js +++ b/ui/packages/consul-ui/app/components/consul/bucket/list/index.js @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ import Component from '@glimmer/component'; diff --git a/ui/packages/consul-ui/app/components/consul/bucket/list/index.scss b/ui/packages/consul-ui/app/components/consul/bucket/list/index.scss index 996323841f587..710f6a3593bf4 100644 --- a/ui/packages/consul-ui/app/components/consul/bucket/list/index.scss +++ b/ui/packages/consul-ui/app/components/consul/bucket/list/index.scss @@ -1,6 +1,6 @@ /** * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 + * SPDX-License-Identifier: MPL-2.0 */ %consul-bucket-list { diff --git a/ui/packages/consul-ui/app/components/consul/datacenter/selector/index.hbs b/ui/packages/consul-ui/app/components/consul/datacenter/selector/index.hbs index 767422e4b9b13..ecc4f51f1a6b1 100644 --- a/ui/packages/consul-ui/app/components/consul/datacenter/selector/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/datacenter/selector/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}
  • diff --git a/ui/packages/consul-ui/app/components/consul/discovery-chain/index.hbs b/ui/packages/consul-ui/app/components/consul/discovery-chain/index.hbs index e25096f849cd2..59d5846061744 100644 --- a/ui/packages/consul-ui/app/components/consul/discovery-chain/index.hbs +++ b/ui/packages/consul-ui/app/components/consul/discovery-chain/index.hbs @@ -1,6 +1,6 @@ {{! Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 + SPDX-License-Identifier: MPL-2.0 }}